Page MenuHomec4science

No OneTemporary

File Metadata

Created
Tue, Mar 11, 06:25
This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/INSTALL b/INSTALL
index eb122c144..a6fcfad30 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,620 +1,624 @@
CERN DOCUMENT SERVER SOFTWARE (CDSware) INSTALLATION
====================================================
Revision: $Id$
About
=====
This document specifies how to build, customize, and install the CERN
Document Server Software (CDSware) for the first time. See
RELEASE-NOTES if you are upgrading from a previous CDSware release.
Contents
========
0. Prerequisites
1. Quick instructions for the impatient CDSware admin
2. Detailed instructions for the patient CDSware admin
3. Configuration philosophy explained and elucidated
0. Prerequisites
================
Here is the software you need to have around before you
start installing CDSware:
a) Unix-like operating system. The main development and
production platform for CDSware at CERN is Debian GNU/Linux,
but any Unix system supporting the software listed below
should do. Note that localhost should have an MTA running
so that CDSware can email notification alerts or registration
information to the end users, contact moderators and
reviewers of submitted documents, inform administrators about
various runtime system information, etc.
b) MySQL server (may be on a remote machine), and MySQL client
(must be available locally too). MySQL versions 4.0.x are
recommended, versions above 4.1.0 may cause troubles.
Please set the variable ``max_allowed_packet'' in your
``my.cnf'' init file to at least 4M.
<http://mysql.com/>
c) Apache 2 server, with support for loading DSO modules.
Tested mainly with version 2.0.43 and above. Apache 2 is
required for the mod_python module (see below).
<http://httpd.apache.org/>
Note for FreeBSD users: Thierry Thomas <thierry@FreeBSD.org>
reports troubles with Python open() in the Apache 2 and
mod_python context. The solution is either (1) to compile
Apache 2 with --enable-threads (the port has a knob
WITH_THREADS to do that); or (2) to add the two following two
lines in Apache's envvars file:
LD_PRELOAD=/usr/lib/libc_r.so # or libpthread.so
export LD_PRELOAD
d) Python v2.2.2 or above (v2.3.2 and above recommended):
<http://python.org/>
as well as the following Python modules:
- (mandatory) MySQLdb:
<http://sourceforge.net/projects/mysql-python>
- (mandatory) Numeric module (v21 and above):
<http://sourceforge.net/projects/numpy>
- (recommended) PyStemmer, for indexing and ranking:
<http://sourceforge.net/projects/pystemmer/>
- (recommended) PyRXP, for very fast XML MARC processing:
<http://www.reportlab.org/pyrxp.html>
- (recommended) Gnuplot.Py, for producing graphs:
<http://gnuplot-py.sourceforge.net/>
- (optional) 4suite, slower alternative to PyRXP:
<http://4suite.org/>
- (optional) Psyco, to speed up the code at places:
<http://psyco.sourceforge.net/>
- (optional) RDFLib, to use RDF ontologies and thesauri:
<http://rdflib.net/>
e) mod_python Apache module. Tested mainly with versions
3.0BETA4 and above. mod_python 3.x is required for Apache 2.
Previous versions (as well as Apache 1 ones) exhibited some
problems with MySQL connectivity in our experience.
<http://www.modpython.org/>
f) PHP compiled as Apache module, including MySQL support.
Tested mainly with PHP version 4.3.0 and above. (Note that if
you are compiling mod_php from source, it is good to compile
it against the same MySQL client library as mod_python, so
that the two Apache modules are using the same MySQL client
library. We saw Apache/PHP/Python problems in the past when
- they weren't.)
+ they weren't. A care should be taken even when you are using
+ precompiled packages. For example, on Ubuntu 5.10 "Breezy
+ Badger" it seems that python2.4-mysqldb depends on
+ libmysqlclient14, while php5-mysql on libmysqlclient12, which
+ leads to Apache segmentation faults.)
<http://www.php.net/>
g) PHP compiled as a standalone command-line executable (CLI)
(in addition to Apache module) is required, too. As of PHP
4.3.0 you'll obtain the CLI executable by default, so you
don't have to compile it separately. Note that PHP CLI should
be compiled with the process control support (--enable-pcntl)
and the compression library (--with-zlib).
<http://www.php.net/manual/en/install.commandline.php>
<http://www.php.net/manual/en/ref.pcntl.php>
h) WML - Website META Language. Tested mainly with versions
2.0.8 and 2.0.9. Note that on Red Hat Linux 9 the WML 2.0.9
compiled with Perl 5.8.0 exhibits problems, so you better use
downgraded/upgraded Perl for compiling WML on that platform.
<http://www.engelschall.com/sw/wml/>
i) If you want to be able to extract references from PDF fulltext
files, then you need to install pdftotext version 3 at least.
<http://www.foolabs.com/xpdf/home.html>
j) If you want to be able to search for words in the fulltext files
(i.e. to have fulltext indexing), then you need as well to install
some of the following tools:
- for PDF files: pdftotext or pstotext
<http://www.foolabs.com/xpdf/home.html>
<http://www.cs.wisc.edu/~ghost/doc/AFPL/>
- for PostScript files: pstotext or ps2ascii
<http://www.cs.wisc.edu/~ghost/doc/AFPL/>
- for MS Word files: antiword, catdoc, or wvText
<http://www.winfield.demon.nl/index.html>
<http://www.ice.ru/~vitus/catdoc/index.html>
<http://sourceforge.net/projects/wvware>
- for MS PowerPoint files: pptHtml and html2text
<http://www.xlhtml.org/>
<http://userpage.fu-berlin.de/~mbayer/tools/html2text.html>
- for MS Excel files: xlhtml and html2text
<http://chicago.sourceforge.net/xlhtml/>
<http://userpage.fu-berlin.de/~mbayer/tools/html2text.html>
k) If you have chosen to install fast XML MARC Python processors
in the step d) above, then you have to install the parsers
themselves:
- (optional) RXP:
<http://www.cogsci.ed.ac.uk/~richard/rxp.html>
- (optional) 4suite:
<http://4suite.org/>
l) (recommended) Gnuplot, the command-line driven interactive
plotting program. It is used to display download and citation
history graphs on the Detailed record pages on the web
interface. Note that Gnuplot is not required, only
recommended.
<http://www.gnuplot.info/>
m) (recommended) A Common Lisp implementation, such as CLISP,
SBCL or CMUCL. It is used for the web server log analysing
tool and the metadata checking program. Note that any of the
three implementations CLISP, SBCL, or CMUCL will do. CMUCL
produces fastest machine code, but it does not support UTF-8
yet. Pick up CLISP if you don't know what to do. Note that a
Common Lisp implementation is not required, only recommended.
<http://clisp.cons.org/>
<http://www.cons.org/cmucl/>
<http://sbcl.sourceforge.net/>
n) GNU Gettext, a set of tools that makes it possible to
translate the application in multiple languages.
<http://www.gnu.org/software/gettext/>
This is available by default on many systems.
Note that the configure script checks whether you have all
the prerequisite software installed and that it won't let
you to continue unless everything is in order. It also warns you
if it cannot find some optional, but recommended software.
1. Quick instructions for the impatient CDSware admin
=====================================================
$ cd /usr/local/src/
$ wget http://cdsware.cern.ch/download/cdsware-0.3.2.tar.gz
$ wget http://cdsware.cern.ch/download/cdsware-0.3.2.tar.gz.md5
$ wget http://cdsware.cern.ch/download/cdsware-0.3.2.tar.gz.sig
$ md5sum -v -c cdsware-0.3.2.tar.gz.md5
$ gpg --verify cdsware-0.3.2.tar.gz.sig cdsware-0.3.2.tar.gz
$ tar xvfz cdsware-0.3.2.tar.gz
$ cd cdsware-0.3.2
$ ./configure --prefix=/usr/local/cdsware-DEMO \
--with-webdir=/var/www/DEMO \
--with-weburl=http://webserver.domain.com/DEMO \
--with-dbhost=sqlserver.domain.com \
--with-dbname=cdsware \
--with-dbuser=cdsware \
--with-dbpass=myp1ss \
--with-python=/opt/python/bin/python2.3
$ vi ./config/config.wml ## optional, but strongly recommended
$ make
$ mysql -h sqlserver.domain.com -u root -p mysql
mysql> CREATE DATABASE cdsware;
mysql> GRANT ALL PRIVILEGES ON cdsware.* TO cdsware@webserver.domain.com IDENTIFIED BY 'myp1ss';
$ sudo vi /path/to/apache/conf/httpd.conf ## see below in part 2
$ sudo vi /path/to/php/conf/php.ini ## see below in part 2
$ sudo /path/to/apache/bin/apachectl graceful
$ sudo ln -s /usr/local/cdsware-DEMO/lib/python/cdsware \
/usr/lib/python2.3/site-packages/cdsware
$ make create-tables ## optional
$ make install
$ make test ## optional
$ sudo chown -R www-data /usr/local/cdsware-DEMO/var
$ make create-demo-site ## optional
$ make load-demo-records ## optional
$ make remove-demo-records ## optional
$ make drop-demo-site ## optional
$ netscape http://webserver.domain.com/cdsware/admin/ ## optional
2. Detailed instructions for the patient CDSware admin
======================================================
The CERN Document Server Software (CDSware) uses standard GNU autoconf
method to build and install its files. This means that you proceed
as follows:
$ cd /usr/local/src/
Change to a directory where we will configure and build the
CDS Software. (The built files will be installed into
different "target" directories later.)
$ wget http://cdsware.cern.ch/download/cdsware-0.3.2.tar.gz
$ wget http://cdsware.cern.ch/download/cdsware-0.3.2.tar.gz.md5
$ wget http://cdsware.cern.ch/download/cdsware-0.3.2.tar.gz.sig
Fetch CDSware source tarball from the CDSware distribution
server, together with MD5 checksum and GnuPG cryptographic
signature files useful for verifying the integrity of the
tarball.
$ md5sum -v -c cdsware-0.3.2.tar.gz.md5
Verify MD5 checksum.
$ gpg --verify cdsware-0.3.2.tar.gz.sig cdsware-0.3.2.tar.gz
Verify GnuPG cryptographic signature. Note that you may
first have to import my public key into your keyring, if you
haven't done that already:
$ gpg --keyserver wwwkeys.pgp.net --recv-keys 0xBA5A2B67
The output of the gpg --verify command should then read:
Good signature from "Tibor Simko <tibor@simko.info>"
You can safely ignore any trusted signature certification
warning that may follow after the signature has been
successfully verified.
$ tar xvfz cdsware-0.3.2.tar.gz
Untar the distribution tarball.
$ cd cdsware-0.3.2
Go to the source directory.
$ ./configure --prefix=/usr/local/cdsware-DEMO \
--with-webdir=/var/www/DEMO \
--with-weburl=http://webserver.domain.com/DEMO \
--with-dbhost=sqlserver.domain.com \
--with-dbname=cdsware \
--with-dbuser=cdsware \
--with-dbpass=myp1ss \
--with-python=/opt/python/bin/python2.3
Configure essential CDSware parameters, with the following
signification:
--prefix=/usr/local/cdsware-DEMO
The CDSware general installation directory, used to
hold command-line binaries and program libraries
containing the core CDSware functionality, but also
to store runtime log and cache information. Several
subdirs like `bin', `lib', and `var' will be created
inside the --prefix directory to this effect. Note
that the --prefix directory should be chosen outside
of the Apache htdocs tree, since no file from this
directory is to be accessible on the Web.
--with-webdir=/var/www/DEMO
The directory holding the web interface to CDSware,
i.e. containing all the callable scripts and web
pages visible to the end user. Must be located
inside Apache htdocs tree. The scripts within this
directory will generally call core CDSware libraries
and binaries installed in the --prefix directory.
--with-weburl=http://webserver.domain.com/DEMO
The URL corresponding to the --with-webdir directory.
It will denote the home URL of your CDSware
installation.
--with-dbhost=sqlserver.domain.com
--with-dbname=cdsware
--with-dbuser=cdsware
--with-dbpass=myp1ss
The database server host, the database name, and the
database user credentials.
--with-python=/opt/python/bin/python2.3
Optionally, specify a path to some specific Python
binary. This is useful if you have more than one
Python installation on your system. If you don't set
this option, then the first Python that will be found
in your PATH will be chosen for running CDSware.
CDSware won't install to any other directory but to the two
mentioned in this configuration line. Do not use trailing
slashes when specifying any of the above values.
This configuration step is mandatory, and is referred to as
"pre-compile time configuration step a)" in the elucidative
explanatory commentary below.
(Note that if you prefer to build CDSware out of its source
tree, you may run the above configure command like this:
$ mkdir build && cd build && ../configure --prefix=...)
$ vi ./config/config.wml ## optional, but strongly recommended
Optionally, customize your CDSware installation. We
strongly recommend you to edit at least the top of this file
where you can define some very essential CDSware parameters
like the name of your CDSware document server or the email
address of the local CDSware administrator. (The latter is
needed if you want to use administration modules, and you
certainly do!)
The rest of the "config.wml" file enables you to change the
CDSware web page look and feel, and otherwise to influence
its behaviour and default parameters.
This configuration step is optional, but strongly
recommended. It is referred to as "compile time
configuration step b)" in the elucidative explanatory
commentary below.
$ make
Launch the CDSware build. Since many messages are printed
during the build process, you may want to run it in a
fast-scrolling terminal such as rxvt or in a detached screen
session.
During this step all the pages and scripts will be
pre-created and customized based on the config you have
edited in the previous step.
Before proceeding further with the CDSware installation, we
have to do some admin-level tasks on the MySQL and Apache
servers.
$ mysql -h sqlserver.domain.com -u root -p mysql
mysql> CREATE DATABASE cdsware;
mysql> GRANT ALL PRIVILEGES ON cdsware.* TO cdsware@webserver.domain.com IDENTIFIED BY 'myp1ss';
You need to create a dedicated database on your MySQL server
that the CDSware can use for its purposes. Please
contact your MySQL administrator and ask him to execute the
above commands that will create the "cdsware" database, a
user called "cdsware" with password "myp1ss", and that will
grant all rights on the "cdsware" database to the "cdsware"
user.
(Of course, you are free to choose your own user credentials
and the database name; the above values were just an
example. See also the configure line below.)
$ sudo vi /path/to/apache/conf/httpd.conf ## see below in part 2
Please ask your webserver administrator to put the following
lines in your "httpd.conf" configuration file:
AddDefaultCharset UTF-8
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
DirectoryIndex index.en.html index.html index.py index.en.php index.php
This is to ensure that the browsers will get UTF-8 as
the default page encoding, that "*.php" files will be
interpreted by the web server as PHP files, and that
"index.py" or "index.en.php" will be considered as directory
index file.
In addition, you have to ask Apache to interpret .py files
in the installation place via mod_python and to indicate
path to CDSware's Python library directory (composed from
your --prefix choice followed by `/lib/python'):
<Directory /var/www/DEMO/>
AddHandler python-program .py
PythonHandler mod_python.publisher
PythonPath "['/usr/local/cdsware-DEMO/lib/python']+sys.path"
PythonDebug On
</Directory>
$ sudo vi /path/to/php/conf/php.ini ## see below in part 2
Please ask your webserver administrator to put the following
lines in your "php.ini" configuration file:
log_errors = on
display_errors = off
expose_php = off
max_execution_time = 160
register_globals = on
short_open_tag = on
This will set up some relevant PHP variables.
$ sudo /path/to/apache/bin/apachectl graceful
Please ask your webserver administrator to restart the
Apache server after the above "httpd.conf" and "php.ini"
changes.
After these admin-level tasks to be performed as root, let's
now go back to finish the installation of the CDSware package.
$ sudo ln -s /usr/local/cdsware-DEMO/lib/python/cdsware \
/usr/lib/python2.3/site-packages/cdsware
You have to create a symbolic link inside Python's
site-packages directory that would indicate Python where to
find CDSware files. Note that the exact location of the
symlink depends on the --prefix option you have used and on
the Python version you are using. (See also --with-python
configure option.)
$ make create-tables ## optional
Optionally, create CDSware tables on the MySQL server. You
probably want to do this step only once, i.e. if you have
not created any CDSware database and tables yet.
$ make install
Install the web pages, scripts, utilities and everything
needed for runtime into the respective directories, as
specified earlier by the configure command.
After this step, you should be able to point your browser to
the chosen URL of your local CDSware installation and see it
running!
$ make test
Optionally, you can run our test suite to verify the results
of known tests on your local CDSware installation. Note
that this command should be run only after you have
installed the whole system via `make install'.
$ sudo chown -R www-data /usr/local/cdsware-DEMO/var
One more superuser step, as we need to enable Apache server
to write some log information and to cache interesting
entities inside the "var" subdirectory of our CDSware
general installation directory.
Here we assume that your Apache server processes are run
under "www-data" group. Change this appropriately for your
system.
$ make create-demo-site ## optional
This step is recommended to test your local CDSware
installation. It should give you our "Atlantis Institute of
Science" demo installation, exactly as you see it at
<http://cdsware.cern.ch/DEMO/>.
$ make load-demo-records ## optional
Optionally, load some demo records to be able to test
indexing and searching of your local demo CDSware
installation.
$ make remove-demo-records ## optional
Optionally, remove the demo records loaded in the previous
step but otherwise keep the demo collection, submit, format
etc configurations that you may reuse and modify for
production purposes.
$ make drop-demo-site ## optional
Optionally, drop also all the demo configuration so that
you'll have a blank CDSware system for your production
purposes.
$ netscape http://webserver.domain.com/DEMO/admin/ ## optional
Optionally, do further runtime configuration of the CDSware,
like definition of data collections, document types,
document formats, word file tables, etc.
This configuration step is optional, and is referred to as
"runtime configuration step c)" in the elucidative
explanatory commentary below.
3. Configuration philosophy explained and elucidated
====================================================
As you could see from the above, the configuration of the CDSware is
threefold:
(a) pre-compile time configuration phase
[uses command line options / while doing "configure"]
(b) compile time configuration phase
[uses WML / after "configure", while doing "make && make install"]
(c) runtime configuration phase
[uses MySQL / after "make install", while doing "netscape http://webserver.domain.com/DEMO/admin/"]
What is the difference, and why?
(a) pre-compile time configuration phase
[uses command line options / while doing "configure"]
This configures essential CDSware parameters that makes your
CDSware copy installable and runable. The essential parameters
include: general CDSware installation directory containing
(among others) binaries, libraries, and log and cache
directories; install directory for Web scripts and pages;
and MySQL user and server credentials.
This configuration step uses standard GNU autoconf approach,
i.e. you will run the standard "configure" script. Note
that the only arguments that CDSware takes into consideration
are the general "--prefix" one and CDSware-specific
"--with-foo" arguments, see the end of "configure --help"
output.
This configuration step is mandatory. Without knowing
theses essential parameters there is nothing to install and
nothing to run.
Usually, you do this step only once.
(b) compile time configuration phase
[uses WML / after "configure", while doing "make && make install"]
Optionally, you may choose to influence CDSware behaviour, to
set up CDSware system name, to choose its default parameters,
to change its look and feel, to add your local web pages, etc.
This configuration step uses WML, the Website META Language.
The most important configuration file is "config/config.wml"
that you can edit at your will. Optionally, if you are an
advanced user, you may edit other WML files in the
distribution tree.
After that, when you type "make", the CDSware pages will be
pre-generated. We prefer that this configuration step is
done during compile-time and not runtime, because of
multiple reasons: (i) the pre-generated pages impose less
load on the web server and the database server and so they
are served faster to the end user; (ii) we use several
different languages (Python, PHP) and by using independent
compile-time configuration language we can share the same
configuration variables across heterogeneous languages;
(iii) use of WML and page templates enables you to easily
change anything in the CDSware system, even into deep
levels.
If you are changing parameters and/or look and feel
of CDSware pages, you may want to repeat these step several
times:
$ vi config/config.wml
$ make drop-tables
$ make create-tables
$ make create-demo-site
$ make load-demo-records
$ netscape http://webserver.domain.com/DEMO/
[...]
to see what it brings, until you are satisfied with the
result.
(Note that you may as well choose to change these parameters
inside the CDSware library configuration files later on,
during runtime, at least for non-static Python and PHP
pages.)
(c) runtime configuration phase
[uses MySQL / after "make install", while doing "netscape http://webserver.domain.com/DEMO/admin/"]
Optionally, you will most probably want to define specific
data collections, to configure submit and search page for those
collections, to specify search options and word files to
search in, formats how to display data, etc.
This configuration step uses MySQL configuration tables and
is done during the runtime, for your convenience. It means
that after previous configuration step (b), and after
successful "make install", if you are happy with its result
you no longer edit WML files within the CDSware source tree but
rather configure "fully running" CDSware installation via
its Administration web interface.
Usually, you will do this step many times in the future, to
tweak the running installation, to add new collections and
data types, etc.
(Note that if you want to change something "deeper" in a
running CDSware installation, such as look and feel of pages,
or to add some new pages, then you may want to edit library
configuration files for Python and PHP non-static pages, as
noted above. But if you want to do really "deep" changes,
you need to go back to WML source, so you may want to leave
your customized copy of the CDSware WML source tree around.)
We hope that this explains why we have chosen this three-level
configuration model, and that you will find it convenient in real
life.
Good luck, and thanks for choosing the CERN Document Server Software.
- CDS Development Group
<cds.support@cern.ch>
<http://cdsware.cern.ch/>
diff --git a/Makefile.am b/Makefile.am
index d5460c578..b02d53372 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,235 +1,235 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
confignicedir = $(sysconfdir)/build
confignice_SCRIPTS=config.nice
SUBDIRS = po config modules
EXTRA_DIST = UNINSTALL RELEASE-NOTES configure-tests.py config.nice.in
## submit stuff for demo data link creation
sbmdir = $(WEBDIR)/submit/access/protected
sbmdat = SBITEXT MBITEXT FTTTEXT SRVTEXT TFUTEXT \
SBIRTEXT MBIRTEXT FTTRTEXT SRVRTEXT TFURTEXT APPRTEXT \
SBIPICT MBIPICT FTTPICT \
SBIRPICT MBIRPICT FTTRPICT APPRPICT
all:
@echo "**************************************************************"
@echo "** CDSware has been successfully built. Proceed now by **"
@echo "** running 'make install'. **"
@echo "**************************************************************"
test:
@if [ -e @prefix@/bin/testsuite ]; then \
@prefix@/bin/testsuite ; \
else \
echo "Hmm, testsuite does not seem to be installed. Please do 'make install' first."; \
fi
install-data-local:
for d in / /cache /log /tmp /data /run ; do \
mkdir -p $(localstatedir)$$d && \
chmod ug=rwx $(localstatedir)$$d ; \
done
@echo "**************************************************************"
@echo "** CDSware has been successfully installed! **"
@echo "** **"
@echo "** If you are installing CDSware for the first time, we **"
@echo "** recommend you to run 'make create-demo-site' now to **"
@echo "** to test your installation. **"
@echo "** **"
@echo "** If you are reinstalling CDSware because you have been **"
@echo "** editing CDSware sources or its WML configuration, you **"
@echo "** may want to restart your Apache server now by running **"
@echo "** 'apachectl restart'. **"
@echo "**************************************************************"
create-tables: local-dbexec local-tabfill
./modules/miscutil/bin/dbexec < $(top_srcdir)/modules/miscutil/sql/tabcreate.sql
./modules/miscutil/bin/dbexec < ./modules/miscutil/sql/tabfill.sql
update-v0.3.0-tables update-v0.3.1-tables: local-dbexec
echo "ALTER TABLE idxINDEXNAME CHANGE id_idxINDEX id_idxINDEX mediumint(9) unsigned NOT NULL FIRST;" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE rnkMETHODNAME CHANGE id_rnkMETHOD id_rnkMETHOD mediumint(9) unsigned NOT NULL FIRST;" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE collectionname CHANGE id_collection id_collection mediumint(9) unsigned NOT NULL FIRST;" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE formatname CHANGE id_format id_format mediumint(9) unsigned NOT NULL FIRST;" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE fieldname CHANGE id_field id_field mediumint(9) unsigned NOT NULL FIRST;" | ./modules/miscutil/bin/dbexec
echo "INSERT INTO accACTION (id,name,description,allowedkeywords,optional) VALUES (NULL,'runbibrank','run BibRank','','no');" | ./modules/miscutil/bin/dbexec
echo "INSERT INTO accACTION (id,name,description,allowedkeywords,optional) VALUES (NULL,'cfgbibrank','configure BibRank','','no');" | ./modules/miscutil/bin/dbexec
update-v0.3.2-tables: local-dbexec
echo "ALTER TABLE sbmCOLLECTION_sbmDOCTYPE CHANGE id_son id_son char(10) NOT NULL default '0';" | ./modules/miscutil/bin/dbexec
update-v0.3.3-tables: local-dbexec
./modules/miscutil/bin/dbexec < $(top_srcdir)/modules/miscutil/sql/tabcreate.sql
echo "ALTER TABLE flxLINKTYPEPARAMS CHANGE pname pname varchar(78) NOT NULL default '';" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE rnkMETHOD DROP star_category_ranges;" | ./modules/miscutil/bin/dbexec
echo "DROP TABLE rnkSET;" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE schTASK CHANGE arguments arguments LONGTEXT;" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE schTASK CHANGE status status varchar(50);" | ./modules/miscutil/bin/dbexec
update-v0.5.0-tables: local-dbexec
./modules/miscutil/bin/dbexec < $(top_srcdir)/modules/miscutil/sql/tabcreate.sql
echo "ALTER TABLE session ADD INDEX uid (uid);" | ./modules/miscutil/bin/dbexec
echo "UPDATE idxINDEXNAME SET ln='cs' WHERE ln='cz';" | ./modules/miscutil/bin/dbexec
echo "UPDATE rnkMETHODNAME SET ln='cs' WHERE ln='cz';" | ./modules/miscutil/bin/dbexec
echo "UPDATE collectionname SET ln='cs' WHERE ln='cz';" | ./modules/miscutil/bin/dbexec
echo "UPDATE collection_portalbox SET ln='cs' WHERE ln='cz';" | ./modules/miscutil/bin/dbexec
echo "UPDATE formatname SET ln='cs' WHERE ln='cz';" | ./modules/miscutil/bin/dbexec
echo "UPDATE fieldname SET ln='cs' WHERE ln='cz';" | ./modules/miscutil/bin/dbexec
echo "UPDATE idxINDEXNAME SET ln='sv' WHERE ln='se';" | ./modules/miscutil/bin/dbexec
echo "UPDATE rnkMETHODNAME SET ln='sv' WHERE ln='se';" | ./modules/miscutil/bin/dbexec
echo "UPDATE collectionname SET ln='sv' WHERE ln='se';" | ./modules/miscutil/bin/dbexec
echo "UPDATE collection_portalbox SET ln='sv' WHERE ln='se';" | ./modules/miscutil/bin/dbexec
echo "UPDATE formatname SET ln='sv' WHERE ln='se';" | ./modules/miscutil/bin/dbexec
echo "UPDATE fieldname SET ln='sv' WHERE ln='se';" | ./modules/miscutil/bin/dbexec
update-v0.7.1-tables: local-dbexec
echo "DROP TABLE oaiHARVEST;" | ./modules/miscutil/bin/dbexec
./modules/miscutil/bin/dbexec < $(top_srcdir)/modules/miscutil/sql/tabcreate.sql
echo "INSERT INTO accACTION (id,name,description,allowedkeywords,optional) VALUES (NULL,'runoaiharvest','run BibHarvest oaiharvest','','no');" | ./modules/miscutil/bin/dbexec
echo "INSERT INTO accACTION (id,name,description,allowedkeywords,optional) VALUES (NULL,'cfgbibharvest','configure BibHarvest','','no');" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE user add nickname varchar(255) NOT NULL default '';" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE user ADD last_login datetime NOT NULL default '0000-00-00 00:00:00';" | ./modules/miscutil/bin/dbexec
echo "ALTER TABLE user ADD INDEX nickname (nickname);" | ./modules/miscutil/bin/dbexec
echo "TRUNCATE TABLE session;" | ./modules/miscutil/bin/dbexec
drop-tables: local-dbexec
./modules/miscutil/bin/dbexec < $(srcdir)/modules/miscutil/sql/tabdrop.sql
local-dbexec:
(cd ./modules/miscutil/bin; make)
local-tabfill: $(srcdir)/modules/miscutil/sql/tabfill.sql.wml
(cd ./modules/miscutil/sql; make)
create-demo-site:
# for f in $(sbmdat); do \
# if [ ! -e $(sbmdir)/$$f.shtml ]; then \
# ln -s $(sbmdir)/go.shtml $(sbmdir)/$$f.shtml ; \
# else \
# echo "link $(sbmdir)/$$f.shtml already exists"; \
# fi \
# done
./modules/miscutil/bin/dbexec < ./modules/miscutil/demo/democfgdata.sql
echo "TRUNCATE schTASK;" | ${prefix}/bin/dbexec
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/webcoll
${prefix}/bin/webcoll 1
@echo "***********************************************************************"
@echo "** The demo site has been successfully created. **"
@echo "** **"
@echo "** Please point your browser to @WEBURL@ "
@echo "** It should ressemble our 'Atlantis Institute of Fictive Science' **"
@echo "** demo site that is available at <http://cdsware.cern.ch/demo/>, **"
@echo "** with the exception that no demo records have been loaded yet. **"
@echo "** **"
@echo "** To load demo records, you can run 'make load-demo-records'. **"
@echo "** To drop the demo site, you can run 'make drop-demo-site'. **"
@echo "***********************************************************************"
load-demo-records:
echo "TRUNCATE schTASK;" | ${prefix}/bin/dbexec
${prefix}/bin/bibupload -i $(srcdir)/modules/miscutil/demo/demobibdata.xml
${prefix}/bin/bibupload 1
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/bibindex
${prefix}/bin/bibindex 2
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/bibreformat -oHB,HD,HP,HC
${prefix}/bin/bibreformat 3
${prefix}/bin/bibupload 4
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/webcoll
${prefix}/bin/webcoll 5
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/bibrank
${prefix}/bin/bibrank 6
@echo "***********************************************************************"
@echo "** The demo records have been successfully loaded. **"
@echo "** **"
@echo "** Please point your browser to @WEBURL@ "
@echo "** It should ressemble our 'Atlantis Institute of Fictive Science' **"
@echo "** demo site that is available at <http://cdsware.cern.ch/demo/>. **"
@echo "** **"
@echo "** To remove demo records, you can run 'make remove-demo-records'. **"
@echo "** To drop also the demo site collection etc configurations, **"
@echo "** you can run 'make drop-demo-site'. **"
@echo "***********************************************************************"
drop-demo-site:
./modules/miscutil/bin/dbexec < $(srcdir)/modules/miscutil/sql/tabdrop.sql
./modules/miscutil/bin/dbexec < $(srcdir)/modules/miscutil/sql/tabcreate.sql
./modules/miscutil/bin/dbexec < ./modules/miscutil/sql/tabfill.sql
echo "TRUNCATE schTASK;" | ${prefix}/bin/dbexec
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/webcoll
${prefix}/bin/webcoll 1
# for f in $(sbmdat); do rm -f $(sbmdir)/$$f.shtml ; done
@echo "***************************************************************"
@echo "** The demo site and records have been successfully dropped. **"
@echo "***************************************************************"
remove-demo-records:
./modules/miscutil/bin/dbexec < $(srcdir)/modules/miscutil/sql/tabbibclean.sql
echo "TRUNCATE schTASK;" | ${prefix}/bin/dbexec
@echo ""
@echo "***********************************************************************"
@echo "** You will be asked for a username, please enter admin email below. **"
@echo "***********************************************************************"
@echo ""
${prefix}/bin/webcoll
${prefix}/bin/webcoll 1
@echo "**********************************************************"
@echo "** The demo records have been successfully removed. **"
@echo "** The demo collection and submit configurations **"
@echo "** have been preserved. **"
@echo "** **"
@echo "** Note that you can run 'make drop-demo-site' to drop **"
@echo "** the demo site fully. **"
@echo "**********************************************************"
CLEANFILES = *~
diff --git a/config/Makefile.am b/config/Makefile.am
index 0c0567d44..2079b5399 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
noinst_SCRIPTS=configbis.wml
wmlincludedir = $(libdir)/wml/cdsware
wmlinclude_DATA = cdsnavbar.wml cdsnavtrail.wml cdspage.wml config.wml configbis.wml \
cdswmllib.wml
EXTRA_DIST = cdsnavbar.wml cdsnavtrail.wml cdspage.wml config.wml configbis.wml.in \
cdswmllib.wml
CLEANFILES = *~
\ No newline at end of file
diff --git a/config/cdsnavbar.wml b/config/cdsnavbar.wml
index d2d035881..819ff6d58 100644
--- a/config/cdsnavbar.wml
+++ b/config/cdsnavbar.wml
@@ -1,502 +1,502 @@
## $Id$
## This file defines CDSware navbar and subnavbars.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## You probably went here from "config.wml", so let's continue with
## its numerotation of CDSware configuration parts...
################################
## Part 4: CDS navigation bar ##
################################
## The navigation bar and sub-bars are defined here. You may modify
## the definitions now, if you wish, and if you really know what you
## are doing. :-). After that return to "config.wml" file, and the
## main CDSware source directory, and type "make clean && make".
#use wml::des::navbar
## navbar admin:
<navbar:define name=admin
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> </navbar:prolog>
<navbar:button id=admin txt="<strong>ADMIN AREA</strong>" url="<WEBURL>/admin/" hint="CDSware Administrators Area">
<navbar:button id=howto txt="HOWTOs" url="<WEBURL>/admin/howto/" hint="CDSware Admin HOWTO Documents" menu="admin-howto">
<navbar:button id=bibclassify txt="BibClassify Admin" url="<WEBURL>/admin/bibclassify/" hint="CDSware BibClassify Admin" menu="admin-bibclassify">
<navbar:button id=bibconvert txt="BibConvert Admin" url="<WEBURL>/admin/bibconvert/" hint="CDSware BibConvert Admin" menu="admin-bibconvert">
<navbar:button id=bibedit txt="BibEdit Admin" url="<WEBURL>/admin/bibedit/" hint="CDSware BibEdit Admin" menu="admin-bibedit">
<navbar:button id=bibformat txt="BibFormat Admin" url="<WEBURL>/admin/bibformat/" hint="CDSware BibFormat Admin" menu="admin-bibformat">
<navbar:button id=bibharvest txt="BibHarvest Admin" url="<WEBURL>/admin/bibharvest/" hint="CDSware BibHarvest Admin" menu="admin-bibharvest">
<navbar:button id=bibindex txt="BibIndex Admin" url="<WEBURL>/admin/bibindex/" hint="CDSware BibIndex Admin" menu="admin-bibindex">
<navbar:button id=bibmatch txt="BibMatch Admin" url="<WEBURL>/admin/bibmatch/" hint="CDSware BibMatch Admin" menu="admin-bibmatch">
<navbar:button id=bibrank txt="BibRank Admin" url="<WEBURL>/admin/bibrank/" hint="CDSware BibRank Admin" menu="admin-bibrank">
<navbar:button id=bibsched txt="BibSched Admin" url="<WEBURL>/admin/bibsched/" hint="CDSware BibSched Admin" menu="admin-bibsched">
<navbar:button id=bibupload txt="BibUpload Admin" url="<WEBURL>/admin/bibupload/" hint="CDSware BibUpload Admin" menu="admin-bibupload">
<navbar:button id=elmsubmit txt="ElmSubmit Admin" url="<WEBURL>/admin/elmsubmit/" hint="CDSware ElmSubmit Admin" menu="admin-elmsubmit">
<navbar:button id=webaccess txt="WebAccess Admin" url="<WEBURL>/admin/webaccess/" hint="CDSware Web Access Rights Admin" menu="admin-webaccess">
<navbar:button id=webalert txt="WebAlert Admin" url="<WEBURL>/admin/webalert/" hint="CDSware WebAlert Admin" menu="admin-webalert">
<navbar:button id=webbasket txt="WebBasket Admin" url="<WEBURL>/admin/webbasket/" hint="CDSware WebBasket Admin" menu="admin-webbasket">
<navbar:button id=webcomment txt="WebComment Admin" url="<WEBURL>/admin/webcomment/" hint="CDSware WebComment Admin" menu="admin-webcomment">
<navbar:button id=webmessage txt="WebMessage Admin" url="<WEBURL>/admin/webmessage/" hint="CDSware WebMessage Admin" menu="admin-webmessage">
<navbar:button id=websearch txt="WebSearch Admin" url="<WEBURL>/admin/websearch/" hint="CDSware Web Search Interface Admin" menu="admin-websearch">
<navbar:button id=websession txt="WebSession Admin" url="<WEBURL>/admin/websession/" hint="CDSware WebSession Admin" menu="admin-websession">
<navbar:button id=webstat txt="WebStat Admin" url="<WEBURL>/admin/webstat/" hint="CDSware WebStat Admin" menu="admin-webstat">
<navbar:button id=webstyle txt="WebStyle Admin" url="<WEBURL>/admin/webstyle/" hint="CDSware WebStyle Admin" menu="admin-webstyle">
<navbar:button id=websubmit txt="WebSubmit Admin" url="<WEBURL>/admin/websubmit/" hint="CDSware Web Submit Interface Admin" menu="admin-websubmit">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:epilog type=S> </td><td></td></tr></navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-howto:
<navbar:define name=admin-howto
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=howto_marc txt="HOWTO MARC" url="<WEBURL>/admin/howto/marc.html" hint="Admin's HOWTO Guides - How to MARC your medatada">
<navbar:button id=howto_migrate txt="HOWTO Migrate" url="<WEBURL>/admin/howto/migrate.html" hint="Admin's HOWTO Guides - How to Migrate your old documents into CDSware">
<navbar:button id=howto_run txt="HOWTO Run" url="<WEBURL>/admin/howto/run.html" hint="Admin's HOWTO Guides - How to Run your CDSware installation day-by-day">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibclassify:
<navbar:define name=admin-bibclassify
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibclassify-admin-guide txt="Guide" url="<WEBURL>/admin/bibclassify/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibconvert:
<navbar:define name=admin-bibconvert
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibconvert-admin-guide txt="Guide" url="<WEBURL>/admin/bibconvert/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibedit:
<navbar:define name=admin-bibedit
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibedit-admin-interface txt="Interface" url="<WEBURL>/admin/bibedit/bibeditadmin.py">
<navbar:button id=bibedit-admin-guide txt="Guide" url="<WEBURL>/admin/bibedit/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibformat:
<navbar:define name=admin-bibformat
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=BEH_display txt="Behaviours" url="<WEBURL>/admin/bibformat/BEH_display.php" hint="BibFormat Admin - Behaviours">
<navbar:button id=OAIER_display txt="Extraction&nbsp;Rules" url="<WEBURL>/admin/bibformat/OAIER_display.php" hint="BibFormat Admin - Extraction Rules">
<navbar:button id=LINK_display txt="Link Rules" url="<WEBURL>/admin/bibformat/LINK_display.php" hint="BibFormat Admin - Link Rules">
<navbar:button id=LINK_FORMAT_display txt="File Formats" url="<WEBURL>/admin/bibformat/LINK_FORMAT_display.php" hint="BibFormat Admin - File Formats">
<navbar:button id=UDF_display txt="UDFs" url="<WEBURL>/admin/bibformat/UDF_display.php" hint="BibFormat Admin - User Defined Functions">
<navbar:button id=FORMAT_display txt="Formats" url="<WEBURL>/admin/bibformat/FORMAT_display.php" hint="BibFormat Admin - Formats">
<navbar:button id=KB_display txt="KBs" url="<WEBURL>/admin/bibformat/KB_display.php" hint="BibFormat Admin - Knowledge Bases">
<navbar:button id=test txt="Execution Test" url="<WEBURL>/admin/bibformat/test.php" hint="BibFormat Admin - Execution Test">
<navbar:button id=BIBREFORMAT_display txt="Reformat&nbsp;Records" url="<WEBURL>/admin/bibformat/BIBREFORMAT_display.php" hint="BibFormat Admin - Reformat Records">
<navbar:button id=bibformat-guide txt="Guide" url="<WEBURL>/admin/bibformat/guide.html" hint="BibFormat Admin - Guide">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibharvest:
<navbar:define name=admin-bibharvest
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibharvest-admin-interface txt="Interface" url="<WEBURL>/admin/bibharvest/bibharvestadmin.py">
<navbar:button id=bibharvest-admin-guide txt="Guide" url="<WEBURL>/admin/bibharvest/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibindex:
<navbar:define name=admin-bibindex
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibindex-admin-interface txt="Indexes" url="<WEBURL>/admin/bibindex/bibindexadmin.py/index">
<navbar:button id=bibindex-admin-interface txt="Fields" url="<WEBURL>/admin/bibindex/bibindexadmin.py/field">
<navbar:button id=bibindex-admin-guide txt="Guide" url="<WEBURL>/admin/bibindex/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibmatch:
<navbar:define name=admin-bibmatch
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibmatch-admin-guide txt="Guide" url="<WEBURL>/admin/bibmatch/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibrank:
<navbar:define name=admin-bibrank
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibrank-admin-interface txt="Interface" url="<WEBURL>/admin/bibrank/bibrankadmin.py">
<navbar:button id=bibrank-admin-guide txt="Guide" url="<WEBURL>/admin/bibrank/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibsched:
<navbar:define name=admin-bibsched
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibsched-admin-guide txt="Guide" url="<WEBURL>/admin/bibsched/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-bibupload:
<navbar:define name=admin-bibupload
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=bibupload-admin-guide txt="Guide" url="<WEBURL>/admin/bibupload/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-elmsubmit:
<navbar:define name=admin-elmsubmit
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=elmsubmit-admin-guide txt="Guide" url="<WEBURL>/admin/elmsubmit/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webaccess:
<navbar:define name=admin-webaccess
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webaccess-admin-manager txt="Manager" url="<WEBURL>/admin/webaccess/webaccessadmin.py">
<navbar:button id=webaccess-admin-delegator txt="Delegator" url="<WEBURL>/admin/webaccess/webaccessadmin.py/delegate_startarea">
<navbar:button id=webaccess-admin-accounts txt="Accounts" url="<WEBURL>/admin/webaccess/webaccessadmin.py/manageaccounts">
<navbar:button id=webaccess-admin-guide txt="Guide" url="<WEBURL>/admin/webaccess/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webalert:
<navbar:define name=admin-webalert
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webalert-admin-guide txt="Guide" url="<WEBURL>/admin/webalert/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webbasket:
<navbar:define name=admin-webbasket
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webbasket-admin-guide txt="Guide" url="<WEBURL>/admin/webbasket/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webcomment:
<navbar:define name=admin-webcomment
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webcomment-admin-interface txt="Interface" url="<WEBURL>/admin/webcomment/webcommentadmin.py">
<navbar:button id=webcomment-admin-guide txt="Guide" url="<WEBURL>/admin/webcomment/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webmessage:
<navbar:define name=admin-webmessage
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webmessage-admin-guide txt="Guide" url="<WEBURL>/admin/webmessage/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-websearch:
<navbar:define name=admin-websearch
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=websearch-admin-interface txt="Interface" url="<WEBURL>/admin/websearch/websearchadmin.py">
<navbar:button id=websearch-admin-guide txt="Guide" url="<WEBURL>/admin/websearch/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-websession:
<navbar:define name=admin-websession
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=websession-admin-guide txt="Guide" url="<WEBURL>/admin/websession/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webstyle:
<navbar:define name=admin-webstyle
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webstyle-admin-guide txt="Guide" url="<WEBURL>/admin/webstyle/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-websubmit:
<navbar:define name=admin-websubmit
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=websubmit_newdoctype txt="New&nbsp;Doctype" url="<WEBURL>/admin/websubmit/newDoctypeEDS.php" hint="New Type of Document">
<navbar:button id=websubmit_deldoctype txt="Remove&nbsp;Doctype" url="<WEBURL>/admin/websubmit/removeDoctypeEDS.php" hint="Remove Type of Document">
<navbar:button id=websubmit_listactions txt="Available&nbsp;Actions" url="<WEBURL>/admin/websubmit/allActionsEDS.php" hint="List Available Actions">
<navbar:button id=websubmit_listchecks txt="Available&nbsp;Javascript&nbsp;Checks" url="<WEBURL>/admin/websubmit/allChecksEDS.php" hint="List Available Javascript Checking functions">
<navbar:button id=websubmit_listelements txt="Available&nbsp;Element&nbsp;Descriptions" url="<WEBURL>/admin/websubmit/allElementsEDS.php" hint="List Available Element Descriptions">
<navbar:button id=websubmit_listfunctions txt="Available&nbsp;Functions" url="<WEBURL>/admin/websubmit/listFunctions.php" hint="List Available Functions">
<navbar:button id=websubmit_organise txt="Organise&nbsp;Main&nbsp;Page" url="<WEBURL>/admin/websubmit/editCatalogues.php" hint="Main Page Organisation">
<navbar:button id=websubmit-admin-guide txt="Guide" url="<WEBURL>/admin/websubmit/guide/" hint="Guide">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## navbar admin-webstat:
<navbar:define name=admin-webstat
imgbase="img/" urlbase="$(ROOT)">
<navbar:header>
<table class=adminbox>
</navbar:header>
<navbar:prolog><tr valign=top><td></td><td class=adminboxbody> &nbsp;&nbsp;&nbsp;</navbar:prolog>
<navbar:button id=webstat-admin-guide txt="Guide" url="<WEBURL>/admin/webstat/guide.html">
<navbar:epilog> </td><td></td></tr> </navbar:epilog>
<navbar:footer>
</table>
</navbar:footer>
</navbar:define>
## End of file. Please return to "config.wml" file, and the main CDSware
## source directory, and type "make clean && make".
diff --git a/config/cdsnavtrail.wml b/config/cdsnavtrail.wml
index acad99586..eddd25d97 100644
--- a/config/cdsnavtrail.wml
+++ b/config/cdsnavtrail.wml
@@ -1,112 +1,112 @@
## $Id$
## CERN Document Server navigation trail generation.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<:
sub navTrail{
# prints out default layout of makeTrial
$PATH = $ENV{'PWD'}; # current path
$menuitem = "title"; # TEXT taken from *.wml file
@TITLE = &makeTrail($PATH,$ROOT);
if ($WML_SRC_FILENAME eq "index.wml") {
pop @TITLE;
}
:>
$(header)
<:
foreach $title(@TITLE){
$filename = $title . "/index.wml";
$out = &readWMLTitle($filename,$menuitem);
if ($out) {
:>
$(prolog)
<:
print " <a class=\"navtrail\" href=\"" . $title . "\">$out</a>";
:>
$(epilog)
<:
}
}
:>
$(footer)
<:
}
#<=
sub makeTrail{
# returns list of relative directories in the trail
my ($PATH,$rot) = @_;
@DIR = split(/\//,$PATH); # PATH values of current directory to be considered
@PATH = split(/\//,$rot); # directory relative to ROOT
if ($rot ne '.'){ #
while (@PATH){ # at each level
$trail = pop(@DIR); # ..get its value
$path = pop(@PATH); #
push(@TRAIL,$trail); # ..and build an array of dirnames
}
@TRAIL = reverse(@TRAIL);
}
$out = $rot;
push(@OUT,$out);
foreach $ITEM(@TRAIL){
$out = $out . "/" . $ITEM;
push(@OUT,$out);
}
return @OUT ;
}
#<=
sub readWMLTitle($file,$key){
# read text from file to display in navtrail
($file,$key) = @_;
if(open(IN,$file)){
$done = 0;
while($line = <IN>){
if((!$done) && (($out) = $line=~/$key="(.*?)"/)){
$done = 1;
}
}
close(IN);
}
else{
$out = "";
}
return($out);
}
:>
diff --git a/config/cdspage.wml b/config/cdspage.wml
index 4903da994..e116b1bae 100644
--- a/config/cdspage.wml
+++ b/config/cdspage.wml
@@ -1,157 +1,157 @@
## $Id$
## CERN Document Server general web page template.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## include local config and customization of this CDS installation:
#include "config.wml"
#include "configbis.wml"
#include "cdswmllib.wml"
## include navigation trail and bar definitions:
#include "cdsnavtrail.wml" \
header="<br><table class=navtrailbox border=0 cellpadding=0 cellspacing=0><tr><td width=15>&nbsp;</td><td class=navtrailboxbody><a class=navtrail href='<WEBURL>'><CDSNAME></a> &gt; " \
prolog="" \
epilog="&gt;" \
footer="$(title)</td></tr></table>"
#include "cdsnavbar.wml"
## HTML header:
<!-- DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware SOURCES. LOOK THERE FOR THE COPYRIGHT INFO. -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title><CDSNAME>: $(title)</title>
<link rev="made" href="mailto:<SUPPORTEMAIL>">
<link rel="stylesheet" href="<WEBURL>/img/cds.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="$(description)">
<meta name="keywords" content="$(keywords)">
</head>
<body>
## CDS page header (first common, then local):
<div class="pageheader">
<:
$header = '<CDSPAGEHEADER>';
$header =~ s/<!--CDSNAMEINTL-->/<CDSNAMEINTL>/g;
$header =~ s/<!--MSGSEARCH-->/_(Search)_/g;
$header =~ s/<!--MSGSUBMIT-->/_(Submit)_/g;
$header =~ s/<!--MSGCONVERT-->/_(Convert)_/g;
$header =~ s/<!--MSGAGENDA-->/_(Agenda)_/g;
$header =~ s/<!--MSGWEBCAST-->/_(Webcast)_/g;
$header =~ s/<!--MSGBULLETIN-->/_(Bulletin)_/g;
$header =~ s/<!--MSGLIBRARY-->/_(Library)_/g;
$header =~ s/<!--MSGHELP-->/_(Help)_/g;
$header =~ s/<!--MSGPERSONALIZE-->/_(Personalize)_/g;
$header =~ s/<!--LN-->/<lang:star: *>/g;
if ('$(navtrail_previous_links)' =~ /\w/) {
$navtrailboxbody = '<a class="navtrail" href="<WEBURL>/?ln=<lang:star: *>">_(Home)_</a> &gt; $(navtrail_previous_links) &gt; $(title)';
} elsif ('$(navtrail_body)' eq '') {
$navtrailboxbody = '<a class="navtrail" href="<WEBURL>/?ln=<lang:star: *>">_(Home)_</a> &gt; $(title)';
} elsif ('$(navtrail_body)' =~ /\w/) {
$navtrailboxbody = '$(navtrail_body)';
}
$header =~ s/<!--NAVTRAILBOXBODY-->/$navtrailboxbody/g;
print $header;
:>
$(cdspageheaderadd)
</div>
## CDS page content:
<div class="pagebody">
<div class="pagebodystripeleft">
## first site-wide CDSPAGEBOXLEFTTOP:
<: if ('<CDSPAGEBOXLEFTTOP>' =~ /\w/) {
print '<div class="pageboxlefttop"><CDSPAGEBOXLEFTTOP></div>';
}
:>
## then optional "left top" page box that each page can define on its own:
<: if ('$(cdspageboxlefttopadd)' =~ /\w/) {
print '<div class="pageboxlefttopadd">$(cdspageboxlefttopadd)</div>';
}
:>
## then optoinal "left bottom" page box that each page can define on its own:
<: if ('$(cdspageboxleftbottomadd)' =~ /\w/) {
print '<div class="pageboxleftbottomadd">$(cdspageboxleftbottomadd)</div>';
}
:>
## then site-wide CDSPAGEBOXLEFTBOTTOM:
<: if ('<CDSPAGEBOXLEFTBOTTOM>' =~ /\w/) {
print '<div class="pageboxleftbottom"><CDSPAGEBOXLEFTBOTTOM></div>';
}
:>
</div>
<div class="pagebodystriperight">
## before everything, print the navbar:
<navbar:render nohints name=$(navbar_name) select=$(navbar_select)>
## first site-wide CDSPAGEBOXRIGHTTOP:
<: if ('<CDSPAGEBOXRIGHTTOP>' =~ /\w/) {
print '<div class="pageboxrighttop"><CDSPAGEBOXRIGHTTOP></div>';
}
:>
## then optional "right top" page box that each page can define on its own:
<: if ('$(cdspageboxrighttopadd)' =~ /\w/) {
print '<div class="pageboxrighttopadd">$(cdspageboxrighttopadd)</div>';
}
:>
## then optional "right bottom" page box that each page can define on its own:
<: if ('$(cdspageboxrightbottomadd)' =~ /\w/) {
print '<div class="pageboxrightbottomadd">$(cdspageboxrightbottomadd)</div>';
}
:>
## then site-wide CDSPAGEBOXRIGHTBOTTOM:
<: if ('<CDSPAGEBOXRIGHTBOTTOM>' =~ /\w/) {
print '<div class="pageboxrightbottom"><CDSPAGEBOXRIGHTBOTTOM></div>';
}
:>
</div>
<div class="pagebodystripemiddle">
<h1 class="headline">$(title)</h1>
<p>
{#BODY#}
</div>
</div>
## CDS page footer (first local, then common):
<div class="pagefooter">
$(cdspagefooteradd)
<:
$footer = '<CDSPAGEFOOTER>';
$lastupdated = `date +"%d %b %Y %H:%M:%S %Z"`;
$footer =~ s/<!--CDSNAMEINTL-->/<CDSNAMEINTL>/g;
$footer =~ s/<!--MSGSEARCH-->/_(Search)_/g;
$footer =~ s/<!--MSGSUBMIT-->/_(Submit)_/g;
$footer =~ s/<!--MSGHELP-->/_(Help)_/g;
$footer =~ s/<!--MSGPERSONALIZE-->/_(Personalize)_/g;
$footer =~ s/<!--LN-->/<lang:star: *>/g;
$footer =~ s/<!--LASTUPDATED-->/_(Last updated:)_ $lastupdated/g;
$footer =~ s/<!--MAINTAINEDBY-->/_(Maintained by)_/g;
$footer =~ s/<!--POWEREDBY-->/_(Powered by)_/g;
$footer =~ s/<!--LANGUAGESELECTIONBOX-->/&generate_language_selection_box_for_html;/ge;
print $footer;
:>
</div>
## CDS page ends:
</body>
</html>
## by default we are in the body:
{#BODY#:
diff --git a/config/cdswmllib.wml b/config/cdswmllib.wml
index f299412a3..a3d70fa12 100644
--- a/config/cdswmllib.wml
+++ b/config/cdswmllib.wml
@@ -1,118 +1,118 @@
## $Id$
## Library of WML functions of general interest.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## language handling:
#use wml::std::lang
<lang:new id=ca short>
<lang:new id=de short>
<lang:new id=en short>
<lang:new id=es short>
<lang:new id=pt short>
<lang:new id=fr short>
<lang:new id=it short>
<lang:new id=ru short>
<lang:new id=sk short>
<lang:new id=cs short>
<lang:new id=no short>
<lang:new id=sv short>
<lang:new id=el short>
<lang:new id=uk short>
<lang:new id=ja short>
<lang:new id=pl short>
## library of WML functions of general interest:
<:
sub get_language_name {
## Return long name for a language.
## Input: en
## Output: English
($ln) = @_;
%longnames = ('en' => 'English',
'fr' => 'Français',
'de' => 'Deutsch',
'es' => 'Español',
'ca' => 'Català',
'pt' => 'Português',
'it' => 'Italiano',
'ru' => 'Русский',
'sk' => 'Slovensky',
'cs' => 'Česky',
'no' => 'Norsk/Bokmål',
'sv' => 'Svenska',
'el' => 'Ελληνικά',
'uk' => 'Українська',
'ja' => '日本語',
'pl' => 'Polski');
return $longnames{$ln};
}
sub generate_language_list_for_python {
## Return Python-ready language list out of user-configured WML language list.
## May return short or long version, depending on the first argument.
## Output example: ['en','fr']
## Output example: [['en','English'],['fr','French']]
($type) = @_;
$out = "[";
foreach $ln (split /\s*,\s*/, '<CDSLANGS>') {
if ($type) {
$out .= "['".$ln."','".get_language_name($ln)."'],";
} else {
$out .= "'".$ln."',";
}
}
$out .= "]";
return $out;
}
sub generate_language_selection_box_for_html {
## Return HTML-ready language selection box links.
## Output example:
($filenamebase, $filenameextension) = split /\./, '$(WML_SRC_BASENAME)';
$out = "_(This site is also available in the following languages:)_<br>";
foreach $ln (split /\s*,\s*/, '<CDSLANGS>') {
$out .= ' <a class="langinfo" href="'.$filenamebase.'.'.$ln.'.'.$filenameextension.'">'.get_language_name($ln).'</a> &nbsp; ';
}
return substr($out, 0, -2);
}
sub generate_pretty_version_string {
## Input: CVS DOLLAR Id DOLLAR string
## Output: nicely formatted version number suitable for `bibtaskex --version'
## Example: ``DOLLAR Id: webcoll.wml,v 1.41 2004/04/21 11:20:06 tibor Exp DOLLAR''
## will generate output like ``CDSware/0.3.2 webcoll/1.41''
($out) = @_;
($junk, $filename, $revision, $date, $junk) = split / /, $out;
$filename =~ s/\.wml,v//g;
return "CDSware/<VERSION> " . $filename . "/" . $revision;
}
sub generate_pretty_revision_date_string {
## Input: CVS DOLLAR Id DOLLAR string
## Output: nicely formatted revision/date number suitable for Admin Guides
## Example: ``DOLLAR Id: webcoll.wml,v 1.41 2004/04/21 11:20:06 tibor Exp DOLLAR''
## will generate output like ``CDSware/0.3.2 webcoll/1.41''
($out) = @_;
($junk, $filename, $revision, $date, $junk) = split / /, $out;
return $revision . ", " . $date;
}
:>
diff --git a/config/config.wml b/config/config.wml
index e89516512..7699757eb 100644
--- a/config/config.wml
+++ b/config/config.wml
@@ -1,812 +1,812 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file enables you to configure the parameters of your local CDS
## installation. It should be self-explanatory. Just go ahead and
## change the values within "define-tag" elements according to your
## needs. When done, return to the main CDSware source directory and
## type 'make'.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## #####################
## About "config.wml" ##
## #####################
## This file ('config.wml') consists of several relatively independent
## configuration parts:
##
## Part 1: Essential parameters
## Part 2: CDS page elements
## Part 3: CDS navigation bar
## Part 5: WebSearch parameters
## Part 4: BibHarvest OAI parameters
## Part 6: WebSubmit parameters
## Part 7: Fulltext Archive parameters
## Part 8: BibFormat parameters
## Part 9: BibIndex parameters
## Part 10: Access Control parameters
##
## The configuration is done by editing the content of the "define-tag"
## WML elements below. Feel free to edit as many as you need. When done,
## return to the main CDSware source directory and type 'make'. Good luck! :-)
## Before starting, let's include helper functions:
#include "cdswmllib.wml"
#include "configbis.wml"
###################################
## Part 1: Essential parameters ##
###################################
## This part defines essential CDSware internal parameters that
## everybody should modify, like the name of the server or the email
## address of the local CDSware administrator.
## CDSNAME -- the visible name of your CDSware installation:
## (example: "My Document Server")
<define-tag CDSNAME whitespace=delete>
Atlantis Institute of Fictive Science
</define-tag>
## CDSNAMEINTL -- the international versions of CDSNAME in various
## languages, defined using the standard locale-like language codes.
## (example: "<fr>Mon Serveur des Documents</fr>")
<define-tag CDSNAMEINTL whitespace=delete>
<en>Atlantis Institute of Fictive Science</en>
<fr>Atlantis Institut des Sciences Fictives</fr>
<de>Atlantis Institut der fiktiven Wissenschaft</de>
<es>Atlantis Instituto de la Ciencia Fictive</es>
<ca>Institut Atlantis de Ciència Fictícia</ca>
<pt>Instituto Atlantis de Ciência Fictícia</pt>
<it>Atlantis Istituto di Scienza Fittizia</it>
<ru>Атлантис Институт фиктивных Наук</ru>
<sk>Atlantis Inštitút Fiktívnych Vied</sk>
<cs>Atlantis Institut Fiktivních Věd</cs>
<no>Atlantis Institutt for Fiktiv Vitenskap</no>
<sv>Atlantis Institut för Fiktiv Vetenskap</sv>
<el>Ινστιτούτο Φανταστικών Επιστημών Ατλαντίδος</el>
<uk>Інститут вигаданих наук в Атлантісі</uk>
<ja>Fictive 科学のAtlantis の協会</ja>
<pl>Instytut Fikcyjnej Nauki Atlantis</pl>
</define-tag>
## CDSLANG -- the default language of the interface:
## (example: "en")
<define-tag CDSLANG whitespace=delete>
en
</define-tag>
## CDSLANGS -- list of all languages the user interface should be
## available in, separated by commas. The order specified below will
## be respected on the interface pages. A good default would be to
## use the alphabetical order. Currently supported languages include
## Catalan, Czech, German, Greek, English, Spanish, French, Italian,
## Japanese, Norwegian, Polish, Portuguese, Russian, Slovak, Swedish,
## and Ukrainian, so that the current eventual maximum you can
## currently select is
## "ca,cs,de,el,en,es,fr,it,ja,no,pl,pt,ru,sk,sv,uk".
## (example: "de,en,fr,it")
<define-tag CDSLANGS whitespace=delete>
ca,cs,de,el,en,es,fr,it,ja,no,pl,pt,ru,sk,sv,uk
</define-tag>
## ALERTENGINEEMAIL -- the email address from which the alert emails will appear to be send:
## (example: "cds.alert@cdsware.cern.ch")
<define-tag ALERTENGINEEMAIL whitespace=delete>
cds.alert@cdsdev.cern.ch
</define-tag>
## SUPPORTEMAIL -- the email address of the support team for this installation:
## (example: "cds.support@cern.ch")
<define-tag SUPPORTEMAIL whitespace=delete>
cds.support@cern.ch
</define-tag>
## ADMINEMAIL -- the email address of the 'superuser' for this
## installation. Enter your email address below and login with this
## address when using CDSware administration modules. You will then
## be automatically recognized as superuser of the system.
## (example: "cds.support@cern.ch")
<define-tag ADMINEMAIL whitespace=delete>
cds.support@cern.ch
</define-tag>
## CFG_MAX_RECID -- maximum record ID number possible, i.e. the upper
## estimate of the total number of documents in the database. A
## reasonable estimate is: if you have 500,000 records in the database
## now, and the size is growing by 10,000 records per month, then a
## value of 700,000 sounds reasonable, as it should suffice for two
## years. Note that if in 6 months you'll suddenly have to upload a
## lot of new input records, so that it may grow past the present
## CFG_MAX_RECID limit, nothing bad happens: you only have to change
## this parameter and reindex the full database content. Note also
## that the lower CFG_MAX_RECID, the faster the search engine and the
## indexation engines are, so you have interest not to put it
## unnecessarily high. The relation between the speed and the value
## of CFG_MAX_RECID is about linear, so that cutting CFG_MAX_RECID by
## half will speed up the indexation about twice.
## (example: "8000")
<define-tag CFG_MAX_RECID whitespace=delete>
8000
</define-tag>
## CFG_APACHE_PASSWORD_FILE -- where Apache user credentials are stored
<define-tag CFG_APACHE_PASSWORD_FILE whitespace=delete>
/soft/httpd-bis/conf/httpd.password
</define-tag>
## CFG_APACHE_GROUP_FILE -- where Apache user groups are stored
<define-tag CFG_APACHE_GROUP_FILE whitespace=delete>
/soft/httpd-bis/conf/httpd.group
</define-tag>
## CFG_CERN_SITE -- do we want to enable CERN-specific code, like the
## one that proposes links to famous HEP sites such as Spires and KEK?
## Put "1" for "yes" and "0" for "no". (example: "0")
<define-tag CFG_CERN_SITE whitespace=delete>
0
</define-tag>
################################
## Part 2: CDS page elements ##
################################
## This part defines CDS portal-like page style and its elements.
## Here is a schematic overview of all the WML-configurable parts:
##
## +-----------------------------------------------------------------------------------------+
## | CDSPAGEHEADER |
## | (cdspageheaderadd) |
## +-------------------------+------------------------------------+--------------------------+
## | CDSPAGEBOXLEFTTOP | | CDSPAGEBOXRIGHTTOP |
## | (cdspageboxlefttopadd) | | (cdspageboxrighttopadd) |
## | | | |
## | | | |
## | | | |
## | | | |
## | | main page body | |
## | | | |
## | | | |
## | | | |
## | | | |
## | | | |
## | | | |
## |(cdspageboxleftbottomadd)| |(cdspageboxrightbottomadd)|
## | CDSPAGEBOXLEFTBOTTOM | | CDSPAGEBOXRIGHTBOTTOM |
## +-------------------------+------------------------------------+--------------------------+
## | (cdspagefooteradd) |
## | CDSPAGEFOOTER |
## +-----------------------------------------------------------------------------------------+
##
## Here, (i) the upper case elements like CDSPAGEHEADER are globally
## defined in this 'config.wml' file, see below. (ii) the lower case
## elements in parentheses like "(cdspageheaderadd)" are optional
## local add-ons that each WML page can define locally and pass to the
## global WML template as parameters. (iii) Note also that the style
## and colours of all these elements is defined in the cascading style
## sheet in the file 'htdocs/img/cds.css' that you can change at your
## will too.
## CFG_TEMPLATE_SKIN -- what template skin do you want to use?
## (example: "default")
<define-tag CFG_TEMPLATE_SKIN whitespace=delete>
default
</define-tag>
## CDSPAGEHEADER -- eventual global HTML page header:
## (example: "")
<define-tag CDSPAGEHEADER>
<div style="background-image: url(<WEBURL>/img/header_background.gif);">
<table class="headerbox">
<tr>
<td rowspan="2" class="headerboxbodylogo">
<!--CDSNAMEINTL-->
</td>
<td align="right" class="userinfoboxbody">
<!--USERINFOBOXBODY-->
</td>
</tr>
<tr>
<td class="headerboxbody" valign="bottom" align="left">
<table class="headermodulebox">
<tr>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="<WEBURL>/?ln=<!--LN-->"><!--MSGSEARCH--></a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="<WEBURL>/submit.py?ln=<!--LN-->"><!--MSGSUBMIT--></a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="<WEBURL>/youraccount.py/display?ln=<!--LN-->"><!--MSGPERSONALIZE--></a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="<WEBURL>/help/index.<!--LN-->.html"><!--MSGHELP--></a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<table class="navtrailbox">
<tr>
<td class="navtrailboxbody">
<!--NAVTRAILBOXBODY-->
</td>
</tr>
</table>
</define-tag>
## CDSPAGEBOXLEFTTOP -- eventual global HTML left top box:
## (example: "")
<define-tag CDSPAGEBOXLEFTTOP>
</define-tag>
## CDSPAGEBOXLEFTBOTTOM -- eventual global HTML left bottom box:
## (example: "")
<define-tag CDSPAGEBOXLEFTBOTTOM>
</define-tag>
## CDSPAGEBOXRIGHTTOP -- eventual global HTML right top box:
## (example: "")
<define-tag CDSPAGEBOXRIGHTTOP>
</define-tag>
## CDSPAGEBOXRIGHTBOTTOM -- eventual global HTML right bottom box:
## (example: "")
<define-tag CDSPAGEBOXRIGHTBOTTOM>
</define-tag>
## CDSPAGEFOOTER -- eventual global HTML page footer:
## (example: "")
<define-tag CDSPAGEFOOTER>
<div class="pagefooterstripeleft">
<!--CDSNAMEINTL-->&nbsp;::&nbsp;<a class="footer" href="<WEBURL>/?ln=<!--LN-->"><!--MSGSEARCH--></a>&nbsp;::&nbsp;<a class="footer" href="<WEBURL>/submit.py?ln=<!--LN-->"><!--MSGSUBMIT--></a>&nbsp;::&nbsp;<a class="footer" href="<WEBURL>/youraccount.py/display?ln=<!--LN-->"><!--MSGPERSONALIZE--></a>&nbsp;::&nbsp;<a class="footer" href="<WEBURL>/help/index.<!--LN-->.html"><!--MSGHELP--></a>
<br>
<!--POWEREDBY--> <a class="footer" href="http://cdsware.cern.ch/">CDSware</a> v<VERSION>
<br>
<!--MAINTAINEDBY--> <a class="footer" href="mailto:<SUPPORTEMAIL>"><SUPPORTEMAIL></a>
<br>
<!--LASTUPDATED-->
</div>
<div class="pagefooterstriperight">
<!--LANGUAGESELECTIONBOX-->
</div>
</define-tag>
################################
## Part 3: CDS navigation bar ##
################################
## The navigation bar and sub-bars are defined in a separate
## "cdsnavbar.wml" file. You may want to modify it now, if you
## really know what you are doing. :-)
##################################
## Part 4: WebSearch parameters ##
##################################
## This section contains some WML-based configuration parameters for
## WebSearch module. Please note that WebSearch is mostly configured
## on run-time via its WebSearch Admin web interface. The parameters
## below are the ones that you do not probably want to modify very
## often during the runtime. (Note that you may modify them
## afterwards too, though.)
## CFG_SEARCH_CACHE_SIZE -- how many queries we want to cache in
## memory per one Apache httpd process? This cache is used mainly for
## "next/previous page" functionality, but it caches also "popular"
## user queries if more than one user happen to search for the same
## thing. Note that large numbers may lead to great memory
## consumption. We recommend a value not greater than 100.
## (example: "100")
<define-tag CFG_SEARCH_CACHE_SIZE whitespace=delete>
100
</define-tag>
## CFG_FIELDS_CONVERT -- if you migrate from an older system, you may
## want to map field codes of your old system (such as 'ti') to
## CDSware/MySQL ("title"). Use Python dictionary syntax for the
## translation table, see the example below. Usually you don't want
## to do that, and would use empty dict {}.
## (example: "{'wau':'author', 'wti':'title'}")
<define-tag CFG_FIELDS_CONVERT whitespace=delete>
{}
</define-tag>
## CFG_GOOGLE_BOX -- on the search results page, do we want propose
## links to other search engines like Google? Put "1" for "yes" and
## "0" for "no".
## (example: "1")
<define-tag CFG_GOOGLE_BOX whitespace=delete>
1
</define-tag>
## CFG_GOOGLE_BOX_SERVERS -- what servers should be proposed in the
## above Google box? See the list of available servers below and put
## "1" for "yes" and "0" for "no" for each server.
<define-tag CFG_GOOGLE_BOX_SERVERS whitespace=delete>
{'Amazon' : 1,
'CERN Intranet' : 1,
'CERN Agenda' : 1,
'CiteSeer' : 1,
'Google Scholar' : 1,
'Google Web' : 1,
'IEC' : 1,
'IHC' : 1,
'INSPEC' : 1,
'ISO' : 1,
'KEK' : 1,
'NEBIS' : 1,
'SPIRES' : 1}
</define-tag>
## CFG_SIMPLESEARCH_PATTERN_BOX_WIDTH -- width of the search pattern
## window in the simple search interface, in characters.
## (example: "50")
<define-tag CFG_SIMPLESEARCH_PATTERN_BOX_WIDTH whitespace=delete>
40
</define-tag>
## CFG_ADVANCEDSEARCH_PATTERN_BOX_WIDTH -- width of the search pattern
## window in the advanced search interface, in characters.
## (example: "50")
<define-tag CFG_ADVANCEDSEARCH_PATTERN_BOX_WIDTH whitespace=delete>
30
</define-tag>
## CFG_NB_RECORDS_TO_SORT -- how many records do we still want to
## sort? For higher numbers we print only a warning and won't perform
## any sorting other than default 'latest records first', as sorting
## would be very time consuming then. We recommend a value of not
## more than a couple of thousands.
## (example: "1000")
<define-tag CFG_NB_RECORDS_TO_SORT whitespace=delete>
1000
</define-tag>
## CFG_CALL_BIBFORMAT -- if "HTML detailed" format is not found, do we
## want to call BibFormat on the fly? Put "1" for "yes" and "0" for
## "no". Usually we want to have "0' here.
## (example: "0")
<define-tag CFG_CALL_BIBFORMAT whitespace=delete>
0
</define-tag>
## CFG_USE_OLD_SYSNOS -- do we want to make old SYSNOs visible rather
## than MySQL's record IDs? You may use this if you migrate from a
## different e-doc system, and you store your old system numbers into
## 909C0o. Put "1" for "yes" and "0" for "no". Usually you don't want
## to do that, though.
## (example: "0")
<define-tag CFG_USE_OLD_SYSNOS whitespace=delete>
0
</define-tag>
## CFG_NB_LATEST_ADDITIONS -- the number of records to display under
## 'Latest Additions' in the web collection pages
## (example: "10")
<define-tag CFG_NB_LATEST_ADDITIONS whitespace=delete>
10
</define-tag>
## CFG_AUTHOR_ET_AL_THRESHOLD -- up to how many author names to print
## explicitely; for more print "et al". Note that this is used in
## default formatting that is seldomly used, as usually BibFormat
## defines all the format. The value below is only used when
## BibFormat fails, for example.
## (example: "3")
<define-tag CFG_AUTHOR_ET_AL_THRESHOLD whitespace=delete>
3
</define-tag>
## CFG_NARROW_SEARCH_SHOW_GRANDSONS -- whether to show or not
## collection grandsons in Narrow Search boxes (sons are shown
## by default, grandsons are configurable here). Use 0 for no
## and 1 for yes.
## (example: "0")
<define-tag CFG_NARROW_SEARCH_SHOW_GRANDSONS whitespace=delete>
1
</define-tag>
## CFG_CREATE_SIMILARLY_NAMED_AUTHORS_LINK_BOX -- shall we create help
## links for Ellis, Nick or Ellis, Nicholas and friends when Ellis, N
## was searched for? Useful if you have one author stored in the
## database under several name formats, namely surname comma firstname
## and surname comma initial cataloging policy. Use 0 for no and 1
## for yes.
## (example: "1")
<define-tag CFG_CREATE_SIMILARLY_NAMED_AUTHORS_LINK_BOX whitespace=delete>
1
</define-tag>
#######################################
## Part 5: BibHarvest OAI parameters ##
#######################################
## This part defines parameters for the CDSware OAI gateway.
## Useful if you are running CDSware as OAI data provider.
## OAIIDSCHEME -- OAI identifier scheme:
## (example: "oai")
<define-tag OAIIDSCHEME whitespace=delete>
oai
</define-tag>
## OAIIDTAG -- OAI identifier tag:
## (example: "0248_a")
<define-tag OAIIDTAG whitespace=delete>
909COo
</define-tag>
## OAISETTAG -- OAI set tag:
## (example: "0248_p")
<define-tag OAISETTAG whitespace=delete>
909COp
</define-tag>
## OAIDELETEDTAG -- OAI tag for deleted records mark. OAI record is considered deleted if the value of this field is set to "DELETED" and the OAI deleted records policy is set either to ``transient'' or ``persistent''.
## (example: "980__c")
<define-tag OAIDELETEDTAG whitespace=delete>
980__c
</define-tag>
## OAIDELETEDPOLICY -- OAI deletedrecordspolicy
## (example: no/transient/persistent)
<define-tag OAIDELETEDPOLICY whitespace=delete>
no
</define-tag>
## OAIIDPREFIX -- OAI identifier prefix:
## (example: "cds.cern.ch")
<define-tag OAIIDPREFIX whitespace=delete>
atlantis.cern.ch
</define-tag>
## OAISAMPLEIDENTIFIER -- OAI sample identifier:
## (example: "oai:cds.cern.ch:CERN-TH-4036")
<define-tag OAISAMPLEIDENTIFIER whitespace=delete>
<OAIIDSCHEME>:<OAIIDPREFIX>:CERN-TH-4036
</define-tag>
## OAIIDENTIFYDESCRIPTION -- description for the OAI Identify verb (optional):
## (example:"")
<define-tag OAIIDENTIFYDESCRIPTION whitespace=delete>
<description>
<oai-identifier xmlns="http://www.openarchives.org/OAI/2.0/oai-identifier"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier
http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">
<scheme>
<OAIIDSCHEME>
</scheme>
<repositoryIdentifier>
<OAIIDPREFIX>
</repositoryIdentifier>
<delimiter>
:
</delimiter>
<sampleIdentifier>
<OAISAMPLEIDENTIFIER>
</sampleIdentifier>
</oai-identifier>
</description>
<description>
<eprints xmlns="http://www.openarchives.org/OAI/1.1/eprints"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/eprints
http://www.openarchives.org/OAI/1.1/eprints.xsd">
<content>
<URL>http://<OAIIDPREFIX>/</URL>
</content>
<metadataPolicy>
<text>Free and unlimited use by anybody with obligation to refer to original record</text>
</metadataPolicy>
<dataPolicy>
<text>Full content, i.e. preprints may not be harvested by robots</text>
</dataPolicy>
<submissionPolicy>
<text>Submission restricted. Submitted documents are subject of approval by OAI repository admins.</text>
</submissionPolicy>
</eprints>
</description>
</define-tag>
## OAILOAD -- OAI number of records in a response:
## (example: "1000")
<define-tag OAILOAD whitespace=delete>
1000
</define-tag>
## OAIEXPIRE -- OAI resumptionToken expiration time:
## (example: "1000")
<define-tag OAIEXPIRE whitespace=delete>
90000
</define-tag>
## OAISLEEP -- service unavailable between two consecutive requests for OAISLEEP seconds
## (example: "10")
<define-tag OAISLEEP whitespace=delete>
10
</define-tag>
##################################
## Part 6: WebSubmit parameters ##
##################################
## This section contains some WML-based configuration parameters for
## WebSubmit module. Please note that WebSubmit is mostly configured
## on run-time via its WebSubmit Admin web interface. The parameters
## below are the ones that you do not probably want to modify during
## the runtime.
## CFG_SUBMIT_COUNTER -- indicates where the counters used by websubmit
## are stored
<define-tag CFG_SUBMIT_COUNTER whitespace=delete>
<DATADIR>/submit/counters
</define-tag>
## CFG_SUBMIT_DIR -- this indicates where the websubmit system will
## keep each submissions running data
<define-tag CFG_SUBMIT_DIR whitespace=delete>
<DATADIR>/submit/storage
</define-tag>
#########################################
## Part 7: Fulltext Archive parameters ##
#########################################
## This section contains some WML-based configuration parameters for
## fulltext archive.
## CFG_FILE_DIR -- this indicates where the fulltext files will be
## stored
<define-tag CFG_FILE_DIR whitespace=delete>
<DATADIR>/files
</define-tag>
## CFG_FILE_DIR_SIZE -- all attached fulltext files are stored
## under the CFG_FILE_DIR directory, inside subdirectories called gX
## this variable indicates the maximum number of files stored in each
## subdirectories
<define-tag CFG_FILE_DIR_SIZE whitespace=delete>
5000
</define-tag>
##################################
## Part 8: BibFormat parameters ##
##################################
## This section contains some WML-based configuration parameters for
## BibFormat module. Please note that BibFormat is mostly configured
## on run-time via its BibFormat Admin web interface. The parameters
## below are the ones that you do not probably want to modify very
## often during the runtime.
## CFG_BIBFORMAT_TIME_LIMIT -- the time limit of BibFormat process
## after which the task will terminate. This is useful to avoid
## eventual runaways.
## (example: "1000")
<define-tag CFG_BIBFORMAT_TIME_LIMIT whitespace=delete>
1000
</define-tag>
#################################
## Part 9: BibIndex parameters ##
#################################
## This section contains some WML-based configuration parameters for
## BibIndex module. Please note that BibIndex is mostly configured
## on run-time via its BibIndex Admin web interface. The parameters
## below are the ones that you do not probably want to modify very
## often during the runtime.
## CFG_BIBINDEX_FULLTEXT_INDEX_LOCAL_FILES_ONLY -- when fulltext indexing, do
## you want to index locally stored files only, or also external URLs?
## Use "0" to say "no" and "1" to say "yes".
## (example: "0")
<define-tag CFG_BIBINDEX_FULLTEXT_INDEX_LOCAL_FILES_ONLY whitespace=delete>
0
</define-tag>
## CFG_BIBINDEX_STEMMER_DEFAULT_LANGUAGE -- when indexing, do you want to use
## stemming? If so, stem according to which language? Use '' for
## no stemming, 'fr' for French, 'en' for English, 'no' for Norwegian,
## 'sv' for Swedish, 'de' for German, 'it' for Italian, 'pt' for
## Portuguese'. This feature is still somewhat experimental. We
## recommend to say nothing ("") at this stage of things.
## (example: "")
<define-tag CFG_BIBINDEX_STEMMER_DEFAULT_LANGUAGE whitespace=delete>
</define-tag>
## CFG_BIBINDEX_REMOVE_STOPWORDS -- when indexing, do we want to remove
## stopwords? Use "0" to say "no" and "1" to say "yes".
## (example: "0")
<define-tag CFG_BIBINDEX_REMOVE_STOPWORDS whitespace=delete>
0
</define-tag>
## CFG_BIBINDEX_PATH_TO_STOPWORDS_FILE -- path to the stopwords file. You
## probably don't want to change this path, although you may want to
## change the content of that file. Note that the file is used by the
## rank engine internally, so it should be given even if stopword
## removal in the indexes is not used.
<define-tag CFG_BIBINDEX_PATH_TO_STOPWORDS_FILE whitespace=delete>
<ETCDIR>/bibrank/stopwords.kb
</define-tag>
## CFG_BIBINDEX_CHARS_ALPHANUMERIC_SEPARATORS -- characters considered as
## alphanumeric separators of word-blocks inside words. You probably
## don't want to change this.
## (example: "\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~")
<define-tag CFG_BIBINDEX_CHARS_ALPHANUMERIC_SEPARATORS whitespace=delete>
\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~
</define-tag>
## CFG_BIBINDEX_CHARS_PUNCTUATION -- characters considered as punctuation
## between word-blocks inside words. You probably don't want to
## change this.
## (example: "\.\,\:\;\?\!\"")
<define-tag CFG_BIBINDEX_CHARS_PUNCTUATION whitespace=delete>
\.\,\:\;\?\!\"
</define-tag>
## CFG_BIBINDEX_REMOVE_HTML_MARKUP -- should we attempt to remove HTML markup
## before indexing? Use 1 if you have HTML markup inside metadata
## (e.g. in abstracts), use 0 otherwise.
## (example: "0")
<define-tag CFG_BIBINDEX_REMOVE_HTML_MARKUP whitespace=delete>
0
</define-tag>
## CFG_BIBINDEX_MIN_WORD_LENGTH -- minimum word length allowed to be added to
## index. The terms smaller then this amount will be discarded.
## Useful to keep the database clean, however you can safely leave
## this value on 0 for up to 1,000,000 documents.
## (example: "0")
<define-tag CFG_BIBINDEX_MIN_WORD_LENGTH whitespace=delete>
0
</define-tag>
## CFG_BIBINDEX_URLOPENER_USERNAME and CFG_BIBINDEX_URLOPENER_PASSWORD --
## access credentials to access restricted URLs, interesting only if
## you are fulltext-indexing files located on a remote server that is
## only available via username/password. But it's probably better to
## handle this case via IP or some convention; the current scheme is
## mostly there for demo only.
## (example: "mysuperuser")
<define-tag CFG_BIBINDEX_URLOPENER_USERNAME whitespace=delete>
mysuperuser
</define-tag>
<define-tag CFG_BIBINDEX_URLOPENER_PASSWORD whitespace=delete>
mysuperpass
</define-tag>
########################################
## Part 10: Access control parameters ##
########################################
## This section contains some WML-based configuration parameters for
## the access control system. Please note that WebAccess is mostly
## configured on run-time via its WebAccess Admin web interface. The
## parameters below are the ones that you do not probably want to
## modify very often during the runtime. (If you do want to modify
## them during runtime, for example te deny access temporarily because
## of backups, you can edit access_control_config.py directly, no need
## to get back here and no need to redo the make process.)
## CFG_ACCESS_CONTROL_LEVEL_SITE -- defines how open this site is.
## Use 0 for normal operation of the site, 1 for read-only site (all
## write operations temporarily closed), 2 for site fully closed.
## Useful for site maintenance.
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_LEVEL_SITE whitespace=delete>
0
</define-tag>
## CFG_ACCESS_CONTROL_LEVEL_GUESTS -- guest users access policy. Use
## 0 to allow guest users, 1 not to allow them (all users must login).
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_LEVEL_GUESTS whitespace=delete>
0
</define-tag>
## CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS -- account registration and
## activation policy. When 0, users can register and accounts are
## automatically activated. When 1, users can register but admin must
## activate the accounts. When 2, users cannot register nor update
## their email address, only admin can register accounts. When 3,
## users cannot register nor update email address nor password, only
## admin can register accounts. When 4, the same as 3 applies, nor
## user cannot change his login method.
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS whitespace=delete>
0
</define-tag>
## CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN -- limit account
## registration to certain email addresses? If wanted, give domain
## name below. If not wanted, leave it empty.
## (example: "cern.ch"):
<define-tag CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN whitespace=delete>
</define-tag>
## CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS -- send a
## notification email to the administrator when a new account is
## created? Use 0 for no, 1 for yes.
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS whitespace=delete>
0
</define-tag>
## CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT -- send a
## notification email to the user when a new account is created? Use
## 0 for no, 1 for yes.
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT whitespace=delete>
0
</define-tag>
## CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION -- send a
## notification email to the user when a new account is activated?
## Use 0 for no, 1 for yes.
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION whitespace=delete>
0
</define-tag>
## CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION -- send a
## notification email to the user when a new account is deleted or
## account demand rejected? Use 0 for no, 1 for yes.
## (example: "0")
<define-tag CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION whitespace=delete>
0
</define-tag>
##########################
## THAT's ALL, FOLKS! ##
##########################
## And this is the end of "config.wml" WML configuration phase. Now
## please return to the main CDS source directory and type 'make'.
## (Note: if you have bravely edited the "cdsnavbar.wml" file too,
## then please do "make clean" before doing "make".)
diff --git a/config/configbis.wml.in b/config/configbis.wml.in
index e1f5e9a29..af0dd964a 100644
--- a/config/configbis.wml.in
+++ b/config/configbis.wml.in
@@ -1,176 +1,176 @@
## $Id$
## DO NOT TOUCH ANY OF THE ``configbis.wml'' AND ``configbis.wml.in''
## FILES. IF YOU DO EDIT THEM, BAD THINGS MAY HAPPEN. YOU HAVE BEEN
## WARNED!
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read autoconf parameters and define new WML tags out of them:
<define-tag VERSION whitespace=delete>
@VERSION@
</define-tag>
<define-tag WML whitespace=delete>
@WML@
</define-tag>
<define-tag MYSQL whitespace=delete>
@MYSQL@
</define-tag>
<define-tag PHP whitespace=delete>
@PHP@
</define-tag>
<define-tag PYTHON whitespace=delete>
@PYTHON@
</define-tag>
<define-tag BINDIR whitespace=delete>
@prefix@/bin
</define-tag>
<define-tag LIBDIR whitespace=delete>
@prefix@/lib
</define-tag>
<define-tag LOGDIR whitespace=delete>
@localstatedir@/log
</define-tag>
<define-tag ETCDIR whitespace=delete>
@prefix@/etc
</define-tag>
<define-tag LOCALEDIR whitespace=delete>
@prefix@/share/locale
</define-tag>
<define-tag TMPDIR whitespace=delete>
@localstatedir@/tmp
</define-tag>
<define-tag CACHEDIR whitespace=delete>
@localstatedir@/cache
</define-tag>
<define-tag DATADIR whitespace=delete>
@localstatedir@/data
</define-tag>
<define-tag WEBDIR whitespace=delete>
@WEBDIR@
</define-tag>
<define-tag WEBURL whitespace=delete>
@WEBURL@
</define-tag>
<define-tag DBHOST whitespace=delete>
@DBHOST@
</define-tag>
<define-tag DBNAME whitespace=delete>
@DBNAME@
</define-tag>
<define-tag DBUSER whitespace=delete>
@DBUSER@
</define-tag>
<define-tag DBPASS whitespace=delete>
@DBPASS@
</define-tag>
<define-tag LYNX whitespace=delete>
@LYNX@
</define-tag>
<define-tag ACROREAD whitespace=delete>
@ACROREAD@
</define-tag>
<define-tag GZIP whitespace=delete>
@GZIP@
</define-tag>
<define-tag GUNZIP whitespace=delete>
@GUNZIP@
</define-tag>
<define-tag TAR whitespace=delete>
@TAR@
</define-tag>
<define-tag DISTILLER whitespace=delete>
@PS2PDF@
</define-tag>
<define-tag GFILE whitespace=delete>
@FILE@
</define-tag>
<define-tag DJPEG whitespace=delete>
@DJPEG@
</define-tag>
<define-tag CONVERT whitespace=delete>
@CONVERT@
</define-tag>
<define-tag GIFTEXT whitespace=delete>
@GIFTEXT@
</define-tag>
<define-tag JPEGSIZE whitespace=delete>
@JPEGSIZE@
</define-tag>
<define-tag PNMSCALE whitespace=delete>
@PNMSCALE@
</define-tag>
<define-tag PPMQUANT whitespace=delete>
@PPMQUANT@
</define-tag>
<define-tag PPMTOGIF whitespace=delete>
@PPMTOGIF@
</define-tag>
<define-tag GIFINTER whitespace=delete>
@GIFINTER@
</define-tag>
<define-tag GIFRSIZE whitespace=delete>
@GIFRSIZE@
</define-tag>
<define-tag PDFTOTEXT whitespace=delete>
@PDFTOTEXT@
</define-tag>
<define-tag PSTOTEXT whitespace=delete>
@PSTOTEXT@
</define-tag>
<define-tag PSTOASCII whitespace=delete>
@PSTOASCII@
</define-tag>
<define-tag ANTIWORD whitespace=delete>
@ANTIWORD@
</define-tag>
<define-tag CATDOC whitespace=delete>
@CATDOC@
</define-tag>
<define-tag WVTEXT whitespace=delete>
@WVTEXT@
</define-tag>
<define-tag PPTHTML whitespace=delete>
@PPTHTML@
</define-tag>
<define-tag XLHTML whitespace=delete>
@XLHTML@
</define-tag>
<define-tag HTMLTOTEXT whitespace=delete>
@HTMLTOTEXT@
</define-tag>
<define-tag CLISP whitespace=delete>
@CLISP@
</define-tag>
<define-tag CMUCL whitespace=delete>
@CMUCL@
</define-tag>
<define-tag SBCL whitespace=delete>
@SBCL@
</define-tag>
<define-tag GNUPLOT whitespace=delete>
@GNUPLOT@
</define-tag>
diff --git a/configure-tests.py b/configure-tests.py
index 664420257..735c62aff 100644
--- a/configure-tests.py
+++ b/configure-tests.py
@@ -1,235 +1,235 @@
"""
Test the suitability of Python core and the availability of various
Python modules for running CDSware. Warn the user if there are
eventual troubles. Exit status: 0 if okay, 1 if not okay. Useful for
running from configure.ac.
"""
## $Id$
## Tests availability of Python modules and their versions.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__version__ = "$Id$"
## minimally recommended/required versions:
cfg_min_python_version = "2.3"
cfg_min_mysqldb_version = "0.9.2"
cfg_min_numeric_version = "21.0"
## 0) import modules needed for this testing:
import string
import sys
import getpass
## 1) check Python version:
if sys.version < cfg_min_python_version:
print """
*******************************************************
** WARNING: OLD PYTHON DETECTED: %s
*******************************************************
** You seem to be using an old version of Python. **
** **
** Note that if you have more than one Python **
** installed on your system, you can specify the **
** --with-python configuration option to choose **
** a specific (e.g. non system wide) Python binary. **
** **
** We strongly recommend you to run CDSware with **
** at least Python %s. Some older versions **
** were known to be problematic with respect to **
** encodings and mod_python, see for example **
** <http://www.modpython.org/pipermail/mod_python/2002-October/002607.html>.
** **
** Note that some operating systems (such as Debian) **
** may backport important bugfixes to older Python **
** releases, so your concrete Python installation **
** may be immune to these problems already. **
** If you are not sure, you may continue the CDSware **
** installation now and recall that in case of **
** problems you may need to upgrade Python and **
** reinstall CDSware from scratch. **
*******************************************************
""" % (string.replace(sys.version, "\n", ""), cfg_min_python_version)
try:
getpass.getpass("Press ENTER to continue the installation anyhow...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
## 2) check for required modules:
try:
import MySQLdb
import Numeric
import base64
import cPickle
import cStringIO
import cgi
import copy
import fileinput
import getopt
import marshal
import md5
import os
import signal
import sre
import string
import tempfile
import time
import traceback
import unicodedata
import urllib
import zlib
except ImportError, e:
print """
*************************************************
** ERROR: PYTHON IMPORT FAILURE %s
*************************************************
** Perhaps you forgot to install some of the **
** prerequisite Python modules? Please look **
** at our INSTALL file for more details and **
** fix the problem before continuing! **
*************************************************
""" % e
sys.exit(1)
## 3) check for recommended modules:
try:
import psyco
except ImportError, e:
print """
*****************************************************
** WARNING: PYTHON IMPORT WARNING %s
*****************************************************
** Note that Psyco is not really required but **
** we recommend it for faster CDSware operation. **
** **
** You can safely continue installing CDSware now, **
** and add this module anytime later. (I.e. even **
** after your CDSware installation is put into **
** production.) **
*****************************************************
""" % e
try:
getpass.getpass("Press ENTER to continue the installation...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
try:
import Stemmer
except ImportError, e:
print """
*****************************************************
** WARNING: PYTHON IMPORT WARNING %s
*****************************************************
** Note that PyStemmer is not really required but **
** we recommend it to enable the stemming feature **
** in the indexing engine and to bump up the speed **
** and accuracy of word-frequency based rankings. **
** **
** You can safely continue installing CDSware now, **
** and add this module anytime later. (But better **
** before you firstly run the indexation/ranking **
** on real production data.) **
*****************************************************
""" % e
try:
getpass.getpass("Press ENTER to continue the installation...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
try:
import pyRXP
except ImportError, e:
print """
*****************************************************
** WARNING: PYTHON IMPORT WARNING %s
*****************************************************
** Note that PyRXP is not really required but **
** we recommend it for fast XML MARC parsing. **
** **
** You can safely continue installing CDSware now, **
** and add this module anytime later. (I.e. even **
** after your CDSware installation is put into **
** production.) **
*****************************************************
""" % e
try:
getpass.getpass("Press ENTER to continue the installation...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
try:
import Gnuplot
except ImportError, e:
print """
*****************************************************
** WARNING: PYTHON IMPORT WARNING %s
*****************************************************
** Note that Gnuplot.py is not really required but **
** we recommend it in order to have nice download **
** and citation history graphs on Detailed record **
** pages. **
** **
** You can safely continue installing CDSware now, **
** and add this module anytime later. (I.e. even **
** after your CDSware installation is put into **
** production.) **
*****************************************************
""" % e
try:
getpass.getpass("Press ENTER to continue the installation...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
## 4) check for versions of some important modules:
if MySQLdb.__version__ < cfg_min_mysqldb_version:
print """
*****************************************************
** WARNING: PYTHON MODULE MYSQLDB %s DETECTED
*****************************************************
** We strongly recommend you to upgrade `MySQLdb' **
** to at least version %s. See the INSTALL **
** file for more details. **
*****************************************************
""" % (MySQLdb.__version__, cfg_min_mysqldb_version)
try:
getpass.getpass("Press ENTER to continue the installation anyhow...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
if Numeric.__version__ < cfg_min_numeric_version:
print """
*****************************************************
** WARNING: PYTHON MODULE NUMERIC %s DETECTED
*****************************************************
** We strongly recommend you to upgrade `Numeric' **
** to at least version %s. See the INSTALL **
** file for more details. **
*****************************************************
""" % (Numeric.__version__, cfg_min_numeric_version)
try:
getpass.getpass("Press ENTER to continue the installation anyhow...")
except KeyboardInterrupt:
print "\n\nInstallation aborted."
sys.exit(1)
diff --git a/configure.ac b/configure.ac
index f5a32031a..1ec6f522a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,697 +1,697 @@
## $Id$
## Purpose: CERN Document Server Software (CDSware) main configure.ac file.
## Note: If you change this file, please run "autoreconf" to regenerate the "configure" script.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Initialize autoconf and automake:
AC_INIT(cdsware, 0.9.0.20060427, cds.support@cern.ch)
AM_INIT_AUTOMAKE(cdsware, 0.9.0.20060427)
## Check for install:
AC_PROG_INSTALL
## Define WEBDIR directory:
AC_ARG_WITH(webdir, AC_HELP_STRING([--with-webdir], [specify where the web files go (e.g. /var/www/cdsware/)]), WEBDIR=${withval})
if test -z "$WEBDIR"; then
AC_MSG_ERROR([
You have not used the "--with-webdir" argument that should define the installation directory for Web programs and documents.
Example: "--with-webdir=/var/www/cdsware/".])
fi
## Define WEBURL URL:
AC_ARG_WITH(weburl, AC_HELP_STRING([--with-weburl], [specify URL where web files will be reached (e.g. http://cdsdev.cern.ch/cdsware/)]), WEBURL=${withval})
if test -z "$WEBURL"; then
AC_MSG_ERROR([
You have not used the "--with-weburl" argument that should define the corresponding URL where the site will be reached.
Example: "--with-weburl=http://webserver.domain.com/cdsware/".])
fi
## Define DBHOST database host:
AC_ARG_WITH(dbhost, AC_HELP_STRING([--with-dbhost], [specify DB server (e.g. cdsdb.cern.ch)]), DBHOST=${withval})
if test -z "$DBHOST"; then
AC_MSG_ERROR([
You have not used the "--with-dbhost" argument that should define which DB server to use.
Example: "--with-dbhost=sqlserver.domain.com".])
fi
## Define DBNAME database name:
AC_ARG_WITH(dbname, AC_HELP_STRING([--with-dbname], [specify DB name (e.g. cdsware)]), DBNAME=${withval})
if test -z "$DBNAME"; then
AC_MSG_ERROR([
You have not used the "--with-dbname" argument that should define DB name.
Example: "--with-dbname=cdsware".])
fi
## Define DBUSER user name:
AC_ARG_WITH(dbuser, AC_HELP_STRING([--with-dbuser], [specify DB user name (e.g. cdsware)]), DBUSER=${withval})
if test -z "$DBUSER"; then
AC_MSG_ERROR([
You have not used the "--with-dbuser" argument that should define DB user name.
Example: "--with-dbuser=cdsware".])
fi
## Define DBPASS user password:
AC_ARG_WITH(dbpass, AC_HELP_STRING([--with-dbpass], [specify DB user password (e.g. myp1ss)]), DBPASS=${withval})
if test -z "$DBPASS"; then
AC_MSG_ERROR([
You have not used the "--with-dbpass" argument that should define DB user password.
Example: "--with-dbpass=myp1ss".])
fi
## Check for gettext support
AM_GNU_GETTEXT(external)
## Check for WML:
AC_PATH_PROG(WML, wml)
if test -z "$WML"; then
AC_MSG_ERROR([
WML (Website META Language) was not found in your PATH. Please install it first.
Available from <http://www.engelschall.com/sw/wml/>.])
fi
## Set option -c in WML so that it can work from a separate build tree
WML="${WML} -c"
## Check for MySQL client:
AC_PATH_PROG(MYSQL, mysql)
if test -z "$MYSQL"; then
AC_MSG_ERROR([
MySQL command-line client was not found in your PATH. Please install it first.
Available from <http://mysql.com/>.])
fi
## Check for Python:
AC_MSG_CHECKING(for python)
AC_ARG_WITH(python, AC_HELP_STRING([--with-python], [path to a specific Python binary (optional)]), PYTHON=${withval})
if test -n "$PYTHON"; then
AC_MSG_RESULT($PYTHON)
else
AC_PATH_PROG(PYTHON, python)
if test -z "$PYTHON"; then
AC_MSG_ERROR([
Python was not found in your PATH. Please either install it
in your PATH or specify --with-python configure option.
Python is available from <http://python.org/>.])
fi
fi
## Check for Python version and modules:
AC_MSG_CHECKING(for required Python modules)
$PYTHON ${srcdir}/configure-tests.py
if test $? -ne 0; then
AC_MSG_ERROR([Please fix the above Python problems before continuing.])
fi
AC_MSG_RESULT(found)
## Check for PHP:
AC_PATH_PROG(PHP, php)
if test -z "$PHP"; then
AC_MSG_ERROR([
PHP standalone command-line executable (i.e. not compiled as Apache module!)
was not found in your PATH. Please install it first.
Available from <http://www.php.net/manual/en/install.commandline.php>.])
fi
## Check for Acrobat Reader:
AC_PATH_PROG(ACROREAD, acroread)
if test -z "$ACROREAD"; then
AC_MSG_WARN([
Acrobat Reader was not found in your PATH. It is used in
the WebSubmit module for automatic conversion of submitted documents.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. Acrobat Reader is available from
<http://www.adobe.com/products/acrobat/readstep.html>.])
fi
## Check for gzip:
AC_PATH_PROG(GZIP, gzip)
if test -z "$GZIP"; then
AC_MSG_WARN([
Gzip was not found in your PATH. It is used in
the WebSubmit module to compress the data submitted in an archive.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. Gzip is available from
<http://www.gzip.org/>.])
fi
## Check for gunzip:
AC_PATH_PROG(GUNZIP, gunzip)
if test -z "$GUNZIP"; then
AC_MSG_WARN([
Gunzip was not found in your PATH. It is used in
the WebSubmit module to correctly deal with submitted compressed
files.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. Gunzip is available from
<http://www.gzip.org/>.])
fi
## Check for tar:
AC_PATH_PROG(TAR, tar)
if test -z "$TAR"; then
AC_MSG_WARN([
Tar was not found in your PATH. It is used in
the WebSubmit module to pack the submitted data into an archive.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. Tar is available from
<ftp://prep.ai.mit.edu/pub/gnu/tar/>.])
fi
## Check for ps2pdf:
AC_PATH_PROG(PS2PDF, ps2pdf)
if test -z "$PS2PDF"; then
AC_MSG_WARN([
ps2pdf was not found in your PATH. It is used in
the WebSubmit module to convert submitted PostScripts into PDF.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. PS2PDF is available from
<http://www.cs.wisc.edu/~ghost/doc/AFPL/6.50/Ps2pdf.htm>.])
fi
## Check for pdftotext:
AC_PATH_PROG(PDFTOTEXT, pdftotext)
if test -z "$PDFTOTEXT"; then
AC_MSG_WARN([
pdftotext was not found in your PATH. It is used for the fulltext indexation
of PDF files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. pdftotext is available from <http://www.foolabs.com/xpdf/home.html>.
])
fi
## Check for pstotext:
AC_PATH_PROG(PSTOTEXT, pstotext)
if test -z "$PSTOTEXT"; then
AC_MSG_WARN([
pstotext was not found in your PATH. It is used for the fulltext indexation
of PDF and PostScript files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. pstotext is available from <http://www.cs.wisc.edu/~ghost/doc/AFPL/>.
])
fi
## Check for ps2ascii:
AC_PATH_PROG(PSTOASCII, ps2ascii)
if test -z "$PSTOASCII"; then
AC_MSG_WARN([
ps2ascii was not found in your PATH. It is used for the fulltext indexation
of PostScript files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. ps2ascii is available from <http://www.cs.wisc.edu/~ghost/doc/AFPL/>.
])
fi
## Check for antiword:
AC_PATH_PROG(ANTIWORD, antiword)
if test -z "$ANTIWORD"; then
AC_MSG_WARN([
antiword was not found in your PATH. It is used for the fulltext indexation
of Microsoft Word files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. antiword is available from <http://www.winfield.demon.nl/index.html>.
])
fi
## Check for catdoc:
AC_PATH_PROG(CATDOC, catdoc)
if test -z "$CATDOC"; then
AC_MSG_WARN([
catdoc was not found in your PATH. It is used for the fulltext indexation
of Microsoft Word files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. catdoc is available from <http://www.ice.ru/~vitus/catdoc/index.html>.
])
fi
## Check for wvText:
AC_PATH_PROG(WVTEXT, wvText)
if test -z "$WVTEXT"; then
AC_MSG_WARN([
wvText was not found in your PATH. It is used for the fulltext indexation
of Microsoft Word files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. wvText is available from <http://sourceforge.net/projects/wvware>.
])
fi
## Check for ppthtml:
AC_PATH_PROG(PPTHTML, ppthtml)
if test -z "$PPTHTML"; then
AC_MSG_WARN([
ppthtml was found in your PATH. It is used for the fulltext indexation
of Microsoft PowerPoint files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. ppthtml is available from <http://www.xlhtml.org/>.
])
fi
## Check for xlhtml:
AC_PATH_PROG(XLHTML, xlhtml)
if test -z "$XLHTML"; then
AC_MSG_WARN([
xlhtml was found in your PATH. It is used for the fulltext indexation
of Microsoft Excel files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. xlhtml is available from <http://chicago.sourceforge.net/xlhtml/>.
])
fi
## Check for html2text:
AC_PATH_PROG(HTMLTOTEXT, html2text)
if test -z "$HTMLTOTEXT"; then
AC_MSG_WARN([
html2text was found in your PATH. It is used for the fulltext indexation
of Microsoft PowerPoint and Excel files.
You can continue without it but you may miss fulltext searching capability
of CDSware. We recomend you to install it first and to rerun the configure
script. html2text is available from <http://userpage.fu-berlin.de/~mbayer/tools/html2text.html>.
])
fi
## Check for Giftext:
AC_PATH_PROG(GIFTEXT, giftext)
if test -z "$GIFTEXT"; then
AC_MSG_WARN([
Giftext was not found in your PATH. It is used in
the WebSubmit module to create an icon from a submitted picture.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. Giftext is available from
<http://prtr-13.ucsc.edu/~badger/software/libungif/getting.shtml>.])
fi
## Check for file:
AC_PATH_PROG(FILE, file)
if test -z "$FILE"; then
AC_MSG_WARN([
File was not found in your PATH. It is used in
the WebSubmit module to check the validity of the submitted files.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. File is available from
<ftp://ftp.astron.com/pub/file/>.])
fi
## Check for convert:
AC_PATH_PROG(CONVERT, convert)
if test -z "$CONVERT"; then
AC_MSG_WARN([
Convert was not found in your PATH. It is used in
the WebSubmit module to create an icon from a submitted picture.
You can continue without it but you will miss some CDSware
functionality. We recommend you to install it first and to rerun
the configure script. Convert is available from
<http://www.imagemagick.org/>.])
fi
## Check for CLISP:
AC_MSG_CHECKING(for clisp)
AC_ARG_WITH(clisp, AC_HELP_STRING([--with-clisp], [path to a specific CLISP binary (optional)]), CLISP=${withval})
if test -n "$CLISP"; then
AC_MSG_RESULT($CLISP)
else
AC_PATH_PROG(CLISP, clisp)
if test -z "$CLISP"; then
AC_MSG_WARN([
GNU CLISP was not found in your PATH. It is used by the WebStat
module to produce statistics about CDSware usage. (Alternatively,
SBCL or CMUCL can be used instead of CLISP.)
You can continue without it but you will miss this feature. We
recommend you to install it first (if you don't have neither CMUCL
nor SBCL) and to rerun the configure script.
GNU CLISP is available from <http://clisp.cons.org/>.])
fi
fi
## Check for CMUCL:
AC_MSG_CHECKING(for cmucl)
AC_ARG_WITH(cmucl, AC_HELP_STRING([--with-cmucl], [path to a specific CMUCL binary (optional)]), CMUCL=${withval})
if test -n "$CMUCL"; then
AC_MSG_RESULT($CMUCL)
else
AC_PATH_PROG(CMUCL, cmucl)
if test -z "$CMUCL"; then
AC_MSG_CHECKING(for lisp) # CMUCL can also be installed under `lisp' exec name
AC_PATH_PROG(CMUCL, lisp)
fi
if test -z "$CMUCL"; then
AC_MSG_WARN([
CMUCL was not found in your PATH. It is used by the WebStat
module to produce statistics about CDSware usage. (Alternatively,
CLISP or SBCL can be used instead of CMUCL.)
You can continue without it but you will miss this feature. We
recommend you to install it first (if you don't have neither CLISP
nor SBCL) and to rerun the configure script.
CMUCL is available from <http://www.cons.org/cmucl/>.])
fi
fi
## Check for SBCL:
AC_MSG_CHECKING(for sbcl)
AC_ARG_WITH(sbcl, AC_HELP_STRING([--with-sbcl], [path to a specific SBCL binary (optional)]), SBCL=${withval})
if test -n "$SBCL"; then
AC_MSG_RESULT($SBCL)
else
AC_PATH_PROG(SBCL, sbcl)
if test -z "$SBCL"; then
AC_MSG_WARN([
SBCL was not found in your PATH. It is used by the WebStat
module to produce statistics about CDSware usage. (Alternatively,
CLISP or CMUCL can be used instead of SBCL.)
You can continue without it but you will miss this feature. We
recommend you to install it first (if you don't have neither CLISP
nor CMUCL) and to rerun the configure script.
SBCL is available from <http://sbcl.sourceforge.net/>.])
fi
fi
## Check for gnuplot:
AC_PATH_PROG(GNUPLOT, gnuplot)
if test -z "$GNUPLOT"; then
AC_MSG_WARN([
Gnuplot was not found in your PATH. It is used by the BibRank
module to produce graphs about download and citation history.
You can continue without it but you will miss these graphs. We
recommend you to install it first and to rerun the configure script.
Gnuplot is available from <http://www.gnuplot.info/>.])
fi
## Substitute variables:
AC_SUBST(VERSION)
AC_SUBST(WML)
AC_SUBST(MYSQL)
AC_SUBST(PHP)
AC_SUBST(PYTHON)
AC_SUBST(WEBDIR)
AC_SUBST(CLIDIR)
AC_SUBST(WEBURL)
AC_SUBST(DBHOST)
AC_SUBST(DBNAME)
AC_SUBST(DBUSER)
AC_SUBST(DBPASS)
AC_SUBST(PDFTOTEXT)
AC_SUBST(PSTOTEXT)
AC_SUBST(PSTOASCII)
AC_SUBST(ANTIWORD)
AC_SUBST(CATDOC)
AC_SUBST(WVTEXT)
AC_SUBST(PPTHTML)
AC_SUBST(XLHTML)
AC_SUBST(HTMLTOTEXT)
AC_SUBST(localstatedir, `eval echo "${localstatedir}"`)
AC_SUBST(CACHEDIR)
AC_SUBST(CLISP)
AC_SUBST(CMUCL)
AC_SUBST(SBCL)
AC_SUBST(GNUPLOT)
AC_SUBST(DJPEG)
AC_SUBST(CONVERT)
AC_SUBST(GIFTEXT)
AC_SUBST(JPEGSIZE)
AC_SUBST(PNMSCALE)
AC_SUBST(PPMQUANT)
AC_SUBST(PPMTOGIF)
AC_SUBST(GIFINTER)
AC_SUBST(GIFRSIZE)
## Define output files:
AC_CONFIG_FILES([config.nice \
Makefile \
po/Makefile.in \
config/Makefile \
config/configbis.wml \
modules/Makefile \
modules/bibconvert/Makefile \
modules/bibconvert/bin/Makefile \
modules/bibconvert/bin/bibconvert \
modules/bibconvert/doc/Makefile \
modules/bibconvert/doc/admin/Makefile \
modules/bibconvert/doc/hacking/Makefile \
modules/bibconvert/etc/Makefile \
modules/bibconvert/lib/Makefile \
modules/bibmatch/Makefile \
modules/bibmatch/bin/Makefile \
modules/bibmatch/bin/bibmatch \
modules/bibmatch/doc/Makefile \
modules/bibmatch/doc/admin/Makefile \
modules/bibmatch/etc/Makefile \
modules/bibmatch/lib/Makefile \
modules/bibedit/Makefile \
modules/bibedit/bin/Makefile \
modules/bibedit/bin/refextract \
modules/bibedit/bin/xmlmarclint \
modules/bibedit/doc/Makefile \
modules/bibedit/doc/admin/Makefile \
modules/bibedit/doc/hacking/Makefile \
modules/bibedit/etc/Makefile \
modules/bibedit/lib/Makefile \
modules/bibedit/web/Makefile \
modules/bibedit/web/admin/Makefile \
modules/bibformat/Makefile \
modules/bibformat/bin/Makefile \
modules/bibformat/bin/bibformat \
modules/bibformat/bin/bibreformat \
modules/bibformat/doc/Makefile \
modules/bibformat/doc/admin/Makefile \
modules/bibformat/doc/hacking/Makefile \
modules/bibformat/lib/Makefile \
modules/bibformat/lib/core/Makefile \
modules/bibformat/lib/common/Makefile \
modules/bibformat/web/Makefile \
modules/bibformat/web/admin/Makefile \
modules/bibharvest/Makefile \
modules/bibharvest/bin/Makefile \
modules/bibharvest/bin/bibharvest \
modules/bibharvest/bin/oaiharvest \
modules/bibharvest/bin/oaiarchive \
modules/bibharvest/doc/Makefile \
modules/bibharvest/doc/admin/Makefile \
modules/bibharvest/doc/hacking/Makefile \
modules/bibharvest/lib/Makefile \
modules/bibharvest/web/Makefile \
modules/bibharvest/web/admin/Makefile \
modules/bibclassify/Makefile
modules/bibclassify/bin/Makefile
modules/bibclassify/bin/bibclassify
modules/bibclassify/doc/Makefile \
modules/bibclassify/doc/admin/Makefile \
modules/bibclassify/doc/hacking/Makefile \
modules/bibclassify/etc/Makefile
modules/bibclassify/lib/Makefile
modules/bibindex/Makefile \
modules/bibindex/bin/Makefile \
modules/bibindex/bin/bibindex \
modules/bibindex/bin/bibstat \
modules/bibindex/doc/Makefile \
modules/bibindex/doc/admin/Makefile \
modules/bibindex/doc/hacking/Makefile \
modules/bibindex/lib/Makefile \
modules/bibindex/web/Makefile \
modules/bibindex/web/admin/Makefile \
modules/bibrank/Makefile \
modules/bibrank/bin/Makefile \
modules/bibrank/bin/bibrank \
modules/bibrank/bin/bibrankgkb \
modules/bibrank/doc/Makefile \
modules/bibrank/doc/admin/Makefile \
modules/bibrank/doc/hacking/Makefile \
modules/bibrank/etc/Makefile \
modules/bibrank/etc/bibrankgkb.cfg \
modules/bibrank/etc/demo_jif.cfg \
modules/bibrank/etc/template_single_tag_rank_method.cfg \
modules/bibrank/lib/Makefile \
modules/bibrank/web/Makefile \
modules/bibrank/web/admin/Makefile \
modules/bibsched/Makefile \
modules/bibsched/bin/Makefile \
modules/bibsched/bin/bibsched \
modules/bibsched/bin/bibtaskex \
modules/bibsched/doc/Makefile \
modules/bibsched/doc/admin/Makefile \
modules/bibsched/doc/hacking/Makefile \
modules/bibupload/Makefile \
modules/bibupload/bin/Makefile \
modules/bibupload/bin/bibupload \
modules/bibupload/doc/Makefile \
modules/bibupload/doc/admin/Makefile \
modules/bibupload/doc/hacking/Makefile \
modules/elmsubmit/Makefile \
modules/elmsubmit/bin/Makefile \
modules/elmsubmit/bin/elmsubmit \
modules/elmsubmit/doc/Makefile \
modules/elmsubmit/doc/admin/Makefile \
modules/elmsubmit/doc/hacking/Makefile \
modules/elmsubmit/etc/Makefile \
modules/elmsubmit/etc/elmsubmit.cfg \
modules/elmsubmit/lib/Makefile \
modules/elmsubmit/lib/magic/Makefile \
modules/miscutil/Makefile \
modules/miscutil/bin/Makefile \
modules/miscutil/bin/dbexec \
modules/miscutil/bin/dbtest \
modules/miscutil/bin/testsuite \
modules/miscutil/lib/Makefile \
modules/miscutil/demo/Makefile \
modules/miscutil/sql/Makefile \
modules/miscutil/web/Makefile \
modules/miscutil/doc/Makefile \
modules/miscutil/doc/hacking/Makefile \
modules/webaccess/Makefile \
modules/webaccess/bin/Makefile \
modules/webaccess/bin/authaction \
modules/webaccess/bin/webaccessadmin \
modules/webaccess/doc/Makefile \
modules/webaccess/doc/admin/Makefile \
modules/webaccess/doc/hacking/Makefile \
modules/webaccess/lib/Makefile \
modules/webaccess/web/Makefile \
modules/webaccess/web/admin/Makefile \
modules/webalert/Makefile \
modules/webalert/bin/Makefile \
modules/webalert/bin/alertengine \
modules/webalert/doc/Makefile \
modules/webalert/doc/admin/Makefile \
modules/webalert/doc/hacking/Makefile \
modules/webalert/lib/Makefile \
modules/webalert/web/Makefile \
modules/webhelp/Makefile \
modules/webhelp/web/Makefile \
modules/webhelp/web/hacking/Makefile \
modules/webhelp/web/admin/Makefile \
modules/webhelp/web/admin/howto/Makefile \
modules/websearch/Makefile \
modules/websearch/bin/Makefile \
modules/websearch/bin/webcoll \
modules/websearch/doc/Makefile \
modules/websearch/doc/admin/Makefile \
modules/websearch/doc/hacking/Makefile \
modules/websearch/lib/Makefile \
modules/websearch/web/Makefile \
modules/websearch/web/admin/Makefile \
modules/websession/Makefile \
modules/websession/bin/Makefile \
modules/websession/doc/Makefile \
modules/websession/doc/admin/Makefile \
modules/websession/doc/hacking/Makefile \
modules/websession/lib/Makefile \
modules/websession/web/Makefile \
modules/webstat/Makefile \
modules/webstat/bin/Makefile \
modules/webstat/bin/webstat \
modules/webstat/doc/Makefile \
modules/webstat/doc/admin/Makefile \
modules/webstat/doc/hacking/Makefile \
modules/webstat/etc/Makefile \
modules/webstat/lib/Makefile \
modules/webstyle/Makefile \
modules/webstyle/css/Makefile \
modules/webstyle/doc/Makefile \
modules/webstyle/doc/admin/Makefile \
modules/webstyle/doc/hacking/Makefile \
modules/webstyle/img/Makefile \
modules/webstyle/lib/Makefile \
modules/webcomment/Makefile \
modules/webcomment/doc/Makefile \
modules/webcomment/doc/admin/Makefile \
modules/webcomment/doc/hacking/Makefile \
modules/webcomment/lib/Makefile \
modules/webcomment/web/Makefile \
modules/webcomment/web/admin/Makefile \
modules/webbasket/Makefile \
modules/webbasket/doc/Makefile \
modules/webbasket/doc/admin/Makefile \
modules/webbasket/doc/hacking/Makefile \
modules/webbasket/lib/Makefile \
modules/webbasket/web/Makefile \
modules/webmessage/Makefile \
modules/webmessage/bin/Makefile \
modules/webmessage/bin/webmessageadmin \
modules/webmessage/doc/Makefile \
modules/webmessage/doc/admin/Makefile \
modules/webmessage/doc/hacking/Makefile \
modules/webmessage/lib/Makefile \
modules/webmessage/web/Makefile \
modules/websubmit/Makefile \
modules/websubmit/bin/Makefile \
modules/websubmit/bin/thumbmaker \
modules/websubmit/etc/Makefile \
modules/websubmit/etc/bibconvert/Makefile \
modules/websubmit/etc/bibconvert/KB/Makefile \
modules/websubmit/etc/bibconvert/config/Makefile \
modules/websubmit/etc/bibconvert/config/EDSPICTcreate.tpl \
modules/websubmit/etc/bibconvert/config/EDSRPICTcreate.tpl \
modules/websubmit/etc/bibconvert/config/EDSTEXTcreate.tpl \
modules/websubmit/etc/bibconvert/config/EDSRTEXTcreate.tpl \
modules/websubmit/doc/Makefile \
modules/websubmit/doc/admin/Makefile \
modules/websubmit/doc/hacking/Makefile \
modules/websubmit/lib/Makefile \
modules/websubmit/lib/functions/Makefile \
modules/websubmit/web/Makefile \
modules/websubmit/web/admin/Makefile \
])
AC_CONFIG_COMMANDS(.wmlrc, [
cat<<EOF>.wmlrc
-Iconfig -I${srcdir}/config
EOF
])
## Finally, write output files:
AC_OUTPUT
## Write help:
AC_MSG_RESULT([****************************************************************************])
AC_MSG_RESULT([** Your CERN Document Server Software (CDSware) installation is now ready **])
AC_MSG_RESULT([** for building. You have entered the following parameters: **])
AC_MSG_RESULT([** - CDSware main install directory: ${prefix}])
AC_MSG_RESULT([** - Web install directory: $WEBDIR])
AC_MSG_RESULT([** - Web home URL: $WEBURL])
AC_MSG_RESULT([** - DB server: $DBHOST])
AC_MSG_RESULT([** - DB name: $DBNAME])
AC_MSG_RESULT([** - DB username: $DBUSER])
AC_MSG_RESULT([** - DB password: $DBPASS])
AC_MSG_RESULT([** - Python executable: $PYTHON])
AC_MSG_RESULT([** - CLISP executable: $CLISP])
AC_MSG_RESULT([** - CMUCL executable: $CMUCL])
AC_MSG_RESULT([** - SBCL executable: $SBCL])
AC_MSG_RESULT([** Here are the steps to continue the building process: **])
AC_MSG_RESULT([** 1) Customize self-explanatory config file './config/config.wml'. **])
AC_MSG_RESULT([** 2) Type 'make' to build your customized CDSware installation. **])
AC_MSG_RESULT([** 3) Type 'make create-tables' if you have not created tables before. **])
AC_MSG_RESULT([** 4) Type 'make install' to install the system. **])
AC_MSG_RESULT([** 5) Type 'make create-demo-site' to install and test the demo site. **])
AC_MSG_RESULT([** Good luck, and thanks for choosing the CERN Document Server Software. **])
AC_MSG_RESULT([** -- CDS Development Group <cds.support@cern.ch> **])
AC_MSG_RESULT([****************************************************************************])
## end of file
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 5b15e3cb2..f9367d95e 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bibclassify bibconvert bibedit bibharvest bibmatch bibsched bibindex bibrank bibupload bibformat elmsubmit miscutil webstyle websession webhelp webbasket webalert websearch websubmit webaccess webmessage webstat webcomment
CLEANFILES = *~
diff --git a/modules/bibclassify/Makefile.am b/modules/bibclassify/Makefile.am
index 812bcc0d9..4433cfe20 100644
--- a/modules/bibclassify/Makefile.am
+++ b/modules/bibclassify/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin etc doc lib
CLEANFILES = *~
diff --git a/modules/bibclassify/bin/Makefile.am b/modules/bibclassify/bin/Makefile.am
index d08fc668a..b069a14d4 100644
--- a/modules/bibclassify/bin/Makefile.am
+++ b/modules/bibclassify/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibclassify
EXTRA_DIST = bibclassify.in
CLEANFILES = *~ *.tmp bibclassifyc
diff --git a/modules/bibclassify/bin/bibclassify.in b/modules/bibclassify/bin/bibclassify.in
index f40427d40..1ae41c399 100644
--- a/modules/bibclassify/bin/bibclassify.in
+++ b/modules/bibclassify/bin/bibclassify.in
@@ -1,52 +1,52 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibClassify.
It extracts keywords from a pdf or text file based on a thesaurus.
Usage: bibclassify [options]
Examples:
bibclassify -f file.pdf -k thesaurus.txt -o TEXT
bibclassify -t file.txt -K ontology.rdf -m SLOW
Specific options:
-f, --pdffile=FILENAME name of the pdf file to be classified
-t, --textfile=FILENAME name of the text file to be classified
-k, --thesaurus=FILENAME name of the text thesaurus (taxonomy)
-K, --ontology=FILENAME name of the RDF or OWL ontology (experimental)
-o, --output=HTML|TEXT output list of keywords in either HTML or text
-n, --nkeywords=NUMBER max number of keywords to be found
-m, --mode=FAST|SLOW processing mode: FAST (run on abstract and selected pages), SLOW (run on whole document - more accurate)
General options:
-h, --help print this help and exit
-V, --version print version and exit
"""
try:
import sys
from cdsware.bibclassifylib import main
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
main()
diff --git a/modules/bibclassify/doc/Makefile.am b/modules/bibclassify/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibclassify/doc/Makefile.am
+++ b/modules/bibclassify/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibclassify/doc/admin/Makefile.am b/modules/bibclassify/doc/admin/Makefile.am
index 3146be3a1..9c24b0cc9 100644
--- a/modules/bibclassify/doc/admin/Makefile.am
+++ b/modules/bibclassify/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir=$(WEBDIR)/admin/bibclassify
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
diff --git a/modules/bibclassify/doc/admin/guide.html.wml b/modules/bibclassify/doc/admin/guide.html.wml
index bb713a297..90f564408 100644
--- a/modules/bibclassify/doc/admin/guide.html.wml
+++ b/modules/bibclassify/doc/admin/guide.html.wml
@@ -1,29 +1,29 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibClassify Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibclassify/>BibClassify Admin</a>" \
navbar_name="admin" \
navbar_select="bibclassify-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<p>FIXME.
diff --git a/modules/bibclassify/doc/admin/index.html.wml b/modules/bibclassify/doc/admin/index.html.wml
index e349e648d..f8732f7ab 100644
--- a/modules/bibclassify/doc/admin/index.html.wml
+++ b/modules/bibclassify/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibClassify Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibclassify"
<dl>
<dt><a href="guide.html">BibClassify Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running BibClassify.</dd>
</dl>
diff --git a/modules/bibclassify/etc/Makefile.am b/modules/bibclassify/etc/Makefile.am
index 9e32deb10..222b195f9 100644
--- a/modules/bibclassify/etc/Makefile.am
+++ b/modules/bibclassify/etc/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir = $(sysconfdir)/bibclassify
etc_DATA = CERESTheme.rdf
EXTRA_DIST = $(etc_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/bibclassify/lib/Makefile.am b/modules/bibclassify/lib/Makefile.am
index f06c0e3c2..71e075c85 100644
--- a/modules/bibclassify/lib/Makefile.am
+++ b/modules/bibclassify/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = bibclassifylib.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibclassify/lib/bibclassifylib.py b/modules/bibclassify/lib/bibclassifylib.py
index 051ec62ab..a29e01616 100644
--- a/modules/bibclassify/lib/bibclassifylib.py
+++ b/modules/bibclassify/lib/bibclassifylib.py
@@ -1,508 +1,508 @@
# -*- coding: utf-8 -*-
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Bibclassify keyword extractor command line entry point.
"""
from marshal import loads,dumps
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import Numeric
import signal
import traceback
# rdflib-2.2.3
import rdflib
from cdsware.config import *
from cdsware.bibindex_engine_config import *
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
fontSize = [12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
def write_message(msg, stream=sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr)."""
if stream == sys.stdout or stream == sys.stderr:
stream.write("BibClassify Message: ")
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
def usage(code, msg=''):
"Prints usage for this module."
if msg:
sys.stderr.write("Error: %s.\n" % msg)
usagetext = """ Usage: bibclassify [options]
Examples:
bibclassify -f file.pdf -k thesaurus.txt -o TEXT
bibclassify -t file.txt -K ontology.rdf -m SLOW
Specific options:
-f, --pdffile=FILENAME name of the pdf file to be classified
-t, --textfile=FILENAME name of the text file to be classified
-k, --thesaurus=FILENAME name of the text thesaurus (taxonomy)
-K, --ontology=FILENAME name of the RDF ontology
-o, --output=HTML|TEXT output list of keywords in either HTML or text
-n, --nkeywords=NUMBER max number of keywords to be found
-m, --mode=FAST|SLOW processing mode: FAST (run on abstract and selected pages), SLOW (run on whole document - more accurate)
General options:
-h, --help print this help and exit
-V, --version print version and exit
"""
sys.stderr.write(usagetext)
sys.exit(code)
def generate_keywords(textfile, dictfile):
""" A method that generates keywords (a list in text format) from a text file thesaurus. """
counter = 0
keylist = []
keyws = []
wordlista = os.popen("more " + dictfile)
thesaurus = [x[:-1] for x in wordlista.readlines()]
for keyword in thesaurus:
try:
string.atoi(keyword)
except ValueError:
dummy = 1
else:
continue
if len(keyword)<=1: #whitespace or one char - get rid of
continue
else:
dictOUT = os.popen('grep -iwc "' +keyword.strip()+'" '+textfile).read()
try:
occur = int(dictOUT)
if occur != 0:
keylist.append([occur, keyword])
except ValueError:
continue
keylist.sort()
keylist.reverse()
for item in keylist:
keyws.append(item[1])
return keyws
def generate_keywords_rdf(textfile, dictfile, output, outwords, mode):
""" A method that generates keywords from an rdf thesaurus. """
keylist = []
keyws = []
counts = {}
entries = []
ns_skos = rdflib.Namespace("http://www.w3.org/2004/02/skos/core#")
ns_dc=rdflib.Namespace("http://purl.org/dc/elements/1.1/")
ns_rdf=rdflib.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
ns_concept=rdflib.Namespace("http://cain.nbii.org/thesauri/CERESTheme.rdf")
store = rdflib.Graph()
store.load(dictfile)
size = int(os.stat(textfile).st_size)
rtmp = open(textfile, 'r')
if mode == 1:
# Fast mode: analysing only abstract + title + middle portion of document
# Abstract and title is never more than 20% of whole document.
text_string = str(rtmp.read(int(size*0.2)))
throw_away = str(rtmp.read(int(size*0.25)))
text_string += str(rtmp.read(int(size*0.2)))
else:
# Slow mode: get all document
text_string = str(rtmp.read())
# text_string = text_string.lower()
rtmp.close()
try:
if text_string.find("Keywords:"):
safe_keys = text_string.split("Keywords:")[1].split("\n")[0]
elif text_string.find("Key words:"):
safe_keys = text_string.split("Key words:")[1].split("\n")[0]
elif text_string.find("Key Words:"):
safe_keys = text_string.split("Key Words:")[1].split("\n")[0]
except:
safe_keys = ""
for s,pref in store.subject_objects(ns_skos["prefLabel"]):
dictOUT = 0
dictOUT_alt = 0
safeOUT = 0
alternatives = " "
broaders = " "
narrowers = " "
relateds = " "
safekey = 0
if pref[:2].isupper():
# First two letters are uppercase. This could be an acronym. Better leave case untouched
pattern = sre.compile('\\b' + pref.strip() + '\\b')
else:
# Let's do some case insensitive search
pattern = sre.compile('\\b' + pref.strip() + '\\b', sre.I)
dictOUT = len(sre.findall(pattern,text_string))
safeOUT = len(sre.findall(pattern,safe_keys))
for alt in store.objects(s, ns_skos["altLabel"]):
if alt[:2].isupper():
# First two letters are uppercase. This could be an acronym. Better leave case untouched
pattern_alt = sre.compile('\\b' + alt.strip() + '\\b')
else:
# Let's do some case insensitive search
pattern_alt = sre.compile('\\b' + alt.strip() + '\\b', sre.I)
dictOUT_alt += len(sre.findall(pattern_alt,text_string))
safeOUT += len(sre.findall(pattern_alt,safe_keys))
alternatives += alt.strip() + ", "
alternatives = alternatives[:-2]
dictOUT_total = int(dictOUT) + int(dictOUT_alt)
if dictOUT_total>1:
if safeOUT>0:
safekey = safeOUT
for bro in store.objects(s, ns_skos["broader"]):
bro_link = store.value(bro, ns_skos["prefLabel"], any=True)
if bro_link:
broaders += bro_link.strip() + ", "
for nar in store.objects(s, ns_skos["narrower"]):
nar_link = store.value(nar, ns_skos["prefLabel"], any=True)
if nar_link:
narrowers += nar_link.strip() + ", "
for rel in store.objects(s, ns_skos["related"]):
rel_link = store.value(rel, ns_skos["prefLabel"], any=True)
if rel_link:
relateds += rel_link.strip() + ", "
broaders = broaders[:-2]
narrowers = narrowers[:-2]
relateds = relateds[:-2]
keylist.append([dictOUT_total, dictOUT, dictOUT_alt, pref.strip(), alternatives, relateds, broaders, narrowers, safekey])
keylist.sort()
keylist.reverse()
if output == 0:
details = "\n"
for i in range(outwords):
details += str(keylist[i][3]) + " ("+ str(keylist[i][0])
if int(keylist[i][8])>0:
details += "*"
details += ")\n"
if len(str(keylist[i][4]))>1:
details += " UF (" + str(keylist[i][2]) + "):" + str(keylist[i][4]) + "\n"
if len(str(keylist[i][5]))>1:
details += " RT:" + str(keylist[i][5]) + "\n"
if len(str(keylist[i][6]))>1:
details += " BT:" + str(keylist[i][6]) + "\n"
if len(str(keylist[i][7]))>1:
details += " NT:" + str(keylist[i][7]) + "\n"
details += "\n"
print details
else:
makeTagCloud(keylist, outwords)
return keyws
def makeTagCloud(entries, outwords):
"""Using the counts for each of the tags, write a simple HTML page to
standard output containing a tag cloud representation. The CSS
describes ten levels, each of which has differing font-size's,
line-height's and font-weight's.
"""
max = int(entries[0][0])
print "<html>"
print "<head>"
print "<title>Keyword Cloud</title>"
print "<style type=\"text/css\">"
print "<!--"
print '.pagebox {color: #000; margin-left: 1em; margin-bottom: 1em; border: 1px solid #000; padding: 1em; background-color: #f1f1f1; font-family: arial, sans-serif; max-width: 700px; margin: 10px; padding-left: 10px; float: left;}'
print '.pagebox1 {color: #B5B5B5; margin-left: 1em; margin-bottom: 1em; border: 1px dotted #B5B5B5; padding: 1em; background-color: #f2f2f2; font-family: arial, sans-serif; max-width: 300px; margin: 10px; padding-left: 10px; float: left;}'
print '.pagebox2 {color: #000; margin-left: 1em; margin-bottom: 1em; border: 0px solid #000; padding: 1em; fond-size: x-small, font-family: arial, sans-serif; margin: 10px; padding-left: 10px; float: left;}'
for i in range(0, 10):
print ".level%d" % i
print "{"
if i < 1:
print " color:#7094FF;"
elif i < 5:
print " color:#3366FF;"
else:
print " color:#003DF5;"
print " font-size:%dpx;" % fontSize[i]
print " line-height:%dpx;" % (fontSize[i] + 5)
if i > 5:
print " font-weight:bold;"
print "}"
print "-->"
print "</style>"
print "</head>"
print "<body>"
print "<table>"
cloud_size = 80
detail_size = outwords
details = ""
cloud = ""
cloud_list = []
if cloud_size > len(entries):
cloud_size = len(entries)
if detail_size > len(entries):
detail_size = len(entries)
details += '<tr><div class="pagebox2" align="top"><small>'
for i in range(0, detail_size):
if detail_size > 0:
detail_size -= 1
details += "<b>" + str(entries[i][3]) + " </b>("+ str(entries[i][0])
if int(entries[i][8])>0:
details += "*"
details += ")<BR>"
if len(str(entries[i][4]))>1:
details += " &nbsp;&nbsp;UF (" + str(entries[i][2]) + "):" + str(entries[i][4]) + "<BR>"
if len(str(entries[i][5]))>1:
details += " &nbsp;&nbsp;RT:" + str(entries[i][5]) + "<BR>"
if len(str(entries[i][6]))>1:
details += " &nbsp;&nbsp;BT:" + str(entries[i][6]) + "<BR>"
if len(str(entries[i][7]))>1:
details += " &nbsp;&nbsp;NT:" + str(entries[i][7]) + "<BR>"
details += "<BR>"
details += '</small></div></tr>'
cloud += '<tr><div class="pagebox" align="top">'
# Generate some ad-hoc count distribution
for i in range(0, len(entries)):
if cloud_size > 0:
cloud_size -= 1
tag = str(entries[i][3])
count = int(entries[i][0])
color = int(entries[i][8])
if count < (max/10):
cloud_list.append([tag,0,color])
elif count < (max/7.5):
cloud_list.append([tag,1,color])
elif count < (max/5):
cloud_list.append([tag,2,color])
elif count < (max/4):
cloud_list.append([tag,3,color])
elif count < (max/3):
cloud_list.append([tag,4,color])
elif count < (max/2):
cloud_list.append([tag,5,color])
elif count < (max/1.7):
cloud_list.append([tag,6,color])
elif count < (max/1.5):
cloud_list.append([tag,7,color])
elif count < (max/1.3):
cloud_list.append([tag,8,color])
else:
cloud_list.append([tag,9,color])
else:
continue
cloud_list.sort()
for i in range(0, len(cloud_list)):
cloud += '<span class=\"level%s\" ' % cloud_list[i][1]
if int(cloud_list[i][2]) > 0:
cloud += 'style="color:red" '
cloud += '> %s </span>' % cloud_list[i][0]
cloud += '</div></tr>'
key = '<tr><div class="pagebox1" align="top"><em>Key:</em><br><b>UF</b> Used For (alternative term)<br> <b>RT</b> Related Term<br><b>BT</b> Broader Term<br><b>NT</b> Narrower Term<br><b>(n*)</b> Denotes author keyword</div></tr>'
print cloud
print key
print details
print "</table></body>"
print "</html>"
def profile(t="", d=""):
import profile
import pstats
profile.run("generate_keywords_rdf(textfile='%s',dictfile='%s')" % (t, d), "bibclassify_profile")
p = pstats.Stats("bibclassify_profile")
p.strip_dirs().sort_stats("cumulative").print_stats()
return 0
def main():
"""Main function """
global options
long_flags =["pdffile=", "textfile="
"thesaurus=","ontology=",
"output=","nkeywords=", "mode=",
"help", "version"]
short_flags ="f:t:k:K:o:n:m:hV"
format_string = "%Y-%m-%d %H:%M:%S"
outwords = 15
input_file = ""
dict_file = ""
output = 1
mode = 1
temp_text = tmpdir + '/bibclassify.pdftotext.' + str(os.getpid())
try:
opts, args = getopt.getopt(sys.argv[1:], short_flags, long_flags)
except getopt.GetoptError, err:
write_message(err, sys.stderr)
usage(1)
if args:
usage(1)
try:
for opt in opts:
if opt == ("-h","") or opt == ("--help",""):
usage(1)
elif opt == ("-V","") or opt == ("--version",""):
print "Version 0.1"
sys.exit(1)
elif opt[0] in [ "-f", "--pdffile" ]:
if input_file=="":
cmd = "%s -nopgbrk -q " % pdftotext + opt[1] + " " + temp_text
errcode = os.system(cmd)
if errcode == 0 and os.path.exists("%s" % temp_text):
input_file = temp_text
else:
print "Error while running %s.\n" % cmd
sys.exit(1)
else:
print "Either text of pdf file in input"
sys.exit(1)
elif opt[0] in [ "-t", "--textfile" ]:
if input_file=="":
input_file = opt[1]
else:
print "Either text of pdf file in input"
sys.exit(1)
elif opt[0] in [ "-k", "--thesaurus" ]:
if dict_file=="":
dict_file = opt[1]
else:
print "Either a text thesaurus or an ontology (in .rdf format)"
sys.exit(1)
elif opt[0] in [ "-K", "--ontology" ]:
if dict_file=="" and opt[1].find(".rdf")!=-1:
dict_file = opt[1]
else:
print "Either a text thesaurus or an ontology (in .rdf format)"
sys.exit(1)
elif opt[0] in [ "-o", "--output" ]:
try:
if str(opt[1]).lower().strip() == "html":
output = 1
elif str(opt[1]).lower().strip() == "text":
output = 0
else:
write_message('Output mode (-o) can only be "HTML" or "TEXT". Using default output mode (HTML)')
except:
write_message('Output mode (-o) can only be "HTML" or "TEXT". Using default output mode (HTML)')
elif opt[0] in [ "-m", "--mode" ]:
try:
if str(opt[1]).lower().strip() == "fast":
mode = 1
elif str(opt[1]).lower().strip() == "slow":
mode = 0
else:
write_message('Processing mode (-m) can only be "FAST" or "SLOW". Using default output mode (fast)')
except:
write_message('Processing mode (-m) can only be "FAST" or "SLOW". Using default output mode (fast)')
elif opt[0] in [ "-n", "--nkeywords" ]:
try:
num = int(opt[1])
if num>1:
outwords = num
else:
write_message("Number of keywords (-nkeywords) must be an integer higher than 1. Using default value of 15...")
except ValueError:
write_message("Number of keywords (-n) must be an integer. Using default value of 15...")
except StandardError, e:
write_message(e, sys.stderr)
sys.exit(1)
if input_file == "" or dict_file == "":
write_message("Need to enter the name of an input file AND a thesaurus file \n")
usage(1)
# Weak method to detect dict_file. Need to improve this (e.g. by looking inside the metadata with rdflib?)
if dict_file.find(".rdf")!=-1:
outcome = generate_keywords_rdf(input_file, dict_file, output, outwords, mode)
# profiling:
# profile(input_file, dict_file)
else: # Treat as text
outcome = generate_keywords(input_file, dict_file)
if outwords > len(outcome): outwords = len(outcome)
if output == 0:
for i in range(outwords):
print outcome[i]
else:
print "<html>"
print "<head>"
print "<title>Keywords</title>"
print "<body>"
print "<table>"
print '<tr><div class="pagebox2" align="top"><small>'
for i in range(outwords):
print "<b>" + str(outcome[i]) + "</b><br>"
print '</small></div></tr>'
print "</table></body>"
print "</html>"
return
if __name__ == '__main__':
# profile("/home/apepe/temp/1bvcecuu6u0qrkgk.txt","/home/apepe/devel/semantic/rdfs/CERESTheme.rdf")
main()
diff --git a/modules/bibconvert/Makefile.am b/modules/bibconvert/Makefile.am
index c2a1b10f2..3a2e4fc98 100644
--- a/modules/bibconvert/Makefile.am
+++ b/modules/bibconvert/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc etc lib
CLEANFILES = *~
diff --git a/modules/bibconvert/bin/Makefile.am b/modules/bibconvert/bin/Makefile.am
index 4a79a4a0f..2808c744f 100644
--- a/modules/bibconvert/bin/Makefile.am
+++ b/modules/bibconvert/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibconvert
EXTRA_DIST = bibconvert.in
CLEANFILES = *~ *.tmp bibconvertc
diff --git a/modules/bibconvert/bin/bibconvert.in b/modules/bibconvert/bin/bibconvert.in
index 2b1544a53..c9894e9b0 100644
--- a/modules/bibconvert/bin/bibconvert.in
+++ b/modules/bibconvert/bin/bibconvert.in
@@ -1,206 +1,206 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""BibConvert tool to convert bibliographic records from any format to any format."""
__version__ = "$Id$"
try:
import fileinput
import string
import os
import re
import sys
import time
import getopt
from time import gmtime, strftime, localtime
import os.path
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
try:
from cdsware.search_engine import perform_request_search
from cdsware.config import *
from cdsware import bibconvert
except ImportError, e:
print "Error: %s" % e
sys.exit(1)
### MAIN ###
ar_ = []
conv_setting = bibconvert.set_conv()
sysno = bibconvert.generate("DATE(%w%H%M%S)")
sysno500 = bibconvert.generate("DATE(%w%H%M%S)")
separator = ""
tcounter = 0
source_data = ""
query_string = ""
match_mode = -1
begin_record_header = ""
ending_record_footer = ""
output_rec_sep = ""
begin_header = ""
ending_footer = ""
oai_identifier_from = 1
opts, args = getopt.getopt(sys.argv[1:],"c:d:hVl:o:b:e:B:E:s:m:C:",
[
"config",
"directory",
"help",
"version",
"length",
"oai",
"header",
"footer",
"record-header",
"record-footer",
"separator",
"match",
"config-alt"
])
# get options and arguments
dirmode = 0
Xcount = 0
for opt, opt_value in opts:
if opt in ["-c", "--config"]:
separator = bibconvert.get_other_par("_RECSEP_", opt_value)
output_rec_sep = ""
query_string = bibconvert.get_other_par("_QRYSTR_", opt_value)
match_mode = bibconvert.get_other_par("_MATCH_", opt_value)
begin_header = bibconvert.get_other_par("_HEAD_", opt_value)
ending_footer = bibconvert.get_other_par("_FOOT_", opt_value)
begin_record_header = bibconvert.get_other_par("_RECHEAD_", opt_value)
ending_record_footer = bibconvert.get_other_par("_RECFOOT_", opt_value)
if(match_mode == ""):
match_mode = -1
for opt, opt_value in opts:
if opt in ["-c", "--config"]:
extract_tpl = opt_value
extract_tpl_parsed = bibconvert.parse_common_template(extract_tpl,1)
source_tpl = opt_value
source_tpl_parsed = bibconvert.parse_common_template(source_tpl,2)
target_tpl = opt_value
target_tpl_parsed = bibconvert.parse_common_template(target_tpl,3)
elif opt in ["-d", "--directory"]:
source_data = opt_value
source_data = source_data + "/"
extract_tpl = "/"
extract_tpl_parsed = None
dirmode = 1
elif opt in ["-h", "--help"]:
bibconvert.printInfo()
sys.exit(0)
elif opt in ["-V", "--version"]:
print __version__
sys.exit(0)
elif opt in ["-l", "--length"]:
try:
conv_setting[0] = string.atoi(opt_value)
except ValueError, e:
conv_setting[0] = 1
elif opt in ["-o", "--oai"]:
try:
oai_identifier_from = string.atoi(opt_value)
except ValueError, e:
oai_identifier_from = 1
elif opt in ["-b", "--header"]:
begin_header = opt_value
elif opt in ["-e", "--footer"]:
ending_footer = opt_value
elif opt in ["-B", "--record-header"]:
begin_record_header = opt_value
elif opt in ["-E", "--record-footer"]:
ending_record_footer = opt_value
elif opt in ["-s", "--separator"]:
separator = opt_value
elif opt in ["-t", "--output_separator"]:
output_rec_sep = opt_value
elif opt in ["-m", "--match"]:
match_mode = string.atoi(opt_value[0:1])
query_string = opt_value[1:]
elif opt in ["-C", "--config-alt"]:
if opt_value[0:1] == "x":
extract_tpl = opt_value[1:]
extract_tpl_parsed = bibconvert.parse_template(extract_tpl)
if opt_value[0:1] == "t":
target_tpl = opt_value[1:]
target_tpl_parsed = bibconvert.parse_template(target_tpl)
if opt_value[0:1] == "s":
source_tpl = opt_value[1:]
source_tpl_parsed = bibconvert.parse_template(source_tpl)
if(separator == "EOLEOL"):
separator = ""
ar_.append(dirmode)
ar_.append(Xcount)
ar_.append(conv_setting)
ar_.append(sysno)
ar_.append(sysno500)
ar_.append(separator)
ar_.append(tcounter)
ar_.append(source_data)
ar_.append(query_string)
ar_.append(match_mode)
ar_.append(begin_record_header)
ar_.append(ending_record_footer)
ar_.append(output_rec_sep)
ar_.append(begin_header)
ar_.append(ending_footer)
ar_.append(oai_identifier_from)
ar_.append(source_tpl)
ar_.append(source_tpl_parsed)
ar_.append(target_tpl)
ar_.append(target_tpl_parsed)
ar_.append(extract_tpl)
ar_.append(extract_tpl_parsed)
bibconvert.convert(ar_)
diff --git a/modules/bibconvert/doc/Makefile.am b/modules/bibconvert/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibconvert/doc/Makefile.am
+++ b/modules/bibconvert/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibconvert/doc/admin/Makefile.am b/modules/bibconvert/doc/admin/Makefile.am
index 1f9f979c5..302369eeb 100644
--- a/modules/bibconvert/doc/admin/Makefile.am
+++ b/modules/bibconvert/doc/admin/Makefile.am
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir=$(WEBDIR)/admin/bibconvert
doc_DATA=index.html guide.html
sampledir=$(WEBDIR)/admin/bibconvert
sample_DATA=sample.cfg sample.dat sample.kb bibtex.cfg dcq.cfg dcq.dat dcxml-to-marcxml.cfg
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%) $(sample_DATA)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibconvert/doc/admin/guide.html.wml b/modules/bibconvert/doc/admin/guide.html.wml
index 36c30e0b4..5518ab575 100644
--- a/modules/bibconvert/doc/admin/guide.html.wml
+++ b/modules/bibconvert/doc/admin/guide.html.wml
@@ -1,939 +1,939 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibConvert Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibconvert/>BibConvert Admin</a>" \
navbar_name="admin" \
navbar_select="bibconvert-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">Overview</a></strong><br>
<strong>2. <a href="#2">Configuration Example</a></strong><br>
<strong>3. <a href="#3">Running BibConvert</a></strong><br>
<strong>4. <a href="#4">BibConvert Configuration Guide</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#G">Conventions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1. <a href="#4.1">Step 1 Definition of Source Record</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2. <a href="#4.2">Step 2 Definition of Source Fields</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3. <a href="#4.3">Step 3 Definition of Target Record</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4. <a href="#4.4">Formatting in BibConvert</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.1 <a href="#4.4.1">Definition of Formatting Functions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4.2 <a href="#4.4.2">Generated Values</a><br>
<a name="1"></a><h2>1. Overview</h2>
<p>BibConvert utility enables you to convert metadata records from
various metadata formats into another metadata format supported by
local database. It is designed to process metadata records harvested
in XML converting them into MARC21 before they are finally uploaded
into database. However, BibConvert is flexible enough to deal also
with other structured metadata according to your needs and offers a
way, how you actually can insert what you want into the database.
<p>It is suitable for tasks such as conversion of records received
from multiple data sources or conversion of records from another
system that may support a different metadata format.
<a name="2"></a><h2>2. Configuration Example</h2>
<p>OAI DublinCore into MARC21 and OAI MARC into MARC21
configurations will be provided as default configuration, ensuring the
standard uploading sequence (incl. <a href="../bibharvest/">BibHarvest</a> and <a
href="../bibupload/">BibUpload</a> utilities). Other configurations can be
created according to your needs. The configuration file that has to be
created for each data source is a text file with following structure:
<protect>
<blockquote>
<pre>
### the configuration starts here
### Configuration of bibconvert templates
### source data : <source_data_name>
=== data extraction configuration template ===
### here comes the data extraction configuration template
# entry example:
AU---%A---MAX---;---
# extracts maximum available data by field from metadata record
# the values are found between specified tags
# in this case between the '%A' tag and other tags defined
# repetitive values are recognized by a semicolon separator
# resp. by multiple presence of '%A' tag
=== data source configuration template ===
### here comes the data source configuration template
# entry example:
AU---<:FIRSTNAME:>-<:SURNAME:>
# describes the contents of extracted source data fields
# in this case, the field AU is described as having two distinct subfields
=== data target configuration template ===
### here comes the data target configuration template
# entry example:
AU::CONF(AU,,0)---&lt;datafield id="700" ind1="" ind2="">&lt;subfield code="a">&lt;:AU*::SURNAME::CAP():>, &lt;AU*::FIRSTNAME::ABR():>&lt;/subfield>&lt;/datafield>
# This section concerns rather the desired output, while previous two were focused on the data source structures.
# Each line equals to one output line, composed of given literals and values from extracted source data fields.
# In this example, the XML Marc21 output line is defined,
# containing re-formatted values of source fields SURNAME and FIRSTNAME
### the configuration ends here
</pre>
</blockquote>
</protect>
<p>Having prepared a configuration, the BibConvert will convert the
source data file according to it in a batch mode. The BibConvert is
fully compatible with the Uploader1.x configuration language. For more
information, have a look at the <a href="#4">BibConvert Configuration
Guide</a> section below.
<a name="3"></a><h2>3. Running BibConvert</h2>
<p>For a fully functional demo, consider the following sample input data:
<blockquote>
<a href="sample.dat">sample.dat</a> -- sample bibliographic data to be converted and inputted into CDSware
<br><a href="sample.cfg">sample.cfg</a> -- sample configuration file, featuring knowledge base demo
</blockquote>
<p>To convert the above data into XML MARC, use the following command:
<blockquote>
<pre>
$ bibconvert -b'&lt;collection>' -csample.cfg -e'&lt;/collection>' < sample.dat > /tmp/sample.xml
<pre>
</blockquote>
and see the XML MARC output file. You would then continue the upload procedure by calling <a
href="../bibupload/">BibUpload</a>.
<p>Other useful BibConvert configuration examples:
<blockquote>
<a href="dcq.cfg">dcq.cfg</a> -- Qualified Dublin Core in SGML to XML MARC example
<br><a href="dcq.dat">dcq.dat</a> -- corresponding data file, featuring collection identifiers demo
</blockquote>
<blockquote>
<a href="dcxml-to-marcxml.cfg">dcxml-to-marcxml.cfg</a> -- OAI XML Dublin Core to XML MARC example
</blockquote>
<blockquote>
<a href="bibtex.cfg">bibtex.cfg</a> -- BibTeX to XML MARC example
</blockquote>
<a name="4"></a><h2>4. BibConvert Configuration Guide</h2>
<h3><A NAME="G"></A>Conventions</h3>
<br/>- comment line starts with '#' sign in the first column
<br/>- each section is declared by a line starting with '===' (further characters on the line are ignored)
<br/>- values are separated by '---'
<h3>
<A NAME="4.1"></A>4.1. Step 1 Definition of Source record</h3>
<P>- Create/edit "data extraction configuration template" section of the configuration file.
<BR>- Each line of this section stands for a definition of one source field:
<P><strong>name---keyword---terminating string---separator---</strong>
<P>- Choose a (valid) name allowed by the system
<BR>- Enter <strong>keyword</strong> and <strong>terminating string</strong>, which are boundary tags for
the wanted value extraction
<BR>- In case the field is repetitive, enter the value <strong>separator</strong>
<BR>- "<strong>---</strong>"is mandatory separator between all values, even zero-length
<BR>- <strong>MAX</strong>/<strong>MIN</strong> keywords can be used instead of terminating string
<BR>&nbsp;
<P>Example of a definition of author(repetitive) and title (non-repetitive)
fields:
<br>
<pre>
=== data extraction configuration template ===
### here comes the data extraction configuration template
<br>
<P>AU---AU_---MAX---;---
<BR>TI---TI_---EOL------
</pre>
<H3>
<A NAME="4.2"></A>4.2. Step 2 Definition of Source fields</H3>
<I>Each field extracted from the source according to the definition done
in the first step can have an internal structure, which is described in
this section.</I>
<P>- Create/edit "data source configuration template" section of the configuration file.
<BR>- Each line of this section stands for a definition of one source field
<BR>- <name> corresponds to the name defined in the step 1
<P>name---{CONST&lt;:SUBFIELD:>[CONST]}}
<P>- Enter only constants that appear systematically.
<BR>- Between two discrete subfields has to be defined a constant of a non zero
length
<BR>- "---"is a mandatory separator between the name and the source
field definition
<P>Example of a definition of author(repetitive) and title (non-repetitive)
fields:
<pre>
=== data source configuration template ===
TI---&lt;:TI:>
AU---&lt;:FIRSTNAME:>-&lt;:SURNAME:>
</pre>
<H3>
<A NAME="4.3"></A>4.3. Step 3 Definition of target record</H3>
<I>This definition describes the layout of the target record that is created by the conversion,
together with the corresponcence to the source fields defined in step 2.</I>
<P>- Create/edit "data target configuration template" section of the configuration file.
<BR>- Each line of this section stands for an output line created by the conversion.
<BR>- &lt;name> corresponds to the name defined in the steps 1 and 2
<P>CODE---CONST&lt;:name::SUBFIELD::FUNCT():>CONST&lt;:GENERATED_VALUE:>
<P>- <strong>CODE</strong> stands for a tag for readability (optional)
<BR>- "<strong>::</strong>"is a mandatory separator between the name and the subfield
definition
<BR>- optionally, you can apply the appropriate <A HREF="#51">formatting function(s)</A>
and <A HREF="#4.4.2">generated values</A>
<BR>- "<strong>::</strong>"is a mandatory separator between the subfield definition and the function(s)
<BR>- "<strong>---</strong>"is a mandatory separator between the tag and the output code definition
<BR>- mark repetitive source fields with an asterisk (*)
<P>Example of a definition of author (repetitive) and title (non-repetitive) codes:
<protect>
<pre>
<br/>AU::CONF(AU,,0)---&lt;datafield id="700" ind1="" ind2="">&lt;subfield code="a">&lt;:AU*::AU:>&lt;/subfield>&lt;/datafield>
<br/>TI::CONF(TI,,0)---&lt;datafield id="245" ind1="" ind2="">&lt;subfield code="a">&lt;:TI::TI::SUP(SPACE, ):>&lt;/subfield>&lt;/datafield>
</pre>
</protect>
<h3><A NAME="4.4"></a>4.4 Formatting in BibConvert</H3>
<H3>&nbsp;<A NAME="4.4.1"></A>4.4.1 Definition of formatting functions</H3>
<BLOCKQUOTE>Every field can be processed with a variety of functions that
partially or entirely change the original value.
<BR>There are three types of functions available that take as element either
single characters, words or the entire value of processed field.
<BR>&nbsp;
<P>Every function requires a certain number of parameters to be entered
in brackets. If an&nbsp; insufficient number of parameters is present,
the function uses default values. Default values are constructed with attempt to keep the original value.
<P>The configuration of templates is case sensitive.
<P>The following functions are available:
<P><A HREF="#ADD">ADD(prefix,suffix) - add prefix/suffix</A>
<BR><A HREF="#KB">KB(kb_file,[0-9]) -lookup in kb_file and replace value</A>
<BR><A HREF="#ABR">ABR(x,suffix)/ABRW(x,suffix) - abbreviation with suffix addition</A>
<BR><A HREF="#ABRX">ABRX() - abbreviate exclusively words longer</A>
<BR><A HREF="#CUT">CUT(prefix,postfix) - remove substring from side</A>
<BR><A HREF="#REP">REP(x,y) - replacement of characters</A>
<BR><A HREF="#SUP">SUP(type) - suppression of characters of specified type</A>
<BR><A HREF="#LIM">LIM(n,L/R)/LIMW(str,L/R) - restriction to n letters</A>
<BR><A HREF="#WORDS">WORDS(n,side) - restriction to n words from L/R</A>
<BR><A HREF="#MINL">MINL(n)/MAXL(n) - replacement of words shorter/greater
than n</A>
<BR><A HREF="#MINLW">MINLW(n) - replacement of short values</A>
<BR><A HREF="#EXPW">EXP(str,1|0)/EXPW(type) - replacement of words from
value if containing spec. type/string</A>
<BR><A HREF="#IF">IF(value,valueT,valueF) - replace T/F value</A>
<BR><A HREF="#UP">UP/DOWN/CAP/SHAPE/NUM - lower case and upper case, shape</A>
<BR><A HREF="#SPLIT">SPLIT(n,h,str,from)/SPLITW(sep,h,str,from) - split
into more lines</A>
<BR><A HREF="#CONF">CONF(field,value,1/0)/CONFL(value,1/0) - confirm validity
of a field</A>
<BR><A HREF="#RANGE">RANGE(from,to) - confirm only entries in the specified
range</A>
<BR>&nbsp;</BLOCKQUOTE>
<H4>
<A NAME="ADD"></A>ADD(prefix,postfix)</H4>
<BLOCKQUOTE>default: ADD(,)&nbsp;&nbsp;&nbsp; no addition
<P>Adds prefix/postfix to the value, we can use this function to add the proper
field name as a prefix of the value itself:
<P>ADD(WAU=,)&nbsp;&nbsp;&nbsp; prefix for the first author (which may
have been taken from the field AU2)
<BR>&nbsp;</BLOCKQUOTE>
<H4>
<A NAME="KB"></A>KB(kb_file)&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp; kb_file search</H4>
<BLOCKQUOTE>default: KB(kb_file,1/0/R)
<P>The input value is compared to a kb_file and may be replaced
by another value. In the case that the input value is not recognized, it is by default kept
without any modification. This default can be overridden by <strong>_DEFAULT_---default value</strong> entry in the kb_file
<P>The file specified in the parameter is a text file representing a table
of values that correspond to each other:
<P>{<strong>input_value---output_value</strong>}
<P>KB(file,1) searches the exact value passed.
<BR>KB(file,0) searches the KB code inside the value passed.
<BR>KB(file,2) as 0 but not case sensitive
<BR>KB(file,R) replacements are applied on substrings/characters only.
<BR/>
<BR/> bibconvert look-up value in KB_file in one of following modes:
<BR/> ===========================================================
<BR/> 1 - case sensitive / match (default)
<BR/> 2 - not case sensitive / search
<BR/> 3 - case sensitive / search
<BR/> 4 - not case sensitive / match
<BR/> 5 - case sensitive / search (in KB)
<BR/> 6 - not case sensitive / search (in KB)
<BR/> 7 - case sensitive / search (reciprocal)
<BR/> 8 - not case sensitive / search (reciprocal)
<BR/> 9 - replace by _DEFAULT_ only
<BR/> R - not case sensitive / search (reciprocal) replace
<BR/>
<BR/>
<P>Edge spaces are not considered.
Output value is not further formated.</BLOCKQUOTE>
<H4>
<A NAME="ABR"></A>ABR(x,trm),ABRW(x,trm)&nbsp; - abbreviate term to x places
with(out) postfix</H4>
<BLOCKQUOTE>default: ABR(1,.)
<BR>default: ABRW(1,.)
<P>The words in the input value are shortened according to the parameters
specified. By default, only the initial character is kept and the output
value is terminated by a dot.
<BR>ABRW takes entire value as one word.
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>ABR()</TD>
<TD>firstname_surname</TD>
<TD>f._s.</TD>
</TR>
<TR>
<TD>ABR(1,)</TD>
<TD>firstname_surname</TD>
<TD>f_s</TD>
</TR>
<TR>
<TD>ABR(10,COMMA)</TD>
<TD>firstname_surname</TD>
<TD>firstname,_surname,</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<h4>
<A NAME="ABRX"></A>ABRX() - abbreviate exclusively words longer than given limit</h4>
<BLOCKQUOTE>default: ABRX(1,.)
<P>Exclusively words that reach the specified length limit in the input value are abbreviated.
No suffix is appended to the words shorter than specified limit.
</blockquote>
<h4>
<A NAME="CUT"></A>CUT(prefix,postfix) - remove substring from side</h4>
<BLOCKQUOTE>default: CUT(,)
<P>Remove string from the value (reverse function to the "ADD")
</BLOCKQUOTE>
<H4>
<A NAME="REP"></A>REP(x,y)&nbsp;&nbsp; - replace x with y</H4>
<BLOCKQUOTE>default: REP(,)&nbsp;&nbsp;&nbsp; no replacement
<P>The input value is searched for the string specified in the first parameter.
All such strings are replaced with the string specified in the second parameter.
</BLOCKQUOTE>
<H4>
<A NAME="SUP"></A>SUP(type,string)&nbsp;&nbsp; - suppress chars of certain
type</H4>
<BLOCKQUOTE>default: SUP(,)&nbsp;&nbsp;&nbsp; type not recognized
<P>All groups of characters belonging to the type specified in the first
parameter are suppressed or replaced with a string specified in the second
parameter.
<P>Recognized types:
<P>SPACE .. invisible chars incl. NEWLINE
<BR>ALPHA .. alphabetic
<BR>NALPHA .. not alphabetic
<BR>NUM .. numeric
<BR>NNUM&nbsp;&nbsp;&nbsp; .. not numeric
<BR>ALNUM&nbsp; .. alphanumeric
<BR>NALNUM&nbsp; .. non alphanumeric
<BR>LOWER&nbsp; .. lower case
<BR>UPPER&nbsp; .. upper case
<BR>PUNCT&nbsp; .. punctuation
<BR>NPUNCT&nbsp; .. not punctuation
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>SUP(SPACE,-)</TD>
<TD>sep_1999</TD>
<TD>sep-1999</TD>
</TR>
<TR>
<TD>SUP(NNUM)</TD>
<TD>sep_1999</TD>
<TD>1999</TD>
</TR>
<TR>
<TD>SUP(NUM)</TD>
<TD>sep_1999</TD>
<TD>sep_</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
<A NAME="LIM"></A>LIM(n,side)/LIMW(str,side)&nbsp;&nbsp; - limit to n letters
from L/R</H4>
<BLOCKQUOTE>default: LIM(0,)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
no change
<BR>default: LIMW(,R)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; no change
<P>Limits the value in order to get the required number of characters by
cutting excess characters from either side.
<BR>LIMW removes the Left/Right side to the (str) string.
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>LIM(4,L)</TD>
<TD>sep_1999</TD>
<TD>1999</TD>
</TR>
<TR>
<TD>LIM(4,R)</TD>
<TD>sep_1999</TD>
<TD>sep_</TD>
</TR>
<TR>
<TD>LIMW(_,R)</TD>
<TD>sep_1999</TD>
<TD>sep_</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
<A NAME="WORDS"></A>WORDS(n,side)&nbsp; - limit to n words from L/R</H4>
<BLOCKQUOTE>default: WORDS(0,R)
<P>Keeps the number of words specified in the first parameter from either
side.
<BR>&nbsp;
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>WORDS(1)</TD>
<TD>sep_1999</TD>
<TD>1999</TD>
</TR>
<TR>
<TD>WORDS(1,L)</TD>
<TD>sep_1999</TD>
<TD>sep_</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
<A NAME="MINL"></A>MINL(n)&nbsp;&nbsp; - exp. words shorter than n</H4>
<BLOCKQUOTE>default: MINL(1)
<P>All words shorter than the limit specified in the parameter are replaced
fro mthe sentence.
<BR>The words with length exactly n are kept.
<BR>&nbsp;
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>MINL(2)</TD>
<TD>History of Physics</TD>
<TD>History of Physics</TD>
</TR>
<TR>
<TD>MINL(3)</TD>
<TD>History of Physics</TD>
<TD>History Physics</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
MAXL(n)&nbsp;&nbsp; - exp. words longer than n</H4>
<BLOCKQUOTE>default: MAXL(0)
<P>All words greater in number of characters than the limit specified in
the parameter are replaced. Words with length exactly n are kept.
<BR>&nbsp;
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>MAXL(2)</TD>
<TD>History of Physics</TD>
<TD>of</TD>
</TR>
<TR>
<TD>MAXL(3)</TD>
<TD>History of Physics</TD>
<TD>of</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
<A NAME="MINLW"></A>MINLW(n) - replacement of short values</H4>
<BLOCKQUOTE>default: MINLW(1) (no change)
<P>The entire value is deleted if shorter than the specified limit.
<BR>This is used for the validation of created records, where we have 20
characters in the header.
<BR>The default validation is MINLW(21), i.e. the record entry will not
be consided as valid, unless it contains at least 21 characters including
the header. This default setting can be overriden by the -l command line option.
<P>In order to increase the necessary length of the output line in the configuration
itself, apply the function on the total value:
<P>AU::MINLW(25)---CER &lt;:SYSNO:> AU&nbsp;&nbsp;&nbsp; L &lt;:SURNAME:>,
&lt;:NAME:>
<BR>&nbsp;
<BR>&nbsp;</BLOCKQUOTE>
<H4>
<A NAME="EXPW"></A>EXP(str,1|0) - exp./aprove word containing specified
string</H4>
<BLOCKQUOTE>default: EXP&nbsp;&nbsp; (,0)&nbsp;&nbsp;&nbsp;&nbsp; leave
all value
<P>The record is shortened by replacing words containing the specified
string.
<BR>The second parameter states whether the string approves the word (0)
or disables it (1).
<P>for example, to get the email address from the value, use the following
<BR>&nbsp;
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>EXP(@,0)</TD>
<TD>mail to: libdesk@cern.ch</TD>
<TD>libdesk@cern.ch</TD>
</TR>
<TR>
<TD>EXP(:,1)</TD>
<TD>mail to: libdesk@cern.ch</TD>
<TD>mail libdesk@cern.ch</TD>
</TR>
<TR>
<TD>EXP(@)</TD>
<TD>mail to: libdesk@cern.ch</TD>
<TD>libdesk@cern.ch</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
EXPW(type)&nbsp;&nbsp; - exp. word from value if containing spec. type</H4>
<BLOCKQUOTE>default: EXPW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type
not recognized
<BR>&nbsp;
<P>The sentence is shortened by replacing words containing specified type
of character.
<P>Types supported in EXPW function:
<P>ALPHA .. alphabetic
<BR>NALPHA .. not alphabetic
<BR>NUM .. numeric
<BR>NNUM&nbsp;&nbsp;&nbsp; .. not numeric
<BR>ALNUM&nbsp; .. alphanumeric
<BR>NALNUM&nbsp; .. non alphanumeric
<BR>LOWER&nbsp; .. lower case
<BR>UPPER&nbsp; .. upper case
<BR>PUNCT&nbsp; .. punctuation
<BR>NPUNCT&nbsp; .. non punctuation
<P>Note: SPACE is not handled as a keyword, since all space characters
are considered as word separators.
<BR>&nbsp;
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>EXPW(NNUM)</TD>
<TD>sep_1999</TD>
<TD>1999</TD>
</TR>
<TR>
<TD>EXPW(NUM)</TD>
<TD>sep_1999</TD>
<TD>sep</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
<A NAME="IF"></A>IF(value,valueT,valueF) - replace T/F value</H4>
<BLOCKQUOTE>default: IF(,,)
<P>Compares the value with the first parameter. In case the result is TRUE,
the input value is replaced with the second parameter, otherwise the input
value is replaced with the third parameter.
<BR>In case the input value has to be kept, whatever it is, the keyword
ORIG can be used (usually in the place of the third parameter)
<BR>&nbsp;
<BR>&nbsp;
<BLOCKQUOTE>&nbsp;
<TABLE BORDER COLS=3 WIDTH="50%" NOSAVE >
<TR>
<TD>example</TD>
<TD>input</TD>
<TD>output</TD>
</TR>
<TR>
<TD>IF(sep_1999,sep)</TD>
<TD>sep_1999</TD>
<TD>sep</TD>
</TR>
<TR>
<TD>IF(oct_1999,oct)</TD>
<TD>sep_1999</TD>
<TD></TD>
</TR>
<TR>
<TD>IF(oct_1999,oct,ORIG)</TD>
<TD>sep_1999</TD>
<TD>oct_1999</TD>
</TR>
</TABLE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H4>
<A NAME="UP"></A>UP&nbsp;&nbsp;&nbsp; - upper case</H4>
<BLOCKQUOTE>Convert all characters to upper case</BLOCKQUOTE>
<H4>
DOWN&nbsp;&nbsp; - lower case</H4>
<BLOCKQUOTE>Convert all characters to lower case</BLOCKQUOTE>
<H4>
CAP&nbsp;&nbsp;&nbsp; - make capitals</H4>
<BLOCKQUOTE>Convert the initial character of each word to upper case
and the rest of characters to lower case</BLOCKQUOTE>
<H4>
SHAPE&nbsp;&nbsp;&nbsp; - format string</H4>
<BLOCKQUOTE>Supresses all invalid spaces</BLOCKQUOTE>
<H4>
<B>NUM&nbsp;&nbsp;&nbsp; - number</B></H4>
<BLOCKQUOTE>If it contains at least one digit, convert it into a
number by suppressing other characters. Leading zeroes are deleted.</BLOCKQUOTE>
<H4>
<A NAME="SPLIT"></A>SPLIT(n,h,str,from)</H4>
<BLOCKQUOTE>Splits the input value into more lines, where each line contains
at most (n+h+length of str) characters, (n) being the number of characters
following the number of characters in the header, specified in (h). The
header repeats at the beginning of each line. An additional string can
be inserted as a separator between the header and the following value.
This string is specified by the third parameter (str). It is possible to
restrict the application of (str) so it does not appear on the first line
by entering "2" for (from)</BLOCKQUOTE>
<H4>
SPLITW(sep,h,str,from)</H4>
<BLOCKQUOTE>Splits the input value into more lines by replacing the line
separator stated in (sep) with CR/LFs. Also, as in the case of the SPLIT
function, the first (h) characters are taken as a header and repeat at
the beginning of each line.&nbsp; An additional string can be inserted
as a separator between the header and the following value. This string
is specified by the third parameter (str). It is possible to restrict the
application of (str) so it does not appear on the first line by entering
"2" for (from)</BLOCKQUOTE>
<H4>
<A NAME="CONF"></A>CONF(field,value,1/0)&nbsp; - confirm validity of a
field</H4>
<BLOCKQUOTE>The input value is taken as it is, or refused depending on
the value of some other field. In case the other (field) contains&nbsp;
the string specified in (value), then the input value is confirmed (1)
or refused (0).</BLOCKQUOTE>
<H4>
CONFL(str,1|0) - confirm validity of a field</H4>
<BLOCKQUOTE>The input value is confirmed if it contains (<B>1</B>)/misses(<B>0</B>)
the specified string (<B>str</B>)</BLOCKQUOTE>
<H4>
<A NAME="RANGE"></A>RANGE(from,to) - confirm only entries in the specified
range</H4>
<BLOCKQUOTE>Left side function of target template configuration section to select the desired
entries from the repetitive field.
<BR>The range can only be continuous.
<P>The entry is confirmed in case its input falls into the range from-to
specified in the parameter, border values included. As an upper limit it
is possibe to use the keyword MAX.
<P>This is useful in case of AU code, where the first entry has a different
definition from other entries:
<P>AU::RANGE(1,1)---CER &lt;:SYSNO:> AU2&nbsp;&nbsp;&nbsp; L &lt;:AU::SURNAME:>,
&lt;:AU::NAME:>&nbsp;&nbsp;&nbsp; ... takes the first name from the defined
AU field
<BR>AU::RANGE(2,MAX)---CER &lt;:SYSNO:> AU&nbsp;&nbsp;&nbsp;&nbsp; L &lt;:AU::SURNAME:>
, &lt;:AU::NAME:>&nbsp;&nbsp;&nbsp; ... takes the the rest of namesfrom
the AU field
<BR>&nbsp;</BLOCKQUOTE>
<H4><A NAME="DEFP"></A>DEFP() - default print</H4>
<BLOCKQUOTE>The value is printed by default even if it does not contain any variable input from the source file.</BLOCKQUOTE>
<H3>
<A NAME="4.4.2"></A>4.4.2 Generated values</H3>
<BLOCKQUOTE>In the template configurations, values can be either taken from the source
or generated in the process itself. This is mainly useful for evaluating constant values.
<P>Currently, the following date values are generated:
<BR>&nbsp;</BLOCKQUOTE>
<H4>
DATE(format,n)</H4>
<BLOCKQUOTE>default: DATE(,10)
<P>where n is the number of digits required.
<P>Generates the current date in the form given as a parameter. The format
has to be given according to the ANSI C notation, i.e. the string is composed
out of following components:
<P><A NAME="date"></A>&nbsp; %a&nbsp;&nbsp;&nbsp; abbreviated weekday name
<BR>&nbsp; %A&nbsp;&nbsp;&nbsp; full weekday name
<BR>&nbsp; %b&nbsp;&nbsp;&nbsp; abbreviated month name
<BR>&nbsp; %B&nbsp;&nbsp;&nbsp; full month name
<BR>&nbsp; %c&nbsp;&nbsp;&nbsp; date and time representation
<BR>&nbsp; %d&nbsp;&nbsp;&nbsp; decimal day of month number (01-31)
<BR>&nbsp; %H&nbsp;&nbsp;&nbsp; hour (00-23)(12 hour format)
<BR>&nbsp; %I&nbsp;&nbsp;&nbsp; hour (01-12)(12 hour format)
<BR>&nbsp; %j&nbsp;&nbsp;&nbsp; day of year(001-366)
<BR>&nbsp; %m&nbsp;&nbsp;&nbsp; month (01-12)
<BR>&nbsp; %M&nbsp;&nbsp;&nbsp; minute (00-59)
<BR>&nbsp; %p&nbsp;&nbsp;&nbsp; local equivalent of a.m. or p.m.
<BR>&nbsp; %S&nbsp;&nbsp;&nbsp; second (00-59)
<BR>&nbsp; %U&nbsp;&nbsp;&nbsp; week number in year (00-53)(starting with
Sunday)
<BR>&nbsp; %V&nbsp;&nbsp;&nbsp; week number in year
<BR>&nbsp; %w&nbsp;&nbsp;&nbsp; weekday (0-6)(starting with Sunday)
<BR>&nbsp; %W&nbsp;&nbsp;&nbsp; week number in year (00-53)(starting with
Monday)
<BR>&nbsp; %x&nbsp;&nbsp;&nbsp; local date representation
<BR>&nbsp; %X&nbsp;&nbsp;&nbsp; local time representation
<BR>&nbsp; %y&nbsp;&nbsp;&nbsp; year (no century prefix)
<BR>&nbsp; %Y&nbsp;&nbsp;&nbsp; year (with century prefix)
<BR>&nbsp; %Z&nbsp;&nbsp;&nbsp; time zone name
<BR>&nbsp; %%&nbsp;&nbsp;&nbsp; %
<BR>&nbsp;</BLOCKQUOTE>
<H4>
WEEK(diff)</H4>
<BLOCKQUOTE>Enters the two-digit number of the current week (%V) increased
by specified difference.
<BR>If the resulting number is negative, the returned value is zero (00).
<BR>Values are kept up to 99, three digit values are shortened from the
left.
<P>WEEK(-4)&nbsp;&nbsp;&nbsp; returns 48, if current week is 52
<BR>WEEK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current
week
<BR>&nbsp;</BLOCKQUOTE>
<H4>
SYSNO</H4>
<BLOCKQUOTE>&nbsp;
<BR>Works the same as DATE, however the format of the resulting value is
fixed so it complies with the requirements of further record handling.
The format is 'whhmmss', where:
<P>w&nbsp;&nbsp;&nbsp;&nbsp; current weekday
<BR>hh&nbsp;&nbsp;&nbsp; current hour
<BR>mm&nbsp;&nbsp;&nbsp; current minute
<BR>ss&nbsp;&nbsp;&nbsp; current second
<P>The system number, if generated like this, contains a variable value
changing every second. For the system number is an identifier of the record,
it is needed to ensure it will be unique for the entire record processed.
Unlike the function DATE, which simply generates the value of format given,
SYSNO keeps the value persistent throughout the entire record and excludes collision
with other records that are generated in period of one week with one second granularity.
<P>It is not possible to use the DATE function for generating a system number instead.
<P>The system number is unique in range of one week only, according to
the current definition.
<BR>&nbsp;
<BR>&nbsp;</BLOCKQUOTE><H4>
OAI</H4>
<BLOCKQUOTE>
<p/>Inserts OAI identifier incremented by one for earch record
Starting value that is used in the first record in the batch job can be specified on the command line using the -o&lt;starting_value> option.
</BLOCKQUOTE>
diff --git a/modules/bibconvert/doc/admin/index.html.wml b/modules/bibconvert/doc/admin/index.html.wml
index 5d696e157..eacc5c42f 100644
--- a/modules/bibconvert/doc/admin/index.html.wml
+++ b/modules/bibconvert/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibConvert Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibconvert"
<dl>
<dt><a href="guide.html">BibConvert Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running BibConvert.</dd>
</dl>
diff --git a/modules/bibconvert/etc/Makefile.am b/modules/bibconvert/etc/Makefile.am
index fc4ac4bea..9095692e9 100644
--- a/modules/bibconvert/etc/Makefile.am
+++ b/modules/bibconvert/etc/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir=$(sysconfdir)/bibconvert/KB
KBS = $(wildcard $(srcdir)/*.kb)
etc_DATA = $(KBS:$(srcdir)/%=%)
EXTRA_DIST = $(etc_DATA)
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/bibconvert/lib/Makefile.am b/modules/bibconvert/lib/Makefile.am
index 1f4b12a20..ce5b1d2c4 100644
--- a/modules/bibconvert/lib/Makefile.am
+++ b/modules/bibconvert/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = bibconvert.py bibconvert_tests.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibconvert/lib/bibconvert.py b/modules/bibconvert/lib/bibconvert.py
index aa271c5bc..5e2b98a0b 100644
--- a/modules/bibconvert/lib/bibconvert.py
+++ b/modules/bibconvert/lib/bibconvert.py
@@ -1,1523 +1,1523 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""BibConvert tool to convert bibliographic records from any format to any format."""
__version__ = "$Id$"
try:
import fileinput
import string
import os
import re
import sys
import time
import getopt
from time import gmtime, strftime, localtime
import os.path
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
try:
from cdsware.config import *
from cdsware.search_engine import perform_request_search
from cdsware.oai_repository_config import oaiidprefix
except ImportError, e:
print "Error: %s" % e
sys.exit(1)
### Matching records with database content
def parse_query_string(query_string):
"""Parse query string, e.g.:
Input: 245__a::REP(-, )::SHAPE::SUP(SPACE, )::MINL(4)::MAXL(8)::EXPW(PUNCT)::WORDS(4,L)::SHAPE::SUP(SPACE, )||700__a::MINL(2)::REP(COMMA,).
Output:[['245__a','REP(-,)','SHAPE','SUP(SPACE, )','MINL(4)','MAXL(8)','EXPW(PUNCT)','WORDS(4,L)','SHAPE','SUP(SPACE, )'],['700__a','MINL(2)','REP(COMMA,)']]
"""
query_string_out = []
query_string_out_in = []
query_string_split_1 = query_string.split('||')
for item_1 in query_string_split_1:
query_string_split_2 = item_1.split('::')
query_string_out_in = []
for item in query_string_split_2:
query_string_out_in.append(item)
query_string_out.append(query_string_out_in)
return query_string_out
def set_conv():
"""
bibconvert common settings
=======================
minimal length of output line = 1
maximal length of output line = 4096
"""
conv_setting = [
1,
4096
]
return conv_setting
def get_pars(fn):
"Read function and its parameters into list"
out = []
out.append(re.split('\(|\)', fn)[0])
out.append(re.split(',', re.split('\(|\)', fn)[1]))
return out
def get_other_par(par, cfg):
"Get other parameter (par) from the configuration file (cfg)"
out = ""
other_parameters = {
'_QRYSTR_' : '_QRYSTR_---.*$',
'_MATCH_' : '_MATCH_---.*$',
'_RECSEP_' : '_RECSEP_---.*$',
'_EXTCFG_' : '_EXTCFG_---.*$',
'_SRCTPL_' : '_SRCTPL_---.*$',
'_DSTTPL_' : '_DSTTPL_---.*$',
'_RECHEAD_': '_RECHEAD_---.*$',
'_RECFOOT_': '_RECFOOT_---.*$',
'_HEAD_' : '_HEAD_---.*$',
'_FOOT_' : '_FOOT_---.*$',
'_EXT_' : '_EXT_---.*$',
'_SEP_' : '_SEP_---.*$',
'_COD_' : '_COD_---.*$',
'_FRK_' : '_FRK_---.*$',
'_NC_' : '_NC_---.*$',
'_MCH_' : '_MCH_---.*$',
'_UPL_' : '_UPL_---.*$',
'_AUTO_' : '_AUTO_---.*$'
}
parameters = other_parameters.keys()
for line in fileinput.input(cfg):
pattern = re.compile(other_parameters[par])
items = pattern.findall(line)
for item in items:
out = item.split('---')[1]
return out
def append_to_output_file(filename, output):
"bibconvert output file creation by output line"
try:
file = open(filename, 'a')
file.write(output)
file.close()
except IOError, e:
exit_on_error("Cannot write into %s" % filename)
return 1
def sub_keywd(out):
"bibconvert keywords literal substitution"
out = string.replace(out, "EOL", "\n")
out = string.replace(out, "_CR_", "\r")
out = string.replace(out, "_LF_", "\n")
out = string.replace(out, "\\", '\\')
out = string.replace(out, "\r", '\r')
out = string.replace(out, "BSLASH", '\\')
out = string.replace(out, "COMMA", ',')
out = string.replace(out, "LEFTB", '[')
out = string.replace(out, "RIGHTB", ']')
out = string.replace(out, "LEFTP", '(')
out = string.replace(out, "RIGHTP", ')')
return out
def check_split_on(data_item_split, sep, tpl_f):
"""
bibconvert conditional split with following conditions
===================================================
::NEXT(N,TYPE,SIDE) - next N chars are of the TYPE having the separator on the SIDE
::PREV(N,TYPE,SIDE) - prev.N chars are of the TYPE having the separator on the SIDE
"""
fn = get_pars(tpl_f)[0]
par = get_pars(tpl_f)[1]
done = 0
while (done == 0):
if ( (( fn == "NEXT" ) and ( par[2]=="R" )) or
(( fn == "PREV" ) and ( par[2]=="L" )) ):
test_value = data_item_split[0][-(string.atoi(par[0])):]
elif ( ((fn == "NEXT") and ( par[2]=="L")) or
((fn == "PREV") and ( par[2]=="R")) ):
test_value = data_item_split[1][:(string.atoi(par[0]))]
data_item_split_tmp = []
if ((FormatField(test_value, "SUP(" + par[1] + ",)") != "") or (len(test_value) < string.atoi(par[0]))):
data_item_split_tmp = data_item_split[1].split(sep, 1)
if(len(data_item_split_tmp)==1):
done = 1
data_item_split[0] = data_item_split[0] + sep + data_item_split_tmp[0]
data_item_split[1] = ""
else:
data_item_split[0] = data_item_split[0] + sep + data_item_split_tmp[0]
data_item_split[1] = data_item_split_tmp[1]
else:
done = 1
return data_item_split
def get_subfields(data, subfield, src_tpl):
"Get subfield according to the template"
out = []
for data_item in data:
found = 0
for src_tpl_item in src_tpl:
if (src_tpl_item[:2] == "<:"):
if (src_tpl_item[2:-2] == subfield):
found = 1
else:
sep_in_list = src_tpl_item.split("::")
sep = sep_in_list[0]
data_item_split = data_item.split(sep, 1)
if (len(data_item_split)==1):
data_item = data_item_split[0]
else:
if (len(sep_in_list) > 1):
data_item_split = check_split_on(data_item.split(sep, 1), sep_in_list[0], sep_in_list[1])
if(found == 1):
data_item = data_item_split[0]
else:
data_item = string.join(data_item_split[1:], sep)
out.append(data_item)
return out
def exp_n(word):
"Replace newlines and carriage return's from string."
out = ""
for ch in word:
if ((ch != '\n') and (ch != '\r')):
out = out + ch
return out
def exp_e(list):
"Expunge empty elements from a list"
out = []
for item in list:
item = exp_n(item)
if ((item != '\r\n' and item != '\r' and item != '\n' and item !="" and len(item)!=0)):
out.append(item)
return out
def sup_e(word):
"Replace spaces"
out = ""
for ch in word:
if (ch != ' '):
out = out + ch
return out
def select_line(field_code, list):
"Return appropriate item from a list"
out = ['']
for field in list:
field[0] = sup_e(field[0])
field_code = sup_e(field_code)
if (field[0] == field_code):
out = field[1]
return out
def parse_field_definition(source_field_definition):
"Create list of source_field_definition"
word_list = []
out = []
word = ""
counter = 0
if (len(source_field_definition.split("---"))==4):
out = source_field_definition.split("---")
else:
element_list_high = source_field_definition.split("<:")
for word_high in element_list_high:
element_list_low = word_high.split(':>')
for word_low in element_list_low:
word_list.append(word_low)
word_list.append(":>")
word_list.pop()
word_list.append("<:")
word_list.pop()
for item in word_list:
word = word + item
if (item == "<:"):
counter = counter + 1
if (item == ":>"):
counter = counter - 1
if counter == 0:
out.append(word)
word = ""
return out
def parse_template(template):
"""
bibconvert parse template
======================
in - template filename
out - [ [ field_code , [ field_template_parsed ] , [] ]
"""
out = []
for field_def in read_file(template, 1):
field_tpl_new = []
if ((len(field_def.split("---", 1)) > 1) and (field_def[:1] != "#")):
field_code = field_def.split("---", 1)[0]
field_tpl = parse_field_definition(field_def.split("---", 1)[1])
field_tpl_new = field_tpl
field_tpl = exp_e(field_tpl_new)
out_data = [field_code, field_tpl]
out.append(out_data)
return out
def parse_common_template(template, part):
"""
bibconvert parse template
=========================
in - template filename
out - [ [ field_code , [ field_template_parsed ] , [] ]
"""
out = []
counter = 0
for field_def in read_file(template, 1):
if (exp_n(field_def)[:3] == "==="):
counter = counter + 1
elif (counter == part):
field_tpl_new = []
if ((len(field_def.split("---", 1)) > 1) and (field_def[:1]!="#")):
field_code = field_def.split("---", 1)[0]
field_tpl = parse_field_definition(field_def.split("---", 1)[1])
field_tpl_new = field_tpl
field_tpl = exp_e(field_tpl_new)
out_data = [field_code, field_tpl]
out.append(out_data)
return out
def parse_input_data_f(source_data_open, source_tpl):
"""
bibconvert parse input data
========================
in - input source data location (filehandle)
source data template
source_field_code list of source field codes
source_field_data list of source field data values (repetitive fields each line one occurence)
out - [ [ source_field_code , [ source_field_data ] ] , [] ]
source_data_template entry - field_code---[const]<:subfield_code:>[const][<:subfield_code:>][]
destination_templace entry - [::GFF()]---[const]<:field_code::subfield_code[::FF()]:>[]
input data file; by line: - fieldcode value
"""
global separator
out = [['',[]]]
count = 0
values = []
while (count < 1):
line = source_data_open.readline()
if (line == ""):
return(-1)
line_split = line.split(" ", 1)
if (re.sub("\s", "", line) == separator):
count = count + 1
if (len(line_split) == 2):
field_code = line_split[0]
field_value = exp_n(line_split[1])
values.append([field_code, field_value])
item_prev = ""
stack = ['']
for item in values:
if ((item[0]==item_prev)or(item_prev == "")):
stack.append(item[1])
item_prev = item[0]
else:
out.append([item_prev, stack])
item_prev = item[0]
stack = []
stack.append(item[1])
try:
if (stack[0] != ""):
if (out[0][0]==""):
out = []
out.append([field_code, stack])
except IndexError, e:
out = out
return out
def parse_input_data_fx(source_tpl):
"""
bibconvert parse input data
========================
in - input source data location (filehandle)
source data template
source_field_code list of source field codes
source_field_data list of source field data values (repetitive fields each line one occurence)
out - [ [ source_field_code , [ source_field_data ] ] , [] ]
extraction_template_entry -
input data file - specified by extract_tpl
"""
global separator
count = 0
record = ""
field_data_1_in_list = []
out = [['',[]]]
while (count <10):
line = sys.stdin.readline()
if (line == ""):
count = count + 1
if (record == "" and count):
return (-1)
if (re.sub("\s", "", line) == separator):
count = count + 10
else:
record = record + line
for field_defined in extract_tpl_parsed:
try:
field_defined[1][0] = sub_keywd(field_defined[1][0])
field_defined[1][1] = sub_keywd(field_defined[1][1])
except IndexError, e:
field_defined = field_defined
try:
field_defined[1][2] = sub_keywd(field_defined[1][2])
except IndexError, e:
field_defined = field_defined
field_data_1 =""
if ((field_defined[1][0][0:2] == '//') and (field_defined[1][0][-2:] == '//')):
field_defined_regexp = field_defined[1][0][2:-2]
try:
####
if (len(re.split(field_defined_regexp, record)) == 1):
field_data_1 = ""
field_data_1_in_list = []
else:
field_data_1_tmp = re.split(field_defined_regexp, record, 1)[1]
field_data_1_in_list = field_data_1_tmp.split(field_defined_regexp)
except IndexError, e:
field_data_1 = ""
else:
try:
if (len(record.split(field_defined[1][0])) == 1):
field_data_1 = ""
field_data_1_in_list = []
else:
field_data_1_tmp = record.split(field_defined[1][0], 1)[1]
field_data_1_in_list = field_data_1_tmp.split(field_defined[1][0])
except IndexError, e:
field_data_1 = ""
spliton = []
outvalue = ""
field_data_2 = ""
field_data = ""
try:
if ((field_defined[1][1])=="EOL"):
spliton = ['\n']
elif ((field_defined[1][1])=="MIN"):
spliton = ['\n']
elif ((field_defined[1][1])=="MAX"):
for item in extract_tpl_parsed:
try:
spliton.append(item[1][0])
except IndexError, e:
spliton = spliton
elif (field_defined[1][1][0:2] == '//') and (field_defined[1][1][-2:] == '//'):
spliton = [field_defined[1][1][2:-2]]
else:
spliton = [field_defined[1][1]]
except IndexError,e :
spliton = ""
outvalues = []
for field_data in field_data_1_in_list:
outvalue = ""
for splitstring in spliton:
field_data_2 = ""
if (len(field_data.split(splitstring))==1):
if (outvalue == ""):
field_data_2 = field_data
else:
field_data_2 = outvalue
else:
field_data_2 = field_data.split(splitstring)[0]
outvalue = field_data_2
field_data = field_data_2
outvalues.append(outvalue)
outvalues = exp_e(outvalues)
if (len(outvalues) > 0):
if (out[0][0]==""):
out = []
outstack = []
if (len(field_defined[1])==3):
spliton = [field_defined[1][2]]
if (field_defined[1][2][0:2] == '//') and (field_defined[1][2][-2:] == '//'):
spliton = [field_defined[1][2][2:-2]]
for item in outvalues:
stack = re.split(spliton[0], item)
for stackitem in stack:
outstack.append(stackitem)
else:
outstack = outvalues
out.append([field_defined[0], outstack])
return out
def parse_input_data_d(source_data, source_tpl):
"""
bibconvert parse input data
========================
in - input source data location (directory)
source data template
source_field_code list of source field codes
source_field_data list of source field data values (repetitive fields each line one occurence)
out - [ [ source_field_code , [ source_field_data ] ] , [] ]
source_data_template entry - field_code---[const]<:subfield_code:>[const][<:subfield_code:>][]
destination_templace entry - [::GFF()]---[const]<:field_code::subfield_code[::FF()]:>[]
input data dir; by file: - fieldcode value per line
"""
out = []
for source_field_tpl in read_file(source_tpl, 1):
source_field_code = source_field_tpl.split("---")[0]
source_field_data = read_file(source_data + source_field_code, 0)
source_field_data = exp_e(source_field_data)
out_data = [source_field_code, source_field_data]
out.append(out_data)
return out
def sub_empty_lines(value):
out = re.sub('\n\n+', '', value)
return out
def set_par_defaults(par1, par2):
"Set default parameter when not defined"
par_new_in_list = par2.split(",")
i = 0
out = []
for par in par_new_in_list:
if (len(par1)>i):
if (par1[i] == ""):
out.append(par)
else:
out.append(par1[i])
else:
out.append(par)
i = i + 1
return out
def generate(keyword):
"""
bibconvert generaded values:
=========================
SYSNO() - generate date as '%w%H%M%S'
WEEK(N) - generate date as '%V' with shift (N)
DATE(format) - generate date in specifieddate FORMAT
VALUE(value) - enter value literarly
OAI() - generate oai_identifier, starting value given at command line as -o<value>
"""
out = keyword
fn = keyword + "()"
par = get_pars(fn)[1]
fn = get_pars(fn)[0]
par = set_par_defaults(par, "")
if (fn == "SYSNO"):
out = sysno500
if (fn == "SYSNO330"):
out = sysno
if (fn == "WEEK"):
par = set_par_defaults(par, "0")
out = "%02d" % (string.atoi(strftime("%V", localtime())) + string.atoi(par[0]))
if (string.atoi(out)<0):
out = "00"
if (fn == "VALUE"):
par = set_par_defaults(par, "")
out = par[0]
if (fn == "DATE"):
par = set_par_defaults(par, "%w%H%M%S," + "%d" % set_conv()[1])
out = strftime(par[0],localtime())
out = out[:string.atoi(par[1])]
if (fn == "XDATE"):
par = set_par_defaults(par,"%w%H%M%S," + ",%d" % set_conv()[1])
out = strftime(par[0],localtime())
out = par[1] + out[:string.atoi(par[2])]
if (fn == "OAI"):
out = "%s:%d" % (oaiidprefix,tcounter + oai_identifier_from)
return out
def read_file(filename,exception):
"Read file into list"
out = []
if (os.path.isfile(filename)):
file = open(filename,'r')
out = file.readlines()
file.close()
else:
if exception:
exit_on_error("Cannot access file: %s" % filename)
return out
def crawl_KB(filename,value,mode):
"""
bibconvert look-up value in KB_file in one of following modes:
===========================================================
1 - case sensitive / match (default)
2 - not case sensitive / search
3 - case sensitive / search
4 - not case sensitive / match
5 - case sensitive / search (in KB)
6 - not case sensitive / search (in KB)
7 - case sensitive / search (reciprocal)
8 - not case sensitive / search (reciprocal)
9 - replace by _DEFAULT_ only
R - not case sensitive / search (reciprocal) (8) replace
"""
if (os.path.isfile(filename) != 1):
pathtmp = string.split(extract_tpl,"/")
pathtmp.pop()
path = string.join(pathtmp,"/")
filename = path + "/" + filename
if (os.path.isfile(filename)):
file_to_read = open(filename,"r")
file_read = file_to_read.readlines()
for line in file_read:
code = string.split(line,"---")
if (mode == "2"):
value_to_cmp = string.lower(value)
code[0] = string.lower(code[0])
if ((len(string.split(value_to_cmp,code[0])) > 1)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif ((mode == "3") or (mode == "0")):
if ((len(string.split(value,code[0])) > 1)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif (mode == "4"):
value_to_cmp = string.lower(value)
code[0] = string.lower(code[0])
if ((code[0] == value_to_cmp)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif (mode == "5"):
if ((len(string.split(code[0],value)) > 1)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif (mode == "6"):
value_to_cmp = string.lower(value)
code[0] = string.lower(code[0])
if ((len(string.split(code[0],value_to_cmp)) > 1)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif (mode == "7"):
if ((len(string.split(code[0],value)) > 1)or(len(string.split(value,code[0])) > 1)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif (mode == "8"):
value_to_cmp = string.lower(value)
code[0] = string.lower(code[0])
if ((len(string.split(code[0],value_to_cmp)) > 1)or(len(string.split(value_to_cmp,code[0]))>1)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
elif (mode == "9"):
if (code[0]=="_DEFAULT_"):
value = code[1]
return value
elif (mode == "R"):
value_to_cmp = string.lower(value)
code[0] = string.lower(code[0])
if ((len(string.split(code[0],value_to_cmp)) > 1)or(len(string.split(value_to_cmp,code[0]))>1)or(code[0]=="_DEFAULT_")):
value = value.replace(code[0],code[1])
else:
if ((code[0] == value)or(code[0]=="_DEFAULT_")):
value = code[1]
return value
return value
def FormatField(value, fn):
"""
bibconvert formatting functions:
================================
ADD(prefix,suffix) - add prefix/suffix
KB(kb_file,mode) - lookup in kb_file and replace value
ABR(N,suffix) - abbreviate to N places with suffix
ABRX() - abbreviate exclusively words longer
ABRW() - abbreviate word (limit from right)
REP(x,y) - replace
SUP(type) - remove characters of certain TYPE
LIM(n,side) - limit to n letters from L/R
LIMW(string,side) - L/R after split on string
WORDS(n,side) - limit to n words from L/R
IF(value,valueT,valueF) - replace on IF condition
MINL(n) - replace words shorter than n
MINLW(n) - replace words shorter than n
MAXL(n) - replace words longer than n
EXPW(type) - replace word from value containing TYPE
EXP(STR,0/1) - replace word from value containing string
NUM() - take only digits in given string
SHAPE() - remove extra space
UP() - to uppercase
DOWN() - to lowercase
CAP() - make capitals each word
SPLIT(n,h,str,from) - only for final Aleph field, i.e. AB , maintain whole words
SPLITW(sep,h,str,from) - only for final Aleph field, split on string
CONF(filed,value,0/1) - confirm validity of output line (check other field)
CONFL(substr,0/1) - confirm validity of output line (check field being processed)
CUT(prefix,postfix) - remove substring from side
RANGE(MIN,MAX) - select items in repetitive fields
RE(regexp) - regular expressions
bibconvert character TYPES
==========================
ALPHA - alphabetic
NALPHA - not alpphabetic
NUM - numeric
NNUM - not numeric
ALNUM - alphanumeric
NALNUM - non alphanumeric
LOWER - lowercase
UPPER - uppercase
PUNCT - punctual
NPUNCT - non punctual
SPACE - space
"""
global data_parsed
out = value
fn = fn + "()"
par = get_pars(fn)[1]
fn = get_pars(fn)[0]
regexp = "//"
NRE = len(regexp)
value = sub_keywd(value)
par_tmp = []
for item in par:
item = sub_keywd(item)
par_tmp.append(item)
par = par_tmp
if (fn == "RE"):
new_value = ""
par = set_par_defaults(par,".*,0")
if (re.search(par[0],value) and (par[1] == "0")):
new_value = value
out = new_value
if (fn == "KB"):
new_value = ""
par = set_par_defaults(par,"KB,0")
new_value = crawl_KB(par[0],value,par[1])
out = new_value
elif (fn == "ADD"):
par = set_par_defaults(par,",")
out = par[0] + value + par[1]
elif (fn == "ABR"):
par = set_par_defaults(par,"1,.")
out = value[:string.atoi(par[0])] + par[1]
elif (fn == "ABRW"):
tmp = FormatField(value,"ABR(1,.)")
tmp = tmp.upper()
out = tmp
elif (fn == "ABRX"):
par = set_par_defaults(par,",")
toout = []
tmp = value.split(" ")
for wrd in tmp:
if (len(wrd) > string.atoi(par[0])):
wrd = wrd[:string.atoi(par[0])] + par[1]
toout.append(wrd)
out = string.join(toout," ")
elif (fn == "SUP"):
par = set_par_defaults(par,",")
if(par[0]=="NUM"):
out = re.sub('\d+',par[1],value)
if(par[0]=="NNUM"):
out = re.sub('\D+',par[1],value)
if(par[0]=="ALPHA"):
out = re.sub('[a-zA-Z]+',par[1],value)
if(par[0]=="NALPHA"):
out = re.sub('[^a-zA-Z]+',par[1],value)
if((par[0]=="ALNUM")or(par[0]=="NPUNCT")):
out = re.sub('\w+',par[1],value)
if(par[0]=="NALNUM"):
out = re.sub('\W+',par[1],value)
if(par[0]=="PUNCT"):
out = re.sub('\W+',par[1],value)
if(par[0]=="LOWER"):
out = re.sub('[a-z]+',par[1],value)
if(par[0]=="UPPER"):
out = re.sub('[A-Z]+',par[1],value)
if(par[0]=="SPACE"):
out = re.sub('\s+',par[1],value)
elif (fn == "LIM"):
par = set_par_defaults(par,",")
if (par[1] == "L"):
out = value[(len(value) - string.atoi(par[0])):]
if (par[1] == "R"):
out = value[:string.atoi(par[0])]
elif (fn == "LIMW"):
par = set_par_defaults(par,",")
if (par[0]!= ""):
if (par[0][0:NRE] == regexp and par[0][-NRE:] == regexp):
par[0] = par[0][NRE:-NRE]
par[0] = re.search(par[0],value).group()
tmp = value.split(par[0])
if (par[1] == "L"):
out = par[0] + tmp[1]
if (par[1] == "R"):
out = tmp[0] + par[0]
elif (fn == "WORDS"):
tmp2 = [value]
par = set_par_defaults(par,",")
if (par[1] == "R"):
tmp = value.split(" ")
tmp2 = []
i = 0
while (i < string.atoi(par[0])):
tmp2.append(tmp[i])
i = i + 1
if (par[1] == "L"):
tmp = value.split(" ")
tmp.reverse()
tmp2 = []
i = 0
while (i < string.atoi(par[0])):
tmp2.append(tmp[i])
i = i + 1
tmp2.reverse()
out = string.join(tmp2, " ")
elif (fn == "MINL"):
par = set_par_defaults(par,"1")
tmp = value.split(" ")
tmp2 = []
i = 0
for wrd in tmp:
if (len(wrd) >= string.atoi(par[0])):
tmp2.append(wrd)
out = string.join(tmp2, " ")
elif (fn == "MINLW"):
par = set_par_defaults(par,"1")
if (len(value) >= string.atoi(par[0])):
out = value
else:
out = ""
elif (fn == "MAXL"):
par = set_par_defaults(par,"4096")
tmp = value.split(" ")
tmp2 = []
i = 0
for wrd in tmp:
if (len(wrd) <= string.atoi(par[0])):
tmp2.append(wrd)
out = string.join(tmp2, " ")
elif (fn == "REP"):
set_par_defaults(par,",")
if (par[0]!= ""):
if (par[0][0:NRE] == regexp and par[0][-NRE:] == regexp):
par[0] = par[0][NRE:-NRE]
out = re.sub(par[0],value)
else:
out = value.replace(par[0],par[1])
elif (fn == "SHAPE"):
if (value != ""):
out = value.strip()
elif (fn == "UP"):
out = value.upper()
elif (fn == "DOWN"):
out = value.lower()
elif (fn == "CAP"):
tmp = value.split(" ")
out2 = []
for wrd in tmp:
wrd2 = wrd.capitalize()
out2.append(wrd2)
out = string.join(out2," ")
elif (fn == "IF"):
par = set_par_defaults(par,",,")
N = 0
while N < 3:
if (par[N][0:NRE] == regexp and par[N][-NRE:] == regexp):
par[N] = par[N][NRE:-NRE]
par[N] = re.search(par[N],value).group()
N += 1
if (value == par[0]):
out = par[1]
else:
out = par[2]
if (out == "ORIG"):
out = value
elif (fn == "EXP"):
par = set_par_defaults(par,",0")
if (par[0][0:NRE] == regexp and par[0][-NRE:] == regexp):
par[0] = par[0][NRE:-NRE]
par[0] = re.search(par[0],value).group()
tmp = value.split(" ")
out2 = []
for wrd in tmp:
if (par[0][0:NRE] == regexp and par[0][-NRE:] == regexp):
par[0] = par[0][NRE:-NRE]
if ((re.search(par[0],wrd).group() == wrd) and (par[1]=="1")):
out2.append(wrd)
if ((re.search(par[0],wrd).group() != wrd) and (par[1]=="0")):
out2.append(wrd)
else:
if ((len(wrd.split(par[0])) == 1)and(par[1]=="1")):
out2.append(wrd)
if ((len(wrd.split(par[0])) != 1)and(par[1]=="0")):
out2.append(wrd)
out = string.join(out2," ")
elif (fn == "EXPW"):
par = set_par_defaults(par,",0")
tmp = value.split(" ")
out2 = []
for wrd in tmp:
if ((FormatField(wrd,"SUP(" + par[0] + ")") == wrd)and(par[1]=="1")):
out2.append(wrd)
if ((FormatField(wrd,"SUP(" + par[0] + ")") != wrd)and(par[1]=="0")):
out2.append(wrd)
out = string.join(out2," ")
elif (fn == "SPLIT"):
par = set_par_defaults(par,"%d,0,,1" % conv_setting[1])
length = string.atoi(par[0]) + (string.atoi(par[1]))
header = string.atoi(par[1])
headerplus = par[2]
starting = string.atoi(par[3])
line = ""
tmp2 = []
tmp3 = []
tmp = value.split(" ")
linenumber = 1
if (linenumber >= starting):
tmp2.append(headerplus)
line = line + headerplus
for wrd in tmp:
line = line + " " + wrd
tmp2.append(wrd)
if (len(line) > length):
linenumber = linenumber + 1
line = tmp2.pop()
toout = string.join(tmp2)
tmp3.append(toout)
tmp2 = []
line2 = value[:header]
if (linenumber >= starting):
line3 = line2 + headerplus + line
else:
line3 = line2 + line
line = line3
tmp2.append(line)
tmp3.append(line)
out = string.join(tmp3,"\n")
out = FormatField(out,"SHAPE()")
elif (fn == "SPLITW"):
par = set_par_defaults(par,",0,,1")
if (par[0][0:NRE] == regexp and par[0][-NRE:] == regexp):
par[0] = par[0][NRE:-NRE]
str = re.search(par[0], value)
header = string.atoi(par[1])
headerplus = par[2]
starting = string.atoi(par[3])
counter = 1
tmp2 = []
tmp = re.split(par[0],value)
last = tmp.pop()
for wrd in tmp:
counter = counter + 1
if (counter >= starting):
tmp2.append(value[:header] + headerplus + wrd + str)
else:
tmp2.append(value[:header] + wrd + str)
if (last != ""):
counter = counter + 1
if (counter >= starting):
tmp2.append(value[:header] + headerplus + last)
else:
tmp2.append(value[:header] + last)
out = string.join(tmp2,"\n")
elif (fn == "CONF"):
par = set_par_defaults(par,",,1")
found = 0
par1 = ""
data = select_line(par[0],data_parsed)
for line in data:
if (par[1][0:NRE] == regexp and par[1][-NRE:] == regexp):
par1 = par[1][NRE:-NRE]
else:
par1 = par[1]
if (par1 == ""):
if (line == ""):
found = 1
elif (len(re.split(par1,line)) > 1 ):
found = 1
if ((found == 1)and(string.atoi(par[2]) == 1)):
out = value
if ((found == 1)and(string.atoi(par[2]) == 0)):
out = ""
if ((found == 0)and(string.atoi(par[2]) == 1)):
out = ""
if ((found == 0)and(string.atoi(par[2]) == 0)):
out = value
return out
elif (fn == "CONFL"):
set_par_defaults(par,",1")
if (par[0][0:NRE] == regexp and par[0][-NRE:] == regexp):
par[0] = par[0][NRE:-NRE]
if (re.search(par[0],value)):
if (string.atoi(par[1]) == 1):
out = value
else:
out = ""
else:
if (string.atoi(par[1]) == 1):
out = ""
else:
out = value
return out
elif (fn == "CUT"):
par = set_par_defaults(par,",")
left = value[:len(par[0])]
right = value[-(len(par[1])):]
if (left == par[0]):
out = out[len(par[0]):]
if (right == par[1]):
out = out[:-(len(par[1]))]
return out
elif (fn == "NUM"):
tmp = re.findall('\d',value)
out = string.join(tmp,"")
return out
def printInfo():
"print out when not enough parmeters given"
print """
BibConvert data convertor
Usage: bibconvert [options] -ctemplate.cfg < input.dat
Options:
-c'config' configuration templates file
-d'directory' source_data fields are located in separated files in 'directory'one record)
-h print this help
-V print version number
-l'length' minimum line length (default = 1)
-o'value' OAI identifier starts with specified value (default = 1)
-b'file header' insert file header
-e'file footer' insert file footer
-B'record header' insert record header
-E'record footer' insert record footer
-s'record separator' record separator, default empty line (EOLEOL)
-m0'query_string' match records using query string, output unmatched
-m1'query_string' match records using query string, output matched
-m2'query_string' match records using query string, output ambiguous
-Cx'field extraction template' alternative to -c when configuration is split to several files
-Cs'source data template' alternative to -c when configuration is split to several files
-Ct'target data template' alternative to -c when configuration is split to several files
"""
## Match records with the database content
##
def match_in_database(record, query_string):
"Check if record is in alreadey in database with an oai identifier. Returns recID if present, 0 otherwise."
query_string_parsed = parse_query_string(query_string)
search_pattern = []
search_field = []
for query_field in query_string_parsed:
ind1 = query_field[0][3:4]
if ind1 == "_":
ind1 = ""
ind2 = query_field[0][4:5]
if ind2 == "_":
ind2 = ""
stringsplit = "<datafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\"><subfield code=\"%s\">" % (query_field[0][0:3], ind1, ind2, query_field[0][5:6])
formatting = query_field[1:]
record1 = string.split(record, stringsplit)
if len(record1) > 1:
matching_value = string.split(record1[1],"<")[0]
for fn in formatting:
matching_value = FormatField(matching_value, fn)
search_pattern.append(matching_value)
search_field.append(query_field[0])
search_field.append("")
search_field.append("")
search_field.append("")
search_pattern.append("")
search_pattern.append("")
search_pattern.append("")
recID_list = perform_request_search(p1=search_pattern[0],f1=search_field[0],p2=search_pattern[1],f2=search_field[1],p3=search_pattern[2],f3=search_field[2])
return recID_list
def parse_query_string(query_string):
"""Parse query string, e.g.:
Input: 245__a::REP(-, )::SHAPE::SUP(SPACE, )::MINL(4)::MAXL(8)::EXPW(PUNCT)::WORDS(4,L)::SHAPE::SUP(SPACE, )||700__a::MINL(2)::REP(COMMA,).
Output:[['245__a','REP(-,)','SHAPE','SUP(SPACE, )','MINL(4)','MAXL(8)','EXPW(PUNCT)','WORDS(4,L)','SHAPE','SUP(SPACE, )'],['700__a','MINL(2)','REP(COMMA,)']]
"""
query_string_out = []
query_string_out_in = []
query_string_split_1 = query_string.split('||')
for item_1 in query_string_split_1:
query_string_split_2 = item_1.split('::')
query_string_out_in = []
for item in query_string_split_2:
query_string_out_in.append(item)
query_string_out.append(query_string_out_in)
return query_string_out
def exit_on_error(error_message):
"exit when error occured"
sys.stderr.write("\n bibconvert data convertor\n")
sys.stderr.write(" Error: %s\n" % error_message)
sys.exit()
return 0
def create_record(begin_record_header, ending_record_footer, query_string, match_mode, Xcount):
"Create output record"
global data_parsed
out_to_print = ""
out = []
field_data_item_LIST = []
ssn5cnt = "%3d" % Xcount
sysno = generate("DATE(%w%H%M%S)")
sysno500 = generate("XDATE(%w%H%M%S)," + ssn5cnt)
for T_tpl_item_LIST in target_tpl_parsed:
# the line is printed only if the variables inside are not empty
print_line = 0
to_output = []
rows = 1
for field_tpl_item_STRING in T_tpl_item_LIST[1]:
DATA = []
if (field_tpl_item_STRING[:2]=="<:"):
field_tpl_item_STRING = field_tpl_item_STRING[2:-2]
field = field_tpl_item_STRING.split("::")[0]
if (len(field_tpl_item_STRING.split("::")) == 1):
value = generate(field)
to_output.append([value])
else:
subfield = field_tpl_item_STRING.split("::")[1]
if (field[-1] == "*"):
repetitive = 1
field = field[:-1]
else:
repetitive = 0
if dirmode:
DATA = select_line(field,data_parsed)
else:
DATA = select_line(field,data_parsed)
if (repetitive == 0):
DATA = [string.join(DATA," ")]
SRC_TPL = select_line(field,source_tpl_parsed)
try:
if (DATA[0] != ""):
DATA = get_subfields(DATA,subfield,SRC_TPL)
FF = field_tpl_item_STRING.split("::")
if (len(FF) > 2):
FF = FF[2:]
for fn in FF:
# DATAFORMATTED = []
if (len(DATA) != 0 and DATA[0] != ""):
DATA = get_subfields(DATA,subfield,SRC_TPL)
FF = field_tpl_item_STRING.split("::")
if (len(FF) > 2):
FF = FF[2:]
for fn2 in FF:
DATAFORMATTED = []
for item in DATA:
item = FormatField(item,fn)
DATAFORMATTED.append(item)
DATA = DATAFORMATTED
if (len(DATA) > rows):
rows = len(DATA)
if DATA != "":
print_line = 1
to_output.append(DATA)
except IndexError, e:
pass
else:
to_output.append([field_tpl_item_STRING])
current = 0
default_print = 0
while (current < rows):
line_to_print = []
for item in to_output:
if (item==[]):
item =['']
if (len(item) <= current):
printout = item[0]
else:
printout = item[current]
line_to_print.append(printout)
output = exp_n(string.join(line_to_print,""))
global_formatting_functions = T_tpl_item_LIST[0].split("::")[1:]
for GFF in global_formatting_functions:
if (GFF[:5] == "RANGE"):
parR = get_pars(GFF)[1]
parR = set_par_defaults(parR,"MIN,MAX")
if (parR[0]!="MIN"):
if (string.atoi(parR[0]) > (current+1)):
output = ""
if (parR[1]!="MAX"):
if (string.atoi(parR[1]) < (current+1)):
output = ""
elif (GFF[:4] == "DEFP"):
default_print = 1
else:
output = FormatField(output,GFF)
if ((len(output) > set_conv()[0] and print_line == 1) or default_print):
out_to_print = out_to_print + output + "\n"
current = current + 1
###
out_flag = 0
if query_string:
recID = match_in_database(out_to_print, query_string)
if len(recID) == 1 and match_mode == 1:
ctrlfield = "<controlfield tag=\"001\">%d</controlfield>" % (recID[0])
out_to_print = ctrlfield + "\n" + out_to_print
out_flag = 1
if len(recID) == 0 and match_mode == 0:
out_flag = 1
if len(recID) > 1 and match_mode == 2:
out_flag = 1
if out_flag or match_mode == -1:
if begin_record_header != "":
out_to_print = begin_record_header + "\n" + out_to_print
if ending_record_footer != "":
out_to_print = out_to_print + "\n" + ending_record_footer
else:
out_to_print = ""
return out_to_print
def convert(ar_):
global dirmode, Xcount, conv_setting, sysno, sysno500, separator, tcounter, source_data, query_string, match_mode, begin_record_header ,ending_record_footer,output_rec_sep, begin_header, ending_footer, oai_identifier_from, source_tpl, source_tpl_parsed, target_tpl, target_tpl_parsed, extract_tpl, extract_tpl_parsed, data_parsed
dirmode, Xcount, conv_setting, sysno, sysno500, separator, tcounter, source_data, query_string, match_mode, begin_record_header ,ending_record_footer,output_rec_sep, begin_header, ending_footer, oai_identifier_from, source_tpl, source_tpl_parsed, target_tpl, target_tpl_parsed, extract_tpl, extract_tpl_parsed = ar_
# separator = spt
# Added by Alberto
separator = sub_keywd(separator)
if dirmode:
if (os.path.isdir(source_data)):
data_parsed = parse_input_data_d(source_data,source_tpl)
record = create_record(begin_record_header, ending_record_footer, query_string, match_mode, Xcount)
if record != "":
print record
tcounter = tcounter + 1
if output_rec_sep != "":
print output_rec_sep
else:
exit_on_error("Cannot access directory: %s" % source_data)
else:
done = 0
print begin_header
while (done == 0):
data_parsed = parse_input_data_fx(source_tpl)
if (data_parsed == -1):
done = 1
else:
if (data_parsed[0][0]!= ''):
record = create_record(begin_record_header, ending_record_footer, query_string, match_mode, Xcount)
Xcount += 1
if record != "":
print record
tcounter = tcounter + 1
if output_rec_sep != "":
print output_rec_sep
print ending_footer
return
diff --git a/modules/bibconvert/lib/bibconvert_tests.py b/modules/bibconvert/lib/bibconvert_tests.py
index d4d42035d..5a0297617 100644
--- a/modules/bibconvert/lib/bibconvert_tests.py
+++ b/modules/bibconvert/lib/bibconvert_tests.py
@@ -1,135 +1,135 @@
# -*- coding: utf-8 -*-
## $Id$
## CDSware bibconvert unit tests.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the bibconvert."""
__version__ = "$Id$"
import unittest
import re
from cdsware import bibconvert
class TestFormattingFunctions(unittest.TestCase):
"""Test bibconvert formatting functions."""
def test_ff(self):
"""bibconvert - formatting functions"""
self.assertEqual("Hello world!", bibconvert.FormatField("ello world", "ADD(H,!)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world", "ABR(11,!)"))
self.assertEqual("Hello world!", bibconvert.FormatField("xHello world!x", "CUT(x,x)"))
self.assertEqual("Hello world!", bibconvert.FormatField("He11o wor1d!", "REP(1,l)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "SUP(NUM)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "LIM(12,R)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "WORDS(2)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "MINL(5)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "MAXL(12)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world! @", "EXP(@,1)"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "IF(Hello world!,ORIG,)"))
self.assertEqual("", bibconvert.FormatField("Hello world!", "NUM()"))
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world! ", "SHAPE()"))
self.assertEqual("HELLO WORLD!", bibconvert.FormatField("Hello world!", "UP()"))
self.assertEqual("hello world!", bibconvert.FormatField("Hello world!", "DOWN()"))
self.assertEqual("Hello World!", bibconvert.FormatField("Hello world!", "CAP()"))
class TestGlobalFormattingFunctions(unittest.TestCase):
"""Test bibconvert global formatting functions."""
def test_gff(self):
"""bibconvert - global formatting functions"""
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!","DEFP()"))
class TestGenerateValues(unittest.TestCase):
"""Test bibconvert value generation."""
def test_gv(self):
"""bibconvert - value generation"""
self.assertEqual("Hello world!", bibconvert.generate("VALUE(Hello world!)"))
class TestParseData(unittest.TestCase):
"""Test bibconvert input data parsing."""
def test_idp(self):
"""bibconvert - input data parsing"""
self.assertEqual(['A','B','C','D'], bibconvert.parse_field_definition("A---B---C---D"))
class TestRegExp(unittest.TestCase):
"""Test bibconvert regular expressions"""
def test_regexp(self):
"""bibconvert - regular expressions"""
self.assertEqual("Hello world!", bibconvert.FormatField("Hello world!", "RE([A-Z][a-z].*!)"))
class TestBCCL(unittest.TestCase):
"""Test bibconvert BCCL complinacy"""
def test_bccl_09(self):
"""bibconvert - BCCL v.0.9 compliancy"""
self.assertEqual(1, 1)
class TestKnowledgeBase(unittest.TestCase):
"""Test bibconvert knowledge base"""
def test_enc(self):
"""bibconvert - knowledge base"""
self.assertEqual(1, 1)
class TestErrorCodes(unittest.TestCase):
"""Test bibconvert error codes"""
def test_enc(self):
"""bibconvert - error codes"""
self.assertEqual(1, 1)
class TestEncodings(unittest.TestCase):
"""Test bibconvert encodings"""
def test_enc(self):
"""bibconvert - encodings"""
self.assertEqual(1, 1)
def create_test_suite():
"""Return test suite for the bibconvert module."""
return unittest.TestSuite((unittest.makeSuite(TestFormattingFunctions, 'test'),
unittest.makeSuite(TestGlobalFormattingFunctions, 'test'),
unittest.makeSuite(TestGenerateValues, 'test'),
unittest.makeSuite(TestParseData, 'test'),
unittest.makeSuite(TestRegExp, 'test'),
unittest.makeSuite(TestBCCL, 'test'),
unittest.makeSuite(TestKnowledgeBase, 'test'),
unittest.makeSuite(TestErrorCodes, 'test'),
unittest.makeSuite(TestEncodings, 'test')))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibedit/Makefile.am b/modules/bibedit/Makefile.am
index 75fda168f..7902b8644 100644
--- a/modules/bibedit/Makefile.am
+++ b/modules/bibedit/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc etc lib web
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/bibedit/bin/Makefile.am b/modules/bibedit/bin/Makefile.am
index 651462fff..300dafcd9 100644
--- a/modules/bibedit/bin/Makefile.am
+++ b/modules/bibedit/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = xmlmarclint refextract
EXTRA_DIST = xmlmarclint.in refextract.in
CLEANFILES = *~ *.tmp
diff --git a/modules/bibedit/bin/refextract.in b/modules/bibedit/bin/refextract.in
index ada784242..0709b479f 100644
--- a/modules/bibedit/bin/refextract.in
+++ b/modules/bibedit/bin/refextract.in
@@ -1,52 +1,52 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
"bibrefextract" is used to extract and process the "references" or "citations" made to other documents from within a document.
A document's "references" section is usually found at the end of the document, and generally consists of a list of the works
cited during the course of the document.
"bibrefextract" can attempt to identify a document's references section and extract it from the document. It can also attempt
to standardise the references (correct the names of journals etc so that they are written in a standard format), and mark them
up so that they can be linked to the full articles on the Web by means of hyper-links.
"bibrefextract" has 4 phases of processing (passes):
1. Convert PDF or Postscript file to plaintext (UTF-8).
2. Extract References from plaintext.
3. Standardise titles in extracted reference lines.
4. Markup standardised titles (this pass can only be performed if pass 3 was also performed).
Options:
--help, -h Display help/usage message and exit.
--version, -V Print version number and exit.
"""
try:
import sys
import os
from cdsware.refextract import *
except ImportError, e:
import sys
sys.exit("E: %s" % e)
if __name__ == '__main__':
main()
diff --git a/modules/bibedit/bin/xmlmarclint.in b/modules/bibedit/bin/xmlmarclint.in
index 0c74276ec..06952466a 100644
--- a/modules/bibedit/bin/xmlmarclint.in
+++ b/modules/bibedit/bin/xmlmarclint.in
@@ -1,104 +1,104 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
XML MARC lint - check your XML MARC files.
"""
__version__ = "$Id$"
import getopt
import string
import sys
from cdsware.bibrecord import *
cmdusage = """Usage: %s [options] <marcxmlfile>
General options:
-h, --help \t\t Print this help.
-V, --version \t\t Print version information.
-v, --verbose=LEVEL \t Verbose level (from 0 to 9, default 0).
Description: checks the validity of MARCXML file.
""" % (sys.argv[0])
verbose = 0
badrecords = []
listofrecs = []
try:
opts, args = getopt.getopt(sys.argv[1:], "hVv:", ["help", "version", "verbose="])
except getopt.GetoptError:
print cmdusage
sys.exit(2)
for opt in opts:
if opt[0] in ("-V","--version"):
print __version__
sys.exit(0)
elif opt[0] in ("-h","--help"):
sys.stderr.write(cmdusage)
sys.exit(0)
elif opt[0] in ("-v", "--verbose"):
try:
verbose = string.atoi(opt[1])
except ValueError:
print "Error: verbose must be an integer."
sys.exit(2)
try:
xmlfile = args[0]
except IndexError:
sys.stderr.write(cmdusage)
sys.exit(0)
try:
xmltext = open(xmlfile,'r').read()
except IOError:
print "Error: File %s not found." % xmlfile
import sys
sys.exit(1)
listofrecs = create_records(xmltext, 0, 1)
badr = filter((lambda x: x[1]==0), listofrecs)
badrecords = map((lambda x:x[0]), badr)
s = ''
e = ''
if xmltext and not listofrecs:
print "Warning: no valid record detected."
if verbose:
if verbose <= 3:
e = print_errors(concat(map((lambda x:x[2]), listofrecs)))
else:
s = print_recs(badrecords)
e = print_errors(concat(map((lambda x:x[2]), listofrecs)))
else:
if badrecords:
print "Error: Bad records detected. For more information, increase verbosity."
sys.exit(1)
if s != '' or e != '':
print s
print e
sys.exit(1)
diff --git a/modules/bibedit/doc/Makefile.am b/modules/bibedit/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibedit/doc/Makefile.am
+++ b/modules/bibedit/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibedit/doc/admin/Makefile.am b/modules/bibedit/doc/admin/Makefile.am
index 2e9d7e450..704f96087 100644
--- a/modules/bibedit/doc/admin/Makefile.am
+++ b/modules/bibedit/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir=$(WEBDIR)/admin/bibedit
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibedit/doc/admin/guide.html.wml b/modules/bibedit/doc/admin/guide.html.wml
index ef25d4af2..548b29e4c 100644
--- a/modules/bibedit/doc/admin/guide.html.wml
+++ b/modules/bibedit/doc/admin/guide.html.wml
@@ -1,199 +1,199 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibEdit Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibedit/>BibEdit Admin</a>" \
navbar_name="admin" \
navbar_select="bibedit-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">Overview</a></strong><br>
<strong>2. <a href="#2">Edit records via Web interface</a></strong><br>
<strong>3. <a href="#3">Edit records via command line</a></strong><br>
<strong>4. <a href="#4">Delete records via command line</a></strong><br>
<strong>5. <a href="#5">Delete all records</a></strong><br>
<a name="1"></a><h2>1. Overview</h2>
<p>BibEdit enables you to directly manipulate bibliographic data, edit a
single record, do global replacements, and other cataloguing tasks.
<a name="2"></a><h2>2. Edit records via Web interface</h2>
<p>Bibliographic Metadata Editor on Web is not implemented yet.
Please use the command-line technique describe below.
<a name="3"></a><h2>3. Edit records via command line</h2>
<p>The idea is to download record in XML MARC format, edit it by using
any editor, and upload the changes back. Note that you can edit any
number of records at the same time: for example, you can download all
records written by <code>Qllis, J</code>, open the file in your
favourite text editor, and change globally the author name to the
proper form <code>Ellis, J</code>.
<p>You therefore continue as follows:
<ol>
<li> Download the record in XML MARC. For example, download record ID 1234:
<pre>
$ wget -O z.xml 'http://your.site/search.py?recid=1234&of=xm'
</pre>
or download latest 5,000 public documents written by <code>Qllis, J</code>:
<pre>
$ wget -O z.xml 'http://your.site/search.py?p=Qllis%2C+J&f=author&of=xm&rg=5000'
</pre>
<li> Edit the metadata as necessary:
<pre>
$ emacs z.xml
</pre>
<li> Upload changes back:
<pre>
$ bibupload -r z.xml
</pre>
<li> See the progress of the treatment of the file via BibSched:
<pre>
$ bibsched
</pre>
If you do not want to wait for the next wake-up time of indexing
and formatting daemons, launch them manually now:
<pre>
$ bibindex
$ bibreformat
$ webcoll
</pre>
and watch the progress via <code>bibsched</code>.
</ol>
After which the record(s) should be fully modified and formatted and
all indexes and collections updated, as necessary.
<a name="4"></a><h2>4. Delete records via command line</h2>
<p>Once a record has been uploaded, we prefer not to *destroy* it fully
anymore (i.e. to wipe it out and to reuse its record ID for another
record) for a variety of reasons. For example, some users may have
put this record already into their baskets in the meantime, or the
record might have already been announced by alert emails to the
external world, or the OAI harvestors might have harvested it already,
etc. We usually prefer only to *mark* records as deleted, so that our
record IDs are ensured to stay permanent.
<p>Thus said, the canonical way to delete the record #1234 in CDSware
v0.1.x development branch is to download its XML MARC:
<pre>
$ wget -O z.xml 'http://your.site/search.py?recid=1234&of=xm'
</pre>
and to mark it as deleted by adding the indicator ``DELETED'' into the
MARC 980 $$c tag:
<pre>
$ emacs z.xml
[...]
&lt;datafield tag="980" ind1="" ind2=""&gt;
&lt;subfield code="a"&gt;PREPRINT&lt;/subfield&gt;
&lt;subfield code="c"&gt;DELETED&lt;/subfield&gt;
&lt;/datafield&gt;
[...]
</pre>
and upload thusly modified record in the `replace' mode:
<pre>
$ bibupload -r z.xml
</pre>
and watch the progress via <code>bibsched</code>, as mentioned in the
<a href="#3">section 3</a>.
<p>This procedure will remove the record from the collection cache so
that the record won't be findable anymore. In addition, if the users
try to access this record via direct URL such as distributed by the
alert engine (search.py?recid=1234) or via their baskets, they will
see a message ``This record has been deleted''. Please note though
that the original MARCXML of the record stays kept in the database,
for example you can access it by:
<pre>
$ python -c "from zlib import decompress; \\
from cdsware.dbquery import run_sql; \\
print decompress(run_sql('SELECT value FROM bibfmt \\
WHERE id_bibrec=1234 AND format=\'xm\'')[0][0])"
</pre>
<p>In some cases you may want to hide the record from the searches,
but to leave it accessible via direct URLs or via baskets. In this
case the best it to alter its collection tag (980) to some
non-existent collection, for example:
<pre>
$ wget -O z.xml 'http:://localhost/search.py?recid=1234&of=xm'
$ perl -pi -e 's,<subfield code="a">ARTICLE</subfield>,<subfield code="a">HIDDENARTICLE</subfield>,g' z.xml
$ bibupload -r z.xml
</pre>
This will make the record non-existent as far as the search engine is
concerned, because it won't belong to any existing collection, but the
record will exist ``on its own'' and the users knowing its recID will
be able to access it.
<p>P.S. Note that the ``bibXXx'' tables will keep having entries for the
deleted records. These entries are to be cleaned from time to
time by the BibEdit garbage collector. This GC isn't part of
CDSware yet; moreover in the future we plan to abolish all the
bibXXx tables, so that this won't be necessary anymore.
<a name="5"></a><h2>5. Delete all records</h2>
<p>If you want to wipe out all the existing bibliographic content of
your site, for example to start uploading the documents from
scratch again, you can launch:
<pre>
$ /path/to/your/cdsware/bin/dbexec &lt; /path/to/your/cdsware-source/modules/miscutil/sql/tabbibclean.sql
$ /path/to/your/cdsware/bin/webcoll
</pre>
Note that you may also want to truncate some idxWORD11* tables,
in case you have created additional indexes. Look into
<code>tabbibclean.sql</code> to see exactly what it does.
Note that you may also want to delete the fulltext files and the
submission counters in <code>/path/to/your/cdsware/var/data</code>
subdirectories, if you use WebSubmit.
diff --git a/modules/bibedit/doc/admin/index.html.wml b/modules/bibedit/doc/admin/index.html.wml
index d160c6af5..33f92f9e2 100644
--- a/modules/bibedit/doc/admin/index.html.wml
+++ b/modules/bibedit/doc/admin/index.html.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibEdit Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibedit"
<p>
This is the gate to the admin area for BibEdit. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/bibedit/">login</a> to enter.
</p>
<dl>
<dt><a href="bibeditadmin.py">BibEdit Admin Interface</a></dt>
<dd>Start area for BibEdit administration.</dd>
</dl>
<dl>
<dt><a href="guide.html">BibEdit Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running BibEdit.</dd>
</dl>
diff --git a/modules/bibedit/etc/MARC21slim.dtd b/modules/bibedit/etc/MARC21slim.dtd
index 260af14a3..f9d645c7c 100644
--- a/modules/bibedit/etc/MARC21slim.dtd
+++ b/modules/bibedit/etc/MARC21slim.dtd
@@ -1,61 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id$
This MARC21slim.dtd was created from XML MARC Schema of the
Library of Congress that is available at
<http://www.loc.gov/standards/marcxml/>. The `leader' treatment
is not considered here.
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
-->
<!--collection is a top level container element for 0 or many records-->
<!ELEMENT collection (record)*>
<!ATTLIST collection
id ID #IMPLIED
>
<!--record is a top level container element for all of the field elements which compose the record-->
<!ELEMENT record (controlfield*, datafield*)?>
<!ATTLIST record
type NMTOKEN #IMPLIED
id ID #IMPLIED
>
<!--MARC21 Leader, 24 bytes-->
<!ELEMENT leader (#PCDATA)>
<!ATTLIST leader
id ID #IMPLIED
>
<!--MARC21 Fields 001-009-->
<!ELEMENT controlfield (#PCDATA)>
<!ATTLIST controlfield
id ID #IMPLIED
tag CDATA #REQUIRED
>
<!--MARC21 Variable Data Fields 010-999-->
<!ELEMENT datafield (subfield)+>
<!ATTLIST datafield
id ID #IMPLIED
tag CDATA #REQUIRED
ind1 CDATA #REQUIRED
ind2 CDATA #REQUIRED
>
<!ELEMENT subfield (#PCDATA)>
<!ATTLIST subfield
id ID #IMPLIED
code CDATA #REQUIRED
>
diff --git a/modules/bibedit/etc/Makefile.am b/modules/bibedit/etc/Makefile.am
index 58f536483..93eaae442 100644
--- a/modules/bibedit/etc/Makefile.am
+++ b/modules/bibedit/etc/Makefile.am
@@ -1,25 +1,25 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir = $(sysconfdir)/bibedit/
etc_DATA = MARC21slim.dtd refextract-journal-titles.kb refextract-report-numbers.kb
EXTRA_DIST = $(etc_DATA)
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/bibedit/lib/Makefile.am b/modules/bibedit/lib/Makefile.am
index c24c356e7..0d792d4bd 100644
--- a/modules/bibedit/lib/Makefile.am
+++ b/modules/bibedit/lib/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = bibrecord.py bibrecord_config.py bibrecord_tests.py \
refextract.py refextract_config.py \
bibeditadminlib.py bibedit_templates.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibedit/lib/bibedit_templates.py b/modules/bibedit/lib/bibedit_templates.py
index 288fa2968..4479be4e3 100644
--- a/modules/bibedit/lib/bibedit_templates.py
+++ b/modules/bibedit/lib/bibedit_templates.py
@@ -1,22 +1,22 @@
## $Id$
## CDSware WebStyle templates.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.config import *
from cdsware.messages import gettext_set_language, language_list_long
diff --git a/modules/bibedit/lib/bibeditadminlib.py b/modules/bibedit/lib/bibeditadminlib.py
index 18322ea33..70a4107d9 100644
--- a/modules/bibedit/lib/bibeditadminlib.py
+++ b/modules/bibedit/lib/bibeditadminlib.py
@@ -1,24 +1,24 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Implementation of BibEdit Admin interface.
"""
diff --git a/modules/bibedit/lib/bibrecord.py b/modules/bibedit/lib/bibrecord.py
index dec21fb2a..7764c1e3b 100644
--- a/modules/bibedit/lib/bibrecord.py
+++ b/modules/bibedit/lib/bibrecord.py
@@ -1,972 +1,972 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
BibRecord - XML MARC processing library for CDSware
"""
### IMPORT INTERESTING MODULES AND XML PARSERS
## import interesting modules:
try:
import sys
import re
from zlib import decompress
import_error = 0
except ImportError, e:
import_error = 1
imperr = e
## test available parsers:
try:
import sys
import string
err=[]
except ImportError, e:
parser = -3
err1 = e
try:
from cdsware.bibrecord_config import *
verbose = cfg_bibrecord_default_verbose_level
correct = cfg_bibrecord_default_correct
parsers = cfg_bibrecord_parsers_available
except ImportError, e:
parser = -2
verbose = 0
correct = 0
parsers = []
if parsers == []:
print 'No parser available'
sys.exit(2)
else:
j,i=1,1
if 2 in parsers:
try:
import pyRXP
parser = 2
## function to show the pyRXP_parser warnings ##
def warnCB(s):
""" function used to treat the PyRXP parser warnings"""
global err
err.append((0,'Parse warning:\n'+s))
err2 = ""
except ImportError,e :
err2=e
i=0
elif 1 in parsers:
try:
from Ft.Xml.Domlette import NonvalidatingReader
parser = 1
except ImportError,e :
err2=e
j=0
elif 0 in parsers:
try:
from xml.dom.minidom import parseString
parser = 0
except ImportError,e :
err2=e
parser = -1
if not i:
if 1 in parsers:
try:
from Ft.Xml.Domlette import NonvalidatingReader
parser = 1
except ImportError,e :
err2=e
j=0
elif 0 in parsers:
try:
from xml.dom.minidom import parseString
parser = 0
except ImportError,e :
err2=e
parser = -1
else:
parser = -1
if not j:
if 0 in parsers:
try:
from xml.dom.minidom import parseString
parser = 0
except ImportError,e :
err2=e
parser = -1
else:
parser = -1
### INTERFACE / VISIBLE FUNCTIONS
def create_records(xmltext,verbose=verbose,correct=correct):
"""
creates a list of records
"""
global import_error
err = []
if import_error == 1:
err.append((6,imperr))
else:
if sys.version >= '2.3':
pat = r"<record.*?>.*?</record>"
p = re.compile(pat,re.DOTALL) # DOTALL - to ignore whitespaces
list = p.findall(xmltext)
else:
l = xmltext.split('<record>')
n=len(l)
ind = (l[n-1]).rfind('</record>')
aux = l[n-1][:ind+9]
l[n-1] = aux
list=[]
for s in l:
if s != '':
i = -1
while (s[i].isspace()):
i=i-1
if i == -1:#in case there are no spaces at the end
i=len(s)-1
if s[:i+1].endswith('</record>'):
list.append('<record>'+s)
listofrec = map((lambda x:create_record(x,verbose,correct)),list)
return listofrec
return []
# Record :: {tag : [Field]}
# Field :: (Subfields,ind1,ind2,value)
# Subfields :: [(code,value)]
def create_record(xmltext,verbose = verbose, correct=correct):
"""
creates a record object and returns it
uses pyRXP if installed else uses 4Suite domlette or xml.dom.minidom
"""
global parser
(i,errors) = testImports(parser)
if i==0:
print "Error: no suitable XML parsers found. Please read INSTALL file."
sys.exit()
try:
if parser==2:
## the following is because of DTD validation
t = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE collection SYSTEM "file://%s">
<collection>\n""" % cfg_marc21_dtd
t = "%s%s" % (t,xmltext)
t = "%s</collection>" % t
xmltext = t
(rec,er) = create_record_RXP(xmltext,verbose,correct)
elif parser:
(rec,er) = create_record_4suite(xmltext,verbose,correct)
else:
(rec,er) = create_record_minidom(xmltext,verbose,correct)
errs = warnings(er)
except Exception, e:
print e
errs = warnings(concat(err))
return (None,0,errs)
if errs == []:
return (rec,1,errs)
else:
return (rec,0,errs)
def record_get_field_instances(rec, tag="", ind1="", ind2=""):
"""Return the list of field instances of record REC matching TAG and IND1 and IND2.
When TAG is an emtpy string, then return all field instances."""
out = []
if tag:
if record_has_field(rec, tag):
for possible_field_instance in rec[tag]:
if possible_field_instance[1] == ind1 and \
possible_field_instance[2] == ind2:
out.append(possible_field_instance)
else:
return rec.items()
return out
def record_has_field(rec,tag):
"""checks whether record 'rec' contains tag 'tag'"""
return rec.has_key(tag)
def record_add_field(rec,tag,value,ind1="",ind2=""):
"""
adds new field defined by the tag|value|ind1|ind2 parameters to record 'rec'
returns the new field
"""
val=rec.values()
if val != []:
ord = max([f[4] for x in val for f in x])
else:
ord = 1
newfield = create_field(value,ind1,ind2,[],ord)
if rec.has_key(tag):
rec[tag].append(newfield)
else:
rec[tag] = [newfield]
return newfield
def record_delete_field(rec,tag,ind1="",ind2=""):
"""
delete all fields defined with marc tag 'tag' and indicators 'ind1' and 'ind2'
from record 'rec'
"""
newlist = []
if rec.has_key(tag):
for field in rec[tag]:
if not (field[1]==ind1 and field[2]==ind2):
newlist.append(field)
rec[tag] = newlist
def record_get_field_value(rec,tag,ind1="",ind2="",code=""):
"""
retrieves the value of the first field containing tag 'tag' and indicators 'ind1' and 'ind2'
inside record 'rec'. Returns the found value as a string. If no matching field is found
returns the empty string.
if the tag has a '%', it will retrieve the value of first field containg tag, which first characters are those before '%' in tag. The ind1, ind2 and code parameters will be ignored
"""
s = tag.split('%')
if len(s) > 1:
t = s[0]
keys=rec.keys()
tags=[k for k in keys if k.startswith(t)]
for tag in tags:
fields = rec[tag]
for field in fields:
if field[3] != "":
return field[3]
else:
for subfield in field[0]:
return subfield[1]
else:
if rec.has_key(tag):
fields = rec[tag]
for field in fields:
if field[1]==ind1 and field[2]==ind2:
if field[3] != "":
return field[3]
else:
for subfield in field[0]:
if subfield[0]==code:
return subfield[1]
return ""
def record_get_field_values(rec,tag,ind1="",ind2="",code=""):
"""
retrieves the values of all the fields containing tag 'tag' and indicators 'ind1' and 'ind2'
inside record 'rec'. Returns the found values as a list. If no matching field is found
returns an empty list.
if the tag has a '%', it will retrieve the value of all fields containg tag, which first characters are those before '%' in tag. The ind1, ind2 and code parameters will be ignored
"""
tmp = []
s = tag.split('%')
if len(s) > 1:
t = s[0]
keys=rec.keys()
tags=[k for k in keys if k.startswith(t)]
for tag in tags:
fields = rec[tag]
for field in fields:
if field[3] != "":
tmp.append(field[3])
else:
for subfield in field[0]:
tmp.append(subfield[1])
else:
if rec.has_key(tag):
fields = rec[tag]
for field in fields:
if field[1]==ind1 and field[2]==ind2:
if field[3] != "":
tmp.append(field[3])
else:
for subfield in field[0]:
if subfield[0]==code:
tmp.append(subfield[1])
return tmp
def print_rec(rec,format=1):
"""prints a record
format = 1 -- XML
format = 2 -- HTML (not implemented)
"""
if format==1:
text = record_xml_output(rec)
else:
return ''
return text
def print_recs(listofrec,format=1):
"""prints a list of records
format = 1 -- XML
format = 2 -- HTML (not implemented)
if 'listofrec' is not a list it returns empty string
"""
text = ""
if type(listofrec).__name__ !='list':
return ""
else:
for rec in listofrec:
text = "%s\n%s" % (text,print_rec(rec,format))
return text
def record_xml_output(rec):
"""generates the XML for record 'rec' and returns it as a string"""
xmltext = "<record>\n"
if rec:
# add the tag 'tag' to each field in rec[tag]
fields=[]
for tag in rec.keys():
for field in rec[tag]:
fields.append((tag,field))
record_order_fields(fields)
for field in fields:
xmltext = "%s%s" % (xmltext,field_xml_output(field[1],field[0]))#field[0]=tag
xmltext = "%s</record>" % xmltext
return xmltext
def records_xml_output(listofrec):
"""generates the XML for the list of records 'listofrec' and returns it as a string"""
xmltext = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE collection SYSTEM "file://%s">
<collection>\n""" % cfg_marc21_dtd
for rec in listofrec:
xmltext = "%s%s" % (xmltext, record_xml_output(rec))
xmltext = "%s</collection>" % xmltext
return xmltext
def field_get_subfield_instances(field):
"""returns the list of subfields associated with field 'field'"""
return field[0]
def field_get_subfield_values(field_instance, code):
"""Return subfield CODE values of the field instance FIELD."""
out = []
for sf_code, sf_value in field_instance[0]:
if sf_code == code:
out.append(sf_value)
return out
def field_add_subfield(field,code,value):
"""adds a subfield to field 'field'"""
field[0].append(create_subfield(code,value))
### IMPLEMENTATION / INVISIBLE FUNCTIONS
def create_record_RXP(xmltext, verbose=verbose, correct=correct):
"""
creates a record object and returns it
uses the RXP parser
If verbose>3 then the parser will be strict and will stop in case of well-formedness errors
or DTD errors
If verbose=0, the parser will not give warnings
If 0<verbose<=3, the parser will not give errors, but will warn the user about possible mistakes
correct != 0 -> We will try to correct errors such as missing attributtes
correct = 0 -> there will not be any attempt to correct errors
"""
record = {}
global err
ord = 1 # this is needed because of the record_xml_output function, where we need to know
# the order of the fields
TAG, ATTRS,CHILD_LIST = range(3)
if verbose > 3:
p = pyRXP.Parser(ErrorOnValidityErrors=1,
ProcessDTD=1,
ErrorOnUnquotedAttributeValues=1,
warnCB = warnCB,
srcName='string input')
else:
p = pyRXP.Parser(ErrorOnValidityErrors=0,
ProcessDTD=1,
ErrorOnUnquotedAttributeValues=0,
warnCB = warnCB,
srcName='string input')
if correct:
(rec,e) = wash(xmltext)
err.extend(e)
return (rec,e)
root1=p(xmltext) #root = (tagname, attr_dict, child_list, reserved)
if root1[0]=='collection':
recs = [t for t in root1[CHILD_LIST] if type(t).__name__=='tuple' and t[TAG]=="record"]
if recs !=[]:
root = recs[0]
else:
root = None
else:
root=root1
# get childs of 'controlfield'
childs_controlfield = []
if not root[2]==None:
childs_controlfield =[t for t in root[CHILD_LIST] if type(t).__name__=='tuple' and t[TAG]=="controlfield"]
# get childs of 'datafield'
childs_datafield = []
if not root[CHILD_LIST]==None:
childs_datafield =[t for t in root[CHILD_LIST] if type(t).__name__=='tuple' and t[TAG]=="datafield"]
for controlfield in childs_controlfield:
s=controlfield[ATTRS]["tag"]
value=''
if not controlfield==None:
value=''.join([ n for n in controlfield[CHILD_LIST] if type(n).__name__ == 'str'])
name = type(value).__name__
if name in ["int","long"] :
st = str(value)
elif name in ['str', 'unicode']:
st = value
else:
if verbose:
err.append((7,'Type found: ' + name))
st = "" # the type of value is not correct. (user insert something like a list...)
field = ([],"","",st,ord) #field = (subfields, ind1, ind2,value,ord)
if record.has_key(s):
record[s].append(field)
else:
record[s]=[field]
ord = ord+1
for datafield in childs_datafield:
#create list of subfields
subfields = []
childs_subfield = []
if not datafield[CHILD_LIST]==None:
childs_subfield =[t for t in datafield[CHILD_LIST] if type(t).__name__=='tuple' and t[0]=="subfield"]
for subfield in childs_subfield:
value=''
if not subfield==None:
value=''.join([ n for n in subfield[CHILD_LIST] if type(n).__name__ == 'str'])
#get_string_value(subfield)
if subfield[ATTRS].has_key('code'):
subfields.append((subfield[ATTRS]["code"],value))
else:
subfields.append(('!',value))
#create field
if datafield[ATTRS].has_key('tag'):
s = datafield[ATTRS]["tag"]
else:
s = '!'
if datafield[ATTRS].has_key('ind1'):
ind1 = datafield[ATTRS]["ind1"]
else:
ind1 = '!'
if datafield[ATTRS].has_key('ind2'):
ind2 = datafield[ATTRS]["ind2"]
else:
ind2 = '!'
field = (subfields,ind1,ind2,"",ord)
if record.has_key(s):
record[s].append(field)
else:
record[s]=[field]
ord = ord+1
return (record,err)
def create_record_minidom(xmltext, verbose=verbose, correct=correct):
"""
creates a record object and returns it
uses xml.dom.minidom
"""
record = {}
ord=1
global err
if correct:
xmlt = xmltext
(rec,e) = wash(xmlt,0)
err.extend(e)
return (rec,err)
dom = parseString(xmltext)
root = dom.childNodes[0]
for controlfield in get_childs_by_tag_name(root,"controlfield"):
s = controlfield.getAttribute("tag")
text_nodes = controlfield.childNodes
v = u''.join([ n.data for n in text_nodes ]).encode("utf-8")
name = type(v).__name__
if (name in ["int","long"]) :
field = ([],"","",str(v),ord) # field = (subfields, ind1, ind2,value)
elif name in ['str', 'unicode']:
field = ([],"","",v,ord)
else:
if verbose:
err.append((7,'Type found: ' + name))
field = ([],"","","",ord)# the type of value is not correct. (user insert something like a list...)
if record.has_key(s):
record[s].append(field)
else:
record[s]=[field]
ord=ord+1
for datafield in get_childs_by_tag_name(root,"datafield"):
subfields = []
for subfield in get_childs_by_tag_name(datafield,"subfield"):
text_nodes = subfield.childNodes
v = u''.join([ n.data for n in text_nodes ]).encode("utf-8")
code = subfield.getAttributeNS(None,'code').encode("utf-8")
if code != '':
subfields.append((code,v))
else:
subfields.append(('!',v))
s = datafield.getAttribute("tag").encode("utf-8")
if s == '':
s = '!'
ind1 = datafield.getAttribute("ind1").encode("utf-8")
ind2 = datafield.getAttribute("ind2").encode("utf-8")
if record.has_key(s):
record[s].append((subfields,ind1,ind2,"",ord))
else:
record[s]=[(subfields,ind1,ind2,"",ord)]
ord = ord+1
return (record,err)
def create_record_4suite(xmltext,verbose=verbose,correct=correct):
"""
creates a record object and returns it
uses 4Suite domlette
"""
record = {}
global err
if correct:
xmlt = xmltext
(rec,e) = wash(xmlt,1)
err.extend(e)
return (rec,e)
dom = NonvalidatingReader.parseString(xmltext,"urn:dummy")
root = dom.childNodes[0]
ord=1
for controlfield in get_childs_by_tag_name(root,"controlfield"):
s = controlfield.getAttributeNS(None,"tag")
text_nodes = controlfield.childNodes
v = u''.join([ n.data for n in text_nodes ]).encode("utf-8")
name = type(v).__name__
if (name in ["int","long"]) :
field = ([],"","",str(v),ord) # field = (subfields, ind1, ind2,value)
elif name in ['str','unicode']:
field = ([],"","",v,ord)
else:
if verbose:
err.append((7,'Type found: ' + name))
field = ([],"","","",ord)# the type of value is not correct. (user insert something like a list...)
if record.has_key(s):
record[s].append(field)
else:
record[s]=[field]
ord=ord+1
for datafield in get_childs_by_tag_name(root,"datafield"):
subfields = []
for subfield in get_childs_by_tag_name(datafield,"subfield"):
text_nodes = subfield.childNodes
v = u''.join([ n.data for n in text_nodes ]).encode("utf-8")
code = subfield.getAttributeNS(None,'code').encode("utf-8")
if code != '':
subfields.append((code,v))
else:
subfields.append(('!',v))
s = datafield.getAttributeNS(None,"tag").encode("utf-8")
if s == '':
s = '!'
ind1 = datafield.getAttributeNS(None,"ind1").encode("utf-8")
ind2 = datafield.getAttributeNS(None,"ind2").encode("utf-8")
if record.has_key(s):
record[s].append((subfields,ind1,ind2,"",ord))
else:
record[s]=[(subfields,ind1,ind2,"",ord)]
ord=ord+1
return (record,err)
def record_order_fields(rec,fun="order_by_ord"):
"""orders field inside record 'rec' according to a function"""
rec.sort(eval(fun))
return
def record_order_subfields(rec,fun="order_by_code"):
"""orders subfield inside record 'rec' according to a function"""
for tag in rec:
for field in rec[tag]:
field[0].sort(eval(fun))
return
def concat(list):
"""concats a list of lists"""
newl = []
for l in list:
newl.extend(l)
return newl
def create_field(value,ind1="",ind2="",subfields=[],ord=-1):
""" creates a field object and returns it"""
name = type(value).__name__
if name in ["int","long"] :
s = str(value)
elif name in ['str', 'unicode']:
s = value
else:
err.append((7,'Type found: ' + name))
s=""
field = (subfields,ind1,ind2,s,ord)
return field
def field_add_subfield(field,code,value):
"""adds a subfield to field 'field'"""
field[0].append(create_subfield(code,value))
def field_xml_output(field,tag):
"""generates the XML for field 'field' and returns it as a string"""
xmltext = ""
if field[3] != "":
xmltext = "%s <controlfield tag=\"%s\">%s</controlfield>\n" % (xmltext,tag,encode_for_xml(field[3]))
else:
xmltext = "%s <datafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">\n" % (xmltext,tag,field[1],field[2])
for subfield in field[0]:
xmltext = "%s%s" % (xmltext,subfield_xml_output(subfield))
xmltext = "%s </datafield>\n" % xmltext
return xmltext
def create_subfield(code,value):
""" creates a subfield object and returns it"""
if type(value).__name__ in ["int","long"]:
s = str(value)
else:
s = value
subfield = (code, s)
return subfield
def subfield_xml_output(subfield):
"""generates the XML for a subfield object and return it as a string"""
xmltext = " <subfield code=\"%s\">%s</subfield>\n" % (subfield[0],encode_for_xml(subfield[1]))
return xmltext
def order_by_ord(field1, field2):
"""function used to order the fields according to their ord value"""
return cmp(field1[1][4], field2[1][4])
def order_by_code(subfield1,subfield2):
"""function used to order the subfields according to their code value"""
return cmp(subfield1[0],subfield2[0])
def get_childs_by_tag_name(node, local):
"""retrieves all childs from node 'node' with name 'local' and returns them as a list"""
cNodes = list(node.childNodes)
res = [child for child in cNodes if child.nodeName==local]
return res
def get_string_value(node):
"""gets all child text nodes of node 'node' and returns them as a unicode string"""
text_nodes = node.childNodes
return u''.join([ n.data for n in text_nodes ])
def get_childs_by_tag_name_RXP(listofchilds,tag):
"""retrieves all childs from 'listofchilds' with tag name 'tag' and returns them as a list.
listofchilds is a list returned by the RXP parser
"""
l=[]
if not listofchilds==None:
l =[t for t in listofchilds if type(t).__name__=='tuple' and t[0]==tag]
return l
def getAttribute_RXP(root, attr):
""" returns the attributte 'attr' from root 'root'
root is a node returned by RXP parser
"""
try:
return u''.join(root[1][attr])
except KeyError,e:
return ""
def get_string_value_RXP(node):
"""gets all child text nodes of node 'node' and returns them as a unicode string"""
if not node==None:
return ''.join([ n for n in node[2] if type(n).__name__ == 'str'])
else:
return ""
def encode_for_xml(s):
"Encode special chars in string so that it would be XML-compliant."
s = string.replace(s, '&', '&amp;')
s = string.replace(s, '<', '&lt;')
return s
def print_errors(list):
""" creates a unique string with the strings in list, using '\n' as a separator """
text=""
for l in list:
text = '%s\n%s'% (text,l)
return text
def wash(xmltext, parser=2):
"""
Check the structure of the xmltext. Returns a record structure and a list of errors.
parser = 1 - 4_suite
parser = 2 - pyRXP
parser = 0 - minidom
"""
errors=[]
i,e1 = tagclose('datafield',xmltext)
j,e2 = tagclose('controlfield',xmltext)
k,e3 = tagclose('subfield',xmltext)
w,e4 = tagclose('record',xmltext)
errors.extend(e1)
errors.extend(e2)
errors.extend(e3)
errors.extend(e4)
if i and j and k and w and parser!=-3:
if parser==1:
(rec,ee) = create_record_4suite(xmltext,0,0)
elif parser==2:
(rec,ee) = create_record_RXP(xmltext,0,0)
else:
(rec,ee) = create_record_minidom(xmltext,0,0)
else:
return (None,errors)
keys = rec.keys()
for tag in keys:
upper_bound = '999'
n = len(tag)
if n>3:
i=n-3
while i>0:
upper_bound = '%s%s' % ('0',upper_bound)
i = i-1
if tag == '!': # missing tag
errors.append((1, '(field number(s): ' + ([f[4] for f in rec[tag]]).__str__()+')'))
v=rec[tag]
rec.__delitem__(tag)
rec['000'] = v
tag = '000'
elif not ("001" <= tag <=upper_bound):
errors.append(2)
v = rec[tag]
rec.__delitem__(tag)
rec['000'] = v
tag = '000'
fields =[]
for field in rec[tag]:
if field[0]==[] and field[3]=='': ## datafield without any subfield
errors.append((8,'(field number: '+field[4].__str__()+')'))
subfields=[]
for subfield in field[0]:
if subfield[0]=='!':
errors.append((3,'(field number: '+field[4].__str__()+')'))
newsub = ('',subfield[1])
else:
newsub = subfield
subfields.append(newsub)
if field[1]=='!':
errors.append((4,'(field number: '+field[4].__str__()+')'))
ind1 = ""
else:
ind1 = field[1]
if field[2]=='!':
errors.append((5,'(field number: '+field[4].__str__()+')'))
ind2 = ""
else:
ind2=field[2]
newf = (subfields,ind1,ind2,field[3],field[4])
fields.append(newf)
rec[tag]=fields
return (rec,errors)
def tagclose(tagname,xmltext):
""" checks if an XML document does not hae any missing tag with name tagname
"""
import re
errors=[]
pat_open = '<'+tagname+'.*?>'
pat_close = '</'+tagname+'>'
p_open = re.compile(pat_open,re.DOTALL) # DOTALL - to ignore whitespaces
p_close = re.compile(pat_close,re.DOTALL)
list1 = p_open.findall(xmltext)
list2 = p_close.findall(xmltext)
if len(list1)!=len(list2):
errors.append((99,'(Tagname : ' + tagname + ')'))
return (0,errors)
else:
return (1,errors)
def testImports(c):
""" Test if the import statements did not failed"""
errors=[]
global err1,err2
if c==-1:
i = 0
errors.append((6,err2))
elif c == -3:
i=0
errors.append((6,err1))
else:
i=1
return (i,errors)
def warning(code):
""" It returns a warning message of code 'code'.
If code = (cd, str) it returns the warning message of code 'cd'
and appends str at the end"""
ws = cfg_bibrecord_warning_msgs
s=''
if type(code).__name__ == 'str':
return code
if type(code).__name__ == 'tuple':
if type(code[1]).__name__ == 'str':
s = code[1]
c = code[0]
else:
c = code
if ws.has_key(c):
return ws[c]+s
else:
return ""
def warnings(l):
"""it applies the function warning to every element in l"""
list = []
for w in l:
list.append(warning(w))
return list
diff --git a/modules/bibedit/lib/bibrecord_config.py b/modules/bibedit/lib/bibrecord_config.py
index 3fc31cceb..e8a8ae10d 100644
--- a/modules/bibedit/lib/bibrecord_config.py
+++ b/modules/bibedit/lib/bibrecord_config.py
@@ -1,51 +1,51 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
### CONFIGURATION OPTIONS FOR BIBRECORD LIBRARY
"""bibrecord configuration"""
from cdsware.config import etcdir
# location of the MARC21 DTD file:
cfg_marc21_dtd = "%s/bibedit/MARC21slim.dtd" % etcdir
# internal dictionary of warning messages:
cfg_bibrecord_warning_msgs = {
0: '' ,
1: 'WARNING: tag missing for field(s)\nValue stored with tag \'000\'',
2: 'WARNING: bad range for tags (tag must be in range 001-999)\nValue stored with tag \'000\'',
3: 'WARNING: Missing atributte \'code\' for subfield\nValue stored with code \'\'',
4: 'WARNING: Missing attributte \'ind1\'\n Value stored with ind1 = \'\'',
5: 'WARNING: Missing attributte \'ind2\'\n Value stored with ind2 = \'\'',
6: 'Import Error\n',
7: 'WARNING: value expected of type string.',
8: 'WARNING: empty datafield',
98:'WARNING: problems importing cdsware',
99: 'Document not well formed'
}
# verbose level to be used when creating records from XML: (0=least, ..., 9=most)
cfg_bibrecord_default_verbose_level=0
# correction level to be used when creating records from XML: (0=no, 1=yes)
cfg_bibrecord_default_correct=0
# XML parsers available: (0=minidom, 1=4suite, 2=PyRXP)
cfg_bibrecord_parsers_available = [0,1,2]
diff --git a/modules/bibedit/lib/bibrecord_tests.py b/modules/bibedit/lib/bibrecord_tests.py
index 9961e7097..69d49f1e5 100644
--- a/modules/bibedit/lib/bibrecord_tests.py
+++ b/modules/bibedit/lib/bibrecord_tests.py
@@ -1,282 +1,282 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import unittest
from string import expandtabs, replace
from cdsware.config import tmpdir, etcdir
from cdsware import bibrecord
class SanityTest(unittest.TestCase):
""" bibrecord - sanity test (xml -> create records -> xml)"""
def test_for_sanity(self):
""" bibrecord - demo file sanity test (xml -> create records -> xml)"""
f=open(tmpdir + '/demobibdata.xml','r')
xmltext = f.read()
f.close()
# let's try to reproduce the demo XML MARC file by parsing it and printing it back:
recs = map((lambda x:x[0]), bibrecord.create_records(xmltext))
xmltext_reproduced = bibrecord.records_xml_output(recs)
x = xmltext_reproduced
y = xmltext
# 'normalize' the two XML MARC files for the purpose of comparing
x = expandtabs(x)
y = expandtabs(y)
x = x.replace(' ','')
y = y.replace(' ','')
x = x.replace('<!DOCTYPEcollectionSYSTEM"file://%s/bibedit/MARC21slim.dtd">\n<collection>' % etcdir,
'<collectionxmlns="http://www.loc.gov/MARC21/slim">')
x = x.replace('</record><record>', "</record>\n<record>")
x = x.replace('</record></collection>', "</record>\n</collection>\n")
self.assertEqual(x,y)
class SuccessTest(unittest.TestCase):
""" bibrecord - demo file parsing test """
def setUp(self):
f=open(tmpdir + '/demobibdata.xml','r')
xmltext = f.read()
f.close()
self.recs = map((lambda x:x[0]),bibrecord.create_records(xmltext))
def test_records_created(self):
""" bibrecord - demo file how many records are created """
self.assertEqual(76,len(self.recs))
def test_tags_created(self):
""" bibrecord - demo file which tags are created """
## check if the tags are correct
tags= ['020', '037', '041', '080', '088', '100', '245', '246', '250', '260', '270', '300', '340', '490', '500', '502', '520', '590', '595', '650', '653', '690', '700', '710', '856','909','980','999']
t=[]
for rec in self.recs:
t.extend(rec.keys())
t.sort()
#eliminate the elements repeated
tt = []
for x in t:
if not x in tt:
tt.append(x)
self.assertEqual(tags,tt)
def test_fields_created(self):
"""bibrecord - demo file how many fields are created"""
## check if the number of fields for each record is correct
fields=[13,13, 8, 11, 10,12, 10, 14, 10, 17, 13, 15, 10, 9, 14, 10, 11, 11, 11, 9, 10, 10, 10, 8, 8, 8, 9, 9, 9, 10, 8, 8, 8,8, 14, 13, 14, 14, 15, 12,12, 12,14, 13, 11, 15, 15, 14, 14, 13, 15, 14, 14, 14, 15, 14, 15, 14, 14, 15, 14, 13, 13, 14, 11, 13, 11, 14, 8, 10, 13, 12, 11, 12, 6, 6]
cr=[]
ret=[]
for rec in self.recs:
cr.append(len(rec.values()))
ret.append(rec)
self.assertEqual(fields,cr)
class BadInputTreatmentTest(unittest.TestCase):
""" bibrecord - testing for bad input treatment """
def test_wrong_attribute(self):
"""bibrecord - bad input subfield \'cde\' instead of \'code\'"""
ws = bibrecord.cfg_bibrecord_warning_msgs
xml_error1 = """
<record>
<controlfield tag="001">33</controlfield>
<datafield tag="041" ind1="" ind2="">
<subfield code="a">eng</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe, John</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="">
<subfield cde="a">On the foo and bar</subfield>
</datafield>
</record>
"""
(rec,st,e) = bibrecord.create_record(xml_error1,1,1)
ee=''
for i in e:
if type(i).__name__ == 'str':
if i.count(ws[3])>0:
ee = i
self.assertEqual(bibrecord.warning((3,'(field number: 4)')),ee)
def test_missing_attribute(self):
""" bibrecord - bad input missing \"tag\" """
ws = bibrecord.cfg_bibrecord_warning_msgs
xml_error2 = """
<record>
<controlfield tag="001">33</controlfield>
<datafield ind1="" ind2="">
<subfield code="a">eng</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe, John</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="">
<subfield code="a">On the foo and bar</subfield>
</datafield>
</record>
"""
(rec,st,e) = bibrecord.create_record(xml_error2,1,1)
ee=''
for i in e:
if type(i).__name__ == 'str':
if i.count(ws[1])>0:
ee = i
self.assertEqual(bibrecord.warning((1,'(field number(s): [2])')),ee)
def test_empty_datafield(self):
""" bibrecord - bad input no subfield """
ws = bibrecord.cfg_bibrecord_warning_msgs
xml_error3 = """
<record>
<controlfield tag="001">33</controlfield>
<datafield tag="041" ind1="" ind2="">
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe, John</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="">
<subfield code="a">On the foo and bar</subfield>
</datafield>
</record>
"""
(rec,st,e) = bibrecord.create_record(xml_error3,1,1)
ee=''
for i in e:
if type(i).__name__ == 'str':
if i.count(ws[8])>0:
ee = i
self.assertEqual(bibrecord.warning((8,'(field number: 2)')),ee)
def test_missing_tag(self):
"""bibrecord - bad input missing end \"tag\""""
ws = bibrecord.cfg_bibrecord_warning_msgs
xml_error4 = """
<record>
<controlfield tag="001">33</controlfield>
<datafield tag="041" ind1="" ind2="">
<subfield code="a">eng</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe, John</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="">
<subfield code="a">On the foo and bar</subfield>
</record>
"""
(rec,st,e) = bibrecord.create_record(xml_error4,1,1)
ee = ''
for i in e:
if type(i).__name__ == 'str':
if i.count(ws[99])>0:
ee = i
self.assertEqual(bibrecord.warning((99,'(Tagname : datafield)')),ee)
class AccentedUnicodeLettersTest(unittest.TestCase):
""" bibrecord - testing accented UTF-8 letters """
def setUp(self):
xml_example_record = """
<record>
<controlfield tag="001">33</controlfield>
<datafield tag="041" ind1="" ind2="">
<subfield code="a">eng</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Döè1, John</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe2, J>ohn</subfield>
<subfield code="b">editor</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="1">
<subfield code="a">Пушкин</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="2">
<subfield code="a">On the foo and bar2</subfield>
</datafield>
</record>
"""
(self.rec, st, e) = bibrecord.create_record(xml_example_record,1,1)
def test_accented_unicode_characters(self):
"""bibrecord - accented Unicode letters"""
self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", "", ""),
[([('a', 'Döè1, John')], '', '', '', 3), ([('a', 'Doe2, J>ohn'), ('b', 'editor')], '', '', '', 4)])
self.assertEqual(bibrecord.record_get_field_instances(self.rec, "245", "", "1"),
[([('a', 'Пушкин')], '', '1', '', 5)])
class GettingFieldValuesTest(unittest.TestCase):
""" bibrecord - testing for getting field/subfield values """
def setUp(self):
xml_example_record = """
<record>
<controlfield tag="001">33</controlfield>
<datafield tag="041" ind1="" ind2="">
<subfield code="a">eng</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe1, John</subfield>
</datafield>
<datafield tag="100" ind1="" ind2="">
<subfield code="a">Doe2, John</subfield>
<subfield code="b">editor</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="1">
<subfield code="a">On the foo and bar1</subfield>
</datafield>
<datafield tag="245" ind1="" ind2="2">
<subfield code="a">On the foo and bar2</subfield>
</datafield>
</record>
"""
(self.rec, st, e) = bibrecord.create_record(xml_example_record,1,1)
def test_get_field_instances(self):
"""bibrecord - getting field instances"""
self.assertEqual(bibrecord.record_get_field_instances(self.rec, "100", "", ""),
[([('a', 'Doe1, John')], '', '', '', 3), ([('a', 'Doe2, John'), ('b', 'editor')], '', '', '', 4)])
self.assertEqual(bibrecord.record_get_field_instances(self.rec, "", "", ""),
[('245', [([('a', 'On the foo and bar1')], '', '1', '', 5), ([('a', 'On the foo and bar2')], '', '2', '', 6)]), ('001', [([], '', '', '33', 1)]), ('100', [([('a', 'Doe1, John')], '', '', '', 3), ([('a', 'Doe2, John'), ('b', 'editor')], '', '', '', 4)]), ('041', [([('a', 'eng')], '', '', '', 2)])])
def test_get_field_values(self):
"""bibrecord - getting field values"""
self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "", "", "a"),
['Doe1, John', 'Doe2, John'])
self.assertEqual(bibrecord.record_get_field_values(self.rec, "100", "", "", "b"),
['editor'])
def test_get_subfield_values(self):
"""bibrecord - getting subfield values"""
fi1, fi2 = bibrecord.record_get_field_instances(self.rec, "100", "", "")
self.assertEqual(bibrecord.field_get_subfield_values(fi1, "b"), [])
self.assertEqual(bibrecord.field_get_subfield_values(fi2, "b"), ["editor"])
def create_test_suite():
"""Return test suite for the bibrecord module"""
return unittest.TestSuite((unittest.makeSuite(SanityTest,'test'),
unittest.makeSuite(SuccessTest,'test'),
unittest.makeSuite(BadInputTreatmentTest,'test'),
unittest.makeSuite(GettingFieldValuesTest,'test'),
unittest.makeSuite(AccentedUnicodeLettersTest,'test')))
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibedit/lib/refextract.py b/modules/bibedit/lib/refextract.py
index af062f5e6..fbe702ed4 100644
--- a/modules/bibedit/lib/refextract.py
+++ b/modules/bibedit/lib/refextract.py
@@ -1,3002 +1,3002 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
try:
import sys, re, string, time
import os, getopt, cgi
from cStringIO import StringIO
from cdsware.refextract_config import *
except ImportError, e:
raise ImportError(e)
class StringBuffer1:
"""This class is a String buffer, used for concatenation of strings.
This version uses a memory file as a string buffer
"""
def __init__(self):
self._bufferFile = StringIO()
def append(self, itm):
"""Add a string to the string buffer"""
self._bufferFile.write("%s"%(itm,))
def get(self):
"""Get buffered string and return it as string object"""
return self._bufferFile.getvalue()
class StringBuffer2:
"""This class is a String buffer, used for concatenation of strings.
This version uses a list as a string buffer
"""
def __init__(self):
self._buffer = []
def append(self, itm):
"""Add a new string into the buffer"""
self._buffer.append(itm)
def get(self):
"""Join all strings in th buffer into a single string and return it"""
return ''.join(self._buffer)
class SystemMessage:
def __init__(self):
self._helpMessage = """refextract recid:pdffile [recid:pdffile]"""
self._versionMessage = cfg_refextract_version
def getHelpMessage(self):
return self._helpMessage
def getVersionMessage(self):
return self._versionMessage
class ReferenceSection:
"""Concrete class representing the Reference section of a document. Once References have been extracted, they are put into a
ReferenceSection object, which contains a list of "ReferenceLine" objects
"""
class ReferenceSectionIterator:
def __init__(self, reflines):
self._mylist = reflines
self._listptr = 0
def next(self):
try:
item = self._mylist[self._listptr]
self._listptr += 1
return item
except IndexError:
raise StopIteration
def __init__(self, refLineStrings = []):
"""Initialise a ReferenceSection object with the lines composing the references of a document. If a string argument
is supplied, it will be appended as the first reference line. If a list argument is supplied, each element of the list
that contains a string will be appended to the list of reference lines in order. Arguments of neither String or
list type will be ignored and an empty ReferenceSection object will be the result
"""
self._referenceLines = []
self._lnPtr = 0
if type(refLineStrings) is list:
for line in refLineStrings:
self.addNewLine(line)
else:
if not self.addNewLine(refLineStrings):
self._referenceLines = []
self.resetLinePointer()
def __iter__(self):
"""return self as iterator object"""
return ReferenceSection.ReferenceSectionIterator(self._referenceLines)
def resetLinePointer(self):
"""Reset the position of the ReferenceLine pointer of a ReferenceSection object to point at the first line"""
self._lnPtr = 0
def gotoNextLine(self):
"""Move the position of the ReferenceLine pointer of a ReferenceSection object to point at the next line"""
if self.lineExists(self._lnPtr+1):
self._lnPtr = self._lnPtr+1
return True
else:
return False
def gotoLine(self, lNum):
"""Move the position of the ReferenceLine pointer of a ReferenceSection object to point at the line number supplied"""
if self.lineExists(lNum-1):
self._lnPtr = lNum-1
return True
else:
return False
def getCurrentLineAsString(self):
"""Return a String containing the text contents of the ReferenceLine object currently pointed to by the internal
pointer of a ReferenceSection object. Returns empty string if no ReferenceLine is currently pointed at
"""
if self.lineExists(self._lnPtr):
return self._referenceLines[self._lnPtr].getContent()
else:
self.resetLinePointer()
return u''
def getCurrentLine(self):
"""Return the ReferenceLine object that is currently pointed to by the internal pointer of a ReferenceSection object. If no
object pointed at, return the 'None' object
"""
if self.lineExists(self._lnPtr):
return self._referenceLines[self._lnPtr]
else:
self.resetLinePointer()
return None
def getLineAsString(self, lNum):
"""Return a String containing the text contents of the ReferenceLine object at the line number supplied (1..n).
Returns ain empty String if line number does not exist
"""
if self.lineExists(lNum-1): return self._referenceLines[lNum-1].getContent()
else: return u""
def getLine(self, lNum):
"""Return the ReferenceLine at the line number supplied (1..n) Returns 'None' object if line number does not exist"""
if self.lineExists(lNum-1): return self._referenceLines[lNum-1]
else: return None
def displayAllLines(self):
"""Display all ReferenceLine objects stored within a ReferenceSection object consecutively as Strings on the standard output stream"""
for x in self._referenceLines: x.display()
def displayCurrentLine(self):
"""Display the ReferenceLine that is currently pointed to by a ReferenceSection object"""
if self.lineExists(self._lnPtr): self._referenceLines[self._lnPtr].display()
else: self.resetLinePointer()
def displayLine(self, lNum):
"""Display the reference line at the line number supplied (1..n). Will display nothing if the line number does not exist"""
if self.lineExists(lNum-1): self._referenceLines[lNum-1].display()
def lineExists(self, lNum):
"""Returns True if line lNum exists in a ReferenceSection, False if not. (Reminder: Lines in the range 0..N)"""
if (lNum < len(self._referenceLines)) and (lNum >= 0): return True
else: return False
def addNewLine(self, lineTxt):
"""Takes one String argument (lineTxt) and attempts to create a new ReferenceLine with this text, adding it to the last
place in the referenceLines list of a ReferenceSection object. Returns True if successful, False if not
"""
if type(lineTxt) is str or type(lineTxt) is unicode:
ln = ReferenceLine(lineTxt)
self._referenceLines.append(ln)
return True
else:
return False
def setContentLine(self, newContent):
"""Set the contents of the current line to that supplied in the 'newContent' argument. Return True on success, False on failure"""
if self.lineExists(self._lnPtr): return self._referenceLines[self._lnPtr].setContent(newContent)
else: return False
def lAppendLineText(self, appendStr):
"""Append text to the beginning of the ReferenceLine object currently pointed at by a ReferenceSection object"""
if self.lineExists(self._lnPtr): return self._referenceLines[self._lnPtr].lAppend(appendStr)
else: return False
def rAppendLineText(self, appendStr):
"""Append text to the end of the ReferenceLine object currently pointed at by a ReferenceSection object"""
if self.lineExists(self._lnPtr): return self._referenceLines[self._lnPtr].rAppend(appendStr)
else: return False
def isEmpty(self):
"""Return True if the reference section contains no reference lines, False if it does contain lines"""
return (len(self._referenceLines) < 1)
class ReferenceLine:
"""Concrete class representing an individual reference line as extracted from a document"""
def __init__(self, data=''):
"""Initialise a ReferenceLine's contents with the supplied String. If argument supplied is not a String, the ReferenceLine
object's contents will be initialised with a blank String
"""
if type(data) is str or type(data) is unicode: self._content = data
else: self._content = u''
def getContent(self):
"""Return a String version of a ReferenceLine's contents"""
return self._content
def display(self):
"""Display a ReferenceLine as a String on the standard output stream"""
print self._content.encode("utf-8")
def setContent(self, newContent=u''):
"""Set the content of a ReferenceLine to a new text String. Returns True if successful, False if not"""
if type(newContent) is str or type(newContent) is unicode:
self._content = newContent
return True
else:
return False
def rAppend(self, appendStr):
"""Append a text String to the end of a ReferenceLine object's textual content. Returns True if append successful, False if not"""
if type(appendStr) is str or type(appendStr) is unicode:
self._content=self._content + appendStr
return True
else:
return False
def lAppend(self, appendStr):
"""Append a text String to the beginning of a ReferenceLine objects textual content. Returns True if append successful False if not"""
if type(appendStr) is str or type(appendStr) is unicode:
self._content = appendStr+self._content
return True
else:
return False
class ReferenceSectionDisplayer:
def display(self, refsect, recid=None, myostream=sys.stdout):
if isinstance(refsect, ReferenceSection):
myostream.write("%s" % (self._rawReferebcesToString(refsect,recid).encode("utf-8"),))
myostream.flush()
elif isinstance(refsect, ProcessedReferenceSection):
myostream.write("%s" % (self._processedReferebcesToMARCXMLString(refsect,recid).encode("utf-8"),))
myostream.flush()
def _rawReferebcesToString(self,refsect,recid=None):
refstr = u""
if not refsect.isEmpty():
# Section Header
refstr += u"#################### START REFERENCE SECTION "
if recid is not None:
refstr += u"SYSID: '%s' " % (recid,)
refstr += u"####################\n"
for x in refsect:
refstr += x.getContent()+u"\n"
# Section Footer
refstr += u"#################### END REFERENCE SECTION ####################\n"
return refstr
def _processedReferebcesToMARCXMLString(self,refsect,recid=None):
refsectmainbody = refsect.getSelfMARCXML()
if len(refsectmainbody.strip()) > 0:
out = u""" <record>\n"""
if recid is not None and (type(recid) is unicode or type(recid) is str):
out += u""" <controlfield tag="001">"""+cgi.escape(recid)+u"""</controlfield>\n"""
out += refsectmainbody
out += u""" </record>\n"""
else:
out = u""
return out
class RegexWordSpacer:
"""Concrete Class. Adds optional regex space matchers and quantifiers (\s*?) between the characters of a word. Useful because sometimes
the document conversion process breaks up words with spaces
"""
def space(self, word):
"""Add the space chars to a word & return the regex pattern (not compiled)"""
newWord = None
if type(word) is str or type(word) is unicode:
newWord = u''
p_spc = re.compile(unicode(r'\s'),re.UNICODE)
for x in word:
m_spc = p_spc.match(x)
if m_spc is None:
newWord = newWord+x+unicode(r'\s*?')
else:
newWord = newWord+x
return newWord
class DocumentSearchPatternListCompiler:
"""Abstract class. Used to get a 'DocumentSearchCompiledPatternList' object, which is used for searching lines of a document for a
given pattern
"""
def getCompiledPatternList(self, prefix = u'', suffix = u''):
"""Return a list of compiled regex patterns"""
pass
def createPatterns(self, prefix = u'', suffix = u''):
"""Create the regex patterns (don't compile though)"""
pass
class RefSecnTitleListCompiler(DocumentSearchPatternListCompiler):
"""Concrete class. Used to return a 'DocumentSearchCompiledPatternList' object containing regex patterns enabling the identification of
possible reference section titles in a text line
"""
def getCompiledPatternList(self, prefix = u'', suffix = u''):
"""Return a list of compiled regex patterns used to ID reference section title"""
patterns = self.createPatterns()
return CompiledPatternList(patterns)
def createPatterns(self, prefix = u'', suffix = u''):
"""Create the regex patterns (don't compile though)"""
patternList = []
titles = self.getTitles()
sectMarker = unicode(r'^\s*?([\[\-\{\(])?\s*?((\w|\d){1,5}([\.\-\,](\w|\d){1,5})?\s*?[\.\-\}\)\]]\s*?)?(?P<title>')
lineEnd = unicode(r'(\s+?s\s*?e\s*?c\s*?t\s*?i\s*?o\s*?n\s*?)?)')
lineEnd = lineEnd+unicode(r'($|\s*?[\[\{\(\<]\s*?[1a-z]\s*?[\}\)\>\]]|\:)')
s = RegexWordSpacer()
for x in titles:
if (type(x) is str or type(x) is unicode) and len(x) > 1:
s = RegexWordSpacer()
namePtn = sectMarker+s.space(x)+lineEnd
patternList.append(namePtn)
elif (type(x) is str or type(x) is unicode) and len(x) > 0:
namePtn = sectMarker+s.space(x)+lineEnd
patternList.append(namePtn)
return patternList
def getTitles(self):
"""Get and return a list of the titles to be searched for"""
titles = []
titles.append(u'references')
titles.append(u'r\u00C9f\u00E9rences')
titles.append(u'r\u00C9f\u00C9rences')
titles.append(u'reference')
titles.append(u'refs')
titles.append(u'r\u00E9f\u00E9rence')
titles.append(u'r\u00C9f\u00C9rence')
titles.append(u'r\xb4ef\xb4erences')
titles.append(u'r\u00E9fs')
titles.append(u'r\u00C9fs')
titles.append(u'bibliography')
titles.append(u'bibliographie')
titles.append(u'citations')
return titles
class PostRefSecnTitleListCompiler(DocumentSearchPatternListCompiler):
"""Concrete class. Used to return a 'DocumentSearchCompiledPatternList' object containing regex patterns enabling the identification of
possible titles that usually follow the reference section in a doc
"""
def getCompiledPatternList(self, prefix = '', suffix = ''):
"""Return a list of compiled regex patterns used to ID post reference section title"""
patterns = self.createPatterns()
return CompiledPatternList(patterns)
def createPatterns(self, prefix = '', suffix = ''):
"""Create the regex patterns (don't compile though)"""
patterns = []
thead = unicode(r'^\s*?([\{\(\<\[]?\s*?(\w|\d)\s*?[\)\}\>\.\-\]]?\s*?)?')
ttail = unicode(r'(\s*?\:\s*?)?')
numatn = unicode(r'(\d+|\w\b|i{1,3}v?|vi{0,3})[\.\,]?\b')
s = RegexWordSpacer()
# Section titles:
patterns.append(thead+s.space(u'appendix')+ttail)
patterns.append(thead+s.space(u'appendices')+ttail)
patterns.append(thead+s.space(u'acknowledgement')+unicode(r's?')+ttail)
patterns.append(thead+s.space(u'table')+unicode(r'\w?s?\d?')+ttail)
patterns.append(thead+s.space(u'figure')+unicode(r's?')+ttail)
patterns.append(thead+s.space(u'annex')+unicode(r's?')+ttail)
patterns.append(thead+s.space(u'discussion')+unicode(r's?')+ttail)
patterns.append(thead+s.space(u'remercie')+unicode(r's?')+ttail)
# Figure nums:
patterns.append(r'^\s*?'+s.space(u'figure')+numatn)
patterns.append(r'^\s*?'+s.space(u'fig')+unicode(r'\.\s*?')+numatn)
patterns.append(r'^\s*?'+s.space(u'fig')+unicode(r'\.?\s*?\d\w?\b'))
# Table nums:
patterns.append(r'^\s*?'+s.space(u'table')+numatn)
patterns.append(r'^\s*?'+s.space(u'tab')+unicode(r'\.\s*?')+numatn)
patterns.append(r'^\s*?'+s.space(u'tab')+unicode(r'\.?\s*?\d\w?\b'))
return patterns
class PostRefSecnKWListCompiler(DocumentSearchPatternListCompiler):
"""Concrete class. Used to return a 'DocumentSearchCompiledPatternList' object containing regex patterns enabling the identification of
Key Words/phrases that are often found in lines following the reference section of a document
"""
def getCompiledPatternList(self, prefix = u'', suffix = u''):
"""Return a list of compiled regex patterns used to ID keywords usually found in lines after a reference section"""
patterns = self.createPatterns()
return CompiledPatternList(patterns)
def createPatterns(self, prefix = u'', suffix = u''):
"""Create the regex patterns (don't compile though)"""
patterns = []
s = RegexWordSpacer()
patterns.append(unicode(r'(')+s.space(u'prepared')+unicode(r'|')+s.space(u'created')+unicode(r').*?(AAS\s*?)?\sLATEX'))
patterns.append(unicode(r'AAS\s+?LATEX\s+?')+s.space(u'macros')+u'v')
patterns.append(unicode(r'^\s*?')+s.space(u'This paper has been produced using'))
patterns.append(unicode(r'^\s*?')+s.space(u'This article was processed by the author using Springer-Verlag')+u' LATEX')
return patterns
class FirstRefLineNumerationListCompiler(DocumentSearchPatternListCompiler):
"""Concrete class. Used to return a 'DocumentSearchCompiledPatternList' object containing regex patterns enabling the identification of
the first reference line by its numeration marker
"""
def getCompiledPatternList(self, prefix = u'', suffix = u''):
"""Return a list of compiled regex patterns used to ID the first reference line by its numeration marker"""
patterns = self.createPatterns()
return CompiledPatternList(patterns)
def createPatterns(self, prefix = u'', suffix = u''):
"""Create the regex patterns (don't compile though)"""
patterns = []
g_name = unicode(r'(?P<mark>')
g_close = u')'
patterns.append(g_name+unicode(r'(?P<left>\[)\s*?(?P<num>\d+)\s*?(?P<right>\])')+g_close)
patterns.append(g_name+unicode(r'(?P<left>\{)\s*?(?P<num>\d+)\s*?(?P<right>\})')+g_close)
return patterns
class RefLineNumerationListCompiler(DocumentSearchPatternListCompiler):
"""Concrete class. Used to return a 'DocumentSearchCompiledPatternList' object containing regex patterns enabling the ID of any reference
line by its numeration marker
"""
def getCompiledPatternList(self, prefix = u'', suffix = u''):
"""Return a list of compiled regex patterns used to ID the numeration marker for a reference line"""
patterns = self.createPatterns()
return CompiledPatternList(patterns)
def createPatterns(self, prefix = u'', suffix = u''):
"""Create the regex patterns (don't compile though)"""
patterns = []
if type(prefix) is str or type(prefix) is unicode:
title = prefix
else:
title = u''
g_name = unicode(r'(?P<mark>')
g_close = u')'
space = unicode(r'\s*?')
patterns.append(space+title+g_name+unicode(r'\[\s*?(?P<linenumber>\d+)\s*?\]')+g_close)
patterns.append(space+title+g_name+unicode(r'\[\s*?[a-zA-Z]+\s?(\d{1,4}[A-Za-z]?)?\s*?\]')+g_close)
patterns.append(space+title+g_name+unicode(r'\{\s*?\d+\s*?\}')+g_close)
patterns.append(space+title+g_name+unicode(r'\<\s*?\d+\s*?\>')+g_close)
patterns.append(space+title+g_name+unicode(r'\(\s*?\d+\s*?\)')+g_close)
patterns.append(space+title+g_name+unicode(r'(?P<marknum>\d+)\s*?\.')+g_close)
patterns.append(space+title+g_name+unicode(r'\d+\s*?')+g_close)
patterns.append(space+title+g_name+unicode(r'\d+\s*?\]')+g_close)
patterns.append(space+title+g_name+unicode(r'\d+\s*?\}')+g_close)
patterns.append(space+title+g_name+unicode(r'\d+\s*?\)')+g_close)
patterns.append(space+title+g_name+unicode(r'\d+\s*?\>')+g_close)
patterns.append(space+title+g_name+unicode(r'\[\s*?\]')+g_close)
patterns.append(space+title+g_name+unicode(r'\*')+g_close)
return patterns
class CompiledPatternList:
"""Concrete Class. List of compiled regex patterns, ready to be used for searching through text lines"""
class CompiledPatternListIterator:
def __init__(self, ptnlines):
self._mylist = ptnlines
self._listptr = 0
def next(self):
try:
item = self._mylist[self._listptr]
self._listptr += 1
return item
except IndexError:
raise StopIteration
def __init__(self, patternList):
"""Accept a list of regex strings and compile them, adding them to the internal list of compiled regex patterns"""
self._patterns = []
if type(patternList) is list:
for x in patternList:
self._patterns.append(re.compile(x, re.I|re.UNICODE))
def __iter__(self):
"""Return a CompiledPatternListIterator object so that the patterns held by a CompiledPatternList can be iterated through"""
return CompiledPatternList.CompiledPatternListIterator(self._patterns)
def getNumPatterns(self):
"""Return the length of the internal pattern list (patterns)"""
return len(self._patterns)
def getPattern(self, ptnIdx):
"""Return the regex pattern at [ptnIdx] in the internal pattern list (self._patterns). Returns 'None' if ptnIdx not valid"""
if type(ptnIdx) is int and ptnIdx < len(self._patterns) and ptnIdx > -1:
return self._patterns[ptnIdx]
else:
return None
def display(self):
"""Display all patterns held in a CompiledPatternList object"""
for x in self._patterns:
print x.pattern.encode("utf-8")
class LineSearchAlgorithm:
"""Search algorithm for matching a pattern in a line"""
def doSearch(self, searcher, line, patternList):
"""Search for a pattern in a line of text"""
match = None
unsafe = False
try: getNumPatterns=patternList.getNumPatterns
except AttributeError: unsafe=True
if (type(line) is str or type(line) is unicode) and not unsafe:
for x in patternList:
match = searcher.goSearch(line, x)
if match is not None:
break
return match
class SearchExecuter:
"""Abstract class. Executes a regex search operation on a line of text which is passed to it"""
def goSearch(self, line, pattern):
"""Execute the search and return a match object or None"""
pass
class MatchSearchExecuter(SearchExecuter):
"""Concrete class. Executes a 're.match()' on a compiled re pattern"""
def goSearch(self, line, pattern):
"""Execute the search and return a 'Match' object or None"""
return pattern.match(line)
class SearchSearchExecuter(SearchExecuter):
"""Concrete class. Executes a 're.search()' on a compiled re pattern"""
def goSearch(self, line, pattern):
"""Execute the search and return a 'Match' object or None"""
return pattern.search(line)
class LineSearcher:
"""Concrete Class. This is the interface through which the user can carry out a line search"""
def findAtStartLine(self, line, patternList):
"""Test a line of text against a list of patterns to see if any of the patterns match at the start of the line"""
al = LineSearchAlgorithm()
searcher = MatchSearchExecuter()
return al.doSearch(searcher, line, patternList)
def findWithinLine(self, line, patternList):
"""Test a line of text against a list of patterns to see if any of the patterns match anywhere within the line"""
al = LineSearchAlgorithm()
searcher = SearchSearchExecuter()
return al.doSearch(searcher, line, patternList)
class TextLineTransformer:
"""Abstract Class Interface. Accepts line, performs some transformationon it and returns transformed line"""
def processLine(self, line):
"""Carry out transformation on line. Return transformed line"""
pass
class EscapeSequenceTransformer(TextLineTransformer):
"""Class to correct escape seq's which were not properly represented in the document conversion"""
def __init__(self):
"""Compile & initialise pattern list"""
self._patterns = self._getPatterns()
def processLine(self, line):
"""Transform accents in a line into correct format"""
try:
for x in self._patterns.keys():
try:
line = line.replace(x,self._patterns[x])
except UnicodedecodeError:
sys.exit(0)
except TypeError:
pass
return line
def _getPatterns(self):
"""Return a list of regex patterns used to recognise escaped patterns"""
plist = {}
def _addLanguageTagCodePoints(ptnlist):
"""Add all language tag code points to remove from document"""
# Language Tag Code Points:
langTagCPs = [u"\U000E0000",u"\U000E0001",u"\U000E0002",u"\U000E0003",u"\U000E0004",u"\U000E0005",u"\U000E0006",u"\U000E0007",u"\U000E0008",u"\U000E0009",u"\U000E000A",u"\U000E000B",u"\U000E000C",u"\U000E000D",u"\U000E000E",u"\U000E000F",
u"\U000E0010",u"\U000E0011",u"\U000E0012",u"\U000E0013",u"\U000E0014",u"\U000E0015",u"\U000E0016",u"\U000E0017",u"\U000E0018",u"\U000E0019",u"\U000E001A",u"\U000E001B",u"\U000E001C",u"\U000E001D",u"\U000E001E",u"\U000E001F",
u"\U000E0020",u"\U000E0021",u"\U000E0022",u"\U000E0023",u"\U000E0024",u"\U000E0025",u"\U000E0026",u"\U000E0027",u"\U000E0028",u"\U000E0029",u"\U000E002A",u"\U000E002B",u"\U000E002C",u"\U000E002D",u"\U000E002E",u"\U000E002F",
u"\U000E0030",u"\U000E0031",u"\U000E0032",u"\U000E0033",u"\U000E0034",u"\U000E0035",u"\U000E0036",u"\U000E0037",u"\U000E0038",u"\U000E0039",u"\U000E003A",u"\U000E003B",u"\U000E003C",u"\U000E003D",u"\U000E003E",u"\U000E003F",
u"\U000E0040",u"\U000E0041",u"\U000E0042",u"\U000E0043",u"\U000E0044",u"\U000E0045",u"\U000E0046",u"\U000E0047",u"\U000E0048",u"\U000E0049",u"\U000E004A",u"\U000E004B",u"\U000E004C",u"\U000E004D",u"\U000E004E",u"\U000E004F",
u"\U000E0050",u"\U000E0051",u"\U000E0052",u"\U000E0053",u"\U000E0054",u"\U000E0055",u"\U000E0056",u"\U000E0057",u"\U000E0058",u"\U000E0059",u"\U000E005A",u"\U000E005B",u"\U000E005C",u"\U000E005D",u"\U000E005E",u"\U000E005F",
u"\U000E0060",u"\U000E0061",u"\U000E0062",u"\U000E0063",u"\U000E0064",u"\U000E0065",u"\U000E0066",u"\U000E0067",u"\U000E0068",u"\U000E0069",u"\U000E006A",u"\U000E006B",u"\U000E006C",u"\U000E006D",u"\U000E006E",u"\U000E006F",
u"\U000E0070",u"\U000E0071",u"\U000E0072",u"\U000E0073",u"\U000E0074",u"\U000E0075",u"\U000E0076",u"\U000E0077",u"\U000E0078",u"\U000E0079",u"\U000E007A",u"\U000E007B",u"\U000E007C",u"\U000E007D",u"\U000E007E",u"\U000E007F"]
for itm in langTagCPs: ptnlist[itm] = u""
def _addMusicNotation(ptnlist):
"""Add all musical notation items to remove from document"""
# Musical Notation Scoping
musicNotation = [u"\U0001D173",u"\U0001D174",u"\U0001D175",u"\U0001D176",u"\U0001D177",u"\U0001D178",u"\U0001D179",u"\U0001D17A"]
for itm in musicNotation: ptnlist[itm] = u""
# Control characters not suited to XML:
plist[u'\u2028'] = u""
plist[u'\u2029'] = u""
plist[u'\u202A'] = u""
plist[u'\u202B'] = u""
plist[u'\u202C'] = u""
plist[u'\u202D'] = u""
plist[u'\u202E'] = u""
plist[u'\u206A'] = u""
plist[u'\u206B'] = u""
plist[u'\u206C'] = u""
plist[u'\u206D'] = u""
plist[u'\u206E'] = u""
plist[u'\u206F'] = u""
plist[u'\uFFF9'] = u""
plist[u'\uFFFA'] = u""
plist[u'\uFFFB'] = u""
plist[u'\uFFFC'] = u""
plist[u'\uFEFF'] = u""
_addLanguageTagCodePoints(plist)
_addMusicNotation(plist)
plist[u'\u0001'] = u"" # START OF HEADING
# START OF TEXT & END OF TEXT:
plist[u'\u0002'] = u""
plist[u'\u0003'] = u""
plist[u'\u0004'] = u"" # END OF TRANSMISSION
# ENQ and ACK
plist[u'\u0005'] = u""
plist[u'\u0006'] = u""
plist[u'\u0007'] = u"" # BELL
plist[u'\u0008'] = u"" # BACKSPACE
# SHIFT-IN & SHIFT-OUT
plist[u'\u000E'] = u""
plist[u'\u000F'] = u""
# Other controls:
plist[u'\u0010'] = u"" # DATA LINK ESCAPE
plist[u'\u0011'] = u"" # DEVICE CONTROL ONE
plist[u'\u0012'] = u"" # DEVICE CONTROL TWO
plist[u'\u0013'] = u"" # DEVICE CONTROL THREE
plist[u'\u0014'] = u"" # DEVICE CONTROL FOUR
plist[u'\u0015'] = u"" # NEGATIVE ACK
plist[u'\u0016'] = u"" # SYNCRONOUS IDLE
plist[u'\u0017'] = u"" # END OF TRANSMISSION BLOCK
plist[u'\u0018'] = u"" # CANCEL
plist[u'\u0019'] = u"" # END OF MEDIUM
plist[u'\u001A'] = u"" # SUBSTITUTE
plist[u'\u001B'] = u"" # ESCAPE
plist[u'\u001C'] = u"" # INFORMATION SEPARATOR FOUR (file separator)
plist[u'\u001D'] = u"" # INFORMATION SEPARATOR THREE (group separator)
plist[u'\u001E'] = u"" # INFORMATION SEPARATOR TWO (record separator)
plist[u'\u001F'] = u"" # INFORMATION SEPARATOR ONE (unit separator)
# \r -> remove it
plist[u'\r'] = u""
# Strange parantheses - change for normal:
plist[u'\x1c'] = u'('
plist[u'\x1d'] = u')'
# Some ff from tex:
plist[u'\u0013\u0010'] = u'\u00ED'
plist[u'\x0b'] = u'ff'
# fi from tex:
plist[u'\x0c'] = u'fi'
# ligatures from TeX:
plist[u'\ufb00'] = u'ff'
plist[u'\ufb01'] = u'fi'
plist[u'\ufb02'] = u'fl'
plist[u'\ufb03'] = u'ffi'
plist[u'\ufb04'] = u'ffl'
# Superscripts from TeX
plist[u'\u2212'] = u'-'
plist[u'\u2013'] = u'-'
# Word style speech marks:
plist[u'\u201d'] = u'"'
plist[u'\u201c'] = u'"'
# pdftotext has problems with umlaut and prints it as diaeresis followed by a letter:correct it
# (Optional space between char and letter - fixes broken line examples)
plist[u'\u00A8 a'] = u'\u00E4'
plist[u'\u00A8 e'] = u'\u00EB'
plist[u'\u00A8 i'] = u'\u00EF'
plist[u'\u00A8 o'] = u'\u00F6'
plist[u'\u00A8 u'] = u'\u00FC'
plist[u'\u00A8 y'] = u'\u00FF'
plist[u'\u00A8 A'] = u'\u00C4'
plist[u'\u00A8 E'] = u'\u00CB'
plist[u'\u00A8 I'] = u'\u00CF'
plist[u'\u00A8 O'] = u'\u00D6'
plist[u'\u00A8 U'] = u'\u00DC'
plist[u'\u00A8 Y'] = u'\u0178'
plist[u'\xA8a'] = u'\u00E4'
plist[u'\xA8e'] = u'\u00EB'
plist[u'\xA8i'] = u'\u00EF'
plist[u'\xA8o'] = u'\u00F6'
plist[u'\xA8u'] = u'\u00FC'
plist[u'\xA8y'] = u'\u00FF'
plist[u'\xA8A'] = u'\u00C4'
plist[u'\xA8E'] = u'\u00CB'
plist[u'\xA8I'] = u'\u00CF'
plist[u'\xA8O'] = u'\u00D6'
plist[u'\xA8U'] = u'\u00DC'
plist[u'\xA8Y'] = u'\u0178'
# More umlaut mess to correct:
plist[u'\x7fa'] = u'\u00E4'
plist[u'\x7fe'] = u'\u00EB'
plist[u'\x7fi'] = u'\u00EF'
plist[u'\x7fo'] = u'\u00F6'
plist[u'\x7fu'] = u'\u00FC'
plist[u'\x7fy'] = u'\u00FF'
plist[u'\x7fA'] = u'\u00C4'
plist[u'\x7fE'] = u'\u00CB'
plist[u'\x7fI'] = u'\u00CF'
plist[u'\x7fO'] = u'\u00D6'
plist[u'\x7fU'] = u'\u00DC'
plist[u'\x7fY'] = u'\u0178'
plist[u'\x7f a'] = u'\u00E4'
plist[u'\x7f e'] = u'\u00EB'
plist[u'\x7f i'] = u'\u00EF'
plist[u'\x7f o'] = u'\u00F6'
plist[u'\x7f u'] = u'\u00FC'
plist[u'\x7f y'] = u'\u00FF'
plist[u'\x7f A'] = u'\u00C4'
plist[u'\x7f E'] = u'\u00CB'
plist[u'\x7f I'] = u'\u00CF'
plist[u'\x7f O'] = u'\u00D6'
plist[u'\x7f U'] = u'\u00DC'
plist[u'\x7f Y'] = u'\u0178'
# pdftotext: fix accute accent:
plist[u'\x13a'] = u'\u00E1'
plist[u'\x13e'] = u'\u00E9'
plist[u'\x13i'] = u'\u00ED'
plist[u'\x13o'] = u'\u00F3'
plist[u'\x13u'] = u'\u00FA'
plist[u'\x13y'] = u'\u00FD'
plist[u'\x13A'] = u'\u00C1'
plist[u'\x13E'] = u'\u00C9'
plist[u'\x13I'] = u'\u00CD'
plist[u'\x13O'] = u'\u00D3'
plist[u'\x13U'] = u'\u00DA'
plist[u'\x13Y'] = u'\u00DD'
plist[u'\x13 a'] = u'\u00E1'
plist[u'\x13 e'] = u'\u00E9'
plist[u'\x13 i'] = u'\u00ED'
plist[u'\x13 o'] = u'\u00F3'
plist[u'\x13 u'] = u'\u00FA'
plist[u'\x13 y'] = u'\u00FD'
plist[u'\x13 A'] = u'\u00C1'
plist[u'\x13 E'] = u'\u00C9'
plist[u'\x13 I'] = u'\u00CD'
plist[u'\x13 O'] = u'\u00D3'
plist[u'\x13 U'] = u'\u00DA'
plist[u'\x13 Y'] = u'\u00DD'
plist[u'\u00B4 a'] = u'\u00E1'
plist[u'\u00B4 e'] = u'\u00E9'
plist[u'\u00B4 i'] = u'\u00ED'
plist[u'\u00B4 o'] = u'\u00F3'
plist[u'\u00B4 u'] = u'\u00FA'
plist[u'\u00B4 y'] = u'\u00FD'
plist[u'\u00B4 A'] = u'\u00C1'
plist[u'\u00B4 E'] = u'\u00C9'
plist[u'\u00B4 I'] = u'\u00CD'
plist[u'\u00B4 O'] = u'\u00D3'
plist[u'\u00B4 U'] = u'\u00DA'
plist[u'\u00B4 Y'] = u'\u00DD'
plist[u'\u00B4a'] = u'\u00E1'
plist[u'\u00B4e'] = u'\u00E9'
plist[u'\u00B4i'] = u'\u00ED'
plist[u'\u00B4o'] = u'\u00F3'
plist[u'\u00B4u'] = u'\u00FA'
plist[u'\u00B4y'] = u'\u00FD'
plist[u'\u00B4A'] = u'\u00C1'
plist[u'\u00B4E'] = u'\u00C9'
plist[u'\u00B4I'] = u'\u00CD'
plist[u'\u00B4O'] = u'\u00D3'
plist[u'\u00B4U'] = u'\u00DA'
plist[u'\u00B4Y'] = u'\u00DD'
# pdftotext: fix grave accent:
plist[u'\u0060 a'] = u'\u00E0'
plist[u'\u0060 e'] = u'\u00E8'
plist[u'\u0060 i'] = u'\u00EC'
plist[u'\u0060 o'] = u'\u00F2'
plist[u'\u0060 u'] = u'\u00F9'
plist[u'\u0060 A'] = u'\u00C0'
plist[u'\u0060 E'] = u'\u00C8'
plist[u'\u0060 I'] = u'\u00CC'
plist[u'\u0060 O'] = u'\u00D2'
plist[u'\u0060 U'] = u'\u00D9'
plist[u'\u0060a'] = u'\u00E0'
plist[u'\u0060e'] = u'\u00E8'
plist[u'\u0060i'] = u'\u00EC'
plist[u'\u0060o'] = u'\u00F2'
plist[u'\u0060u'] = u'\u00F9'
plist[u'\u0060A'] = u'\u00C0'
plist[u'\u0060E'] = u'\u00C8'
plist[u'\u0060I'] = u'\u00CC'
plist[u'\u0060O'] = u'\u00D2'
plist[u'\u0060U'] = u'\u00D9'
# \02C7 : caron
plist[u'\u02C7C'] = u'\u010C'
plist[u'\u02C7c'] = u'\u010D'
plist[u'\u02C7S'] = u'\u0160'
plist[u'\u02C7s'] = u'\u0161'
plist[u'\u02C7Z'] = u'\u017D'
plist[u'\u02C7z'] = u'\u017E'
# \027 : aa (a with ring above)
plist[u'\u02DAa'] = u'\u00E5'
plist[u'\u02DAA'] = u'\u00C5'
# \030 : cedilla
plist[u'\u0327c'] = u'\u00E7'
plist[u'\u0327C'] = u'\u00C7'
return plist
class URLRepairer(TextLineTransformer):
"""Class to attempt to re-assemble URLs which have been broken during the document's conversion to text"""
def __init__(self):
"""Initialise the URI correction pattern list"""
self._patterns = self._compilePatterns(self._getPatterns())
def processLine(self, line):
"""Repair any broken URLs in line and return newly repaired line"""
def chop_spaces(m):
chopper = SpaceNullifier()
line = m.group(1)
return chopper.processLine(line)
if type(line) is str or type(line) is unicode:
for x in self._patterns:
line = x.sub(chop_spaces, line)
return line
def _getPatterns(self):
"""Return a list regex patterns and corrective measures to be used when broken URLs are encountered in a line"""
fileTypesList = []
fileTypesList.append(unicode(r'h\s*?t\s*?m')) # htm
fileTypesList.append(unicode(r'h\s*?t\s*?m\s*?l')) # html
fileTypesList.append(unicode(r't\s*?x\s*?t')) # txt
fileTypesList.append(unicode(r'p\s*?h\s*?p')) # php
fileTypesList.append(unicode(r'a\s*?s\s*?p\s*?')) # asp
fileTypesList.append(unicode(r'j\s*?s\s*?p')) # jsp
fileTypesList.append(unicode(r'p\s*?y')) # py (python)
fileTypesList.append(unicode(r'p\s*?l')) # pl (perl)
fileTypesList.append(unicode(r'x\s*?m\s*?l')) # xml
fileTypesList.append(unicode(r'j\s*?p\s*?g')) # jpg
fileTypesList.append(unicode(r'g\s*?i\s*?f')) # gif
fileTypesList.append(unicode(r'm\s*?o\s*?v')) # mov
fileTypesList.append(unicode(r's\s*?w\s*?f')) # swf
fileTypesList.append(unicode(r'p\s*?d\s*?f')) # pdf
fileTypesList.append(unicode(r'p\s*?s')) # ps
fileTypesList.append(unicode(r'd\s*?o\s*?c')) # doc
fileTypesList.append(unicode(r't\s*?e\s*?x')) # tex
fileTypesList.append(unicode(r's\s*?h\s*?t\s*?m\s*?l')) # shtml
plist = []
plist.append(unicode(r'(h\s*t\s*t\s*p\s*\:\s*\/\s*\/)'))
plist.append(unicode(r'(f\s*t\s*p\s*\:\s*\/\s*\/\s*)'))
plist.append(unicode(r'((http|ftp):\/\/\s*[\w\d])'))
plist.append(unicode(r'((http|ftp):\/\/([\w\d\s\._\-])+?\s*\/)'))
plist.append(unicode(r'((http|ftp):\/\/([\w\d\_\.\-])+\/(([\w\d\_\s\.\-])+?\/)+)'))
plist.append(unicode(r'((http|ftp):\/\/([\w\d\_\.\-])+\/(([\w\d\_\s\.\-])+?\/)*([\w\d\_\s\-]+\.\s?[\w\d]+))'))
# some possible endings for URLs:
for x in fileTypesList:
plist.append(unicode(r'((http|ftp):\/\/([\w\d\_\.\-])+\/(([\w\d\_\.\-])+?\/)*([\w\d\_\-]+\.') + x + u'))')
# if url last thing in line, and only 10 letters max, concat them
plist.append(unicode(r'((http|ftp):\/\/([\w\d\_\.\-])+\/(([\w\d\_\.\-])+?\/)*'\
r'\s*?([\w\d\_\.\-]\s?){1,10}\s*)$'))
return plist
def _compilePatterns(self, plist):
"""Compile regex patterns. Return mapping object containing patterns and replacement strings for each pattern"""
ptns = []
for x in plist:
ptns.append(re.compile(x, re.I+re.UNICODE))
return ptns
class SpaceNullifier(TextLineTransformer):
"""Class to remove all spaces from a text string"""
def __init__(self):
"""Initialise space chopping pattern"""
self.ptn = re.compile(unicode(r'\s+'), re.UNICODE)
self.rep = u''
def processLine(self, line):
"""Perform the act of chopping spaces from a line. Return line with no spaces in it"""
newLine = line
if type(newLine) is str or type(newLine) is unicode:
newLine = self.ptn.sub(self.rep, line)
return newLine
class MultispaceTruncator(TextLineTransformer):
"""Class to transform multiple spaces into a single space"""
def __init__(self):
"""Initialise space detection pattern"""
self.ptn = re.compile(unicode(r'\s{2,}'), re.UNICODE)
self.rep = u' '
def processLine(self, line):
"""Perform the act of detecting and replacing multiple spaces"""
newLine = line
if type(newLine) is str or type(newLine) is unicode:
newLine = self.ptn.sub(self.rep, line)
return newLine
class Document:
"""Abstract class Representing a fulltext document in the system"""
def __init__(self, newDocBody = [], filepath = None):
"""Initialise state of a document object"""
self._content = []
if filepath is not None:
self._file_readlines(filepath)
elif type(newDocBody) is list or type(newDocBody) is str or type(newDocBody) is unicode:
self.appendData(newDocBody)
def _file_readlines(self, fname):
try:
fh=open("%s" % (fname,), "r")
for line in fh: self._content.append(line.decode("utf-8"))
fh.close()
except IOError:
sys.stderr.write("""E: Failed to read in file "%s".\n""" % (fname,))
except ValueError:
sys.stderr.write("""E: Failed to read in file "%s".\n""" % (fname,))
def displayDocument(self):
"""Abstract: Display the Document"""
pass
def appendData(self, newData):
"""Add a text line to a TextDocument object"""
if type(newData) is list:
for line in newData:
self._content.append(line)
elif type(newData) is str or type(newData) is unicode:
self._content.append(newData)
def isEmpty(self):
"""Return 1 if self._content is empty; 0 if not"""
return (len(self._content) < 1)
class TextDocument(Document):
"""Concrete class representing a TextDocument - effectively a list of Strings of plaintext"""
def __init__(self, newDocBody = [], filepath = None):
"""Initialise a TextDocument object"""
Document.__init__(self, newDocBody, filepath)
def displayDocument(self):
for i in self._content: print i.encode("utf-8")
def getReferences(self, start, end):
"""Get the reference section lines, put them into a ReferenceSectionRebuilder object, ask it to rebuild the
lines, and return the resulting ReferenceSection object
"""
startIdx = None
if start.firstLineIsTitleAndMarker():
# Title on same line as 1st ref- take title out!
t = start.getTitleString()
startIdx = start.getLineNum()
newline = None
sp = re.compile(unicode(r'^.*?')+t,re.UNICODE)
newl = sp.split(self._content[startIdx],1)
self._content[startIdx] = newl[1]
elif start.titlePresent():
# Pass title
startIdx = start.getLineNum()+1
else:
startIdx = start.getLineNum()
if type(end) is int:
b = ReferenceSectionRebuilder(self._content[startIdx:end+1])
else:
b = ReferenceSectionRebuilder()
return b.getRebuiltLines(start)
def findEndReferenceSection(self, refStart):
"""Find the line number of the end of a TextDocument's reference section. Should be passed a ReferenceSectionStartPoint
object containing at least the start line of the reference section. Returns the reference section end line number
details if success, None if not
"""
if refStart is None or refStart.getLineNum() is None:
# No reference section start info!
return None
sectEnded = 0
x = refStart.getLineNum()
if (type(x) is not int) or (x<0) or (x>len(self._content)) or (len(self._content)<1):
# Cant safely find end of refs with this info - quit!
return None
# Get line test patterns:
t_patterns = PostRefSecnTitleListCompiler().getCompiledPatternList()
kw_patterns = PostRefSecnKWListCompiler().getCompiledPatternList()
if refStart.markerCharPresent():
mk_patterns = CompiledPatternList([refStart.getMarkerPattern()])
else:
mk_patterns = RefLineNumerationListCompiler().getCompiledPatternList()
garbageDigit_pattern = re.compile(unicode(r'^\s*?([\+\-]?\d+?(\.\d+)?\s*?)+?\s*?$'),re.UNICODE)
searcher=LineSearcher()
while (x<len(self._content)) and (not sectEnded):
end_match = searcher.findWithinLine(self._content[x], t_patterns)
if end_match is None:
end_match = searcher.findWithinLine(self._content[x], kw_patterns)
if end_match is not None:
# End reference section? Check within next 5 lines for other reference numeration markers
y = x+1
lineFnd = 0
while (y<x+6) and (y<len(self._content)) and (not lineFnd):
num_match=searcher.findWithinLine(self._content[y], mk_patterns)
if num_match is not None and not num_match.group(0).isdigit():
lineFnd = 1
y = y + 1
if not lineFnd:
# No ref line found-end section
sectEnded = 1
if not sectEnded:
# Does this & the next 5 lines simply contain numbers? If yes, it's probably the axis
# scale of a graph in a fig. End refs section
dm = garbageDigit_pattern.match(self._content[x])
if dm is not None:
y = x + 1
digitLines = 4
numDigitLns = 1
while(y<x+digitLines) and (y<len(self._content)):
dm = garbageDigit_pattern.match(self._content[y])
if dm is not None:
numDigitLns = numDigitLns + 1
y = y + 1
if numDigitLns == digitLines:
sectEnded = 1
x = x + 1
return x - 1
def extractReferences(self,no_rebuild = False):
"""Extract references from a TextDocument and return a ReferenceSection object"""
# Try to remove pagebreaks, headers, footers
self._removePageBoundaryInformation()
# Find start of refs section:
sectStart = self.findReferenceSection()
if sectStart is None:
# No references found
sectStart = self.findReferenceSectionNoTitle()
if sectStart is None:
# No References
refs = ReferenceSection()
else:
sectEnd = self.findEndReferenceSection(sectStart)
if sectEnd is None:
# No End to refs? Not safe to extract
refs = ReferenceSection()
else:
# Extract
refs = self.getReferences(sectStart, sectEnd)
return refs
def findReferenceSectionNoTitle(self):
"""Find the line number of the start of a TextDocument object's reference section by searching for the first reference
line. Can only find reference sections with distinct line markers such as [1]. Returns a ReferenceSectionStartPoint
object containing ref start line number & marker char, or the None type if nothing found
"""
refStartLine = refLineMarker = refStart = None
if len(self._content) > 0:
mk_patterns = FirstRefLineNumerationListCompiler().getCompiledPatternList()
searcher = LineSearcher()
p_blank = re.compile(unicode(r'^\s*$'))
x = len(self._content)-1
foundSect = 0
while x >= 0 and not foundSect:
mk_match = searcher.findAtStartLine(self._content[x], mk_patterns)
if mk_match is not None and string.atoi(mk_match.group('num')) == 1:
# Get mark recognition pattern:
mk_ptn = mk_match.re.pattern
# Look for [2] in next 10 lines:
nxtTestLines = 10
y = x + 1
tmpFnd = 0
while y < len(self._content) and y < x+nxtTestLines and not tmpFnd:
mk_match2=searcher.findAtStartLine(self._content[y], mk_patterns)
if (mk_match2 is not None) and (string.atoi(mk_match2.group('num')) == 2) and (mk_match.group('left') == mk_match2.group('left')) and (mk_match.group('right') == mk_match2.group('right')):
# Found next line:
tmpFnd = 1
elif y == len(self._content) - 1:
tmpFnd = 1
y = y + 1
if tmpFnd:
foundSect = 1
refStartLine = x
refLineMarker = mk_match.group('mark')
refLineMarkerPattern = mk_ptn
x = x - 1
if refStartLine is not None:
# Make ReferenceSectionStartPoint object with ref section start location details
refStart = ReferenceSectionStartPoint()
refStart.setLineNum(refStartLine)
refStart.setMarkerChar(refLineMarker)
refStart.setMarkerPattern(refLineMarkerPattern)
return refStart
def findReferenceSection(self):
"""Find the line number of the start of a TextDocument object's reference section. Returns a 'ReferenceSectionStartPoint'
object containing details of the reference section start line number, the reference section title & the marker char
used for each reference line or returns None if not found
"""
refStartLine = refTitle = refLineMarker = refLineMarkerPattern = None
refStart = titleMarkerSameLine = foundPart = None
if len(self._content) > 0:
t_patterns = RefSecnTitleListCompiler().getCompiledPatternList()
mk_patterns = RefLineNumerationListCompiler().getCompiledPatternList()
searcher = LineSearcher()
p_blank = re.compile(unicode(r'^\s*$'))
# Try to find refs section title:
x = len(self._content)-1
foundTitle = 0
while x >= 0 and not foundTitle:
title_match = searcher.findWithinLine(self._content[x], t_patterns)
if title_match is not None:
temp_refStartLine = x
tempTitle = title_match.group('title')
mk_wtitle_ptrns = RefLineNumerationListCompiler().getCompiledPatternList(tempTitle)
mk_wtitle_match = searcher.findWithinLine(self._content[x], mk_wtitle_ptrns)
if mk_wtitle_match is not None:
mk = mk_wtitle_match.group('mark')
mk_ptn = mk_wtitle_match.re.pattern
p_num = re.compile(unicode(r'(\d+)'))
m_num = p_num.search(mk)
if m_num is not None and string.atoi(m_num.group(0)) == 1:
# Mark found.
foundTitle = 1
refTitle = tempTitle
refLineMarker = mk
refLineMarkerPattern = mk_ptn
refStartLine=temp_refStartLine
titleMarkerSameLine = 1
else:
foundPart = 1
refStartLine = temp_refStartLine
refLineMarker = mk
refLineMarkerPattern = mk_ptn
refTitle = tempTitle
titleMarkerSameLine = 1
else:
try:
y = x + 1
# Move past blank lines
m_blank = p_blank.match(self._content[y])
while m_blank is not None and y < len(self._content):
y = y+1
m_blank = p_blank.match(self._content[y])
# Is this line numerated like a reference line?
mark_match = searcher.findAtStartLine(self._content[y], mk_patterns)
if mark_match is not None:
# Ref line found. What is it?
titleMarkerSameLine=None
mark = mark_match.group('mark')
mk_ptn = mark_match.re.pattern
p_num = re.compile(unicode(r'(\d+)'))
m_num = p_num.search(mark)
if m_num is not None and string.atoi(m_num.group(0)) == 1:
# 1st ref truly found
refStartLine = temp_refStartLine
refLineMarker = mark
refLineMarkerPattern = mk_ptn
refTitle = tempTitle
foundTitle = 1
elif m_num is not None and m_num.groups(0) != 1:
foundPart = 1
refStartLine = temp_refStartLine
refLineMarker = mark
refLineMarkerPattern = mk_ptn
refTitle = tempTitle
else:
if foundPart:
foundTitle = 1
else:
foundPart = 1
refStartLine = temp_refStartLine
refTitle=tempTitle
refLineMarker = mark
refLineMarkerPattern = mk_ptn
else:
# No numeration
if foundPart:
foundTitle = 1
else:
foundPart = 1
refStartLine = temp_refStartLine
refTitle=tempTitle
except IndexError:
# References section title was on last line for some reason. Ignore
pass
x = x - 1
if refStartLine is not None:
# Make ReferenceSectionStartPoint object with ref
# section start location details
refStart = ReferenceSectionStartPoint()
refStart.setLineNum(refStartLine)
refStart.setTitleString(refTitle)
refStart.setMarkerChar(refLineMarker)
refStart.setMarkerPattern(refLineMarkerPattern)
if titleMarkerSameLine is not None:
refStart.setTitleMarkerSameLine()
return refStart
def _removePageBoundaryInformation(self):
"""Locate page breaks, headers and footers within the doc body. remove them when found"""
numHeadLn = numFootLn = 0
pageBreaks = []
# Make sure document not just full of whitespace:
if not self.documentContainsText():
return 0
# Get list of index posns of pagebreaks in document:
pageBreaks = self.getDocPageBreakPositions()
# Get num lines making up each header if poss:
numHeadLn = self.getHeadLines(pageBreaks)
# Get num lines making up each footer if poss:
numFootLn = self.getFootLines(pageBreaks)
# Remove pagebreaks,headers,footers:
self.chopHeadFootBreaks(pageBreaks, numHeadLn, numFootLn)
def getheadFootWordPattern(self):
"""Regex pattern used to ID a word in a header/footer line"""
return re.compile(unicode(r'([A-Za-z0-9-]+)'),re.UNICODE)
def getHeadLines(self, breakIndices = []):
"""Using list of indices of pagebreaks in document, attempt to determine how many lines page headers consist of"""
remainingBreaks = (len(breakIndices) - 1)
numHeadLns = emptyLine = 0
p_wordSearch = self.getheadFootWordPattern()
if remainingBreaks > 2:
if remainingBreaks > 3:
# Only check odd page headers
nxtHead = 2
else:
# Check headers on each page
nxtHead = 1
keepChecking = True
while keepChecking:
curBreak = 1
#m_blankLineTest = p_wordSearch.search(self._content[(breakIndices[curBreak]+numHeadLns+1)])
m_blankLineTest = re.compile(u'\S',re.UNICODE).search(self._content[(breakIndices[curBreak]+numHeadLns+1)])
if m_blankLineTest == None:
# Empty line in header:
emptyLine = 1
if (breakIndices[curBreak]+numHeadLns+1) == (breakIndices[(curBreak + 1)]):
# Have reached next pagebreak: document has no body - only head/footers!
keepChecking = False
grps_headLineWords = p_wordSearch.findall(self._content[(breakIndices[curBreak]+numHeadLns+1)])
curBreak = curBreak + nxtHead
while (curBreak < remainingBreaks) and keepChecking:
grps_thisLineWords = p_wordSearch.findall(self._content[(breakIndices[curBreak]+numHeadLns+1)])
if emptyLine:
if len(grps_thisLineWords) != 0:
# This line should be empty, but isnt
keepChecking = False
else:
if (len(grps_thisLineWords) == 0) or (len(grps_headLineWords) != len(grps_thisLineWords)):
# Not same num 'words' as equivilent line in 1st header:
keepChecking = False
else:
keepChecking = self.checkBoundaryLinesSimilar(grps_headLineWords, grps_thisLineWords)
# Update curBreak for nxt line to check
curBreak = curBreak + nxtHead
if keepChecking:
# Line is a header line: check next
numHeadLns = numHeadLns+1
emptyLine = 0
return numHeadLns
def getFootLines(self, breakIndices = []):
"""Using list of indices of pagebreaks in document, attempt to determine how many lines page footers consist of"""
numBreaks = (len(breakIndices))
numFootLns = 0
emptyLine = 0
keepChecking = 1
p_wordSearch = self.getheadFootWordPattern()
if numBreaks > 2:
while keepChecking:
curBreak = 1
#m_blankLineTest = p_wordSearch.match(self._content[(breakIndices[curBreak]-numFootLns-1)])
m_blankLineTest = re.compile(u'\S',re.UNICODE).search(self._content[(breakIndices[curBreak] - numFootLns - 1)])
if m_blankLineTest == None:
emptyLine = 1
grps_headLineWords = p_wordSearch.findall(self._content[(breakIndices[curBreak]-numFootLns-1)])
curBreak=curBreak + 1
while (curBreak < numBreaks) and keepChecking:
grps_thisLineWords = p_wordSearch.findall(self._content[(breakIndices[curBreak] - numFootLns - 1)])
if emptyLine:
if len(grps_thisLineWords) != 0:
keepChecking = 0
else:
if (len(grps_thisLineWords) == 0) or (len(grps_headLineWords) != len(grps_thisLineWords)):
keepChecking = 0
else:
keepChecking = self.checkBoundaryLinesSimilar(grps_headLineWords, grps_thisLineWords)
curBreak = curBreak + 1
if keepChecking:
numFootLns = numFootLns+1
emptyLine = 0
return numFootLns
def chopHeadFootBreaks(self, breakIndices = [], headLn = 0, footLn = 0):
"""Remove document lines containing breaks, headers, footers"""
numBreaks = len(breakIndices)
pageLens = []
for x in range(0,numBreaks):
if x < numBreaks - 1:
pageLens.append(breakIndices[x + 1] - breakIndices[x])
pageLens.sort()
if (len(pageLens) > 0) and (headLn+footLn+1 < pageLens[0]):
# Safe to chop hdrs & ftrs
breakIndices.reverse()
first = 1
for i in range(0, len(breakIndices)):
# Unless this is the last page break, chop headers
if not first:
for j in range(1,headLn+1):
self._content[breakIndices[i]+1:breakIndices[i]+2] = []
else:
first = 0
# Chop page break itself
self._content[breakIndices[i]:breakIndices[i]+1] = []
# Chop footers (unless this is the first page break)
if i != len(breakIndices) - 1:
for k in range(1,footLn + 1):
self._content[breakIndices[i] - footLn:breakIndices[i] - footLn + 1] = []
def checkBoundaryLinesSimilar(self, l_1, l_2):
"""Compare two lists to see if their elements are roughly the same"""
numMatches = 0
if (type(l_1) != list) or (type(l_2) != list) or (len(l_1) != len(l_2)):
return False
p_int = re.compile(unicode(r'^(\d+)$'))
for i in range(0,len(l_1)):
m_int1 = p_int.match(l_1[i])
m_int2 = p_int.match(l_2[i])
if(m_int1 != None) and (m_int2 != None):
numMatches=numMatches+1
else:
l1_str = l_1[i].lower()
l2_str = l_2[i].lower()
if (l1_str[0] == l2_str[0]) and (l1_str[len(l1_str) - 1] == l2_str[len(l2_str) - 1]):
numMatches=numMatches+1
if (len(l_1) == 0) or (float(numMatches)/float(len(l_1)) < 0.9):
return False
else:
return True
def getDocPageBreakPositions(self):
"""Locate page breaks in the list of document lines and make a list of their indices to be returned"""
pageBreaks = []
p_break = re.compile(unicode(r'^\s*?\f\s*?$'),re.UNICODE)
for i in range(len(self._content)):
if p_break.match(self._content[i]) != None:
pageBreaks.append(i)
return pageBreaks
def documentContainsText(self):
"""Test whether document contains text, or is just full of worthless whitespace. Return 1 if has text, 0 if not"""
foundWord = False
p_word = re.compile(unicode(r'\S+'))
for i in self._content:
if p_word.match(i) != None:
foundWord = True
break
return foundWord
class Ps2asciiEncodedTextDocument(Document):
"""Text document that is encoded with PS coordinate information. This type of document is result of a ps2ascii conversion"""
class Ps2asciiOutputLine:
"""Represents a line from a ps2ascii conversion"""
def __init__(self, posx, posy, content, diffx):
"""Initialise a dataline's state"""
self._posnX = self._posnY = 0
self._dataContent = ''
self._diff_posnX = 0
self.setPosX(int(posx))
self.setPosY(int(posy))
self.setText(content)
self.setDiffPosX(int(diffx))
def setPosX(self, x):
"""Set posnX value for a Ps2asciiOutputLine object"""
self._posnX = x
def setPosY(self, y):
"""Set posnY value for a Ps2asciiOutputLine object"""
self._posnY = y
def setText(self, data):
"""Set dataContent value for Ps2asciiOutputLine object"""
self._dataContent = data
def setDiffPosX(self, dpx):
"""Set diff_posnX value for a Ps2asciiOutputLine object"""
self._diff_posnX = dpx
def getPosX(self):
"""Return the posnX value for a Ps2asciiOutputLine object"""
return self._posnX
def getPosY(self):
"""Return the posnY value for a Ps2asciiOutputLine object"""
return self._posnY
def getText(self):
"""Return a cleaned up version of the dataContent in this Ps2asciiOutputLine object"""
return self._dataContent
def getDiffPosX(self):
"""Return the diff_posnX value for a Ps2asciiOutputLine object"""
return self._diff_posnX
def isNewLine(self, previousLine):
"""Check the positional coordinates of this line with those of the supplied Ps2asciiOutputLine object to
determine whether this is a new line. Return 1 if yes, or 0 if no
"""
if (self.getPosX() <= previousLine.getPosX()) and (self.getPosY() != previousLine.getPosY()):
return 1
else:
return 0
def isSpaceSeparated(self, posnxEst):
"""Return 1 if the text in this Ps2asciiOutputLine object should be separated from that in a
previous Ps2asciiOutputLine object, as determined by an X position estimate (posnxEst). Return 0 if not
"""
if (self.getPosX() > (posnxEst + 7)):
return 1
else:
return 0
def __init__(self, newDocBody = []):
Document.__init__(self, newDocBody)
def convertToPlainText(self):
"""Tell a Ps2asciiEncodedTextDocument to convert itself to convert itself to pure plaintext. Returns TextDocument object"""
# Converted document:
plaintextContent = []
tempLine = ''
# Fictitious old line to compare with 1st line:
oldRawLine = self.Ps2asciiOutputLine(9999,9999,"",0)
posnxEst = 9999
for line in self._content:
curRawLine = self.getDataLine(line)
if curRawLine != None:
# Find out if this a new line or a continuation of the last line
if curRawLine.isNewLine(oldRawLine):
# Append previous full line:
plaintextContent.append(self.prepareLineForAppending(tempLine))
# Start a new line buffer:
tempLine = curRawLine.getText()
else:
# Not new line: concat with last line
if curRawLine.isSpaceSeparated(posnxEst):
tempLine = tempLine+' '+curRawLine.getText()
else:
tempLine = tempLine+curRawLine.getText()
posnxEst = (curRawLine.getPosX() + curRawLine.getDiffPosX())
oldRawLine = curRawLine
# Append very last line to list:
plaintextContent.append(self.prepareLineForAppending(tempLine))
# Remove first, empty cell from list:
plaintextContent[0:1] = []
# Make a TextDocument with the newly converted text content and return it:
return TextDocument(plaintextContent)
def getDataLine(self, rawLine):
"""Take a raw line from ps2ascii, and put its components into a Ps2asciiOutputLine object"""
idPattern = re.compile(r'^S\s(?P<posnX>\d+)\s(?P<posnY>\d+)\s\((?P<content>.*)\)\s(?P<diff_posnX>\d+)$')
match = idPattern.search(rawLine)
if match != None:
return self.Ps2asciiOutputLine(match.group('posnX'), match.group('posnY'), match.group('content'), match.group('diff_posnX'))
else:
return None
def prepareLineForAppending(self, line):
"""Prepare the contents of a plaintext line which has been rebuilt from Ps2asciiOutputLine(s) to be appended to the
list of plaintext lines which make up the plaintext document Test its contents: if all whitespace, but not formfeed,
return an empty line; if contains non-whitespace or a formfeed, return the line as is
"""
# Clean line to append of control codes:
line = self.cleanLine(line)
ep = re.compile('\S')
em = ep.match(line)
if em == None:
fp = re.compile('^ *\f *$')
fm = fp.match(line)
if fm == None:
line = ''
return line
def cleanLine(self, line):
"""Clean a line of text of the messy character codes that ps2ascii adds during conversion"""
# Correct escaped parentheses
p = re.compile(r'\\\(')
line = p.sub('(', line)
p = re.compile(r'\\\)')
line = p.sub(r')', line)
# Correct special symbols
p = re.compile(r'\\\\')
line = p.sub('', line)
p = re.compile('\n')
line = p.sub(r' ', line)
# Change '\013' to 'ff' (ps2ascii messes this up)
p = re.compile(r'\\013')
line = p.sub('ff', line)
# Change '\017' (bullet point) into '*'
p = re.compile(r'\\017')
line = p.sub('*', line)
# Change '\003' into '*'
p = re.compile(r'\\003')
line = p.sub('', line)
# Change '\\f' to 'fi' (ps2ascii messes this up)
p = re.compile(r'\\f')
line = p.sub('fi', line)
# Remove page numbers:
p = re.compile('\{\s\d+\s\{')
line = p.sub(r'', line)
# Correct Hyphens:
p = re.compile('\{')
line = p.sub('-', line)
return line
def displayDocument(self):
"""Let Ps2asciiEncodedTextDocument display itself on standard output stream"""
for i in self._content:
print i
class ReferenceSectionStartPoint:
"""Concrete class to hold information about the start line of a document's reference section (e.g. line number, title, etc)"""
def __init__(self):
self._lineNum = self._title = self._lineMarkerPresent = None
self._haveMarkerRegex = self._markerChar = self._markerRegexPattern = self._markerTitleSameLine=None
def setLineNum(self, num):
"""Set the line number of the references section start"""
self._lineNum = num
def setTitleString(self, t):
"""Set the title string for the references section start"""
self._title = t
def setMarkerChar(self, m):
"""Set the marker char for the references section start"""
if m is not None and (type(m) is str or type(m) is unicode):
self._markerChar = m
self._lineMarkerPresent = 1
else:
self._markerChar = None
self._lineMarkerPresent = 0
def setMarkerPattern(self, p):
"""Set the regex pattern for the start of the first reference line"""
if p is not None and (type(p) is str or type(p) is unicode):
self._markerRegexPattern = p
self._haveMarkerRegex = 1
else:
self._markerRegexPattern = None
self._haveMarkerRegex = 0
def setTitleMarkerSameLine(self):
"""Set a flag to say that the first reference line contains both a title and the first line"""
self._markerTitleSameLine = 1
def getLineNum(self):
"""Return the line number of the references section start"""
return self._lineNum
def getTitleString(self):
"""Return the title string for the references section start if there is one, else it will be None"""
return self._title
def firstLineIsTitleAndMarker(self):
"""Return 1 if the first reference line contains both reference section title & first line numeration marker"""
if self._markerTitleSameLine is not None:
return True
else:
return False
def titlePresent(self):
"""Return 1 if there is a title present in the first reference line, 0 if not"""
if self._title is not None:
return True
else:
return False
def markerCharPresent(self):
"""Return 1 if there is a marker char, 0 if not"""
if self._lineMarkerPresent:
return True
else:
return False
def markerPatternPresent(self):
"""Return 1 if there is a marker regex pattern, 0 if not"""
if self._haveMarkerRegex:
return True
else:
return False
def getMarkerChar(self):
"""Return the marker char for the reference section start if there is one, else it will be None"""
return self._markerChar
def getMarkerPattern(self):
return self._markerRegexPattern
class ReferenceSectionRebuilder:
"""Concrete class whose job is to rebuild broken reference lines. Contains a list of Strings. Each String in this list
represents the contents of either a complete reference line or part of a reference line. When a document is converted from
its original format to plaintext, lines are often broken because the converter cant distinguish between wrapped lines and
new lines. Objects of this class can be used to try to rebuild broken reference lines and create a 'ReferenceSection' object
"""
def __init__(self, lines = []):
"""Initialise a ReferenceSectionRebuilder object with a list of 'broken' reference lines"""
if type(lines) is list:
self._dataLines = lines
elif type(lines) is str or type(lines) is unicode:
self._dataLines.append(lines)
else:
self._dataLines = []
def getRebuiltLines(self, refStartInfo):
"""Trigger reference lines rebuilding process & return ReferenceSection object containing rebuilt ReferenceLine objects"""
# Ensure we have a real 'ReferenceSectionStartPoint'
try: getLineNum = refStartInfo.getLineNum
except AttributeError: return ReferenceSection()
self._removeLeadingGarbageLines()
numatnInfo = self._getLineNumerationStyle(refStartInfo)
return ReferenceSection(self._rebuild(numatnInfo))
def _testBlankLineRefSeparators(self):
"""Test to see if reference lines are separated by blank lines so that these can be used to rebuild reference lines"""
p_ws = re.compile(unicode(r'^\s*$'),re.UNICODE)
numblank = 0 # No blank lines fnd between non-blanks
numline = 0 # No ref lines separated by blanks
blankLnSep = 0 # Flag to indicate if blanks lines separate ref lines
multi_nonblanks_fd = 0 # Flag to indicate if multiple nonblank lines are found together (used because
# if line is dbl-spaced, it isnt a blank that separates refs & cant be relied upon)
x = 0
max = len(self._dataLines)
while x < max:
m_ws = p_ws.search(self._dataLines[x])
if m_ws is None:
# ! empty line
numline = numline+1
x = x + 1 # Move past line
while x < len(self._dataLines) and p_ws.search(self._dataLines[x]) is None:
multi_nonblanks_fd=1
x = x + 1
x = x - 1
else:
# empty line
numblank = numblank + 1
x = x + 1
while x< len(self._dataLines) and p_ws.search(self._dataLines[x]) is not None:
x = x + 1
if x == len(self._dataLines):
# Blanks at end doc: dont count
numblank = numblank-1
x = x - 1
x = x + 1
# Now from data of num blank lines & num text lines, if numline>3, & numblank=numline or numblank=numline-1
# then we hav blank line separators between ref lines
if (numline > 3) and ((numblank == numline) or (numblank == numline - 1)) and (multi_nonblanks_fd):
blankLnSep = 1
return blankLnSep
def _rebuild(self, refNum):
"""Based on whether a reference line numeration pattern was found, either have the reference lines rebuild by the
identification of marker characters, or join all lines together if no numeration was found
"""
# Private internal function
def cleanAndAppendToRefsList(transformers, refList, line):
"""Before appending to list, process line with 'TextLineTransformers'"""
for x in transformers:
line = x.processLine(line)
sp = re.compile(unicode(r'^\s*$'),re.UNICODE)
if sp.match(line) is None:
refList.append(line)
rebuilt = []
lineTrans = []
tl = u''
# List of line transformers to clean up line:
lineTrans.append(URLRepairer())
lineTrans.append(EscapeSequenceTransformer())
lineTrans.append(MultispaceTruncator())
if refNum is None or (type(refNum) is not str and type(refNum) is not unicode):
if self._testBlankLineRefSeparators():
# Use blank lines to separate ref lines
refNum = unicode(r'^\s*$')
else:
# No ref line dividers: unmatchable pattern
refNum = unicode(r'^A$^A$$')
p_refNum = re.compile(refNum,re.I|re.UNICODE)
p_leadingws = re.compile(unicode(r'^\s+'))
p_trailingws = re.compile(unicode(r'\s+$'))
for x in range(len(self._dataLines)-1,-1,-1):
tstr = p_leadingws.sub(u'',self._dataLines[x])
tstr = p_trailingws.sub(u'',tstr)
m = p_refNum.match(tstr)
if m is not None:
# Ref line start marker
if tstr == '':
# Blank line to separate refs
tl = p_trailingws.sub(u'',tl)
cleanAndAppendToRefsList(lineTrans, rebuilt, tl)
tl = u''
else:
if tstr[len(tstr)-1] == u'-' or tstr[len(tstr)-1] == u' ':
tl = tstr + tl
else:
tl = tstr + u' ' + tl
tl = p_trailingws.sub(u'',tl)
cleanAndAppendToRefsList(lineTrans, rebuilt, tl)
tl = u''
else:
if tstr != u'':
# Continuation of line
if tstr[len(tstr) - 1] == u'-' or tstr[len(tstr) - 1] == u' ':
tl = tstr + tl
else:
tl = tstr + u' ' + tl
if tl != u'':
# Append last line
tl = p_trailingws.sub(u'',tl)
cleanAndAppendToRefsList(lineTrans, rebuilt, tl)
rebuilt.reverse()
d=self._testAndCorrectRebuiltLines(rebuilt, p_refNum)
if d is not None: rebuilt = d
return rebuilt
def _testAndCorrectRebuiltLines(self, rebuiltlines, p_refmarker):
"""EXPERIMENTAL METHOD. Try to correct any rebuild reference lines that have been given a bad reference number at the start. Needs testing."""
fixed = []
unsafe = False
try:
m = p_refmarker.match(rebuiltlines[0])
last_marknum = int(m.group("marknum"))
if last_marknum != 1:
return None # Even the first mark isnt 1 - probaby too dangerous to try to repair
except IndexError:
return None # Either no references or not a "numbered line marker" - cannot do anything
except AttributeError:
return None # No reference line marker (i.e. NoneType because couldn't match marker) - cannot do anything
fixed.append(rebuiltlines[0])
try:
for x in range(1,len(rebuiltlines)):
m = p_refmarker.match(rebuiltlines[x])
try:
if int(m.group("marknum")) == last_marknum + 1:
# All is well
fixed.append(rebuiltlines[x])
last_marknum += 1
continue
elif len(string.strip(rebuiltlines[x][m.end():])) == 0:
# this line consists of a number only. And it is not a coorrect marker. Add it to the last line:
fixed[len(fixed) - 1] += rebuiltlines[x]
continue
else:
# Problem maybe. May have taken some of the last line into this line. Can we find the next marker in this line?
m_fix = p_refmarker.search(rebuiltlines[x])
if m_fix is not None and int(m_fix.group("marknum")) == last_marknum + 1:
m_fix_test = re.match(u"%s\s*[A-Z]"%(m_fix.group(),))
if m_fix_test is not None:
movesect = rebuiltlines[x][0:m_fix.start()]
rebuiltlines[x] = rebuiltlines[x][m_fix.start():]
fixed[len(fixed) - 1] += movesect
fixed.append(rebuiltlines[x])
else:
unsafe = True
break
else:
unsafe = True
break
except AttributeError:
# This line does not have a line marker at the start! This line shall be added to the end of the previous line.
fixed[len(fixed) - 1] += rebuiltlines[x]
continue
except IndexError:
unsafe = True
if unsafe: return None
else: return fixed
def _getLineNumerationStyle(self, refStartInfo):
"""Try to determine the numeration marker style for the reference lines"""
mkregex = None
if refStartInfo.markerPatternPresent():
mkregex = refStartInfo.getMarkerPattern()
return mkregex
def _removeLeadingGarbageLines(self):
"""Sometimes, the first lines of the extracted references are completely blank or email addresses. These must be removed as they are not references"""
p_emptyline = re.compile(unicode(r'^\s*$'),re.UNICODE)
p_email = re.compile(unicode(r'^\s*e\-?mail'),re.UNICODE)
while (len(self._dataLines)>0) and (p_emptyline.match(self._dataLines[0]) is not None or p_email.match(self._dataLines[0]) is not None):
self._dataLines[0:1] = []
class DocumentConverter:
"""Abstract Class representing a document format conversion
tool which converts a document from one format to another
"""
def convertDocument(self, toConvert):
"""Document Conversion Method - returns a Document object"""
pass
def checkConvertFile(self, filePath):
"""Check that the file to convert is usable"""
pass
class OSDependentDocumentConverter(DocumentConverter):
"""ABSTRACT CLASS: Represents a document conversion tool which is a
separate program which needs to be executed via a call to the shell below
"""
def __init__(self):
self._converterSessionLink = self._convertCommand = ''
def setConvertCommand(self, filePath):
"""ABSTRACT METHOD: Set the shell command used for calling the
converter application. Declared abstract because it differs
according to which specific application is used
"""
pass
def getConvertCommand(self):
"""Return the shell command by which the conversion application is called"""
return self._convertCommand
def openConverterSession(self):
"""Open a session with the shell 'converter' application"""
if self._converterSessionLink is file:
self._converterSessionLink.close()
self._converterSessionLink = ""
self._converterSessionLink = os.popen(self.getConvertCommand(),'r')
def closeConverterSession(self):
"""Close session with the shell 'converter' application"""
if self._converterSessionLink is file:
self._converterSessionLink.close()
self._converterSessionLink = ""
def getConversionResult(self):
"""Return list of lines from shell conversion session"""
return self._converterSessionLink.readlines()
class PDFtoTextDocumentConverter(OSDependentDocumentConverter):
"""Converts PDF documents to ASCII plaintext documents"""
def __init__(self):
"""Initialise PDFtoTextDocumentConverter object"""
OSDependentDocumentConverter.__init__(self)
self._applicationPath = ''
self.setApplicationPath(cfg_refextract_pdftotext)
def setApplicationPath(self, newPath):
"""Set path to conversion application"""
self._applicationPath = newPath
def getApplicationPath(self):
"""Return the path to the conversion application"""
return self._applicationPath
def setConvertCommand(self, filePath):
"""Set up the command by which to call pdftotext application"""
self._convertCommand = self.getApplicationPath() + ' -raw -q -enc UTF-8 ' + filePath + ' -'
def getConversionResult(self):
mylines = []
for line in self._converterSessionLink: mylines.append(line.decode("utf-8"))
return mylines
def convertDocument(self, toConvert):
"""Perform a conversion from PDF to text, returning the document contents as a TextDocument object"""
if self._canAccessConvertFile(toConvert):
self.setConvertCommand(toConvert)
self.openConverterSession()
convRes = self.getConversionResult()
self.closeConverterSession()
if self._conversionIsBad(convRes):
# Bad conversion: empty document
textDoc = TextDocument()
else:
# Good conversion
textDoc = TextDocument(convRes)
else:
textDoc = TextDocument()
return textDoc
def _conversionIsBad(self, convertedLines):
"""Sometimes pdftotext performs a bad conversion which consists of many spaces and garbage characters.
This method takes a list of strings obtained from a pdftotext conversion and examines them to see if
they are likely to be the result of a bad conversion. Returns 1 if bad conversion, 0 if not
"""
# Numbers of 'words' and 'whitespaces' found in document:
numWords = numSpaces = 0
# whitespace line pattern:
ws_patt = re.compile(unicode(r'^\s+$'),re.UNICODE)
# whitespace character pattern:
p_space = re.compile(unicode(r'(\s)'),re.UNICODE)
# non-whitespace 'word' pattern:
p_noSpace = re.compile(unicode(r'(\S+)'),re.UNICODE)
for line in convertedLines:
numWords = numWords + len(p_noSpace.findall(line))
numSpaces = numSpaces + len(p_space.findall(line))
if numSpaces >= (numWords * 3):
# Too many spaces - probably bad conversion
return True
else:
return False
def _canAccessConvertFile(self, filePath):
"""Check that the path to the file to convert really exists and is readable by the shell"""
if os.access(filePath, os.R_OK): return True
else: return False
class PS2AsciiDocumentConverter(OSDependentDocumentConverter):
"""Converts PS documents to ASCII plaintext documents"""
def __init__(self):
"""Initialise PS2AsciiDocumentConverter object"""
OSDependentDocumentConverter.__init__(self)
self._catAppPath = self._gunzipAppPath = self._gsAppPath = ''
self.setCATapplicationPath(cfg_refextract_cat)
self.setGUNZIPapplicationPath(cfg_refextract_gunzip)
self.setGSapplicationPath(cfg_refextract_gs)
def setCATapplicationPath(self, catAppPath):
"""Set the path to the 'cat' application, used in conversion"""
self._catAppPath = catAppPath
def setGUNZIPapplicationPath(self, gunzipAppPath):
"""Set the path to the 'gunzip' application, used in conversion if the PS file has been zipped"""
self._gunzipAppPath = gunzipAppPath
def setGSapplicationPath(self, gsAppPath):
"""Set the path to the 'GhostScript' application, which is the means of calling 'ps2ascii'"""
self._gsAppPath = gsAppPath
def getCATapplicationPath(self):
"""Return the path to 'cat' as a string"""
return self._catAppPath
def getGUNZIPapplicationPath(self):
"""Return the path to 'gunzip' as a string"""
return self._gunzipAppPath
def getGSapplicationPath(self):
"""Return the path to 'gs' as a string"""
return self._gsAppPath
def setUnzippedPSConvertCommand(self, filePath):
"""Set converter command for unzipped PS file conversion"""
self._convertCommand = self.getCATapplicationPath() + " " + filePath + " | " + self.getGSapplicationPath() + " -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -c save -f ps2ascii.ps - -c quit"
def setZippedPSConvertCommand(self, filePath):
"""Set converter command for zipped PS file conversion"""
self._convertCommand = self.getGUNZIPapplicationPath() + " -c " + filePath + " | " + self.getGSapplicationPath() + " -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -c save -f ps2ascii.ps - -c quit"
def setConvertCommand(self, filePath):
"""Set up the shell command by which to call applications needed to perform the conversion"""
if re.search(r'(\w{2})$', filePath).group(0) == "ps":
self.setUnzippedPSConvertCommand(filePath)
else:
self.setZippedPSConvertCommand(filePath)
def _canAccessConvertFile(self, filePath):
"""Check that the path to the file to convert really exists and is readable by the shell"""
if os.access(filePath, os.R_OK): return True
else: return False
def _correctConvertFileName(self, filename):
"""Strip file extension from filename & replace with '.ps' or '.ps.gz' depending on which exists. If neither exist,
replace with no extension
"""
regexPattern = re.compile(r'(?P<fname>.*?)(\.\w+)?$')
match = regexPattern.search(filename)
name = match.group('fname')
if self._canAccessConvertFile(name+'.ps'): name = name + '.ps'
else: name = name + '.ps.gz'
return name
def convertDocument(self, toConvert):
"""This method performs a conversion from PS to text. If the file 'toConvert' exists and can be converted, a
TextDocument object is returned. If not, then an empty TextDocument is returned"""
toConvert = self._correctConvertFileName(toConvert)
if self._canAccessConvertFile(toConvert):
self.setConvertCommand(toConvert)
self.openConverterSession()
ps2asciiDoc = Ps2asciiEncodedTextDocument(self.getConversionResult())
# Convert the ps2asciiDoc to plaintext:
textDoc = ps2asciiDoc.convertToPlainText()
self.closeConverterSession()
else:
textDoc = TextDocument()
return textDoc
class BadKBLineError(Exception):
"""Exception thrown if a line in the periodicals knowledge base does not comply with the expected format"""
pass
class KnowledgeBase:
"""The knowledge base of periodical titles. Consists of search & replace terms. The search terms consist of non-standard periodical titles in upper case.
These are often found in the text of documents. Replacement terms consist of standardised periodical titles in a standardised case. These will be used to
replace identified non-standard titles
"""
def __init__(self, fn = None):
self._kb = {}
self._compiledPatternsKB = {}
self._unstandardisedTitle = {}
if type(fn) is str: self._buildKB(fn)
def _buildKB(self, fn):
"""From the filename provided (fn), read the periodicals knowledge base into memory, and build a dictionary of seek/replace values to be stored in self._kb"""
def _mychop(line):
if line[:-1] == u'\n':
line = line[:-1]
return line
try:
fh=open(fn, 'r')
p_kbLine = re.compile(unicode('^\s*(?P<seek>\w.*?)\s*---\s*(?P<repl>\w.*?)\s*$'),re.UNICODE)
for x in fh:
y = x.decode("utf-8")
y = _mychop(y)
m_kbLine = p_kbLine.search(y)
if m_kbLine is None:
raise BadKBLineError()
if len(m_kbLine.group('seek')) > 1:
# Only add KB line if the search term is more than 1 char in length
self._kb[m_kbLine.group('seek')] = m_kbLine.group('repl')
tmp_ptn = re.compile(unicode(r'\b(') + re.escape(m_kbLine.group('seek')) + unicode(r')[^A-Z0-9]'), re.UNICODE)
self._compiledPatternsKB[tmp_ptn] = m_kbLine.group('repl')
self._unstandardisedTitle[tmp_ptn] = m_kbLine.group('seek')
fh.close()
except IOError:
sys.exit('E: Cannot Open Knowledge Base File "%s".' % fn)
except (BadKBLineError, AttributeError):
sys.exit('E: Unexpected Line in Knowledge Base "%s".' % fn)
def display(self):
"""Display the contents of the KB on the standard output stream"""
print u"Knowledge Base Contents:"
for x in self._kb.keys():
sys.stdout.write("Search Term: '%s';\t\tReplace Term: '%s'\n" % (x.encode("utf-8"), (self._kb[x]).encode("utf-8")))
def findPeriodicalTitles(self, ln):
"""Identify periodical titles in text line 'ln' and record information about where in the line they occur. Replace them for lower-case versions or
lowercase letter 'a's if the match was numerical. Return a Tuple containing dictionaries containing information about the substitutions, along with the new line
"""
def _bytitlelen(a, b):
(aa,bb) = (self._unstandardisedTitle[a],self._unstandardisedTitle[b])
if len(aa) < len(bb): return 1
elif len(aa) == len(bb): return 0
else: return -1
def _byLen(a, b):
(aa,bb) = (a.pattern,b.pattern)
if len(aa) < len(bb): return 1
elif len(aa) == len(bb): return 0
else: return -1
foundMatch = False
title_match_len = {}
title_match_txt = {}
kb_keys = self._compiledPatternsKB.keys()
kb_keys.sort(_bytitlelen)
word_ptn = re.compile(unicode(r'^[ A-Z-a-z]+$'),re.UNICODE)
for t_ptn in kb_keys:
matches_iter = t_ptn.finditer(ln)
# Record dets of each match:
for m in matches_iter:
# Record match info
title_match_len[m.start()] = (len(m.group(0)) - 1)
title_match_txt[m.start()] = self._unstandardisedTitle[t_ptn]
# Replace matched txt in line with lowercase version (or n*'_' where n is len of match)
rep_str = m.group(1)
word_mtch = word_ptn.search(rep_str)
if word_mtch is None:
# None alpha/whitespace chars
rep_str = u'_'*len(rep_str)
else:
# Words
rep_str = rep_str.lower()
ln = u''.join([ln[0:m.start(1)],rep_str,ln[m.end(1):]])
if len(title_match_len) > 0: foundMatch = True
return (title_match_len, title_match_txt, ln, foundMatch)
def __getitem__(self, non_std_title):
"""Return the standardised title thought to be keyed by 'non_std_title'. Return None if not there"""
try: return self._kb[non_std_title]
except KeyError: return None
class PreprintClassificationItem:
def __init__(self, srch = '', repl = ''):
self._srchStr, self._rpStr = srch, repl
def setSearchString(self, sstr): self._srchStr = sstr
def setReplString(self, repstr): self._rpStr = repstr
def getSearchString(self): return self._srchStr
def getReplString(self): return self._rpStr
def getLength(self): return len(self._srchStr)
r_str = property(fget = getReplString, fset = setReplString)
s_str = property(fget = getSearchString, fset = setSearchString)
length = property(fget = getLength)
del setSearchString, setReplString, getSearchString, getReplString
del getLength
class Institute:
def __init__(self, nm):
self._name = nm
self._preprintCatsList = []
self._numerationList = []
self._numerationRegex = ""
self._preprintCatPatternsList = {}
def setName(self, nm): self._name = nm
def getName(self): return self._name
def display(self):
print u"----------------------"
print u"Name: " + self._name.encode("utf-8")
print u"Preprint Categories:"
for x in self._preprintCatsList: print u"Search:", x.s_str.encode("utf-8"), u"Replace With:", x.r_str.encode("utf-8")
print u"Numeration Styles List:"
for x in self._numerationList: print x
print u"Numeration Styles Regular expression List:"
print self._numerationRegex
print u"----------------------"
def _getPatternLenList(self):
"""Make a copy of the list of numeration patterns for an Institute object. Return this new list"""
nl = []
ccp = re.compile(unicode(r'\[[^\]]+\]'),re.UNICODE)
for x in self._numerationList:
# Remove the character class & append to newList
nx = ccp.sub(u'1', x)
nl.append((len(nx),x))
return nl
def _createPattern(self, ptn):
"""Accept a user-defined search pattern, transform it, according to some simple rules, into a regex pattern, then compile and return it as a compiled RE object
\ -> \\
9 -> \d
a -> [A-Za-z]
mm -> (0[1-9]|1[0-2])
yy -> \d{2}
yyyy -> [12]\d{3}
/ -> \/
"""
# Make the search/replace patterns:
s_r = []
s_r.append((re.compile(unicode(r'([^\]A-Za-z0-9\/\[ "])'),re.UNICODE), unicode(r'\\\g<1>')))
s_r.append((re.compile(u'9',re.UNICODE), unicode(r'\d')))
s_r.append((re.compile(u'a',re.UNICODE), unicode(r'[A-Za-z]')))
s_r.append((re.compile(u'mm',re.UNICODE), unicode(r'(0[1-9]|1[0-2])')))
s_r.append((re.compile(u'yyyy',re.UNICODE), unicode(r'[12]\d\d\d')))
s_r.append((re.compile(u'yy',re.UNICODE), unicode(r'\d\d')))
s_r.append((re.compile(unicode(r'\/'),re.UNICODE), unicode(r'\/')))
s_r.append((re.compile(unicode(r'\"([^"]+)\"'),re.UNICODE), unicode(r'\g<1>')))
s_r.append((re.compile(unicode(r' \[([^\]]+) \]'),re.UNICODE), unicode(r'( [\g<1>])?')))
for x in s_r:
ptn = x[0].sub(x[1], ptn)
return ptn
def _makeOrderedPtns(self, ptns):
"""Using the list ordered by lengths, produce a list of ordered regex patterns"""
p_list = u""
if len(ptns) > 0:
p_list = u"(?P<numn>"
for i in ptns: p_list += self._createPattern(i[1]) + u"|"
p_list = p_list[0:len(p_list)-1]
p_list += u")"
return p_list
def assignNumerationRegex(self):
"""Build the regex patterns for this institute's numeration styles"""
def _my_cmpfunc(a,b):
if a[0] < b[0]: return 1
elif a[0] == b[0]: return 0
else: return -1
# Remove user-defined character classes:
lenPtns = self._getPatternLenList()
lenPtns.sort(_my_cmpfunc)
# Set own list of regex patterns:
self._numerationRegex = self._makeOrderedPtns(lenPtns)
##
def _makeOrderedPtnsList(self, ptns):
p_list = []
if len(ptns) > 0:
for p in ptns:
p_itm = u"(?P<numn>"+self._createPattern(p[1])+u")"
p_list.append(p_itm)
return p_list
def assignNumerationRegexList(self):
"""Build the regex patterns for this institute's numeration styles"""
def _my_cmpfunc(a,b):
if a[0] < b[0]: return 1
elif a[0] == b[0]: return 0
else: return -1
# Remove user-defined character classes:
lenPtns = self._getPatternLenList()
lenPtns.sort(_my_cmpfunc)
# Set own list of regex patterns:
self._numerationRegexList = self._makeOrderedPtnsList(lenPtns)
def createTestPatternsList(self):
def _my_cmpfunc(a,b):
if a.length < b.length: return 1
elif a.length == b.length: return 0
else: return -1
self.assignNumerationRegexList()
self._preprintCatsList.sort(_my_cmpfunc)
preprintCatPatternsList = {}
for categ in self._preprintCatsList:
categptnslist = []
for num_ptn in self._numerationRegexList:
categptnslist.append(re.compile(unicode(r'\b((?P<categ>') + categ.s_str + u')' + num_ptn + r')',re.UNICODE))
preprintCatPatternsList[categ] = categptnslist
self._preprintCatPatternsList = preprintCatPatternsList
def matchCategs2(self, ln):
"""Accept a line. Try to find matches for each of the preprint categories of this institute within that line"""
def _my_cmpfunc(a,b):
if a.length < b.length: return 1
elif a.length == b.length: return 0
else: return -1
inst_full_len = {}
inst_RN_rep_str = {}
self._preprintCatsList.sort(_my_cmpfunc)
for categ in self._preprintCatsList:
for ptn in self._preprintCatPatternsList[categ]:
# Search for this categ in line:
matches_iter = ptn.finditer(ln)
for x in matches_iter:
# Get hyphenated numeration segment of category:
numnMatch = x.group('numn')
numnMatch = re.sub(r'\s', '-', numnMatch)
# Replace found categ in string with lowercase version:
foundCateg = x.group('categ')
foundCateg = foundCateg.lower()
ln = ln[0:x.start()] + foundCateg + ln[x.end('categ'):]
inst_full_len[x.start()] = len(x.group(0))
inst_RN_rep_str[x.start()] = categ.r_str + numnMatch
return (inst_full_len, inst_RN_rep_str, ln)
##
def matchCategs(self, ln):
"""Accept a line. Try to find matches for each of the preprint categories of this institute within that line"""
def _my_cmpfunc(a,b):
if a.length < b.length: return 1
elif a.length == b.length: return 0
else: return -1
inst_full_len = {}
inst_RN_rep_str = {}
self._preprintCatsList.sort(_my_cmpfunc)
for categ in self._preprintCatsList:
# Search for this categ in line:
# Make the regex:
my_ptn = re.compile(unicode(r'\b((?P<categ>') + categ.s_str + u')' + self._numerationRegex + r')',re.UNICODE)
# Perform the search:
matches_iter = my_ptn.finditer(ln)
# For each match, record its position, etc and replace it with lower-case version
for x in matches_iter:
# Get hyphenated numeration segment of category:
numnMatch = x.group('numn')
numnMatch = re.sub(r'\s', '-', numnMatch)
# Replace found categ in string with lowercase version:
foundCateg = x.group('categ')
foundCateg = foundCateg.lower()
ln = ln[0:x.start()] + foundCateg + ln[x.end('categ'):]
inst_full_len[x.start()] = len(x.group(0))
inst_RN_rep_str[x.start()] = categ.r_str + numnMatch
return (inst_full_len, inst_RN_rep_str, ln)
def addCategory(self, k, v): self._preprintCatsList.append(PreprintClassificationItem(k,v))
def addNumerationStyle(self, num): self._numerationList.append(num)
name = property(fget = getName, fset = setName)
del setName, getName
class InstituteList:
def __init__(self, fn = ''):
self._iList = self._getInstituteList(fn)
self._buildInstNumtnRegexs()
def _buildInstNumtnRegexs(self):
for i in self._iList: i.createTestPatternsList()
def display(self):
for x in self._iList: x.display()
def _getInstituteList(self, fn):
"""Read the list of institutes in from the file and return an institute list. Terminates execution if cant read the file"""
try:
fh = open(fn, 'r')
iList = []
p_instName = re.compile(unicode(r'^\#{5}\s*(.+)\s*\#{5}$'),re.UNICODE)
p_prepClass = re.compile(unicode(r'^\s*(\w.*?)\s*---\s*(\w.*?)\s*$'),re.UNICODE)
p_numtn = re.compile(unicode(r'^\<(.+)\>$'),re.UNICODE)
for x in fh:
y = x.decode("utf-8")
m_instName = p_instName.search(y)
m_prepClass = p_prepClass.search(y)
m_numtn = p_numtn.search(y)
if m_instName is not None:
curInst = Institute(m_instName.group(1))
iList.append(curInst)
elif m_prepClass is not None:
try: curInst.addCategory(m_prepClass.group(1), m_prepClass.group(2))
except AttributeError, NameError: pass
elif m_numtn is not None:
try: curInst.addNumerationStyle(m_numtn.group(1))
except AttributeError, NameError: pass
fh.close()
return iList
except IOError:
import sys
sys.exit('E: Cannot Open Institutes File "%s".' % fn)
def identifyPreprintReferences(self, ln):
"""Accept a line of text (String) and search it against the institutes records held in order to identify references to an institutes preprints"""
foundMatch = False
identified_pp_len = {}
identified_pp_repStr = {}
for inst in self._iList:
#(tmp_id_lens, tmp_id_repStrs, ln) = inst.matchCategs(ln)
(tmp_id_lens, tmp_id_repStrs, ln) = inst.matchCategs2(ln)
identified_pp_len.update(tmp_id_lens)
identified_pp_repStr.update(tmp_id_repStrs)
if len(identified_pp_len) > 0: foundMatch = True
return (identified_pp_len, identified_pp_repStr, ln, foundMatch)
class LineIBIDidentifier:
"""Class to identify and record information about IBID ocurrences in a text line"""
def __init__(self):
"""Initialise regex pattern used to identify an IBID item"""
self._p_ibid = re.compile(unicode(r'(-|\b)(IBID\.?( ([A-H]|(I{1,3}V?|VI{0,3})|[1-3]))?)\s?:'),re.UNICODE)
self._pIbidPresent = re.compile(unicode(r'IBID\.?\s?([A-H]|(I{1,3}V?|VI{0,3})|[1-3])?'),re.UNICODE)
def lineHasIbid(self, ln):
m_ibidPresent = self._pIbidPresent.search(ln)
if m_ibidPresent is not None: return True
else: return False
def getIbidSeriesLetter(self, ln):
m_ibid = self._pIbidPresent.search(ln)
try: series_letter = m_ibid.group(1)
except IndexError: series_letter = u""
if series_letter is None: series_letter = u""
return series_letter
def identify_record_ibids(self, ln):
"""Identify the IBIDs in "line". Record their information (index position in line, match length, and matched text. When identified, the word IBID
is replaced with a lower-case version of itself Finally, the line is returned with all IBIDs identified, along with a lists of the identified
IBID text and length. These 3 items are returned in a tuple.
"""
ibid_match_len = {}
ibid_match_txt = {}
matches_iter = self._p_ibid.finditer(ln)
# Record dets of each match:
for m in matches_iter:
# Record match info
ibid_match_len[m.start()] = len(m.group(2))
ibid_match_txt[m.start()] = m.group(2)
# Replace matched txt in line with
# Lowercase version
rep_str = m.group(2)
rep_str = rep_str.lower()
ln = ln[0:m.start(2)] + rep_str + ln[m.end(2):]
return (ibid_match_len, ibid_match_txt, ln)
class URLidentifier:
"""Identify, record information about, and remove URLs from a line"""
def __init__(self):
"""Initialise url recognition patterns"""
self._urlstr = unicode(r'((https?|s?ftp):\/\/([\w\d\_\.\-])+(\/([\w\d\_\.\-])+)*(\/([\w\d\_\-]+\.\w{1,6})?)?)')
self._p_rawURL = re.compile(self._urlstr,re.UNICODE|re.I)
self._p_taggedURL = re.compile(unicode(r'(\<a\s+href\s*=\s*([\'"])?(((https?|s?ftp):\/\/)?([\w\d\_\.\-])+(\/([\w\d\_\.\-])+)*(\/([\w\d\_\-]+\.\w{1,6})?)?)([\'"])?\>([^\<]+)\<\/a\>)'),re.UNICODE|re.I)
def removeURLs(self, ln):
# Find URLS in tags:
urlfound = False
found_urlmatch_fulllen = {}
found_urlstr = {}
found_urldescstr = {}
# Record and remove tagged URLs found in line
m_taggedURL_iter = self._p_taggedURL.finditer(ln)
for m in m_taggedURL_iter:
urlfound = True
startpos = m.start()
endpos = m.end()
matchlen = len(m.group())
found_urlmatch_fulllen[startpos] = matchlen
found_urlstr[startpos] = m.group(3)
found_urldescstr[startpos] = m.group(12)
ln = ln[0:startpos] + u"_"*matchlen + ln[endpos:]
# Record and remove raw URLs found in line:
m_rawURL_iter = self._p_rawURL.finditer(ln)
for m in m_rawURL_iter:
urlfound = True
startpos = m.start()
endpos = m.end()
matchlen = len(m.group())
found_urlmatch_fulllen[startpos] = matchlen
found_urlstr[startpos] = m.group(1)
found_urldescstr[startpos] = m.group(1)
ln = ln[0:startpos] + u"_"*matchlen + ln[endpos:]
return (found_urlmatch_fulllen, found_urlstr, found_urldescstr, urlfound, ln)
class ProcessedReferenceLineBuilder:
"""Create a "ProcessedReferenceLine" from a reference line and information about where any matched items are"""
def __init__(self, titles_list, ibid_identifier, numeration_processor, line_cleaner):
self._titleslist = titles_list
self._ibidIdentifier = ibid_identifier
self._numerationprocessor = numeration_processor
self._linecleaner = line_cleaner
self._p_lineMarker = RefLineNumerationListCompiler().getCompiledPatternList()
self._searcher = LineSearcher()
self._p_tagFinder = re.compile(unicode(r'(\<cds\.(TITLE|VOL|YR|PG|RN|SER|URI value="[^\>]+")\>)'),re.UNICODE)
self._p_leadRubbishRemover = re.compile(unicode(r'^([\.,;:-]+|\s+)+'),re.UNICODE)
self._p_getNumatn = re.compile(unicode(r'^(\s*.?,?\s*:\s\<cds\.VOL\>(\d+)\<\/cds\.VOL> \<cds\.YR\>\(([1-2]\d\d\d)\)\<\/cds\.YR\> \<cds\.PG\>([RL]?\d+[c]?)\<\/cds\.PG\>)'),re.UNICODE)
def _buildProcessedLine(self,ln,rawline):
"""Given a potentially marked up reference line, build and return a "ProcessedReferenceLine" object"""
processedLine = ProcessedReferenceLine()
linebckp = ln
ln = string.lstrip(ln)
# Trim line marker from start of line if possible & add it as a line segment
m_lineMarker = self._searcher.findAtStartLine(ln, self._p_lineMarker)
if m_lineMarker is not None:
processedLine.addSection(LineMarker(m_lineMarker.group(u'mark')))
ln = ln[m_lineMarker.end():]
else:
processedLine.addSection(LineMarker(u" "))
m_tag = self._p_tagFinder.search(ln)
thismisc = u""
while m_tag is not None:
# Found citation markup tag in line
tagtype = m_tag.group(2)
if tagtype == u"TITLE":
# Title section
thisyr = thispg = thisvol = None
# Get text up to point of this match:
if len(self._p_leadRubbishRemover.sub(u"",ln[0:m_tag.start()])) > 0: thismisc += ln[0:m_tag.start()]
m_titletxt = re.match(unicode(r'^(%s(\<cds\.TITLE\>([^\<]+)\<\/cds\.TITLE\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thistitle = m_titletxt.group(3)
ln = ln[m_titletxt.end():]
# Remove and add volume, year and pagination tags which follow title if present
m_numatn = self._p_getNumatn.match(ln)
if m_numatn is not None:
thisvol = m_numatn.group(2)
thisyr = m_numatn.group(3)
thispg = m_numatn.group(4)
ln = ln[m_numatn.end():]
if len(thismisc) == 0: thismisc = None
processedLine.addSection(TitleCitationStandard(thistitle, thismisc, thispg, thisvol, thisyr))
thismisc = u""
else:
thismisc += u" " + thistitle
elif tagtype == u"RN":
# Preprint reference number section
# Get misc text up to point of match
if len(self._p_leadRubbishRemover.sub(u"",ln[0:m_tag.start()])) > 0: thismisc += ln[0:m_tag.start()]
m_rntxt = re.match(unicode(r'^(%s(\<cds\.RN\>([^\<]+)\<\/cds\.RN\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thisrn = m_rntxt.group(3)
ln = ln[m_rntxt.end():]
if len(thismisc) == 0: thismisc = None
processedLine.addSection(InstitutePreprintReferenceCitation(thisrn, thismisc))
thismisc = u""
elif string.find(tagtype ,u"URI") == 0:
# URL found
# Get misc text up to point of match
if len(self._p_leadRubbishRemover.sub(u"",ln[0:m_tag.start()])) > 0: thismisc += ln[0:m_tag.start()]
m_urlinfo = re.match(unicode(r'^(%s(\<cds\.URI value\=\"([^\>]+)\"\>([^\<]+)\<\/cds\.URI\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thisurl = m_urlinfo.group(3)
thisurldescr = m_urlinfo.group(4)
if len(thisurldescr) == 0: thisurldescr = thisurl
if len(thismisc) == 0: thismisc = None
processedLine.addSection(URLCitation(thisurl, thisurldescr, thismisc))
thismisc = u""
ln = ln[m_urlinfo.end():]
elif tagtype == u"VOL":
# Volume info - it wasnt found after a title, so treat as misc
thismisc += ln[0:m_tag.start()]
m_voltxt = re.match(unicode(r'^(%s(\<cds\.VOL\>(\d+)\<\/cds\.VOL\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thismisc += m_voltxt.group(3)
ln = ln[m_voltxt.end():]
elif tagtype == u"YR":
# Year info - discard as misc since not found after title info
thismisc += ln[0:m_tag.start()]
m_yrtxt = re.match(unicode(r'^(%s(\<cds\.YR\>(\([1-2]\d\d\d\))\<\/cds\.YR\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thismisc += m_yrtxt.group(3)
ln = ln[m_yrtxt.end():]
elif tagtype == u"PG":
# Pagination info - discard since not found after title info
thismisc += ln[0:m_tag.start()]
m_pgtxt = re.match(unicode(r'^(%s(\<cds\.PG\>([RL]?\d+[c]?)\<\/cds\.PG\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thismisc += m_pgtxt.group(3)
ln = ln[m_pgtxt.end():]
elif tagtype == u"SER":
# Series info - discard since not after title info (should have been caught earlier infact)
thismisc += ln[0:m_tag.start()]
m_sertxt = re.match(unicode(r'^(%s(\<cds\.SER\>([A-H]|(I{1,3}V?|VI{0,3}))\<\/cds\.SER\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thismisc += m_sertxt.group(3)
ln = ln[m_sertxt.end():]
else:
# Unknown tag (never happen) - discard as misc
thismisc += ln[0:m_tag.start()]
m_uknowntag = re.match(unicode(r'^(%s(\<cds\.[^\>]+?\>([^\<]+?)\<\/cds\.[^\>]+?\>))'%(re.escape(ln[0:m_tag.start()]),)),ln,re.UNICODE)
thismisc += m_uknowntag.group(3)
ln = ln[m_uknowntag.end():]
m_tag = self._p_tagFinder.search(ln)
if processedLine.getNumberCitations() == 0 and cfg_refextract_no_citation_treatment == 0:
# No Citations were found and strict mode in use demanding that when no citations are found the entire ORIGINAL, UNTOUCHED line be marked up into misc
processedLine = ProcessedReferenceLine()
untouchedline = string.lstrip(rawline)
m_lineMarker = self._searcher.findAtStartLine(untouchedline, self._p_lineMarker)
if m_lineMarker is not None:
processedLine.addSection(LineMarker(m_lineMarker.group(u'mark')))
untouchedline = untouchedline[m_lineMarker.end():]
else:
processedLine.addSection(LineMarker(u" "))
if len(self._p_leadRubbishRemover.sub(u"",untouchedline)) > 0:
processedLine.addSection(LineMiscellaneousText(untouchedline))
else:
thismisc += ln
if len(self._p_leadRubbishRemover.sub(u"",thismisc)) > 0:
processedLine.addSection(LineMiscellaneousText(thismisc))
return processedLine
def getProcessedReferenceLine(self, titlematch_len, titlematch_str, pprintmatch_str, pprintmatch_len, urlmatchfull_len, urlmatch_str, url_desc_str,\
removed_spaces, rawline, original_line, working_line, foundCitations):
marked_line = u"" # line after titles etc have been recognised & marked up with "<cds.TITLE/>" etc tags
if not foundCitations:
marked_line = original_line
else:
# Rebuild line with citations marked up and standardised:
start_pos = 0 # First cell of the reference line...
last_match = u""
extras = 0 # Variable to count the extra spaces to add
series_letter = u""
replacement_types = {}
url_keys = urlmatch_str.keys()
url_keys.sort()
title_keys = titlematch_str.keys()
title_keys.sort()
pp_keys = pprintmatch_str.keys()
pp_keys.sort()
spaces_keys = removed_spaces.keys()
spaces_keys.sort()
# First, adjust the index replacement values of the URI replacements as they were made before the multispaces etc were
# stripped & other replacements made after this could therefore have the same replacement indeces
uri_virtual_locations = self._getVirtualUrlPositions(url_keys, spaces_keys, removed_spaces)
# Make dictionary containing the types of replacements to be made at each position:
rep_types = self._getReplacementTypes(uri_virtual_locations,title_keys,pp_keys)
rep_types_keys = rep_types.keys()
rep_types_keys.sort()
# Begin the rebuild:
for repidx in rep_types_keys:
true_repidx = repidx
spare_repidx = repidx
extras = 0
# Account for any spaces stripped before these values:
(true_repidx,spare_repidx,extras) =\
self._addExtraStrippedSpaces(spaces_keys,removed_spaces,rep_types,pprintmatch_len,titlematch_len,true_repidx,spare_repidx,repidx,extras)
if rep_types[repidx] == u"TITLE":
# Process addition of text into line for title:
(marked_line,start_pos,last_match) = self._addLineTitle(titlematch_str,titlematch_len,original_line,marked_line,start_pos,repidx,true_repidx,extras,last_match)
elif rep_types[repidx] == u"RN":
# Process addition of text into line for preprint reference:
(marked_line,start_pos) = self._replaceLineItemPreprintRef(pprintmatch_str,pprintmatch_len,original_line,marked_line,start_pos,repidx,true_repidx,extras)
elif rep_types[repidx] == u"URI":
# Process addition of text into line for URL:
(marked_line,start_pos) = self._addLineURI(urlmatch_str,url_desc_str,urlmatchfull_len,uri_virtual_locations,original_line,marked_line,start_pos,repidx,true_repidx)
marked_line = marked_line + original_line[start_pos:]
marked_line = self._numerationprocessor.restandardise(marked_line)
marked_line = self._numerationprocessor.removeSeriesTags(marked_line) # Remove any "Series tags"
marked_line = self._linecleaner.clean(marked_line)
return self._buildProcessedLine(marked_line,rawline)
def _replaceIbid(self,series_letter,last_match,rebuiltLine,ibid_str):
"""Replace an IBID occurrence in a line with the "last matched" title in the line. Also take into account a new series letter governed by the ibid"""
if series_letter != u"":
# IBID to replace has a series letter, so if the last matched title had a series letter, this must be changed to the new series letter
if string.find(last_match,",") != -1:
# Presence of comma signifies possible series information. Only replace if it is a single item (e.g. "A")
m_lastMatch = re.search(unicode(r'\, +([A-H]|(I{1,3}V?|VI{0,3}))$'),last_match,re.UNICODE)
if m_lastMatch is not None:
temp_series = m_lastMatch.group(1)
if temp_series == series_letter:
rebuiltLine = rebuiltLine + u" <cds.TITLE>" + last_match + u"</cds.TITLE>"
else:
last_match = re.sub(u"(\\.?)(,?) %s$"%(temp_series,),u"\\g<1>\\g<2> %s"%(series_letter,),last_match)
rebuiltLine = rebuiltLine + u" <cds.TITLE>" + last_match + u"</cds.TITLE>"
else:
# Series info of last match not letter or roman numeral: cannot be sure about meaning of IBID - dont replace it
rebuiltLine = rebuiltLine + ibid_str
else:
# Match had no series letter but IBID did. Add comma followed by IBID series letter to last match, then add it
last_match = string.rstrip(last_match)
if last_match[-1] == u".":
last_match = last_match + u", " + series_letter
else:
# Last match end with space - replace all spaces at end
last_match = last_match + u"., " + series_letter
rebuiltLine = rebuiltLine + u" <cds.TITLE>" + last_match + u"</cds.TITLE>"
else:
# IBID has no series letter. Replace as-is:
rebuiltLine = rebuiltLine + u" <cds.TITLE>" + last_match + u"</cds.TITLE>"
return (rebuiltLine,last_match)
def _addLineTitle(self,titlematch_str,titlematch_len,orig_line,rebuiltLine,start_pos,repidx,true_repidx,extras,last_match):
rebuiltLine=rebuiltLine+orig_line[start_pos:true_repidx]
series_letter = u""
#if self._ibidIdentifier.lineHasIbid(titlematch_str[repidx]):
if titlematch_str[repidx].upper().find(u"IBID") != -1:
# Replace IBID item
# Get series letter
series_letter = self._ibidIdentifier.getIbidSeriesLetter(titlematch_str[repidx])
if last_match != "":
# Replacement has already been made in this line. IBID can therefore be replaced
(rebuiltLine,last_match) = self._replaceIbid(series_letter, last_match, rebuiltLine, titlematch_str[repidx])
start_pos=true_repidx+titlematch_len[repidx]+extras
if orig_line[start_pos] == u"." or orig_line[start_pos] == u":" or\
orig_line[start_pos] == u";":
# Skip past ".:;" which may have followed an IBID:
start_pos=start_pos+1
else:
# No replacements made in this line before this IBID (its a line with an IBID and
# we dont know what the IBID refers to..ignore it
rebuiltLine = rebuiltLine + orig_line[true_repidx:true_repidx + titlematch_len[repidx] + extras]
start_pos=true_repidx+titlematch_len[repidx]+extras
else:
# Normal title replacement - not an IBID
# Skip past any "[" or "(" chars
rebuiltLine = rebuiltLine + u"<cds.TITLE>" + self._titleslist[titlematch_str[repidx]] + u"</cds.TITLE>"
last_match = self._titleslist[titlematch_str[repidx]]
start_pos = true_repidx+titlematch_len[repidx]+extras
if orig_line[start_pos] == u"." or orig_line[start_pos] == u":" or\
orig_line[start_pos] == u";":
# Skip past punctuation at end of title
start_pos = start_pos + 1
return (rebuiltLine,start_pos,last_match)
def _replaceLineItemPreprintRef(self,pprintmatch_str,pprintmatch_len,orig_line,rebuiltLine,start_pos,repidx,true_repidx,extras):
"""Replace a Preprint reference item in the line with a marked-up, standardised version of itself"""
# Often pprint refs are enclosed in "[]" chars which we dont want. Stop 1 char before this if possible:
if (true_repidx - start_pos - 1) >= 0:
rebuiltLine = rebuiltLine + orig_line[start_pos:true_repidx - 1]
else:
rebuiltLine = rebuiltLine + orig_line[start_pos:true_repidx]
# Is next char a "[" or "("? Skip past it if yes:
if orig_line[true_repidx] == u"[" or \
orig_line[true_repidx] == u"(":
rebuiltLine = rebuiltLine + u" - "
else:
rebuiltLine = rebuiltLine + orig_line[true_repidx-1]
rebuiltLine = rebuiltLine + u"<cds.RN>" + pprintmatch_str[repidx] + u"</cds.RN>"
start_pos = true_repidx + pprintmatch_len[repidx] + extras
try:
if orig_line[start_pos] == u"]" or orig_line[start_pos] == u")":
# Skip past preprint ref no closing brace
start_pos = start_pos + 1
except IndexError:
# Went past end of line. Ignore.
pass
return (rebuiltLine, start_pos)
def _addLineURI(self,urlmatch_str,urldesc_str,urlmatchfull_len,uri_virtual_locations,orig_line,rebuiltLine,start_pos,repidx,true_repidx):
rebuiltLine = rebuiltLine + orig_line[start_pos:start_pos + true_repidx - start_pos]
rebuiltLine = rebuiltLine + u"<cds.URI value=\"" + urlmatch_str[uri_virtual_locations[repidx]] + u"\">" + urldesc_str[uri_virtual_locations[repidx]] + u"</cds.URI>"
start_pos = true_repidx + urlmatchfull_len[uri_virtual_locations[repidx]]
return (rebuiltLine, start_pos)
def _addExtraStrippedSpaces(self, spacesKeys, removed_spaces, rep_types, pprintmatch_len, titlematch_len, true_repidx, spare_repidx, repidx, extras):
"""For a replacement index position, calculate a new (correct) replacement index, based on any spaces that have been removed before it, according to the type of the replacement"""
for strip_space in spacesKeys:
if strip_space < true_repidx:
# Spaces were removed before this replacement item should be placed. Add number of spaces removed to current replacement idx:
true_repidx = true_repidx + removed_spaces[strip_space]
spare_repidx = spare_repidx + removed_spaces[strip_space]
elif (strip_space >= spare_repidx) and (rep_types[repidx] == u"TITLE") and\
(strip_space < (spare_repidx + titlematch_len[repidx])):
# Replacing a periodical title. Account for double spaces that may have been removed
# from the title before it was recognised.
spare_repidx = spare_repidx + removed_spaces[strip_space]
extras = extras + removed_spaces[strip_space]
elif (strip_space >= spare_repidx) and (rep_types[repidx] == u"RN") and\
(strip_space < (spare_repidx + pprintmatch_len[repidx])):
# Replacing an institute preprint reference. Spaces would have been removed from this
# pprint reference itself, and must therefore be added
spare_repidx = spare_repidx + removed_spaces[strip_space]
extras = extras + removed_spaces[strip_space]
return (true_repidx, spare_repidx, extras)
def _getReplacementTypes(self,urls,titles,preprints):
"""Make dictionary detailing the type of replacement made at each position"""
rep_types = {}
for idx in urls:
rep_types[idx] = u"URI"
for idx in titles:
rep_types[idx] = u"TITLE"
for idx in preprints:
rep_types[idx] = u"RN"
return rep_types
def _getVirtualUrlPositions(self, url_keys, spaces_keys, removed_spaces):
"""URLs were removed before punctuation and multiple spaces were recorded and stripped. This method makes a dictionary of
URL positions as-if the URLs had been identified/removed after the punctuation/spaces
"""
uri_virtual_locations = {}
for idx in url_keys:
virtual_pos = idx
for spcidx in spaces_keys:
if spcidx < idx:
# Spaces were removed before this URL. Account for this.
virtual_pos = virtual_pos - removed_spaces[spcidx]
# All spaces removed before this URL accounted for - add it to the dictionary
uri_virtual_locations[virtual_pos] = idx
return uri_virtual_locations
class ReferenceSectionMarkupProcessor:
"""Process a reference section. Line will be cleaned, and cited items will be identified and their notation standardised. ProcessedReferenceLine will be returned"""
def __init__(self, institutes, titles):
self._instlist = institutes
self._titleslist = titles
self._ibidIdentifier = LineIBIDidentifier()
self._numerationIdentifier = NumerationHandler()
self._lineCleaner = LineCleaner()
self._lineBuilder = ProcessedReferenceLineBuilder(self._titleslist, self._ibidIdentifier, self._numerationIdentifier, self._lineCleaner)
self._accentTransformer = EscapeSequenceTransformer()
self._punctuationStripper = PunctuationStripper()
self._multispaceRemover = MultispaceRemover()
self._urlRemover = URLidentifier()
def getProcessedReferenceSection(self, refSect):
"""Take a ReferenceSection as argument. For each line, process it"""
processedRefSection = ProcessedReferenceSection()
for line in refSect:
citationMatch=False
found_ibids_len = {}
found_ibids_matchtxt = {}
found_title_len = {}
found_title_txt = {}
tmpLine = line.getContent() # Got line as unicode string
# Remove and record details of URLs
#(found_urlmatch_fulllen, found_urlstr, found_urldescstr, foundItem, tmpLine) = self._urlRemover.removeURLs(tmpLine)
found_urlmatch_fulllen = {}
found_urlstr = {}
found_urldescstr = {}
foundItem = False
if foundItem: citationMatch=True
# Preliminary line cleaning: transform bad accents, clean punctuation & remove dbl-spaces
tmpLine = self._accentTransformer.processLine(tmpLine)
tmpLine = self._lineCleaner.clean(tmpLine)
# Standardise numeration:
tmpLine = self._numerationIdentifier.standardise(tmpLine)
tmpLine = self._lineCleaner.clean(tmpLine)
# ---> Standardise the titles:
tmpLine2 = string.upper(tmpLine) # uppercase the line
tmpLine2 = self._punctuationStripper.strip(tmpLine2) # Strip punctuation
(removedSpaces,tmpLine2) = self._multispaceRemover.recordRemove(tmpLine2) # remove multispace & record their positions
(found_pp_len, found_pp_rep_str, tmpLine2, foundItem) = self._instlist.identifyPreprintReferences(tmpLine2)
if foundItem: citationMatch=True
# find_nonstandard_titles
(found_title_len,found_title_txt,tmpLine2,foundItem) = self._titleslist.findPeriodicalTitles(tmpLine2)
if foundItem: citationMatch=True
# If there is an IBID in the line, do a 2nd pass to try to catch it & identify its meaning
if tmpLine2.upper().find(u"IBID") != -1:
# Record/remove IBID(s) in line
(found_ibids_len,found_ibids_matchtxt,tmpLine2) = self._ibidIdentifier.identify_record_ibids(tmpLine2)
# Add found ibids to title matches:
for itm in found_ibids_len.keys(): found_title_len[itm] = found_ibids_len[itm]
for itm in found_ibids_matchtxt.keys(): found_title_txt[itm] = found_ibids_matchtxt[itm]
# Create "ProcessedReferenceLine":
thisProcessedLine = self._lineBuilder.getProcessedReferenceLine(found_title_len,found_title_txt,found_pp_rep_str,found_pp_len,\
found_urlmatch_fulllen, found_urlstr, found_urldescstr,removedSpaces,line.getContent(),tmpLine,tmpLine2,citationMatch)
processedRefSection.appendLine(thisProcessedLine)
return processedRefSection
class LineItem:
def getSelfMARCXML(self):
"""Return self, as marc xml string"""
pass
class LineMarker(LineItem):
def __init__(self, val):
if type(val) is str or type(val) is unicode: self._value = val
else: self._value = u""
def getSelfMARCXML(self):
return u""" <datafield tag="999" ind1="C" ind2="5">
<subfield code="o">""" + cgi.escape(self._value)+u"""</subfield>
</datafield>\n"""
class LineMiscellaneousText(LineItem):
def __init__(self, val):
if type(val) is str or type(val) is unicode: self._value = val.strip()
else: self._value = u""
def getSelfMARCXML(self):
return u""" <datafield tag="999" ind1="C" ind2="5">
<subfield code="m">"""+cgi.escape(self._value)+u"""</subfield>
</datafield>\n"""
class Citation(LineItem):
"""Abstract - represents a citation instance. Could be used to count citations found in a line"""
pass
class TitleCitation(Citation):
def __init__(self, title, misc = None, pg = None, vol = None, yr = None):
self._title = title
if misc is not None: self._misc = misc.strip()
else: self._misc = misc
self._page = pg
self._volume = vol
self._yr = yr
def getSelfMARCXML(self):
out = u""" <datafield tag="999" ind1="C" ind2="5">\n"""
if self._misc is not None and (type(self._misc) is unicode or type(self._misc) is str):
out += u""" <subfield code="m">"""+cgi.escape(self._misc)+u"""</subfield>\n"""
out += u""" <subfield code="t">"""+cgi.escape(self._title)+u"""</subfield>\n"""
if self._page is not None and (type(self._page) is unicode or type(self._page) is str):
out += u""" <subfield code="p">"""+cgi.escape(self._page)+u"""</subfield>\n"""
if self._volume is not None and (type(self._volume) is unicode or type(self._volume) is str):
out += u""" <subfield code="v">"""+cgi.escape(self._volume)+u"""</subfield>\n"""
if self._yr is not None and (type(self._yr) is unicode or type(self._yr) is str):
out += u""" <subfield code="y">"""+cgi.escape(self._yr)+u"""</subfield>\n"""
out += u""" </datafield>\n"""
return out
class TitleCitationStandard(Citation):
"""[journal name] [volume] ([year]) [pagination]"""
def __init__(self, title, misc = None, pg = None, vol = None, yr = None):
self._title = title
if misc is not None: self._misc = misc.strip()
else: self._misc = misc
self._page = pg
self._volume = vol
self._yr = yr
def hasMisc(self):
if self._misc is not None and (type(self._misc) is unicode or type(self._misc) is str) and len(self._misc.strip("()[], {}-")) > 0 or not\
(self._title is not None and self._page is not None and self._volume is not None and self._yr is not None):
return True
else:
return False
def getS_subfield(self):
if self._title is not None and self._page is not None and self._volume is not None and self._yr is not None:
return u""" <subfield code="s">%s %s (%s) %s</subfield>\n"""%(self._title,self._volume,self._yr,self._page)
else:
return None
def getSelfMARCXML(self, xtra_subfield=None):
subfieldOpen = False
out = u""" <datafield tag="999" ind1="C" ind2="5">\n"""
if self._misc is not None and (type(self._misc) is unicode or type(self._misc) is str):
out += u""" <subfield code="m">"""+cgi.escape(self._misc)
subfieldOpen=True
if self._title is not None and self._page is not None and self._volume is not None and self._yr is not None:
if subfieldOpen:
out += u"""</subfield>\n"""
subfieldOpen=False
out += u""" <subfield code="s">%s %s (%s) %s</subfield>\n"""%(self._title,self._volume,self._yr,self._page)
else:
if not subfieldOpen:
out += u""" <subfield code="m">"""
subfieldOpen = True
if self._title is not None: out += u" %s"%(self._title,)
if self._title is not None: out += u" %s"%(self._volume,)
if self._title is not None: out += u" (%s)"%(self._yr,)
if self._title is not None: out += u" %s"%(self._page,)
if subfieldOpen:
out += u"""</subfield>\n"""
subfieldOpen=False
if xtra_subfield is not None:
out += xtra_subfield
out += u""" </datafield>\n"""
return out
class InstitutePreprintReferenceCitation(Citation):
def __init__(self, rn, misc = None):
self._rn = rn
if misc is not None and len(misc.strip("()[], {}-")) > 0: self._misc = misc.strip()
else: self._misc = None
def hasMisc(self):
if self._misc is not None and (type(self._misc) is unicode or type(self._misc) is str) and len(self._misc.strip()) > 0:
return True
else:
return False
def getRN_subfield(self):
return u""" <subfield code="r">"""+cgi.escape(self._rn)+u"""</subfield>\n"""
def getSelfMARCXML(self, xtra_subfield=None):
out = u""" <datafield tag="999" ind1="C" ind2="5">\n"""
if self._misc is not None and (type(self._misc) is unicode or type(self._misc) is str):
out += u""" <subfield code="m">"""+cgi.escape(self._misc)+u"""</subfield>\n"""
out += u""" <subfield code="r">"""+cgi.escape(self._rn)+u"""</subfield>\n"""
if xtra_subfield is not None:
out += xtra_subfield
out += u""" </datafield>\n"""
return out
class URLCitation(Citation):
def __init__(self, url, urldescr, misc=None):
self._url = url
self._urldescr = urldescr
if misc is not None: self._misc = misc.strip()
else: self._misc = misc
def getSelfMARCXML(self):
out = u""" <datafield tag="999" ind1="C" ind2="5">\n"""
if self._misc is not None and (type(self._misc) is unicode or type(self._misc) is str):
out += u""" <subfield code="m">"""+cgi.escape(self._misc)+u"""</subfield>\n"""
out += u""" <subfield code="u">"""+cgi.escape(self._url)+u"""</subfield>\n"""
out += u""" <subfield code="z">"""+cgi.escape(self._urldescr)+u"""</subfield>\n"""
out += u""" </datafield>\n"""
return out
class ProcessedReferenceLine:
"""This is a reference line that has been processed for cited items"""
def __init__(self):
self._segments = {} # Segments of reference line, each keyed by start point index. Each is a 'LineItem'.
self._nextposn = 0
def getSelfMARCXML(self):
"""Return an XML string containing this lines contents, marked up in XML MARC, as used in CDS"""
i = 0
lenline = len(self._segments)
out = u""
while i < lenline:
if isinstance(self._segments[i],TitleCitationStandard) and i < lenline-1 and isinstance(self._segments[i+1],InstitutePreprintReferenceCitation) and not self._segments[i+1].hasMisc():
# This is a $s (periodical title) reference, followed immediately by its report number ($r). Concat them both under the $s.
out += self._segments[i].getSelfMARCXML(self._segments[i+1].getRN_subfield())
i = i + 1
elif isinstance(self._segments[i],InstitutePreprintReferenceCitation) and i < lenline-1 and isinstance(self._segments[i+1],TitleCitationStandard) and not self._segments[i+1].hasMisc():
# This is a report number ($r) reference followed immediately by its periodical title ($s) reference. Concat them both under $s.
out += self._segments[i].getSelfMARCXML(self._segments[i+1].getS_subfield())
i = i + 1
else:
out += self._segments[i].getSelfMARCXML()
i = i + 1
return out
def addSection(self, newSect):
if isinstance(newSect,LineItem):
self._segments[self._nextposn] = newSect
self._nextposn += 1
def getNumberCitations(self):
numcitations = 0
numsegments = len(self._segments)
for i in range(0,numsegments):
if isinstance(self._segments[i], Citation): numcitations += 1
return numcitations
class ProcessedReferenceSection:
"""This is a reference section after it has been processed to identify cited items. It contains a list of ProcessedReferenceLines."""
def __init__(self):
self._lines = {}
self._nextline = 0
def getSelfMARCXML(self):
"""Return a unicode string of all reference lines marked up in MARC XML"""
out = u""
numlines = len(self._lines)
for i in range(0,numlines): out += self._lines[i].getSelfMARCXML()
return out
def appendLine(self, ln):
"""Add a new line to the list of processed reference lines"""
if isinstance(ln, ProcessedReferenceLine):
self._lines[self._nextline] = ln
self._nextline += 1
def getTotalNumberCitations(self):
"""Return an integer representing the total number of citations recognised (and thus marked up) in the reference section"""
numcitations = 0
numlines = len(self._lines)
for i in range(0,numlines): numcitations += self._lines[i].getNumberCitations()
return numcitations
class NumerationHandler:
"""Class whose instances identify reference numeration patterns in a text line and rearrange them into standardised numeration patterns
Returns line with numeration patterns marked up in an XML style
"""
def __init__(self):
self._ptnList = []
self._checkAgainPtnList = []
self._ptn_seriesRemove = re.compile(unicode(r'((\<cds.TITLE\>)([^\<]+)(\<\/cds.TITLE\>)\s*.?\s*\<cds\.SER\>([A-H]|(I{1,3}V?|VI{0,3}))\<\/cds\.SER\>)'),re.UNICODE)
self._setSearchPatterns()
self._setRecheckPatterns()
def _setRecheckPatterns(self):
"""After the line has been rebuilt with marked up titles, it can be rechecked for numeration patterns because perhaps now more can be found with the aid of the recognised titles"""
self._checkAgainPtnList.append([re.compile(unicode(r'\(?([12]\d{3})([A-Za-z]?)\)?,? *(<cds\.TITLE>(\.|[^<])*<\/cds\.TITLE>),? *(\b[Vv]o?l?\.?)?\s?(\d+)(,\s*|\s+)[pP]?[p]?\.?\s?([RL]?\d+[c]?)\-?[RL]?\d{0,6}[c]?'),re.UNICODE),unicode('\\g<1>\\g<2>, \\g<3> \\g<6> (\\g<1>) \\g<8>')])
self._checkAgainPtnList.append([re.compile(unicode(r'\(?([12]\d{3})([A-Za-z]?)\)?,? *(<cds\.TITLE>(\.|[^<])*<\/cds\.TITLE>),? *(\b[Vv]o?l?\.?)?\s?(\d+)\s?([A-H])\s?[pP]?[p]?\.?\s?([RL]?\d+[c]?)\-?[RL]?\d{0,6}[c]?'),re.UNICODE),unicode('\\g<1>\\g<2>, \\g<3> \\g<6> \\g<7> \\g<8> (\\g<1>)')])
def _setSearchPatterns(self):
"""Populate self._ptnList with seek/replace numeration pattern pairs"""
# Delete the colon and expressions as Serie, vol, V. inside the pattern <serie : volume>
self._ptnList.append([re.compile(unicode(r'(Serie\s|\bS\.?\s)?([A-H])\s?[:,]\s?(\b[Vv]o?l?\.?)?\s?(\d+)'),re.UNICODE),unicode('\\g<2> \\g<4>')])
# Use 4 different patterns to standardise numeration as <serie(?) : volume (year) page>
# Pattern 1: <x, vol, year, page>
self._ptnList.append([re.compile(unicode(r'(\b[Vv]o?l?\.?)?\s?(\d+)\s?\(([1-2]\d\d\d)\),?\s?[pP]?[p]?\.?\s?([RL]?\d+[c]?)(?:\-|\255)?[RL]?\d{0,6}[c]?'),re.UNICODE), unicode(' : <cds.VOL>\\g<2></cds.VOL> <cds.YR>(\\g<3>)</cds.YR> <cds.PG>\\g<4></cds.PG> ')])
# Pattern 2: <vol, serie, year, page>
self._ptnList.append([re.compile(unicode(r'(\b[Vv]o?l?\.?)?\s?(\d+)\s?([A-H])\s?\(([1-2]\d\d\d)\),?\s?[pP]?[p]?\.?\s?([RL]?\d+[c]?)(?:\-|\255)?[RL]?\d{0,6}[c]?'),re.UNICODE), unicode(' <cds.SER>\\g<3></cds.SER> : <cds.VOL>\\g<2></cds.VOL> <cds.YR>(\\g<4>)</cds.YR> <cds.PG>\\g<5></cds.PG> ')])
# Pattern 3: <x, vol, page, year>
self._ptnList.append([re.compile(unicode(r'(\b[Vv]o?l?\.?)?\s?(\d+)\s?[,:]\s?[pP]?[p]?\.?\s?([RL]?\d+[c]?)(?:\-|\255)?[RL]?\d{0,6}[c]?,?\s?\(?([1-2]\d\d\d)\)?'),re.UNICODE), unicode(' : <cds.VOL>\\g<2></cds.VOL> <cds.YR>(\\g<4>)</cds.YR> <cds.PG>\\g<3></cds.PG> ')])
# Pattern 4: <vol, serie, page, year>
self._ptnList.append([re.compile(unicode(r'(\b[Vv]o?l?\.?)?\s?(\d+)\s?([A-H])[,:\s]\s?[pP]?[p]?\.?\s?([RL]?\d+[c]?)(?:\-|\255)?[RL]?\d{0,6}[c]?,?\s?\(([1-2]\d\d\d)\)'),re.UNICODE), unicode(' <cds.SER>\\g<3></cds.SER> : <cds.VOL>\\g<2></cds.VOL> <cds.YR>(\\g<5>)</cds.YR> <cds.PG>\\g<4></cds.PG> ')])
def removeSeriesTags(self, ln):
"""Remove any "<cds.SER/>" tags from a line. Series information should be part of a title, not separate"""
m_seriesTagLine = self._ptn_seriesRemove.search(ln)
while m_seriesTagLine is not None:
whole_match = m_seriesTagLine.group(0)
title_tag_opener = m_seriesTagLine.group(2)
title_text = m_seriesTagLine.group(3)
title_tag_closer = m_seriesTagLine.group(4)
series_letter = m_seriesTagLine.group(5)
real_title_text = title_text
# If there is no comma in the matched title, add one to the end of it before series info added. If there is already a comma present, simply discard the series info
if string.find(real_title_text,u",") != -1:
real_title_text = string.rstrip(real_title_text)
if real_title_text[-1] == u".":
real_title_text = real_title_text + u", " + series_letter
else:
real_title_text = real_title_text + u"., " + series_letter
ln = re.sub(u"%s"%(re.escape(whole_match),),u"%s%s%s"%(title_tag_opener,real_title_text,title_tag_closer),ln,1)
m_seriesTagLine = self._ptn_seriesRemove.search(ln)
return ln
def restandardise(self, ln):
"""Given that some more titles have been recognised within a line, reprocess that line in the hopes of recognising more numeration patterns"""
for x in self._checkAgainPtnList:
ln = x[0].sub(x[1], ln)
return self.standardise(ln)
def standardise(self, ln):
"""Accept ln (text line) as argument. Perform transformations on this line to replace non-standard numeration styles with marked-up versions in a standard format.
These recognised and marked-up numeration patterns can later be used to identify cited documents
"""
for x in self._ptnList:
ln = x[0].sub(x[1], ln)
return ln
class LineCleaner:
"""Class to enable lines to be cleaned of punctuation errors"""
def __init__(self):
self._correctionList = {}
self._setCorrectionList()
def _setCorrectionList(self):
"""Set the list of punctuation (etc) errors in a line to be corrected"""
self._correctionList[re.compile(unicode(r'\s,'),re.UNICODE)] = u','
self._correctionList[re.compile(unicode(r'\s;'),re.UNICODE)] = u';'
self._correctionList[re.compile(unicode(r'\s\.'),re.UNICODE)] = u'.'
self._correctionList[re.compile(unicode(r':\s:'),re.UNICODE)] = u':'
self._correctionList[re.compile(unicode(r',\s:'),re.UNICODE)] = u':'
self._correctionList[re.compile(unicode(r'\s\]'),re.UNICODE)] = u']'
self._correctionList[re.compile(unicode(r'\[\s'),re.UNICODE)] = u'['
self._correctionList[re.compile(unicode(r'\\255'),re.UNICODE)] = u'-' # Hyphen symbols
self._correctionList[re.compile(u'\u02D7',re.UNICODE)] = u'-'
self._correctionList[re.compile(u'\u0335',re.UNICODE)] = u'-'
self._correctionList[re.compile(u'\u0336',re.UNICODE)] = u'-'
self._correctionList[re.compile(u'\u2212',re.UNICODE)] = u'-'
self._correctionList[re.compile(u'\u002D',re.UNICODE)] = u'-'
self._correctionList[re.compile(u'\uFE63',re.UNICODE)] = u'-'
self._correctionList[re.compile(u'\uFF0D',re.UNICODE)] = u'-'
def clean(self, ln):
# Remove double spaces:
p_dblSpace = re.compile(unicode(r'\s{2,}'),re.UNICODE)
ln = p_dblSpace.sub(u' ', ln)
# Correct other bad punctuation:
for x in self._correctionList.keys():
ln = x.sub(self._correctionList[x], ln)
return ln
class PunctuationStripper:
"""Class to strip punctuation characters from a line & replace them with a space character"""
def __init__(self):
self._punct = re.compile(unicode(r'[\.\,\;\'\(\)\-]'),re.UNICODE)
self._rep = u' '
def strip(self, ln):
return self._punct.sub(self._rep, ln)
class MultispaceRemover:
"""Class to remove all ocurrences of multiple spaces from a line and replace them with a single space while recording information about their positioning"""
def __init__(self):
self._spcPtn = re.compile(unicode(r'(\s{2,})'),re.UNICODE)
def recordRemove(self, ln):
removedSpaces = {} # Records posn of removed multispace & length of truncation
fromPos = 0 # Posn in line from which to check for multispaces
# Search for multispace:
ms_matches = self._spcPtn.finditer(ln)
for m in ms_matches:
removedSpaces[m.start()] = m.end() - m.start() - 1
ln = self._spcPtn.sub(u' ', ln)
# Return a tuple of 2 items: a dictionary containing the removed multispace info,
# and the line itself after the multispaces have been converted to single spaces
return (removedSpaces, ln)
def getFileList(fname):
"""Return a list of files to be processed"""
flist = []
if os.access(fname, os.R_OK):
try:
f = open(fname, "r")
for line in f:
flist.append(line.strip())
f.close()
except IOError:
return None
return flist
else:
return None
def getRecidFilenames(args):
files = []
for x in args:
items = string.split(x, ":")
if len(items) != 2:
sys.stderr.write(u"W: Recid:filepath argument invalid. Skipping.\n")
continue
files.append((items[0],items[1]))
return files
def main():
myoptions, myargs = getopt.getopt(sys.argv[1:], "hV", ["help","version"])
for o in myoptions:
if o[0] in ("-V","--version"):
sys.stderr.write("%s\n" % (SystemMessage().getVersionMessage(),)) # Version message and stop
sys.exit(0)
elif o[0] in ("-h","--help"):
sys.stderr.write("%s\n" % (SystemMessage().getHelpMessage(),)) # Help message and stop
sys.exit(0)
if len(myargs) == 0:
sys.stderr.write("%s\n" % (SystemMessage().getHelpMessage(),)) # Help message and stop
sys.exit(0)
recidfiles = getRecidFilenames(myargs)
if len(recidfiles) == 0:
sys.stderr.write("%s\n" % (SystemMessage().getHelpMessage(),)) # Help message and stop
sys.exit(0)
converterList=[PDFtoTextDocumentConverter()] # List of document converters to use
titles_kb = KnowledgeBase(fn = cfg_refextract_kb_journal_titles)
institutes = InstituteList(fn = cfg_refextract_kb_report_numbers)
refSect_processor = ReferenceSectionMarkupProcessor(institutes, titles_kb)
openxmltag = u"""<?xml version="1.0" encoding="UTF-8"?>"""
opencollectiontag = u"""<collection xmlns="http://www.loc.gov/MARC21/slim">"""
closecollectiontag = u"""</collection>\n"""
done_coltags = False
for curitem in recidfiles:
# Perform required processing (according to stages):
if not os.access(curitem[1], os.F_OK):
# path to file invalid
sys.stderr.write("E: File Path %s invalid! Ignored.\n" % (curitem,))
continue
doc = None
if len(converterList) < 1:
sys.stderr.write("E: No document converter tools available - cannot process reference extraction.\n" % (curitem,))
sys.exit(1)
# Convert file to text:
for conv in converterList:
doc = conv.convertDocument(curitem[1])
try:
if not doc.isEmpty():
break
except AttributeError:
pass
if doc is None:
sys.stderr.write("""W: File "%s" cannot be converted to plain-text. Cannot be processed.\n""" % (curitem,))
continue
# Do "Extract References" Stage
try:
if doc.isEmpty():
sys.stderr.write("""W: File "%s" appears to be empty or cannot be read-in. Cannot be processed.\n""" % (curitem,))
continue
except AttributeError:
sys.stderr.write("""W: File "%s" appears to be empty or cannot be read-in. Cannot be processed.\n""" % (curitem,))
continue
if doc is None:
sys.stderr.write("""W: File "%s" appears to be empty or cannot be read-in. Cannot be processed.\n""" % (curitem,))
continue
refSection = doc.extractReferences()
if not done_coltags and not refSection.isEmpty():
# Output collection tags:
sys.stdout.write("%s\n" % (openxmltag.encode("utf-8"),))
sys.stdout.write("%s\n" % (opencollectiontag.encode("utf-8"),))
done_coltags = True
# Do citation title standardisation stage
processedReferenceSection = refSect_processor.getProcessedReferenceSection(refSection)
ReferenceSectionDisplayer().display(processedReferenceSection, curitem[0])
if done_coltags:
sys.stdout.write("%s\n" % (closecollectiontag.encode("utf-8"),))
diff --git a/modules/bibedit/lib/refextract_config.py b/modules/bibedit/lib/refextract_config.py
index 3958113e4..c98386101 100644
--- a/modules/bibedit/lib/refextract_config.py
+++ b/modules/bibedit/lib/refextract_config.py
@@ -1,54 +1,54 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.config import version, etcdir, pdftotext
# version number:
cfg_refextract_version = "CDSware/%s refextract/%s" % (version, version)
# periodicals knowledge base:
cfg_refextract_kb_journal_titles = "%s/bibedit/refextract-journal-titles.kb" % etcdir
# report numbers knowledge base:
cfg_refextract_kb_report_numbers = "%s/bibedit/refextract-report-numbers.kb" % etcdir
# path to pdftotext executable:
cfg_refextract_pdftotext = pdftotext
### FIXME. The following are not used in this early release. Do not change them.
# Not important in this version:
cfg_refextract_cat = "LD_LIBRARY_PATH='/opt/SUNWspro/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib'; export LD_LIBRARY_PATH; /bin/cat"
# Again, not important in this version:
cfg_refextract_gunzip = "LD_LIBRARY_PATH='/opt/SUNWspro/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib'; export LD_LIBRARY_PATH; /bin/gunzip"
# Again not important in this version:
cfg_refextract_gs = "/usr/bin/gs"
# cfg_refextract_no_citation_treatment:
# If no usable citations are found in a line, there are 2 options:
# 1) If this flag is set to 0, DO NOT use the standardised version of the line. Instead, strip off the line marker and
# mark up the original UNTOUCHED line as miscellaneous text.
# 2) If this flag is set to 1, mark up the "standardised" version of the line
# as Miscellaneous text. This could result in a better formed reference line as titles could be
# standardised and corrected, BUT, there is a risk that the line could also be corrupted by
# partial title identification for example.
cfg_refextract_no_citation_treatment = 0
diff --git a/modules/bibedit/web/Makefile.am b/modules/bibedit/web/Makefile.am
index b1171321a..52c701cf6 100644
--- a/modules/bibedit/web/Makefile.am
+++ b/modules/bibedit/web/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
\ No newline at end of file
diff --git a/modules/bibedit/web/admin/Makefile.am b/modules/bibedit/web/admin/Makefile.am
index 5b4eed473..f211df7a4 100644
--- a/modules/bibedit/web/admin/Makefile.am
+++ b/modules/bibedit/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/bibedit
webapp_DATA = bibeditadmin.py
EXTRA_DIST = bibeditadmin.py
CLEANFILES = *~ *.tmp
diff --git a/modules/bibedit/web/admin/bibeditadmin.py b/modules/bibedit/web/admin/bibeditadmin.py
index aa7afcb53..8e960c4bc 100644
--- a/modules/bibedit/web/admin/bibeditadmin.py
+++ b/modules/bibedit/web/admin/bibeditadmin.py
@@ -1,39 +1,39 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibEdit Administrator Interface."""
__lastupdated__ = """$Date$"""
from cdsware.config import cdslang
from cdsware.webpage import page
from cdsware.webuser import getUid
__version__ = "$Id$"
def index(req, ln=cdslang):
"BibEdit Admin interface."
uid = getUid(req)
return page(title="BibEdit Admin Interface",
body="TODO",
uid=uid,
language=ln,
navtrail = "FIXME",
lastupdated=__lastupdated__,
urlargs=req.args)
diff --git a/modules/bibformat/Makefile.am b/modules/bibformat/Makefile.am
index 67f12cffd..92752473c 100644
--- a/modules/bibformat/Makefile.am
+++ b/modules/bibformat/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc lib web
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/bibformat/bin/Makefile.am b/modules/bibformat/bin/Makefile.am
index 4603042c3..c6c33bde9 100644
--- a/modules/bibformat/bin/Makefile.am
+++ b/modules/bibformat/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibformat bibreformat
EXTRA_DIST = bibformat.in bibreformat.in
CLEANFILES = *~ *.tmp
diff --git a/modules/bibformat/bin/bibformat.in b/modules/bibformat/bin/bibformat.in
index 5e8aef3ea..511b7a062 100644
--- a/modules/bibformat/bin/bibformat.in
+++ b/modules/bibformat/bin/bibformat.in
@@ -1,118 +1,118 @@
#!@PHP@ -q
<?
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
$__version__ = '$Id$';
define( GLOBALCONFIG, "@prefix@/lib/php/cdsware/bibformat/common/global.inc.php");
//======================================================================
function getTime()
{
list($sec, $usec)=explode(" ", microtime());
return (float)$sec+(float)$usec;
}
//======================================================================
//======================================================================
// Main
//======================================================================
require(GLOBALCONFIG);
include_once(MAIN);
define(DEFAULT_ITYPE, "DEFAULT");
define(DEFAULT_OTYPE, "DEFAULT");
$itype=DEFAULT_ITYPE;
$otype=explode(",", DEFAULT_OTYPE);
if(count($argv)>3)
{
print "Usage:\n\tbibformat [itype=<input type>] [otype=<output type>]\n";
exit;
}
foreach($argv as $value)
{
if ($value == "-V" || $value == "--version") {
print $__version__."\n";
exit();
}
if ($value == "-h" || $value == "--help") {
print "Usage:\n\tbibformat [itype=<input type>] [otype=<output type>]\n";
exit();
}
$par=explode("=", strtoupper(trim($value)));
if(count($par)>1)
{
if($par[0]=="ITYPE")
{
if(trim($par[1])!="")
{
$itype=$par[1];
}
}
elseif($par[0]=="OTYPE")
{
if(trim($par[1])!="")
{
$otype=explode(",", $par[1]);
}
}
}
}
$fxk=new FlexElink();
$error=$fxk->initialise("OAIMARC");
$err_fh=fopen("php://stderr", "w");
if($error)
{
fputs($err_fh, "Error initialising: $error");
exit;
}
$stime=getTime();
$code=0;
$count_rec=0;
while(1)
{
list($code, $res)=$fxk->getRecordResult($otype);
if($code<0) break;
if($code==0)
{
fputs($err_fh, "--------------------------------------------------------\n");
fputs($err_fh, "Errors processing record# $count_rec\n");
fputs($err_fh, "$res\n");
fputs($err_fh, "--------------------------------------------------------\n");
continue;
}
print eval("?>$res<?");
$count_rec++;
}
$etime=getTime();
$total_time=$etime-$stime;
fputs($err_fh, "--------------------------------------------------------\n");
fputs($err_fh, "Total processed records: $count_rec\n");
fputs($err_fh, "Total time: $total_time sec\n");
fputs($err_fh, "Avg. time per record: ".$total_time/$count_rec." sec\n");
fputs($err_fh, "--------------------------------------------------------\n");
fclose($err_fh);
?>
diff --git a/modules/bibformat/bin/bibreformat.in b/modules/bibformat/bin/bibreformat.in
index 0ac8731b6..81c897c42 100644
--- a/modules/bibformat/bin/bibreformat.in
+++ b/modules/bibformat/bin/bibreformat.in
@@ -1,671 +1,671 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Call BibFormat engine and create HTML brief (and other) formats for bibliographic records.
Upload formats via BibUpload."""
__version__ = "$Id$"
## import interesting modules:
try:
import sys
pylibdir = "@prefix@/lib/python"
sys.path.append('%s' % pylibdir)
from cdsware.dbquery import run_sql
from cdsware.config import *
from cdsware.search_engine import perform_request_search
from cdsware.search_engine import print_record
from cdsware.access_control_engine import acc_authorize_action
import getopt
import getpass
import marshal
import signal
import string
import sys
import os
import re
import time
import MySQLdb
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
sql_queries = [] # holds SQL queries to be executed
cds_query = {} # holds CDS query parameters (fields, collection, pattern)
process_format = 0 # flag, process records without created format
process = 1 # flag, process records (unless count only)
fmt = "hb" # default format to be processed
sleeptime = "" # default sleeptime
format_string = "%Y-%m-%d %H:%M:%S" # date/time format
sched_time = time.strftime(format_string) # scheduled execution time in the date/time format
### run the bibreformat task bibsched scheduled
###
def bibreformat_task(sql, sql_queries, cds_query, process_format):
global process, fmt
t1 = os.times()[4]
### Query the database
###
if process_format:
print "Querying database for records with missing format ..."
without_format = without_fmt(sql)
recIDs = []
if cds_query['field'] != "" or \
cds_query['collection'] != "" or \
cds_query['pattern'] != "":
print "Querying database for records with old format (CDS query)..."
res = perform_request_search(req=None, of='id', c=cds_query['collection'], p=cds_query['pattern'], f=cds_query['field'])
for item in res:
recIDs.append(item)
for sql_query in sql_queries:
print "Querying database for records with old format (SQL query) ..."
res = run_sql(sql_query)
for item in res:
recIDs.append(item[0])
### list of corresponding record IDs was retrieved
### bibformat the records selected
if process_format:
print "Records to be processed: %d" % (len(recIDs)+len(without_format))
print "Out of it records without created format: %d" % len(without_format)
else:
print "Records to be processed: %d" % (len(recIDs))
### Initialize main loop
total_rec = 0 # Total number of records
xml_content = '' # hold the contents
tbibformat = 0 # time taken up by external call
tbibupload = 0 # time taken up by external call
### Iterate over all records prepared in lists I (option)
if process:
iterate_over(recIDs, weburl, fmt)
### Iterate over all records prepared in list II (no_format)
if process_format and process:
iterate_over(without_format, weburl, fmt)
### Final statistics
t2 = os.times()[4]
elapsed = t2 - t1
message = "total records processed: %d" % total_rec
print message
message = "total processing time: %2f sec" % elapsed
print message
message = "Time spent on external call (os.system):"
print message
message = " bibformat: %2f sec" % tbibformat
print message
message = " bibupload: %2f sec" % tbibupload
print message
### Result set operations
###
def lhdiff(l1, l2):
"Does list difference via intermediate hash."
d = {}
ld = []
for e in l2:
d[e]=1
for e in l1:
if not d.has_key(e):
ld.append(e)
return ld
### Result set operations
###
def ldiff(l1, l2):
"Returns l1 - l2."
ld = []
for e in l1:
if not e in l2:
ld.append(e)
return ld
### Identify recIDs of records with missing format
###
def without_fmt(sql):
"List of record IDs to be reformated, not having the specified format yet"
global fmt
xm1, xm2, format1, format2 = [],[],[],[]
q1 = sql['q1']
q2 = sql['q2']
## get complete recID list of xm formatted records
xm1 = run_sql(q1)
for item in xm1:
xm2.append(item[0])
## get complete recID list of formatted records
format1 = run_sql(q2)
for item in format1:
format2.append(item[0])
return lhdiff(xm2,format2)
### Bibreformat all selected records
###
def iterate_over(list, weburl, fmt):
"Iterate odver list of IDs"
n_rec = 0
n_max = 10000
total_rec = 0 # Total number of records
xml_content = '' # hold the contents
tbibformat = 0 # time taken up by external call
tbibupload = 0 # time taken up by external call
for record in list:
n_rec = n_rec + 1
total_rec = total_rec + 1
message = "Processing record: %d" % (record)
print message
query = "id=%d&of=xm" % (record)
count = 0
contents = print_record(record, 'xm')
while (contents == "") and (count < 10):
contents = print_record(record, 'xm')
count = count + 1
time.sleep(10)
if count == 10:
sys.stderr.write("Failed to download %s from %s after 10 attempts... terminating" % (query, weburl))
sys.exit(0)
xml_content = xml_content + contents
if xml_content:
if n_rec >= n_max:
finalfilename = "%s/rec_fmt_%s.xml" % (tmpdir,time.strftime('%Y%m%d_%H%M%S'))
filename = "%s/bibreformat.xml" % tmpdir
filehandle = open(filename ,"w")
filehandle.write(xml_content)
filehandle.close()
### bibformat external call
###
t11 = os.times()[4]
message = "START bibformat external call"
print message
command = "%s/bibformat otype='%s' < %s/bibreformat.xml > %s 2> %s/bibreformat.err" % (bindir,string.upper(fmt),tmpdir,finalfilename,tmpdir)
os.system(command)
t22 = os.times()[4]
message = "END bibformat external call (time elapsed:%2f)" % (t22-t11)
print message
tbibformat = tbibformat + (t22 - t11)
### bibupload external call
###
t11 = os.times()[4]
message = "START bibupload external call"
print message
command = "%s/bibupload -f %s" % (bindir,finalfilename)
os.system(command)
t22 = os.times()[4]
message = "END bibupload external call (time elapsed:%2f)" % (t22-t11)
print message
tbibupload = tbibupload + (t22- t11)
n_rec = 0
xml_content = ''
### Process the last re-formated chunk
###
if n_rec > 0:
print "Processing last record set (%d)" % n_rec
finalfilename = "%s/rec_fmt_%s.xml" % (tmpdir,time.strftime('%Y%m%d_%H%M%S'))
filename = "%s/bibreformat.xml" % tmpdir
filehandle = open(filename ,"w")
filehandle.write(xml_content)
filehandle.close()
### bibformat external call
###
t11 = os.times()[4]
message = "START bibformat external call"
print message
command = "%s/bibformat otype='%s' < %s/bibreformat.xml > %s 2> %s/bibreformat.err" % (bindir,string.upper(fmt),tmpdir,finalfilename,tmpdir)
os.system(command)
t22 = os.times()[4]
message = "END bibformat external call (time elapsed:%2f)" % (t22-t11)
print message
tbibformat = tbibformat + (t22 - t11)
### bibupload external call
###
t11 = os.times()[4]
message = "START bibupload external call"
print message
command = "%s/bibupload -f %s" % (bindir,finalfilename)
os.system(command)
t22 = os.times()[4]
message = "END bibupload external call (time elapsed:%2f)" % (t22-t11)
print message
tbibupload = tbibupload + (t22- t11)
return
### Bibshed compatibility procedures
###
def get_date(var, format_string = "%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
shift_re=re.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
print value
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def write_message(msg, stream=sys.stdout):
"""Prints message and flush output stream (may be sys.stdout or sys.stderr). Useful for debugging stuff."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
write_message("stopping...")
task_update_status("STOPPING")
write_message("flushing cache or whatever...")
time.sleep(3)
write_message("closing tables or whatever...")
time.sleep(1)
write_message("stopped")
task_update_status("STOPPED")
sys.exit(0)
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def authenticate(user, header="BibReformat Task Submission", action="runbibformat"):
"""Authenticate the user against the user database.
Check for its password, if it exists.
Check for action access rights.
Return user name upon authorization success,
do system exit upon authorization failure.
"""
print header
print "=" * len(header)
if user == "":
print >> sys.stdout, "\rUsername: ",
user = string.strip(string.lower(sys.stdin.readline()))
else:
print >> sys.stdout, "\rUsername: ", user
## first check user pw:
res = run_sql("select id,password from user where email=%s", (user,), 1)
if not res:
print "Sorry, %s does not exist." % user
sys.exit(1)
else:
(uid_db, password_db) = res[0]
if password_db:
password_entered = getpass.getpass()
if password_db == password_entered:
pass
else:
print "Sorry, wrong credentials for %s." % user
sys.exit(1)
## secondly check authorization for the action:
(auth_code, auth_message) = acc_authorize_action(uid_db, action)
if auth_code != 0:
print auth_message
sys.exit(1)
return user
def task_submit(options):
"""Submits task to the BibSched task queue. This is what people will be invoking via command line."""
global sched_time, sleep_time
## sanity check: remove eventual "task" option:
if options.has_key("task"):
del options["task"]
## authenticate user:
user = authenticate(options.get("user", ""))
## submit task:
task_id = run_sql("""INSERT INTO schTASK (id,proc,user,status,arguments,sleeptime,runtime) VALUES (NULL,'bibreformat',%s,'WAITING',%s,%s,%s)""",
(user, marshal.dumps(options),sleeptime,MySQLdb.escape_string(sched_time)))
## update task number:
options["task"] = task_id
run_sql("""UPDATE schTASK SET arguments=%s WHERE id=%s""", (marshal.dumps(options),task_id))
write_message("Task #%d submitted." % task_id)
return task_id
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
global task_id
return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, task_id))
def task_update_status(val):
"""Updates status information in the BibSched task table."""
global task_id
return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, task_id))
def task_read_status(task_id):
"""Read status information in the BibSched task table."""
res = run_sql("SELECT status FROM schTASK where id=%s", (task_id,), 1)
try:
out = res[0][0]
except:
out = 'UNKNOWN'
return out
def task_get_options(id):
"""Returns options for the task 'id' read from the BibSched task queue table."""
out = {}
res = run_sql("SELECT arguments FROM schTASK WHERE id=%s AND proc='bibreformat'", (id,))
try:
out = marshal.loads(res[0][0])
except:
write_message("Error: BibReformat task %d does not seem to exist." % id)
sys.exit(1)
return out
def task_run(process_format):
"""Runs the task by fetching arguments from the BibSched task queue. This is what BibSched will be invoking via daemon call."""
global task_id, process, fmt, sched_time
options = task_get_options(task_id) # get options from BibSched task table
## check task id:
if not options.has_key("task"):
write_message("Error: The task #%d does not seem to be a BibReformat task." % task_id)
return
## initialize parameters
if options.has_key("format"):
fmt = options["format"]
else:
fmt = "hb"
sql = {
"all" : "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format ='%s'" % fmt,
"last": "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format='%s' and bf.last_updated < br.modification_date" % fmt,
"q1" : "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format ='xm'",
"q2" : "select br.id from bibrec as br, bibfmt as bf where bf.id_bibrec=br.id and bf.format ='%s'" % fmt
}
if options.has_key("all"):
sql_queries.append(sql['all'])
if options.has_key("without"):
process_format = 1
if options.has_key("noprocess"):
process = 0
if options.has_key("last"):
sql_queries.append(sql['last'])
if options.has_key("collection"):
cds_query['collection'] = options['collection']
else:
cds_query['collection'] = ""
if options.has_key("field"):
cds_query['field'] = options['field']
else:
cds_query['field'] = ""
if options.has_key("pattern"):
cds_query['pattern'] = options['pattern']
else:
cds_query['pattern'] = ""
### sql commands to be executed during the script run
###
## check task status:
task_status = task_read_status(task_id)
if task_status != "WAITING":
write_message("Error: The task #%d is %s. I expected WAITING." % (task_id, task_status))
return
## update task status:
task_update_status("RUNNING")
## initialize signal handler:
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
## run the task:
bibreformat_task(sql, sql_queries, cds_query, process_format)
## we are done:
task_update_status("DONE")
return
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write(" -u, --user=USER \t\t User name to submit the task as, password needed.\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.stderr.write(" -v, --verbose=LEVEL \t\t Verbose level (0=min,1=normal,9=max).\n")
sys.stderr.write(" -s, --sleeptime=SLEEP\t\t Time after which to repeat tasks (no)\n")
sys.stderr.write(" -t, --time=DATE \t\t Moment for the task to be active (now).\n")
sys.stderr.write(" -a, --all \t\t All records\n")
sys.stderr.write(" -c, --collection \t\t Select records by collection\n")
sys.stderr.write(" -f, --field \t\t Select records by field.\n")
sys.stderr.write(" -p, --pattern \t\t Select records by pattern.\n")
sys.stderr.write(" -o, --format \t\t Specify output format to be (re-)created. (default HB)\n")
sys.stderr.write(" -n, --noprocess \t\t Count records to be processed only (no processing done)\n")
sys.stderr.write("\n")
sys.stderr.write(" Example: bibreformat -n Show how many records are to be bibreformated.")
sys.stderr.write("\n")
sys.exit(exitcode)
def main():
"""Main function that analyzes command line input and calls whatever is appropriate.
Useful for learning on how to write BibSched tasks."""
global task_id, sched_time, sleeptime
## parse command line:
if len(sys.argv) == 2 and sys.argv[1].isdigit():
## A - run the task
task_id = int(sys.argv[1])
process_format = 0
task_run(process_format)
else:
## B - submit the task
process_format = 0
options = {} # will hold command-line options
options["verbose"] = 1
try:
opts, args = getopt.getopt(sys.argv[1:], "hVv:u:ac:f:s:p:lo:nt:wl", ["help", "version", "verbose=","user=","all","collection=","field=","sleeptime=","pattern=","format=","noprocess","time=","without","last"])
except getopt.GetoptError, err:
usage(1, err)
clp = 0 # default parameters flag
try:
for opt in opts:
if opt[0] in ["-h", "--help"]:
usage(0)
elif opt[0] in ["-V", "--version"]:
print __version__
sys.exit(0)
elif opt[0] in [ "-u", "--user"]:
options["user"] = opt[1]
elif opt[0] in ["-v", "--verbose"]:
options["verbose"] = int(opt[1])
elif opt[0] in ["-a", "--all"]:
options["all"] = 1
options["without"] = 1
clp = 1
elif opt[0] in ["-c", "--collection"]:
options["collection"]=opt[1]
clp = 1
elif opt[0] in ["-n", "--noprocess"]:
options["noprocess"] = 1
elif opt[0] in ["-f", "--field"]:
options["field"] = opt[1]
clp = 1
elif opt[0] in ["-p","--pattern"]:
options["pattern"] = opt[1]
clp = 1
elif opt[0] in ["-o","--format"]:
options["format"] = opt[1]
elif opt[0] in ["-s", "--sleeptime" ]:
get_date(opt[1]) # see if it is a valid shift
sleeptime = opt[1]
elif opt[0] in [ "-t", "--time" ]:
sched_time = get_date(opt[1])
if clp == 0: # default
options["without"] = 1
options["last"] = 1
except StandardError, e:
usage(e)
task_submit(options)
return
### okay, here we go:
if __name__ == '__main__':
main()
diff --git a/modules/bibformat/doc/Makefile.am b/modules/bibformat/doc/Makefile.am
index 979e6f361..3bddf7636 100644
--- a/modules/bibformat/doc/Makefile.am
+++ b/modules/bibformat/doc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
diff --git a/modules/bibformat/doc/admin/Makefile.am b/modules/bibformat/doc/admin/Makefile.am
index 2113cca37..f7bae784e 100644
--- a/modules/bibformat/doc/admin/Makefile.am
+++ b/modules/bibformat/doc/admin/Makefile.am
@@ -1,35 +1,35 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/bibformat
gifsdir=$(WEBDIR)/admin/bibformat
doc_DATA = guide.html
IMGS = $(wildcard $(srcdir)/*.gif $(srcdir)/*.jpg $(srcdir)/*.png)
gifs_DATA = $(IMGS:$(srcdir)/%=%)
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%) $(gifs_DATA)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibformat/doc/admin/guide.html.wml b/modules/bibformat/doc/admin/guide.html.wml
index fa1ace31b..8c7065a12 100644
--- a/modules/bibformat/doc/admin/guide.html.wml
+++ b/modules/bibformat/doc/admin/guide.html.wml
@@ -1,1605 +1,1605 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibFormat Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="bibformat-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">Overview</a></strong><br>
<strong>2. <a href="#2">Configuring BibFormat</a></strong><br>
<strong>3. <a href="#3">Running BibFormat</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1 <a href="#2.1">From Web interface</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2 <a href="#2.2">From the command-line interface</a><br>
<strong>4. <a href="#4">Detailed Configuration Manual</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1 <a href="#4.1">About BibFormat</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2 <a href="#4.2">How it works?</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3 <a href="#4.3">A first look at the web configuration interface</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.4 <a href="#4.4">Mapping the input (OAI Extraction Rules)</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.5 <a href="#4.5">Defining output types: Behaviors</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.6 <a href="#4.6">Formats</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.7 <a href="#4.7">Knowledge bases (KBs)</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.8 <a href="#4.8">User Defined Functions (UDFs)</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.9 <a href="#4.9">Defining links</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.9.1 <a href="#4.9.1">EXTERNAL link conditions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.9.2 <a href="#4.9.2">INTERNAL link conditions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.9.3 <a href="#4.9.3">Example</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.10 <a href="#4.10">User management</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.11 <a href="#4.11">Evaluation Language Reference</a></br>
<a name="1"></a><h2>1. Overview</h2>
<p>The BibFormat admin interface enables you to specify how the
bibliographic data is presented to the end user in the search
interface and search results pages. For example, you may specify that
titles should be printed in bold font, the abstract in small italic,
etc. Moreover, the BibFormat is not only a simple bibliographic data
<em>output formatter</em>, but also an automated <em>link
constructor</em>. For example, from the information on journal name
and pages, it may automatically create links to publisher's site based
on some configuration rules.
<a name="2"></a><h2>2. Configuring BibFormat</h2>
<p>By default, a simple HTML format based on the most common fields
(title, author, abstract, keywords, fulltext link, etc) is defined.
You certainly want to define your own ouput formats in case you have a
specific metadata structure.
<p>Here is a short guide of what you can configure:
<blockquote>
<dl>
<dt><a href="BEH_display.php">Behaviours</a>
<dd>Define one or more output BibFormat behaviours. These are then
passed as parameters to the BibFormat modules while executing
formatting.
<br><em>Example:</em> You can tell BibFormat that is has to enrich the
incoming metadata file by the created format, or that it only has to
print the format out.
<dt><a href="OAIER_display.php">Extraction Rules</a>
<dd>Define how the metadata tags from input are mapped into internal
BibFormat variable names. The variable names can afterwards be used
in formatting and linking rules.
<br><em>Example:</em> You can tell that <code>100 $a</code> field
should be mapped into <code>$100.a</code> internal variable that you
could use later.
<dt><a href="LINK_display.php">Link Rules</a>
<dd>Define rules for automated creation of URI links from mapped
internal variables.
<br><em>Example:</em> You can tell a rule how to create a link to
People database out of the <code>$100.a</code> internal variable
repesenting author's name. (The <code>$100.a</code> variable was mapped
in the previous step, see the Extraction Rules.)
<dt><a href="LINK_FORMAT_display.php">File Formats</a>
<dd>Define file format types based on file extensions. This will be
used when proposing various fulltext services.
<br><em>Example:</em> You can tell that <code>*.pdf</code> files will
be treated as PDF files.
<dt><a href="UDF_display.php">User Defined Functions (UDFs)</a>
<dd>Define your own functions that you can reuse when creating your
own output formats. This enables you to do complex formatting without
ever touching the BibFormat core code.
<br><em>Example:</em> You can define a function how to match and
extract email addresses out of a text file.
<dt><a href="FORMAT_display.php">Formats</a>
<dd>Define the output formats, i.e. how to create the output out of
internal BibFormat variables that were extracted in a previous step.
This is the functionality you would want to configure most of the
time. It may reuse formats, user defined functions, knowledge bases,
etc.
<br><em>Example:</em> You can tell that authors should be printed in
italic, that if there are more than 10 authors only the first three
should be printed, etc.
<dt><a href="KB_display.php">Knowledge Bases (KBs)</a>
<dd>Define one or more knowledge bases that enables you to transform
various forms of input data values into the unique standard form on
the output.
<br><em>Example:</em> You can tell that <em>Phys Rev D</em> and
<em>Physical Review D</em> are both the same journal and that these
names should be standardized to <em>Phys Rev : D</em>.
<dt><a href="test.php">Execution Test</a>
<dd>Enables you to test your formats on your sample data file. Useful
when debugging newly created formats.
</dl>
</blockquote>
<p>To learn more on BibFormat configuration, you can consult the <a
href="guide.html">BibFormat Admin Guide</a>.
<a name="3"></a><h2>3. Running BibFormat</h2>
<a name="3.1"></a><h3>3.1. From the Web interface</h3>
<p>
Run <a href="BIBREFORMAT_display.php">Reformat Records</a> tool.
This tool permits you to update stored formats for bibliographic records.
<br>
It should normally be used after configuring BibFormat's
<a href="BEH_display.php">Behaviours</a> and
<a href="FORMAT_display.php">Formats</a>.
When these are ready, you can choose to rebuild formats for selected
collections or you can manually enter a search query and the web interface
will accomplish all necessary formatting steps.
<br>
<em>Example:</em> You can request Photo collections to have their HTML
brief formats rebuilt, or you can reformat all the records written by Ellis.
<a name="3.2"></a><h3>3.2. From the command-line interface</h3>
<p>Consider having an XML MARC data file that is to be uploaded into
the CDSware. (For example, it might have been harvested from other
sources and processed via <a href="../bibconvert/">BibConvert</a>.)
Having configured BibFormat and its default output type behaviour, you
would then run this file throught BibFormat as follows:
<blockquote>
<pre>
$ bibformat < /tmp/sample.xml > /tmp/sample_with_fmt.xml
</pre>
</blockquote>
that would create default HTML formats and would "enrich" the input
XML data file by this format. (You would then continue the upload
procedure by calling successively <a
href="../bibupload/">BibUpload</a> and <a
href="../bibwords/">BibWords</a>.)
<p>Now consider a different situation. You would like to add a new
possible format, say "HTML portfolio" and "HTML captions" in order to
nicely format multiple photographs in one page. Let us suppose that
these two formats are called <code>hp</code> and <code>hc</code> and
are already loaded in the <code>collection_format</code> table.
(TODO: describe how this is done via WebAdmin.) You would then
proceed as follows: firstly, you would prepare the corresponding <a
href="BEH_display.php">output behaviours</a> called <code>HP</code>
and <code>HC</code> (TODO: note the uppercase!) that would not enrich
the input file but that would produce an XML file with only
<code>001</code> and <code>FMT</code> tags. (This is in order not to
update the bibliographic information but the formats only.) You would
also prepare corresponding <a href="FORMAT_display.php">formats</a>
at the same time. Secondly, you would launch the formatting as
follows:
<blockquote>
<pre>
$ bibformat otype=HP,HC < /tmp/sample.xml > /tmp/sample_fmts_only.xml
</pre>
</blockquote>
that should give you an XML file containing only 001 and FMT tags.
Finally, you would upload the formats:
<blockquote>
<pre>
$ bibupload < /tmp/sample_fmts_only.xml
</pre>
</blockquote>
and that's it. The new formats should now appear in <a
href="<WEBURL>">WebSearch</a>.
<a name="4"></a><h2>4. Detailed Configuration Manual</h2>
<p><small>What follows is a transcription of an old
FlexElink Configuration Manual v0.3 (2002-07-31). The text suffers
from missing screen snapshots, and the terminology may not be fully up-to-date
at places.<!--FIXME-->
</small>
<a name="4.1"></a><h3>4.1. About BibFormat</h3>
<p>BibFormat is a piece
of software that is part of the CERN Document Server software (CDS, <a
href="http://cdsweb.cern.ch/">http://cdsweb.cern.ch</a>).
</p>
<p>Its mission, in few
words, is to provide a flexible mechanism to format the bibliographic records
that are shown as a result of CDS Search user queries allowing the
administrators or users customize the view of them. Besides, it offers the
possibility of using a linking system that can generate automatically all the
links included in the displayed records (fulltext access, electronic journals
reference, etc) reducing considerably maintenance.</p>
<p>To clarify this too
formal definition, we'll try to illustrate the role of BibFormat inside the CDS
Search module by showing the following figure. Please, note that this drawing
is trying to show the main role that BibFormat plays in the CDS structure and
it's quite simplified, but of course the underlying logic is a bit more
complex.</p>
<p><img src="./guide001.gif"></p>
<p>[Fig. 0]</p>
<p>As you can see, when a
user query is received, Weblib determines which records from the database match
it; then it ask BibFormat to format the obtained records. BibFormat looks at
its rule repository and for each record determines which format has to be
taken, applies the format specification and solves the possible links; gives
all this (in a formatted way) back to Weblib and it makes a nice HTML page
including the formatted results given by BibFormat among other info.</p>
<p>The good point in all
this is that anyone that has access to BibFormat rule repository is able to
modify the final appearance of a query result in the CDS Search module without
altering the logic of the search engine.</p>
<p>In order to be able to
modify this BibFormat rule repository, a web configuration interface is
provided. Trough this paper, we'll try to explain (in a friendly way and form
the user point of view) how to access this interface, how it's structured and
how to configure BibFormat trough it to achieve desired results.</p>
<a name="4.2"></a><h3>4.2. How it works?</h3>
<p>We've outlined which is
the role of BibFormat inside the CDS, so it's time now to have an overview of
how it works and how it's organized. We'll try not to be very technical,
however a few explanation about the BibFormat repository and architecture is
needed to understand how it works.</p>
<p>BibFormat, basically,
takes some bibliographic records as input and produces a formatted &amp; linked
version of them as output. By "formatted" we mean that BibFormat can produce an
output containing a transformed version of the input data (normally an HTML
view); the good part is that you can entirely specify the transformation to
apply. At the same time, by "linked" we mean that you can ask BibFormat to
include (if necessary) inside this formatted version references to some
Internet resources that are related to the data from some pre-configured rules.
</p>
<p>As an example, we could
imagine that you'd want to see the resulting records from CDS Search queries to
show their title in bold followed by their authors separated by comas. For
achieving this you'll have to go to the BibFormat configuration interface and
define a behavior for BibFormat in which you describe how to format incoming
records:</p>
<p>
<table border cellspacing="0" width="100%">
<tr>
<td>
<pre>
"&lt;b&gt;" $title "&lt;/b&gt;"
forall($author){
$author separator(", ")
}
</pre>
</td>
</tr>
</table>
<p align="center">Figure 1.-
A very first <em>Evaluation Language</em> example</p>
<p>Don't be scared!! It's a
first approach to the way BibFormat allows you to describe formats. As you can
see, BibFormat uses a special language that you'll have to learn if you want to
be able to specify formats or links; it seems difficult (as much as a
programming language) but you'll see that it's quite more easy than it seems at
first sight.</p>
<p>In the next figure, is
shown how BibFormat works internally. When BibFormat is called, it receives a
set of bibliographic records to format. It separates each record and translates
it into a set of what we call "internal variables"; these "internal variables"
are simply an internal representation of the bibliographic record; the
important thing with them is that they will be available when you have to describe
the formats. Once it has these "internal vars", the processor module looks into
the behavior repository for that one (let's say format) you've asked BibFormat
to apply (when BibFormat is called, you can indicate which of the
pre-configured behaviors to apply; this allows it to have more than one
behavior); inside this behavior you can specify which data you want to appear,
how it has to appear, some links if they exist... in other words, the format
(actually, it's something more than a format, it describes how BibFormat has to
behave for a given input; that's why we refer to it as behavior). As we've already said, you can include links
in a behavior specification; links are a special BibFormat feature that helps
you to reduce the maintenance of your formats: you can include a link in
several formats or behaviors.</p>
<p>The picture below,
describes all this explanation.</p>
<p><img src="./guide003.jpg">
<p>[Fig. 2]</p>
<p>Summarizing, BibFormat can
transform an input made up of bibliographic records in an HTML output (not only
HTML but any text-based output) according to certain pre-configured
specifications (behaviors) that you can entirely define using a certain
language.</p>
<p>Just to mention, currently
BibFormat is working taking OAI MARC XML as format for input records, but it
can be adapted to other ways of inputs (reading a database, function call, etc)
with a little of development.</p>
<a name="4.3"></a><h3>4.3. A first look at the web configuration interface</h3>
<p>BibFormat can be
configured through its configuration interface that is accessible via web. It's
made up of a bunch of web pages that present you the main configuration aspects
of BibFormat allowing you to change them. In this section we are going to have
a first look at this web interface, how it's structured and its correspondence
with BibFormat features.</p>
<p>Before entering
these web pages you'll be asked for your accessing username &amp; password.
Only certain users are allowed to access BibFormat WI; first you need a CDS
account that you can create easily by using the standard CDS account manager;
then you have to ask BibFormat administrator to give privileges to access the
WI.</p>
<p>. Once your password is accepted you'll access
the configuration interface. You'll see that is quite simple: It's structured
in different sections; each of them corresponds to a BibFormat feature and you
can navigate through them by using a navigation bar that is always present on
the left.</p>
<p>[Fig. 3]</p>
<p>Here you are a list
of the different sections the interface offers you and their correspondence
with BibFormat features:</p>
<ul>
<li><strong>Behaviors:</strong> This is the main section, the one you
enter by default when you access the web interface. It contains definitions for
the different pre-configured output types or behaviors that allow you to define
how you want BibFormat to behave when each output type is selected. More information
in chapter <em>Defining output types: Behaviors</em> of this manual.</li>
<li><strong>OAI Extraction Rules:</strong> The input types and
mapping rules for OAI MARC XML inputs are defined here. You'll find here the
information about all the internal variables and their correspondence with the
input XML tags. See chapter <em>Mapping the input</em> of this manual for more
information.</li>
<li><strong>Link Rules:</strong> Allows you to access the link rules
repository for defining the way links are generated. See chapter <em>Defining
Links</em> for a more detailed description about the BibFormat linking system.</li>
<li><strong>UDFs:</strong> Presents you a list of all the User
Defined Functions (UDFs) that you can use inside <em>Evaluation Language</em> (<em>EL</em>)
statements that are used for specifying different configuration aspects.
You'll also be able to modify or extend this list within this section.
Everything about using UDFs and defining new ones in chapter <em>User Defined
Functions (UDFs)</em>.</li>
<li><strong>Formats:</strong> Another <em>EL</em> feature: You can
define a certain piece of <em>EL</em> code under a name for re-using it whenever
you want. See chapter <em>Formats</em>.</li>
<li><strong>KBs:</strong> A complete management interface for <em>Knowledge
Bases</em> (<em>KBs</em>); those <em>KBs</em> will also be available inside <em>EL</em>
statements. See chapter <em>Knowledge Bases(Kbs)</em> for more specific
information.</li>
<li><strong>Execution Test:</strong> You'll be able to execute
BibFormat from this section and view the results and some debug info in a web
page. You have to specify an input data file (through a URL).</li>
<li><strong>User management:</strong> Allows you to define which CDS
users can access or not the BibFormat web interface.</li>
</ul>
<p>Each section has
different particularities but the way of dealing with them follows a common
line through the interface. However, each section with their common things and
particular characteristics are treated in the following chapters of this
manual.</p>
<a name="4.4"></a><h3>4.4. Mapping the input (OAI Extraction Rules)</h3>
<p>We have already spoken a bit about BibFormat <em>internal
variables</em>. These are a key point to understand the BibFormat way of
working. As you know, BibFormat takes some bibliographic records as input and,
according to some pre-configured behavior, formats them into HTML, for example.
The problem is that this input records can come in several formats: different
XML conventions, database records, etc. For now, at CDS we only consider that
the input comes in OAI MARC XML but for the near future we'll may be have to
extend it to accept other input formats.</p>
<p>That's the reason why <em>internal variables</em> appear; they
provide a common way to refer to input data without relaying in any concrete
format. In other words, we will define BibFormat links and behaviors referring
to these <em>internal variables</em> and we'll have some rules that define how to
map an input format to them, so we would be able to use any BibFormat defined
behavior with any input that can be mapped to <em>internal variables</em>.</p>
<p><img src="./guide004.gif"></p>
<p>[Fig. 4]</p>
<p>You shouldn't worry about this because is more in the
development/administration side, but it's important to know where <em>internal
variables</em> come from and what they refer to. Besides, for CDS we only
consider the incoming data in OAI MARC XML format, so we'll talk only about
this case.</p>
<p><em>Internal variables</em> are quite a simple concept: It's just
a label that represents some values from the input. Besides, a variable can
have <em>fields</em> that are also labels that represent values from the input
but that are related to other under the variable (e.g. You can have a variable
that maps authors and another that maps authors home institutes independently;
but if you want to have represent an author and his home institute you need to
relate these two variables in some way). Variables and their fields also
support multiple values.</p>
<p>Focusing on OAI MARC XML, the concept of variable and field is
already in the input structure.:</p>
<ul>
<li>Each occurrence of OAI MARC XML <em>varfield</em> element
will correspond to a different variable value.</li>
<li>Each occurrence of OAI MARC XML <em>subfield</em> inside
a certain <em>varfield</em> element will correspond to a different field value of
the variable that maps the <em>varfield</em>.</li>
</ul>
<p>So what we will have in BibFormat is a set of rules that tells a
variable name to which <em>varfield</em> element corresponds and each variable
field name which <em>subfield</em> element maps. Trough the web interface you'll
be able to add or delete new fields to variables or variables themselves,
you'll be able even to modify the mapping tags of variables (this way you can
keep your formats independent of changes in the meaning of MARC tags).</p>
<p>In the web interface, all this is located in <em>OAI Ext. Rules</em>
section as you can see in the following figure:</p>
<p>[Fig. 5]</p>
<p>Let's illustrate how BibFormat maps a certain input to variables
and fields with an example:</p>
<p>We have this variable &amp; field definition on BibFormat:</p>
<p>
<table border cellspacing='0' cellpadding='5'>
<tr bgcolor='#e0e0e0'>
<th align='center'>Var.<br>label</th>
<th align='center'>Mapping tag</th>
<th align='center'>Mult. V.</th>
<th align='center'>Fields</th>
</tr>
<tr>
<td align='center'>100</td>
<td align='center'>&lt;varfield id="100" i1="" i2=""&gt;</td>
<td align='center'>Yes</td>
<td align='center'>
<table border cellspacing='0'>
<tr bgcolor='#e0e0e0'>
<td align='center'>Field label</td>
<td align='center'>Mapping tag</td>
</tr>
<tr>
<td align='center'>a</td>
<td align='center'>&lt;subfield label="a"&gt;</td>
</tr>
<tr>
<td align='center'>e</td>
<td align='center'>&lt;subfield label="e"&gt;</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align='center'>909C0</td>
<td align='center'>&lt;varfield id="909" i1="C" i2="0"&gt;</td>
<td align='center'>No</td>
<td>
<table border cellspacing='0'>
<tr bgcolor='#e0e0e0'>
<td align='center'>Field label</td>
<td align='center'>Mapping tag</td>
</tr>
<tr>
<td align='center'>b</td>
<td align='center'>&lt;subfield label="b"&gt;</td>
</tr>
</table>
</td>
</tr>
</table>
<p>
<p>And then a record like the following arrives as input:</p>
<p>
<table border cellspacing="0" width="100%">
<tr>
<td>
<pre>
&lt;oai_marc&gt;
&lt;varfield id="037" i1="" i2=""&gt;
&lt;subfield label="a"&gt;SCAN-0009119&lt;/subfield&gt;
&lt;/varfield&gt;
&lt;varfield id="100" i1="" i2=""&gt;
&lt;subfield label="a"&gt;Racah, Giulio&lt;/subfield&gt;
&lt;/varfield&gt;
&lt;varfield id="100" i1="" i2=""&gt;
&lt;subfield label="a"&gt;Guignard, G&lt;/subfield&gt;
&lt;subfield label="e"&gt;editor&lt;/subfield&gt;
&lt;/varfield&gt;
&lt;varfield id="909" i1="C" i2="0"&gt;
&lt;subfield label="b"&gt;11&lt;/subfield&gt;
&lt;/varfield&gt;
&lt;varfield id="909" i1="C" i2="0"&gt;
&lt;subfield label="b"&gt;12&lt;/subfield&gt;
&lt;/varfield&gt;
&lt;/oai_marc&gt;
</pre>
</td>
</tr>
</table>
<p>The result of the mapping would be like this:</p>
<p>
<table border cellspacing='0' cellpadding='5' width="60%">
<col width="25%">
<col width="25%">
<col width="25%">
<col width="25%">
<tr bgcolor='#e0e0e0'>
<th align='center' colspan='4'>Variable "100"</th>
</tr>
<tr>
<td align='center' bgcolor='#e0e0e0'>Value# 0</td>
<td>&nbsp;</td>
<td align='center' bgcolor='#e0e0e0'>Field "a" value</td>
<td align='center'><samp>Racah, Giulio</samp></td>
</tr>
<tr>
<td align='center' rowspan='2' bgcolor='#e0e0e0'>Value# 1</td>
<td align='center' rowspan='2'>&nbsp;</td>
<td align='center' bgcolor='#e0e0e0'>Field "a" value</td>
<td align='center'><samp>Guignard, G</samp></td>
</tr>
<tr>
<td align='center' bgcolor='#e0e0e0'>Field "e" value</td>
<td align='center'><samp>editor</samp></td>
</tr>
</table>
<p>
<table border cellspacing='0' cellpadding='5' width="60%">
<col width="25%">
<col width="25%">
<col width="25%">
<col width="25%">
<tr bgcolor='#e0e0e0'>
<th align='center' colspan='4'>Variable "909C0"</th>
</tr>
<tr>
<td align='center'>Value# 0</td>
<td align='center'>&nbsp;</td>
<td align='center'>Field "b" value</td>
<td align='center'><samp>12</samp></td>
</tr>
</table>
<p>Notice how <em>varfield 037</em> is not considered because there
isn't an entry in the BibFormat configuration. Also notice how the values are
created: if "allow multiple values" is set to "Yes" each occurrence of a <em>varfield</em>
element determines a new value (variable "100"); in other case, the last value
is taken as single value for the variable (variable "909C0").</p>
<a name="4.5"></a><h3>4.5. Defining output types: Behaviors</h3>
<p>Now that we already know how internal variables are structured
and what they represent in the input, it's time to have a look at how to
configure BibFormat to transform that input data mapped into variables into
HTML results (although any text-based output could be generated).</p>
<p>When BibFormat is asked to format a bunch of bibliographic
records, it is also necessary to specify which <em>output type</em> it has to
use. This output type is a string that identifies a pre-configured set of
conditions and actions that tells BibFormat how to behave with the given input
data (that's why the terms <em>output type</em> and <em>behavior</em> are used
indifferently along this document).</p>
<p>BibFormat can have several pre-configured behaviors each one
identified by a different label. There are two different types of behaviors
(you can choose the behavior type when you define it):</p>
<ol>
<li>Normal:
Consists in a behavior that outputs exactly the result of its evaluation.</li>
<li>Input Erich (only for XML inputs): It echoes each xml record
from the input inserting the behavior result just before the xml closing
element of the record.</li>
</ol>
<p>Each behavior contains an ordered list of conditions; a
condition can contain zero or more associated actions (actions are ordered
inside a condition). A condition is a behavior item described by an <em>Evaluation
Language</em> expression that gives as result "TRUE" or "FALSE". An action is an
<em>Evaluation Language</em> (<em>EL</em>) statement that produces any output.</p>
<p>When BibFormat is called to format a set of input records with a
given behavior label, it looks for the behavior conditions. It evaluates their <em>EL</em>
in order and when one of them produces "TRUE" as result, it looks for their
associated actions. Then BibFormat evaluates the actions in the specified order
and concatenates their result.</p>
<p>By using different conditions you can specify alternative
formats inside a behavior (imagine that you want to format a record differently
depending on its base number); it's true that you could also reach this
solution by using <em>EL IF</em> statements, but it's more clear, efficient and
re-usable (you can change one condition without touching the rest or you can
give it more priority than others, that means give it the chance to be
evaluated before others, by changing its apply order).</p>
<p>Actions are used for specifying the format itself or the actions
you want to carry on with in case the condition is accomplished.</p>
<p>Through the web interface you can define new output types or
modify the ones that already exist. The use is quite easy: you just have to
select the link in the desired item with the operation you want to do over it.</p>
<p>[Fig. 6]</p>
<p>Let's have a look at a simple example to illustrate how to
define behavior that fit our needs:</p>
<p>Imagine a typical case where you want to format bibliographic
records but depending on their base number you want to apply different formats.
Whenever a record from base 27 (standards) arrives we want only to show its
title and the standard numbers, in other case a default format will be applied
in which the title and authors are shown. We'll assume CDS variable notation
and that the input rules are defined properly.</p>
<p>We are going to define a new NORMAL behavior for this new
situation, let's call it <em>SIMPLE</em>. In it we'll need two conditions to be
defined: one for applying the default format and another one for the 27-base
special one. The base number comes in variable 909C0.b, so the conditions would
be based on this variable content.</p>
<p>The result behavior should be defined like this:</p>
<p>
<table border cellspacing='0' width="60%">
<tr>
<th align='center' colspan='2' bgcolor='#a0a0a0'>SIMPLE<small>(NORMAL)</small></th>
</tr>
<tr>
<td bgcolor='#e6e6e6'>10</td>
<td bgcolor='#e6e6e6'>$909C0.b="27"</td>
</tr>
<tr>
<td colspan='2'>
<pre>
"&lt;b&gt;"$245.a"&lt;/b&gt;"
forall($0248.a){
&nbsp;rep_prefix(" - ") $0248.a separator("; ")
}
</pre>
</td>
</tr>
<tr>
<td bgcolor='#e6e6e6'>50</td>
<td bgcolor='#e6e6e6'>""=""</td>
</tr>
<tr>
<td colspan='2'>
<pre>
"&lt;b"$245.a"&lt;/b&gt;"
forall($100.a){
&nbsp;rep_prefix(" - Authors:") $100.a separator("; ")
}
</pre>
</td>
</tr>
</table>
<p>
<p>Some explanations on this example are needed:</p>
<ul>
<li>As you can see we have defined two conditions: one for
the 27-format and another for the default format. The point that is important
is the order in which we put the conditions: For each record in the input the
special one is evaluated first (because it has a lower evaluation number, 10)
and if the condition is true the format will be applied; in case the base is
not 27 the default condition is evaluated and because its condition <em>EL</em> code
is always true the default will be used to format the record.</li>
<li>Don't worry too much about the action code because it's
quite trivial. There are some "strange" things like the use of functions <em>rep_prefix</em>
and <em>separator</em>. These are special <em>UDFs</em> that have a special
behavior inside a FORALL statement:
<ul>
<li><em>rep_prefix</em>: Prints the string argument only when we are in the
first iteration of a <em>FORALL</em>. In order words, put the prefix of the
string which is to be generated by the <em>FORALL</em> statement.</li>
<li><em>Separator</em>: Prints the string argument in every <em>FORALL</em>
iteration but not in the last one.</li>
</ul>
</li>
</ul>
<a name="4.6"></a><h3>4.6. Formats</h3>
<p><em>Formats</em> are a special construction that BibFormat <em>Evaluation
Language</em> (<em>EL</em>) offers. It allows you to group under an identifier
some <em>EL</em> code and after you can call it from every <em>EL</em> statement.</p>
<p>You can manage these formats using the web interface. It is
quite easy to do so: When you access the <em>Formats</em> section it will present
you a list with all the format identifiers that are already defined and a small
documentation about what's the format for. From there you can see the whole <em>EL
</em>code by using the link <em>[Code]</em>. You can add a new format by using the
set of input boxes that you'll find at the end of the page. Also delete and
modify operations are possible for already defined formats.</p>
<p>[Fig. 7]</p>
<p><strong><u>Note:</u></strong> When defining formats,
one has to pay attention not to use "recursive" format calls (either direct or
indirect); this can lead to execution problems. For example, imagine that we
have a format called "ex 1" that has a call for itself:</p>
<blockquote>
<table border cellspacing='0' width="60%">
<tr>
<td align='center'>Format "ex_1"</td>
</tr>
<tr>
<td align='center'>
<pre>
"hello world"
format("ex_1")
</pre>
</td>
</tr>
</table>
</blockquote>
<p>this is a "direct" recursive call; you
should never have these kind of calls as the web interface should warn you if
it finds these kind of troubles. However, "indirect" calls are not detected by
the web interface, so you have to care about them. One example of "indirect"
recursion:</p>
<p>
<blockquote>
<table border cellspacing='0' width="60%">
<tr>
<td align='center'>Format "ex_1"</td>
</tr>
<tr>
<td align='center'>
<pre>
"hello world"
format("ex_2")
</pre>
</td>
</tr>
</table>
</blockquote>
<a name="4.7"></a><h3>4.7. Knowledge bases (KBs)</h3>
<p>This is yet another special feature provided by BibFormat <em>Evaluation
Language</em>. In a few words, this allows you to map one string value to
another according to a pre-stored set of key values that map to other values
(the knowledge bases). All the knowledge bases are identified by a label that
has to be unique (among other KBs identifiers); remember that identifiers are
not case-sensitive.</p>
<p>These sets of values, normally lived in a file, but with this
new development there was the need to have an easy KB management that was
integrated in BibFormat. For this reason, you can manage KBs from the BibFormat
configuration interface: section <em>KBs</em>.</p>
<p>When accessing to <em>KBs</em> section, the list of all the KBs
identifiers defined will be displayed. Below it you'll find a set of controls
to add new KBs; the use of these controls is as usual along the interface but
there's something a bit special: Normally, you shouldn't fill in the input box
that asks you for the <em>Knowledge base table name</em>; all the knowledge base
data is handled by a database in which each KB corresponds to a DB table; this
input box gets the internal table name for that KB; normally the KB manager
will generate it for you so you shouldn't need to use it.</p>
<p>[Fig. 8]</p>
<p>Each KB has a link for accessing the list of values that it
contains. If you click on it, a new window will show you the list of current
values (key and mapped ones) and a very easy interface to add new values or to
delete existing ones (KB values are case sensitive).</p>
<p>[Fig. 9]</p>
<a name="4.8"></a><h3>4.8. User Defined Functions (UDFs)</h3>
<p>The use of <em>User Defined Functions</em> (<em>UDFs</em>) is one of
the more powerful features of BibFormat <em>Evaluation Language</em> (<em>EL</em>).
The idea is that inside <em>EL</em> you can use operations or functions over
strings; normally a large number of different string transformations are needed
when talking about formatting but we cannot pretend implement all this
operations inside <em>EL</em> because it's in constant growing and new needs
appear all the time. For dealing with this problem, BibFormat defines a
mechanism that allows you to use define as much functions (<em>UDFs</em>) as you
want and use them inside any <em>EL</em> statement.</p>
<p>These functions are identified by a unique name and they receive
data (over which they do operations) by parameters. These functions are defined
in a programming language (PHP) and therefore good knowledge of this language
is needed.</p>
<p>BibFormat offers a complete UDF management through the <em>UDFs</em>
web interface section. There you'll see a complete list of all defined <em>UDFs</em>
with their identifier, parameters and a small documentation about what the UDF
does. You can also add, delete or modify <em>UDFs</em> or even have a look at the
PHP code of an already defined function (there you'll be able to launch small
tests over the defined functions).</p>
<p>[Fig. 10]</p>
<p>The definition of these functions should be reserved to
administrators and some particularities have to be taken into account when
defining <em>UDFs</em>:</p>
<ul>
<li>When you want to add or modify a <em>UDF</em> you are
asked for the parameter list; you have to enter the parameter names separated
by comas. Ex: You want to define a new function for prefixing a given string
with another, so you need two parameters (one for the string which is going to
be prefixed, let's name it <em>str</em>, and another one for the prefix itself,
let's name it <em>prefix</em>); you should enter them in the parameter input box
like this: <em>prefix, str</em></li>
<li>The order in which you specify the parameters when
defining a function is the order in which they have to be passed to the <em>UDF</em>
from an <em>EL</em> statement.</li>
<li>When defining the PHP code of a function, there are
some important things to consider:
<ul>
<li>The result of a function has to be a string.</li>
<li>The parameters are available inside the PHP code as
variables with the parameter name.</li>
<li>The result of the function has to be defined by a PHP
result clause giving the resulting string.</li>
<li>Make sure the PHP code is correct (there's no way to
know if the code is correct from BibFormat and it won't tell you if it is).</li>
<li>There are some special variables available inside the
PHP definition:
<ul>
<li>$FIRST_ITERATION: Is equal to "1" when we are in the first iteration
of an <em>EL FORALL</em> statement. "0" in other case. If the call is made outside
a <em>FORALL</em> is set to "1".</li>
<li>$LAST_ITERATION: Just the opposite case.</li>
</ul>
<p>With these two
variables you can define <em>FORALL</em> special functions like a function to
print a separator.</p>
</li>
</ul>
</li>
</ul>
<a name="4.9"></a><h3>4.9. Defining links</h3>
<p>As we've already said, BibFormat is not only a formatter but it
also provides a link manager but, what do we mean by 'link manager'? The idea
is to have a set of rules that describe how to generate a link using certain
data; if the link can be generated from those rules, then the link manager can
check different things (i.e. see if the link is valid, if it's a link to a file
it can check if the file exists and in which formats it exists, etc) and
finally return the solved link. In other words, if you have a set of
bibliographic records that can contain a certain link and that link can be
coded in the link manager rules, you don't need to store each link in each
bibliographic record, you just use the link manager to generate them
dynamically; like this, you only have to maintain a small set of rules and not
thousands of static links in records.</p>
<p>BibFormat allows you to configure different <em>link definitions</em>
each of them identified by a unique name; each of these <em>link definitions</em>
have some associated <em>parameters</em> which are the information passed to the
rules defined for it. Then, when you call the link manager to solve a link
(from an <em>EL</em> statement, for example) you'll have to specify the
identifier of the <em>link definition</em> you want to be used and the value for
each of the parameters used by that <em>link definition</em> (always string
values). The link manager will retrieve the rules associated to the <em>link
definition</em> specified and will interpret those rules using the given
parameter values, informing you if the link was generated correctly and result
(the solved link).</p>
<p>BibFormat provides this mechanism and through the web interface
you can access to the rule repository for having a look at what are the
available <em>link definitions</em>, define new link rules or maintain already
defined ones. When adding or modifying a <em>link definition</em> you'll have to
specify the parameters, please remember to separate them by using comas.</p>
<p>[Fig. 10]</p>
<p><em>Link definitions</em> are structurally quite similar to
behaviors: Although there can be different types of them (as we'll see later),
a <em>link definition</em> is made up of one or more conditions and each of these
conditions can have one or more actions that tell how the link has to be built
in case its condition is accomplished. In general, link rules (this includes
conditions and actions) have a particular structure and they are described in <em>Evaluation
Language</em> (<em>EL</em>) with one restriction: <em>EL LINK</em> statement
cannot be used. Each group of conditions-actions of a link definition can be of
a different <em>solving type</em> (actually, when you create a new link
definition, its <em>solving type</em> its asked; this is just because all
conditions that will be created for that link definition will have the selected
<em>solving type</em> as default; but you can change it afterwards having a
"mixed" <em>link definition</em>). Their structure and way the link manager interprets
them will depend in their <em>solving type</em>. Currently, there you can define
link conditions of two different <em>solving types</em>: EXTERNAL or INTERNAL. A
more detailed explanation about each type is given later.</p>
<p>As we've said a link definition is made up of various link
conditions. When a solving for a concrete <em>link definition</em> is asked, the
link manager retrieves all link conditions associated to it. Then it takes the
first of them (following the <em>evaluation order</em> - the lower is the
evaluation order number, the first the condition is considered), it evaluates
its <em>EL</em> code with the parameter values passed and if the result is "TRUE"
associated actions are executed, the link is returned and the solving process
finishes. In case a condition fails, it looks for the next one. If all the
conditions fail then the link manager returns that the link couldn't be solved.
This is the general behavior of the link manager, but the way of determining if
a link has been solved or not and the link building depends on the condition <em>solving
type</em>.</p>
<a name="4.9.1"></a><h4>4.9.1. EXTERNAL link conditions</h4>
<p>This is the simplest way of solving links. It's intended to be
used when you want to generate a link that points to an external resource
(normally a web page). In this case the link condition is composed by only one
action that will be evaluated if the associated condition is "TRUE". When a
condition of this type is evaluated "TRUE" and the action is executed, the
result of the action is given as the solved link and the link manager finishes.</p>
<p>[Fig. 11]</p>
<a name="4.9.2"></a><h4>4.9.2. INTERNAL link conditions</h4>
<p>This condition solving type is intended to be used when you want
to link to a document which is a file (inside or outside your file system) and
that can be in different file formats.</p>
<p>This case is a bit more complex than the previous one, so we'll
go step-by-step explaining differences and special features:</p>
<ul>
<li>An INTERNAL condition has a <em>base file path</em> and a
<em>base URL</em> associated. The <em>base file path</em> is the string that will
be used as prefix when looking for a file generated by the actions associated
to that condition. On the other hand, the <em>base URL</em> will be a string to
which the link string (resulting from the actions) will be added (i.e. if the <em>base
file path</em> of a condition is <code>/tmp/docs</code>
and the <em>base URL</em> is <code>http://doc.cern.ch/</code>,
if the condition is true and the result of the actions is <code>test.pdf</code>, the file path the link manager
will have to check will be <code>/tmp/docs/test.pdf</code>
and, if the file exists, the generated link will be <code>http:/doc.cern.ch/test.pdf</code>)</li>
<li>Any condition of this type can several associated <em>file
formats</em>. This is a new concept that is only used for INTERNAL condition
solving. A <em>file format</em> is simply a set of file extensions that are
grouped under an identifier. Then, you can associate a <em>file format</em>
identifier with a link condition. When the condition is true the link manager
will combine each result from the condition actions with the associated file
formats to check the existence of a file of any format; this means that when an
action is evaluated, the link manager takes the file extensions of each
associated file format identifier and checks if the <em>file base path</em> +
resulting action string + file extension exists in the file system.</li>
<li>One condition of this type can have more than one
associated action. Each of its actions describes an alternative way of building
the file path. When a condition of this type is evaluated to "TRUE", the link
manager retrieves its actions (following actions <em>apply order</em>) and
evaluates the first one; with the action result it builds the file path in this
way: <em>file base path</em> + resulting action string, and then combines this
string with each of the <em>file extensions</em>. If any of the combination
exists in the file system, the link is generated (if there are more than one
file format combination that exist, the link variable will have multiple values
containing the different links); if not, it starts the same process with the
next action. If any of the actions drive to a existing file, the link is not
generated.</li>
<li>When calling the link manager from a <em>EL</em>
statement (see chapter <em>Evaluation Language Reference</em>), if the link is
solved we'll be able to access to a special internal variable that contains as
value the resulting link. In the INTERNAL condition links, we have said that
this variable can contain multiple values in case the link manager finds
different file formats. In this case, there's another extension that consists
in having some special variable fields containing special values for each value
in the <em>LINK</em> variable and to which you can access when the link is solved;
here's a table detailing the different variable LINK fields which are defined
when a INTERNAL condition link is solved:</li>
</ul>
<blockquote>
<table border cellspacing='0'>
<tr>
<th bgcolor='#a0a0a0'>Field name</th>
<th bgcolor='#a0a0a0'>Value that contains</th>
</tr>
<tr>
<th align='left'>url</th>
<td>The same value as the LINK variable: The solved URL.</td>
</tr>
<tr>
<th align='left'>file</th>
<td>Contains the local full path to the file the solved URL points to.</td>
</tr>
<tr>
<th align='left'>format_id</th>
<td>Contains the file format id string</td>
</tr>
<tr>
<th align='left'>format_desc</th>
<td>Contains the file format description string (this
is defined for each file format)</td>
</tr>
</table>
</blockquote>
<a name="4.9.3"></a><h4>4.9.2 Example</h4>
<p>As the link generation is quite a complex topic (specially when
talking about INTERNAL linking) we'll try to illustrate it with a simple
example.</p>
<p>Let's imagine we want to create a new link definition for
generating full-text access to the documents that are archived on a document
server (a file system which contains document's electronic versions). These
documents are organized systematically depending in three characteristics that
are included in the bibliographic records: BASE, CATEGORY and ID. When the base
corresponds to "CERNREP" then the files are archived below directory <code>/pub/www/home/cernrep/</code>
and can be stored following two different criteria that depend on the CATEGORY
and ID values; the documents are all HTML. However, if the base is "PREPRINT"
and the CATEGORY is either "HEP-TH" or "HEP-PH" they are stored under directory
<code>/archive/electronic|/pub/www/home/</code> following a certain criteria; in this
case the documents can be in several file formats: PDF, Postscript, MS Word.</p>
<p>Of course, we want only the link to be created if the files
corresponding to the bibliographic records exist.</p>
<p>So we start creating a new link definition that we'll call <em>FULLTEXT</em>.
It will receive three parameters that are the information we need for
generating this kind of links: BASE, CATEGORY and ID. We select INTERNAL as
solving type as default and then we fill it the base file path and url with
some default values (these values are not important, they will be copied by
default to the conditions we are going to create afterwards).</p>
<p>[Fig. 12]</p>
<p>Then we create a condition for the first possibility: when BASE
is "CERNREP". We select INTERNAL as link condition because we want to link to a
file and we want to check its existence and we fill in the base file path and
URL with the corresponding values. Then we assign the file format types and we
enter the file archiving criteria as different actions.</p>
<p>[Fig. 13]</p>
<p>For the other possibility we proceed in the same way by adapting
the definition to the requirements; we'll have something like this as result:</p>
<p>[Fig. 14]</p>
<p>Once we have finished the link definition, we can insert links
of this type from a BibFormat behavior, for example. Let's imagine we have
included a piece of <em>EL</em> code like this in a behavior because we want to
insert a link to the full-text documents of any record:</p>
<p>
<table border cellspacing="0" width="100%">
<tr>
<td>
<pre>
link("FULLTEXT",$base, $category, $id)
{
"Fulltext: "
forall($link){
"&lt;a href=\"" $link.url "\"&gt;" $link.format_desc "&lt;/a&gt;"
separator " - "
}
}
</pre>
</td>
</tr>
</table>
<p>This <em>EL</em> statement will include the string "Fulltext: "
followed by a link to all the documents found for the values of internal
variables $base, $category, $id separated by " - ".</p>
<p><a name="4.10"></a><h3>4.10. User management</h3>
<p>The BibFormat web interface (WI) comes with a security mechanism
which allows you to define which users can access the WI. BibFormat doesn't
have a user management incorporated; instead it uses CDS user schema (as is a
part of CDS). So if you are not registered as CDS user and you want to have
access to BibFormat WI, first thing to do is to register in CDS through the
standard procedure (for example via the CDS Search interface you can access the
CDs account management system).</p>
<p>BibFormat WI access policy is rather simple: it keeps a list of
CDS users that can access the WI. Then if someone tries to access any part of
the WI, the system will ask the user to identify him as CDS user. If the CDS
login is successful and the user is in BibFormat's access list, then the user
will gain access to the WI.</p>
<p>There's a section in the WI which allows you to define which CDS
users will have access to the WI. The use is rather simple: You can add CDS
users to the access list by specifying either their CDS user id or their CDS
login; then you can delete a CDS uses from the access list by simply selecting
the link "delete" for the corresponding user.</p>
<p>[Fig. 15]</p>
<p>When you install BibFormat for the first time and you access to
the WI you'll see that no login or password is asked. The security mechanism
doesn't get activate until at least one user is added to the BibFormat's access
list. So if you don't want to limit the access to BibFormat WI keep the access
list without any user in.</p>
<a name="4.11"></a><h4>4.11. Evaluation Language Reference</h4>
<p>In this section we'll present a more or less formal definition
of the <em>Evaluation Language</em> (EL); although we are using some formal
methods to describe it we'll also make a quick explanation about the elements
that made up the language and how to combine them to arrive to desired results.
</p>
<p>Just below you can find the EL definition, expressed in terms of
EBNF (<em>Extended Backus-Naur Form</em>) notation. We have used capital letters
to express non-terminal elements and non-capital/bold characters for the
terminal ones. There's one remark to make: Whenever you find the mark
<small><code>[REX]</code></small> after
any definition, it means that we have used a regular expression just before in
order to express a set of non-terminals.</p>
<p>
<table border cellspacing="0" width="100%">
<tr>
<td>
<pre>
SENTENCE ::= TERM {<strong>&amp;&amp;</strong> TERM | <strong>||</strong> TERM}
TERM ::= FACTOR {<strong>=</strong> FACTOR | <strong>!=</strong> FACTOR | FACTOR}
FACTOR ::= [<strong>!</strong>] BASIC
BASIC ::= VARIABLE | LITERAL | FUNCTION | <strong>(</strong> SENTENCE <strong>)</strong> | FORALL |
IF | FORMAT | LINK | COUNT | KB
VARIABLE ::= <strong>$</strong> STRING [<strong>.</strong> STRING]
LITERAL ::= <strong>"([^"] | \")*"</strong> <small>[REX]</small>
FUNCTION ::= STRING <strong>(</strong> [ SENTENCE {<strong>,</strong> SENTENCE} ] <strong>)</strong>
FORALL ::= <strong>forall (</strong> VARIABLE [<strong>,</strong> LITERAL] <strong>) {</strong> SENTENCE <strong>}</strong>
IF ::= <strong>if(</strong> SENTENCE <strong>) {</strong> SENTENCE <strong>}</strong> [<strong>else {</strong> SENTENCE <strong>}</strong>]
FORMAT ::= <strong>format(</strong> SENTENCE <strong>)</strong>
LINK ::= <strong>link(</strong> SENTENCE <strong>,</strong> [SENTENCE {<strong>,</strong> SENTENCE}] <strong>) {</strong> SENTENCE <strong>}</strong>
[<strong>else {</strong> SENTENCE <strong>}</strong>]
COUNT ::= <strong>count(</strong> VARIABLE <strong>)</strong>
KB ::= <strong>kb(</strong> SENTENCE <strong>)</strong>
STRING ::= <strong>[a-zA-Z0-9_]</strong> <small>[REX]</small>
</pre>
</td>
</tr>
</table>
<p>
<p>This is just a formal way of describing the language, but don't
worry if you don't understand it very well because just below these lines we'll
try to describe it in a more informal way.</p>
<p>To begin with, you should know that EL is a language designed to
work with strings (a string is a collection of characters) but it has also some
logic and comparison operations. One important thing you have to be aware of is
that in EL blank spaces, tabulators or carriage returns have no more meaning
than separator for elements of the language; that means that between two basic
elements you can have as many spaces or carriage returns as you want.</p>
<p>One of the basic elements of the language is what we call <em>LITERALS</em>.
These things represent constant string values; they are delimited by a pair of
double quote (") symbols surrounding the string you want to express. Everything
you put inside the double quotes will be considered as it is, so inside a
literal several spaces or carriage have meaning (it's the only case). If you
want to express a double quote symbol inside a literal you have to <em>escape</em>
it using \.</p>
<p>Some examples of literals:</p>
<ul>
<li>If you want to represent the string <em>hello</em>,
inside the EL you'll have to use <code>"hello"</code>.</li>
<li>For the string <em>hello "big"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; man</em>, the representation in EL is <code>"hello \"big\"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; man"</code>
(notice the escape characters and that spaces have meaning).</li>
<li><em>Let's see \""</em> string has to be expressed in this
way <code>"Let's see \\\"\""</code>.</li>
</ul>
<p>Another important basic element of the language is <em>VARIABLES</em>.
These elements represent string data from the input to which you can refer
inside of the language (and is considered also as a string). Variables are defined
in advance by the administrator (or even users) so you have to know which of
them you have access to. Additionally, variables can contain <em>FIELDS</em> that
are simply other input values that are grouped under a variable because they
have some kind of relationship between them (for example, you could have a
variable for the information about the author and fields like name, born place,
etc for it). If you want to know more about variables and their correspondence
with the input you can look at the <em>Mapping the Input</em> section. The way of
expressing a variable in EL is by a dollar symbol followed by any letter,
number or underscore; variables are case-insensitive. To refer to any field of
a variable, you simply put a dot followed by the field name (which is also made
up of any character, number or underscore).</p>
<p>Some examples about variables and fields:</p>
<ul>
<li>Imagine you have a variable which contains the author
information and which is called <em>author</em>, to represent in EL you would
have to write <code>"Author: " $100.a</code>. In every place
that $author appears BibFormat will consider the value defined for it from the
current input record.</li>
<li>Then you know that the field <em>name</em> of variable <em>author</em>
contains the author full name and you want to refer to it inside an EL
statement, so you'd write <code>$author.name</code>.</li>
<li>If we speak about CDS configuration, variable and field
names correspond to MARC 21 tag &amp; indicator names; so to refer to the main
title of a bibliographic record we should use variable <em>245</em> field <em>b</em>,
in EL terms: <code>$245.b</code>.</li>
</ul>
<p>Now that we know basic elements of the language we can start
thinking about how to combine them. The most important (and unique) string
operation is concatenation: adding strings. This operation is implicit to the
language, so we just put language elements one before another, and the representation
result will be the result of the basic elements one after another.</p>
<p>Some samples:</p>
<ul>
<li>To represent the constant string <em>Author:</em>
followed by the name of the author of the input record you should write <code>"Author: " $100.a</code> (it's supposed CDS
configuration in which MARC 21 notation is used; authors correspond to variable
100 field a).</li>
<li>You want to output the title in bold (always HTML
speaking) followed by the author in normal chars separated of the title by char
/: <code>"&lt;b&gt;" $245.b "&lt;/b&gt;/" $100.a</code></li>
</ul>
<p>These two, literals and variables, are only basic elements of
the EL. You can combine them using concatenation to get new strings. But, of
course, there are some more operations you can apply over strings: UDFs (<em>User
Defined Functions</em>). We'll also name these elements as functions, because
they are that: functions or operations to be applied over strings; when talking
about strings we include basic elements or resulting string from applying any
operations. A UDF has a name that identifies it uniquely and needs to get some information
that we call <em>parameters</em>. A UDF gives another string as result depending
on the parameter values (always strings). So to represent a function in EL you
need its name followed by an open parenthesis, the parameter values separated
by comas and a closing parenthesis. There's a list of UDF you can look at
through the interface but this list can be extended to fit your needs (look at <em>UDFs</em>
section of this manual).</p>
<p>Some examples:</p>
<ul>
<li>You want to ensure that the title of a bibliographic
record is always going to be in capital letters; good, there's a function
called <em>upper</em> that takes one parameter and gives as result the parameter
transformed in capital letters. You have to write the call like this: <code>upper($245.b)</code>.</li>
<li>You want only the 3 first chars of an author name to
appear in capital letters. We've seen there's a function for uppercasing a
string but there's another one, called <em>copy</em> that gets a sub string from
a string passed as first parameter from the char position indicated by the 2<sup>nd</sup>
parameter and with the length given by the 3<sup>rd</sup> one: <code>copy(
upper($100.a), "0", "3")</code>.</li>
</ul>
<p>As you can see, these UDFs are very powerful because you can
concatenate their result with another element (literal, variable or even
function) and the parameters can be basic elements or expressions. We can
extend this ensuring that any element or expression of the EL that gives as
result a string value can be combined with other EL expressions or elements.</p>
<p>Another very useful feature of EL is the possibility to use <em>KWONLEDGE
BASES</em> (KBs). A KB is just a set of key values that map (one-to-one) another
set of values; may be knowledge bases isn't a very appropriate name because
they are more like translation tables. BibFormat offers tools to create and
maintain KBs that can be used in the EL afterwards (see chapter <em>KBs
management</em> in this manual). You can see KB invocation as a special function
(the syntax for calling it is the same) with name <em>kb</em> and that takes two
parameters: one for indicating the KB name (BibFormat can handle several KBs)
and another one for the key value to translate. The result is the mapped KB
value or an empty string if it doesn't exist as a key value in the specified
KB. A typical example is when you have months with numbers and you want to
translate them into month names; you could have a KB that maps all the month
numbers to month names and then call it like this <code>kb("MONTH", $m)</code>.</p>
<p>Now let's move to <em>FORMATS</em>. Formats are some <em>EL</em>
code which is grouped under a label (a name) and that can be used in any other
EL statement. BibFormat allows the user to define as many formats as he wants
and identify each of them with a simple name. In few words, formats allow you
to reuse EL code; within a format you can put any EL code (even other format
calls) and all the variable values are completely available.  Again, a format call in EL follows the same
convention as functions: the word <em>format</em> followed by the format name (a
string) between parenthesis. When you call a format is like if the EL code
define inside that format was pasted, as it is in the place you make the call.</p>
<p>Example: Imagine you have to write the title of a bibliographic
records with a certain format, let's say in bold and red; but this formatted
title you are going to use it in several places. So can take advantages of EL
formats and define a format called <em>TITLE</em> that contains the code <code>"&lt;font color=\"red\"&gt;&lt;b&gt;" $245.b
"&lt;/b&gt;&lt;/font&gt;"</code>. Once this is done, you could use it to format
records by printing their title in that way and their author after it:
<code>format("TITLE") "/" $100.a</code>. The good thing
is that if some day you decide to change the title formatting you'd only need
to modify the <em>TITLE</em> format definition and not all the places where you
show the title.</p>
<p>At this point, you have seen basic elements and operations with
EL. You may think that is powerful enough to express your formatting work, but
there are more complex situations that you'll have to face. We have tried to
design the EL to be easy enough but with the next advanced structures,
sometimes, can arrive to be a bit complex.</p>
<p>All these basic elements and operations are quite OK. But there
are sometimes where you want to compare expressions and decide what to do
depending on the result of the comparison. For this purpose, EL has an IF
statement and a few comparison and logic operators built in (don't forget that
any functionality needed can be achieved by defining new UDFs; EL gives basic
operations to provide this possibility). Let's go step by step: First let's
talk about the set of operators that can be used in a comparison:</p>
<ol>
<li>Comparison operators: Equal and non-equal (=, !=). They take
two operators that have to be strings and produce a logic (true or false)
value.</li>
<li>Logical operators: AND, OR and NOT (&amp;&amp;, ||, !). All of
them have to be used over logical values, taking two operators AND and OR, and
one operator NOT.</li>
</ol>
<p>All of them are right associative (except NOT which is unary
left-associative) and their precedence goes like this (more to less): NOT,
(EQUAL, NON-EQUAL), (AND, OR). These operators cannot be used anywhere, only
inside statements that expect a logic value as result, in other words, inside
condition statements.</p>
<p>The IF structure is quite easy to learn: First we indicate the
word <em>IF</em> followed by a condition statement surrounded by parenthesis;
then a EL statement into braces can be specified, this statement will be
executed only if the condition was true; optionally, we can add an <em>ELSE</em>
word followed by another EL statement into braces, that will only be triggered
if the IF condition was not true.</p>
<p>Let's have a look at some examples:</p>
<ul>
<li>I want the title of a record to appear followed by the
constant <em>Author:</em> and its author afterwards. But it could be nice if the
constant string appeared only if the record has author:
<pre>
format("TITLE") if($100.a!="") { "Author: " $100.a }
</pre>
</ul>
<p>BibFormat is not only an EL processor. Among others, it contains
a link solver that contains it's own rule repository in order to be able to
automatically solve links (see chapter Link solver of this manual). EL has one
special structure for asking the link solver for some links and including them
in the formatted version of the bibliographic record. This way links are easy
to maintain (you modify the rules independently from where the link is being
used) and as re-usable as formats or UDFs. Links are identified by a label and
need some information to be passed as parameters; then an EL statement has to
be specified which will be effective only if the link is solved and inside
which, you'll have access to an special variable, named <em>LINK</em>, which
contains the solved link among other information (see chapter Link solver for
more information about which values are accessible); additionally, an else
statement can be added (following the same syntax as in the IF construction)
that will be effective only if the link can't be solved by the Link solver.</p>
<p>Example:</p>
<ul>
<li>We are with our typical example of the simple format
that contains the title and the author, but now we want the author to be linked
to the search. Supposing that a this kind of link is already defined under the
label "AUTHOR_SEARCH" we should proceed like this:
<pre>
format("TITLE") "/"
link("AUTHOR_SEARCH", $100.a)
{ "&lt;a href=\""$link "\"&gt;"$100.a"&lt;/a&gt;"}
</pre>
</li>
</ul>
<p>The next step when talking about EL components is to deal with
multiple values. Life is no so easy and, of course, and a bibliographic record
can have more than one author or can have a related document which is in more
than one format and that has to be linked. In other words, BibFormat supports
having variables and fields with multiple values (see chapter <em>Mapping input</em>),
consequently a way of applying an EL statement over all the values of a
variable or a field would be quite useful. <em>FORALL</em> is our construction!!
It allows you to specify a variable or a field followed by a EL statement
(between braces) that will be applied for every value of the variable or the
field; any reference to the iteration variable inside the <em>FORALL</em> EL
statement will be related to the current iteration variable value (if you refer
to a variable that has multiple values outside a <em>FORALL</em> the first value
is considered). One limitation is that you shouldn't nest <em>FORALL</em>
statements, in other words, never put a <em>FORALL</em> inside another one. This
construction let's you also limit the number of times you want to iterate over
a variable or field by adding a literal with the number of iterations.</p>
<p>Some examples:</p>
<ul>
<li>Let's continue refining our simple format; now we have
to consider that there can be more than one author for one bibliographic
record, so we want to show all of them with the link included, of course.
<pre>
format("TITLE") "/"
forall($100.a)
{
link("AUTHOR_SEARCH", $100.a)
{ "&lt;a href=\""$link "\"&gt;"$100.a"&lt;/a&gt;"}
}
</pre>
</li>
<li>Although this <em>FORALL</em> construction could seem not
very useful, it's used a lot when defining formats or behaviors. Quite often
you will have the case where you want only some EL piece of code to be
effective if a certain variable or field exist; <em>FORALL</em> can also be used
in that situation and it has to be said that is the most comfortable way of
doing it. Imagine the case you want the title, the constant string "Author: "
followed by the authors of a bibliographic record; but you don't want the
constant <em>"</em>Author: " to appear if there's no author at all. You could use
something like this:
<pre>
format("TITLE") " - "
forall($100.a)
{
rep_prefix("Author: ") $100.a " "
}
</pre>
As you can see we are
using a new function: <em>rep_prefix</em>. In fact this is an UDF which prints
the string passed as parameter only once at the beginning inside a <em>FORALL</em>
statement. But the interesting thing here is the <em>FORALL</em> application.</li>
</ul>
<p>Finally, there's still one EL special function: <em>COUNT</em>.
Due to certain special situations or strange input data in the variables,
sometimes is useful to know how many values contain a variable or a field. So
this function, simply takes a variable or field as argument and returns a
string with the number of values that contains; if the value returned is 0,
that means that no value is in the variable, what means that variable doesn't
exist or there weren't any values mapped from the input.</p>
<p>Examples:</p>
<ul>
<li>As this is the last example, let's do it a bit more
complicated: Continuing with our very well known simple format, we want all the
authors of the record appear if there are less than 10, in any other case we
want only the first one to appear followed by the string "et al.". We'll also
use a function called <em>GT</em> which returns a non-empty string if the first
parameter is greater than the second one.
<pre>
format("TITLE") "/"
if(gt(count($100.a), "10")!="")
{ $100.a "et al." }
else
{
forall($100.a)
{
link("AUTHOR_SEARCH", $100.a)
{ "&lt;a href=\""$link "\"&gt;"$100.a"&lt;/a&gt;"}
}
}
</pre>
</li>
</ul>
diff --git a/modules/bibformat/lib/Makefile.am b/modules/bibformat/lib/Makefile.am
index 21b30f481..027a78455 100644
--- a/modules/bibformat/lib/Makefile.am
+++ b/modules/bibformat/lib/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = common core
CLEANFILES = *~
diff --git a/modules/bibformat/lib/common/Makefile.am b/modules/bibformat/lib/common/Makefile.am
index a502d3da0..04dddae4c 100644
--- a/modules/bibformat/lib/common/Makefile.am
+++ b/modules/bibformat/lib/common/Makefile.am
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
phplibdir = $(libdir)/php/cdsware/bibformat/common
phplib_DATA = general.inc.php global.inc.php dbparams.inc.php
EXTRA_DIST = general.inc.php global.inc.php.wml dbparams.inc.php.wml
CLEANFILES = global.inc.php dbparams.inc.php *~ *.tmp
global.inc.php: global.inc.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdspage.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
dbparams.inc.php: dbparams.inc.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdspage.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibformat/lib/common/dbparams.inc.php.wml b/modules/bibformat/lib/common/dbparams.inc.php.wml
index 565f24bb0..277132867 100644
--- a/modules/bibformat/lib/common/dbparams.inc.php.wml
+++ b/modules/bibformat/lib/common/dbparams.inc.php.wml
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
$DB_HOST="<DBHOST>";
$DB_USER="<DBUSER>";
$DB_PASSWD="<DBPASS>";
$DB_DB="<DBNAME>";
?>
diff --git a/modules/bibformat/lib/common/general.inc.php b/modules/bibformat/lib/common/general.inc.php
index ddb0770f4..6450871c3 100644
--- a/modules/bibformat/lib/common/general.inc.php
+++ b/modules/bibformat/lib/common/general.inc.php
@@ -1,72 +1,72 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//----------------------------------------------------------------------
// General purpose functions
//----------------------------------------------------------------------
function array2str($a){
reset($a);
$t="[";
while(current($a))
{
$t.=current($a).",";
next($a);
}
return ($t."]");
}
//----------------------------------------------------------------------
function getmicrotime(){
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec +(float)$sec);
}
//----------------------------------------------------------------------
function printtime(){
$ti=gettimeofday();
print "<font color=\"red\">[".$ti["sec"].":".$ti["usec"]."]</font><br>";
}
//----------------------------------------------------------------------
function printDuration( $cad, $tini )
{
$t1=$tini["sec"]*1000000+$tini["usec"];
$tnow=gettimeofday();
$t2=$tnow["sec"]*1000000+$tnow["usec"];
$dur=($t2-$t1)/1000000;
print "<br><font color=\"blue\">$cad: $dur sec</font><br>";
}
//----------------------------------------------------------------------
function text2HTML($text)
{
$text=htmlspecialchars($text);
$text=str_replace("\n", "<br>", $text);
$text=str_replace(" ", "&nbsp;", $text);
return $text;
}
//----------------------------------------------------------------------
?>
diff --git a/modules/bibformat/lib/common/global.inc.php.wml b/modules/bibformat/lib/common/global.inc.php.wml
index dbb6a6852..ba6b389dd 100644
--- a/modules/bibformat/lib/common/global.inc.php.wml
+++ b/modules/bibformat/lib/common/global.inc.php.wml
@@ -1,53 +1,53 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
//---------------------------------------------------------------------
define(CORE_DIR, "<LIBDIR>/php/cdsware/bibformat/core/");
define(COMMON_DIR, "<LIBDIR>/php/cdsware/bibformat/common/");
define(WEBCONF_DIR, "<WEBDIR>/admin/bibformat/");
define(CDSLOGIN_DIR, "<WEBDIR>");
//---------------------------------------------------------------------
define(DB, COMMON_DIR."/dbparams.inc.php");
define(FUNCTION_LIB, COMMON_DIR."/general.inc.php");
define(MAIN, CORE_DIR."/FlexElink.inc.php");
define(RECORD_SEP, CORE_DIR."/RecordSeparator.inc.php");
define(VARIABLE_EXT, CORE_DIR."/OAISpecExtractor.inc.php");
define(PROCESSOR, CORE_DIR."/Processor.inc.php");
define(EXECUTOR, CORE_DIR."/AEvalLan.inc.php");
define(UDF_RETRIEVER, CORE_DIR."/UDFRetriever.inc.php");
define(FORMAT_RETRIEVER, CORE_DIR."/FormatRetriever.inc.php");
define(KB_RETRIEVER, CORE_DIR."/KBRetriever.inc.php");
define(INTVARS, CORE_DIR."/IntVars.inc.php");
define(LINK_RESOLVER, CORE_DIR."/LinkResolver.inc.php");
define(TIMELIMIT, <CFG_BIBFORMAT_TIME_LIMIT>);
?>
diff --git a/modules/bibformat/lib/core/AEvalLan.inc.php b/modules/bibformat/lib/core/AEvalLan.inc.php
index b5590a995..bd3f2468d 100644
--- a/modules/bibformat/lib/core/AEvalLan.inc.php
+++ b/modules/bibformat/lib/core/AEvalLan.inc.php
@@ -1,1607 +1,1607 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: AEvalLan.inc (flexElink core)
// Classes: LAEvalLan
// AELInterpreter
// AELNode
// AELAtribs
// AEvalLan
// AELExecutor
//
// Requires: FormatRetriever, UDFRetriever, KBRetriever
// Included: core/FormatRetriever.inc
// core/UDFRetriever.inc
// core/KBRetriever.inc
// general.inc
//
//
//==========================================================================
include_once(FORMAT_RETRIEVER);
include_once(UDF_RETRIEVER);
include_once(KB_RETRIEVER);
include_once(FUNCTION_LIB);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LAEvalLan
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Constants that define lexical categories
define(LAEL_NONE, -1);
define(LAEL_LITERAL, 0);
define(LAEL_VAR, 2);
define(LAEL_OPAR, 6);
define(LAEL_CPAR, 7);
define(LAEL_END, 8);
define(LAEL_FORALL, 10);
define(LAEL_FUNCTION, 13);
define(LAEL_COMA, 14);
define(LAEL_NOT, 15);
define(LAEL_COP, 16);
define(LAEL_LOP, 17);
define(LAEL_OBRACE, 18);
define(LAEL_CBRACE, 19);
define(LAEL_IF, 20);
define(LAEL_ELSE, 21);
define(LAEL_DOT, 22);
define(LAEL_FORMAT, 23);
define(LAEL_LINK, 24);
define(LAEL_KB, 25);
define(LAEL_COUNT, 26);
class LAEvalLan
{
var $text;
var $pos;
function LAEvalLan( $text )
{
$this->text=$text;
$this->pos=0;
}
function nextItem($debug=0)
{
$cat=LAEL_NONE;
$lex="";
$state=0;
while($state>=0)
{
if($this->pos>strlen($this->text))
{
$cat=LAEL_END;
$lex="";
break;
}
$cchar=$this->text[$this->pos];
switch($state)
{
case 0:
if($cchar=='"')
$state=1;
elseif($cchar=='$')
$state=5;
elseif($cchar=='(')
{
$cat=LAEL_OPAR;
$state=-1;
}
elseif($cchar==')')
{
$cat=LAEL_CPAR;
$state=-1;
}
elseif($cchar==',')
{
$cat=LAEL_COMA;
$state=-1;
}
elseif($cchar=='{')
{
$cat=LAEL_OBRACE;
$state=-1;
}
elseif($cchar=='}')
{
$cat=LAEL_CBRACE;
$state=-1;
}
elseif($cchar=='.')
{
$cat=LAEL_DOT;
$state=-1;
}
elseif($cchar=='!')
{
$lex.=$cchar;
$state=7;
}
elseif((($cchar=='&')&&($this->text[$this->pos+1]=='&'))||
(($cchar=='|')&&($this->text[$this->pos+1]=='|')))
{
$lex=$cchar.$this->text[$this->pos+1];
$this->pos++;
$cat=LAEL_LOP;
$state=-1;
}
elseif($cchar=='=')
{
$cat=LAEL_COP;
$lex=$cchar;
$state=-1;
}
elseif(($cchar=='>')||($cchar=='<'))
{
$cat=LAEL_COP;
$lex=$cchar;
if($this->text[$this->pos+1]=="=")
{
$lex.="=";
$this->pos++;
}
$state=-1;
}
elseif((($cchar>='a')&&($cchar<='z'))||
(($cchar>='A')&&($cchar<='Z'))||
(($cchar>='0')&&($cchar<='9')))
{
$lex.=$cchar;
$state=6;
}
$this->pos++;
break;
case 7:
if($cchar=='=')
{
$cat=LAEL_COP;
$lex.=$cchar;
$state=-1;
$this->pos++;
}
else
{
$cat=LAEL_NOT;
$state=-1;
}
break;
case 6:
if( (($cchar>='a')&&($cchar<='z'))||(($cchar>='A')&&($cchar<='Z'))||
(($cchar>='0')&&($cchar<='9'))||($cchar=='_')||($cchar=='.') )
{
$lex.=$cchar;
$this->pos++;
}
else
{
$lex=strtoupper($lex);
if($lex=="FORALL")
$cat=LAEL_FORALL;
elseif($lex=="IF")
$cat=LAEL_IF;
elseif($lex=="ELSE")
$cat=LAEL_ELSE;
elseif($lex=="FORMAT")
$cat=LAEL_FORMAT;
elseif($lex=="LINK")
$cat=LAEL_LINK;
elseif($lex=="KB")
$cat=LAEL_KB;
elseif($lex=="COUNT")
$cat=LAEL_COUNT;
else
$cat=LAEL_FUNCTION;
$state=-1;
}
break;
case 5:
if( (($cchar>='a')&&($cchar<='z'))||(($cchar>='A')&&($cchar<='Z'))||
(($cchar>='0')&&($cchar<='9'))||($cchar=='_') )
{
$lex.=$cchar;
$this->pos++;
}
else
{
$cat=LAEL_VAR;
$lex=strtoupper($lex);
$state=-1;
}
break;
case 1:
if($cchar!='"')
{
if(($cchar=='\\')&&($this->text[$this->pos+1]=='"'))
{
$lex.="\"";
$this->pos++;
}
else
$lex.=$cchar;
}
else
{
$cat=LAEL_LITERAL;
$state=-1;
}
$this->pos++;
break;
default:
break;
}
}
return array($cat, $lex);
}
}//end class: LAEvalLan
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: AELInterpreter
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
define(SCEL_VAR,0);
define(SCEL_LITERAL,1);
define(SCEL_FUNCTION, 2);
define(SCEL_FORALL, 3);
define(SCEL_IF, 4);
define(SCEL_OR, 5);
define(SCEL_AND, 6);
define(SCEL_EQUAL, 7);
define(SCEL_DIFFERENT, 8);
define(SCEL_NOT, 9);
define(SCEL_CONCAT, 11);
define(SCEL_SUBFIELD, 12);
define(SCEL_FORMAT, 13);
define(SCEL_LINK, 14);
define(SCEL_PARAMS, 15); //Not a Semantic cathegory, just a mark one
define(SCEL_KB, 16);
define(SCEL_COUNT, 17);
class AELInterpreter
{
var $vars;
var $format_ret;
var $udf_ret;
var $kb_ret;
var $link_res;
var $first;
var $last;
function AELInterpreter( $vars )
{
$this->vars=$vars;
$this->format_ret=& FormatRetriever::getInstance();
$this->udf_ret=& UDFRetriever::getInstance();
$this->kb_ret=& KBRetriever::getInstance();
$this->link_res=& LinkResolver::getInstance();
$this->first=1;
$this->last=0;
}
function interpret( & $node, $curr_var="" )
{
$str=""; //Will contain the son built string
//----------------------
// SCEL_LITERAL
//----------------------
if($node->cat==SCEL_LITERAL)
{
$str=$node->lex;
}
//----------------------
// SCEL_VAR
//----------------------
elseif($node->cat==SCEL_VAR)
{
if($node->hasSons())
{
//Only can have a SF son, so we should get its value from the
// internal vars
$str=$this->vars->getSFValue($node->lex, $node->sons[0]->lex);
}
else
{
$str=$this->vars->getValue($node->lex);
}
}
//----------------------
// SCEL_FUNCTION
//----------------------
elseif($node->cat==SCEL_FUNCTION)
{
$params=array();
foreach($node->sons as $son)
{
$value=$this->interpret( $son, $curr_var );
array_push($params, $value);
}
/*
$last=1;
$first=0;
if($curr_var!="")
{
$last=$this->vars->varExist($curr_var)&&
$this->vars->lastValue($curr_var);
$first=$this->vars->varExist($curr_var)&&
$this->vars->firstValue($curr_var);
}
*/
$first=$this->first;
$last=$this->last;
list($ok, $str)=$this->udf_ret->execute( $node->lex,
$params,
$last,
$first);
}
//----------------------
// SCEL_CONCAT
//----------------------
elseif($node->cat==SCEL_CONCAT)
{
foreach($node->sons as $son)
{
$str.=$this->interpret( $son, $curr_var );
}
}
//----------------------
// SCEL_EQUAL, SCEL_DIFERENT
//----------------------
elseif(($node->cat==SCEL_EQUAL)||($node->cat==SCEL_DIFFERENT))
{
$val1=$this->interpret( $node->sons[0], $curr_var );
$val2=$this->interpret( $node->sons[1], $curr_var );
$str="FALSE";
if(($node->cat==SCEL_EQUAL)&&($val1==$val2))
$str="TRUE";
elseif(($node->cat==SCEL_DIFFERENT)&&($val1!=$val2))
$str="TRUE";
}
//----------------------
// SCEL_AND, SCEL_OR
//----------------------
elseif(($node->cat==SCEL_AND)||($node->cat==SCEL_OR))
{
$temp=$this->interpret( $node->sons[0], $curr_var );
if(($node->cat==SCEL_AND)&&($temp=="FALSE"))
{
$str="FALSE";
}
elseif(($node->cat==SCEL_OR) &&($temp=="TRUE"))
{
$str="TRUE";
}
else
{
$str=$this->interpret( $node->sons[1], $curr_var );
}
}
//----------------------
// SCEL_KB
//----------------------
elseif($node->cat==SCEL_KB)
{
$kb_name=$node->sons[0]->lex;
$key=$this->interpret( $node->sons[1], $curr_var );
//$str=getKBValue( $kb_name, $key );
$str=$this->kb_ret->getValue( $kb_name, $key );
}
//----------------------
// SCEL_IF
//----------------------
elseif($node->cat==SCEL_IF)
{
$temp=$this->interpret( $node->sons[0], $curr_var );
if($temp=="TRUE")
{
$str=$this->interpret( $node->sons[1], $curr_var );
}
else
{
if($node->sons[2])
$str=$this->interpret( $node->sons[2], $curr_var );
}
}
//----------------------
// SCEL_LINK
//----------------------
elseif($node->cat==SCEL_LINK)
{
//First, get the link type which is specified in the first son
$linktype=$node->sons[0]->lex;
//Then let's have the param values which are specified by a PARAMS node
$params=array();
$tparams=$node->sons[1]->sons;
reset($tparams);
while($temp=current($tparams))
{
$pv=$this->interpret( $temp, $curr_var );
array_push($params, $pv);
next($tparams);
}
//Now call the linkresolver to solve the link
list($ok, $link, $linkvar)=$this->link_res->solveLink( $linktype,
$params );
if($ok)
{
$this->vars->add($linkvar);
$str=$this->interpret( $node->sons[2], $curr_var );
$this->vars->remove("LINK");
}
else
{
if($node->sons[3]!=null)
{
$str=$this->interpret( $node->sons[3], $curr_var );
}
}
}
//----------------------
// SCEL_FORALL
//----------------------
elseif($node->cat==SCEL_FORALL)
{
$varname=$node->lex;
$sfname="";
if($node->sons[0]!=null)
{
$sfname=$node->sons[0]->lex;
}
$maxiter=-1;
if($node->sons[1]!=null)
{
$maxiter=$node->sons[1]->lex;
}
if($this->vars->vreset($varname))
{
if(!$this->vars->isEmpty($varname))
{
$numvalues=$this->vars->countValues($varname, $sfname);
$str="";
$morevalues=1;
if($sfname!="")
$morevalues=$this->vars->vfirstSFValue($varname, $sfname);
$iter=0;
while($morevalues)
{
$iter++;
$this->first=0;
if($iter==1) $this->first=1;
$this->last=0;
if(($iter==$numvalues) ||
(($maxiter>=0) && ($iter>=$maxiter)))
$this->last=1;
$str.=$this->interpret( $node->sons[2], $varname );
if(($maxiter>=0)&&($iter>=$maxiter))
break;
if($sfname!="")
$morevalues=$this->vars->vnextSFValue($varname, $sfname);
else
$morevalues=$this->vars->vnextvalue($varname);
}
$this->vars->vreset($varname);
}
}
}
//----------------------
// SCEL_COUNT
//----------------------
elseif($node->cat==SCEL_COUNT)
{
$sf="";
if($node->sons[0]!=null)
{
$sf=$node->sons[0]->lex;
}
$str=$this->vars->countValues($node->lex, $sf);
}
//----------------------
// SCEL_NOT
//----------------------
elseif($node->cat==SCEL_NOT)
{
$temp=$this->interpret( $node->sons[0], $curr_var );
$str="TRUE";
if($temp=="TRUE")
$str="FALSE";
}
//----------------------
// SCEL_FORMAT
//----------------------
elseif($node->cat==SCEL_FORMAT)
{
$fname=$this->interpret( $node->sons[0], $curr_var );
//call to the format retriever in order to get the corresponding format
list($ok, $ftree)=$this->format_ret->getParsedFormat( $fname );
if($ok)
{
$str=$this->interpret( $ftree, $curr_var );
}
}
return $str;
}
}//end class: AELInterpreter
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: AELNode
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AELNode
{
var $cat;
var $lex;
var $sons;
function AELNode($cat, $lex="")
{
$this->cat=$cat;
$this->lex=$lex;
$this->sons=array();
}
function addSon( $son )
{
if($son)
array_push( $this->sons, $son );
}
function addSonNoCheck( $son )
{
array_push( $this->sons, $son );
}
function hasSons()
{
return count($this->sons);
}
function debug($prefix="")
{
print "$prefix Node(Cat: <b>".$this->cat."</b>--Lex: <b>".$this->lex."</b>)<br>";
foreach($this->sons as $son)
{
print $prefix.$this->cat."--".$this->lex." SON <br>";
$son->debug($prefix."..");
}
}
}//end clas: AELNode
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: AELAtribs
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AELAtribs
{
var $void;
function AELAtribs()
{
$this->void="";
}
}//end class: AELAtribs
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: AEvalLan
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AEvalLan
{
var $lexa;
var $cat;
var $text;
var $code;
var $debug;
var $vars;
var $tree;
var $udf_ret;
var $format_ret;
var $text_error;
var $notforall;
var $vars_needed;
var $formats_forbidden;
function AEvalLan()
{
$this->tree=null;
$this->udf_ret=& UDFRetriever::getInstance();
$this->format_ret=& FormatRetriever::getInstance();
$this->formats_forbidden = array();
}
function vars_needed( $text, $debug=false )
{
$this->debug=$debug;
$this->code=$text;
$this->notforall=0;
$this->vars_needed=array();
$this->lexa=new LAEvalLan( $this->code );
list($this->cat, $this->text)=$this->lexa->nextItem();
$ats=new AELAtribs();
if($this->auxS( $ats ))
{
$this->tree=$ats->tree;
return array(1, $this->vars_needed);
}
else
{
$this->tree=null;
$this->text_error.="(at char ".$this->lexa->pos.")<br>";
$cad=substr($this->code, 0, $this->lexa->pos-1);
$this->text_error.="<font color=\"black\">".htmlspecialchars($cad)."</font>";
return array(0, $this->text_error);
}
}
function notAllowFormats( $ff )
{
if(!is_array($ff)) {
$this->formats_forbidden = array( $ff );
}
else {
$this->formats_forbidden = $ff;
}
}
function parse( $text )
{
$this->debug=$debug;
$this->code=$text;
$this->notforall=0;
$this->vars_needed=array();
$this->lexa=new LAEvalLan( $this->code );
list($this->cat, $this->text)=$this->lexa->nextItem();
$ats=new AELAtribs();
if($this->auxS( $ats ))
{
$this->tree=$ats->tree;
return array(1, $this->tree);
}
else
{
$this->tree=null;
$this->text_error.="(at char ".$this->lexa->pos.")<br>";
$cad=substr($this->code, 0, $this->lexa->pos-1);
$this->text_error.="<font color=\"black\">".text2HTML($cad)."</font>";
return array(0, $this->text_error);
}
}
function getParsedTree( $text )
{
list($ok, $msg)=$this->parse( $text );
if($ok)
{
return array(1, $this->tree);
}
else
{
return array(0, $msg);
}
}
function execute( $vars )//, & $format_ret, & $udf_ret, & $kb_ret )
{
if(!$this->tree)
{
return array(0, "There isn't a previous compilation");
}
$err="";
$nulo=null;
$int=new AELInterpreter( $vars );
$str=$int->interpret( $this->tree );
$this->kb_ret->print_acc();
if($err!="")
return array(0, "Error interpreting: $err");
else
return array(1, $str);
}
function newexecute( $text, $vars, $debug=false )
{
$this->code=$text;
$this->notforall=0;
$this->vars_needed=array();
$this->lexa=new LAEvalLan( $this->code );
list($this->cat, $this->text)=$this->lexa->nextItem();
$ats=new AELAtribs();
if($this->auxS( $ats ))
{
$this->tree=$ats->tree;
$format_ret=new FormatRetriever();
list($err, $str)=$ats->tree->getResult($vars, "", $format_ret);
if($err!="")
{
return array(0, "Error interpreting: $err");
}
else
{
return array(1, $str);
}
}
else
{
$this->text_error.="(at char ".$this->lexa->pos.")";
return array(0, $this->text_error);
}
}
function auxS( & $aS )
{
//<S>-><E>end
if(in_array($this->cat, array(LAEL_NOT, LAEL_VAR,
LAEL_LITERAL, LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL,
LAEL_IF, LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT)))
{
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
if($this->cat==LAEL_END)
{
$aS->tree=$aE->tree;
$aS->type=$aE->type;
return 1;
}
}
}
//<S>->end
elseif($this->cat==LAEL_END)
{
$aS->tree=null;
$aS->type="STRING";
return 1;
}
return 0;
}
function auxE( & $aE )
{
//<E>-><T><Ep>
if(in_array($this->cat, array(LAEL_NOT, LAEL_VAR, LAEL_LITERAL,
LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL, LAEL_IF,
LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT)))
{
$aT=new AELAtribs();
if($this->auxT( $aT ))
{
$aEp=new AELAtribs();
$aEp->h=$aT->tree;
$aEp->th=$aT->type;
if($this->auxEp( $aEp ))
{
$aE->type=$aEp->ts;
$aE->tree=$aEp->s;
return 1;
}
}
}
else
{
$this->text_error="Expresion expected";
}
return 0;
}
function auxEp( & $aEp )
{
//<Ep>->lop<T><Ep>
if($this->cat==LAEL_LOP)
{
if($this->text=="&&")
$tempcat=SCEL_AND;
else
$tempcat=SCEL_OR;
list($this->cat, $this->text)=$this->lexa->nextItem();
$aT=new AELAtribs();
if($this->auxT( $aT ))
{
$temp=new AELNode( $tempcat );
$temp->addSon( $aEp->h );
$temp->addSon( $aT->tree );
$aEp1=new AELAtribs();
$aEp1->h=$temp;
if(($aEp->th!="BOOL")&&($aT->type!="BOOL"))
{
$this->text_error="Logical operations(&&,||) can only be applied over logical expressions";
return 0;
}
$aEp1->th="BOOL";
if($this->auxEp( $aEp1 ))
{
$aEp->s=$aEp1->s;
$aEp->ts=$aEp1->ts;
return 1;
}
}
}
//<Ep>->lambda
elseif(in_array($this->cat, array(LAEL_END, LAEL_CPAR, LAEL_COMA,
LAEL_CBRACE)))
{
$aEp->s=$aEp->h;
$aEp->ts=$aEp->th;
return 1;
}
return 0;
}
function auxT( & $aT )
{
//<T>-><F><Tp>
if(in_array($this->cat, array(LAEL_NOT, LAEL_VAR, LAEL_LITERAL,
LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL, LAEL_IF,
LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT)))
{
$aF=new AELAtribs();
if($this->auxF( $aF ))
{
$aTp=new AELAtribs();
$aTp->h=$aF->tree;
$aTp->th=$aF->type;
if($this->auxTp( $aTp ))
{
$aT->tree=$aTp->s;
$aT->type=$aTp->ts;
return 1;
}
}
}
return 0;
}
function auxTp( & $aTp )
{
//<Tp>->cop<F><Tp>
if($this->cat==LAEL_COP)
{
if($this->text=="=")
$tempcat=SCEL_EQUAL;
else
$tempcat=SCEL_DIFFERENT;
list($this->cat, $this->text)=$this->lexa->nextItem();
$aF=new AELAtribs();
if($this->auxF( $aF ))
{
if(($aTp->th!="STRING")&&($aF->type!="STRING"))
{
$this->text_error="Comparison operations(=,!=) can only be applied over STRING expressions";
return 0;
}
$temp=new AELNode( $tempcat );
$temp->addSon( $aTp->h );
$temp->addSon( $aF->tree );
$aTp1=new AELAtribs();
$aTp1->h=$temp;
$aTp1->th="BOOL";
if($this->auxTp( $aTp1 ))
{
$aTp->s=$aTp1->s;
$aTp->ts=$aTp1->ts;
return 1;
}
}
}
//<Tp>-><F><Tp>
elseif(in_array($this->cat, array(LAEL_NOT, LAEL_VAR, LAEL_LITERAL,
LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL, LAEL_IF,
LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT)))
{
$aF=new AELAtribs();
if($this->auxF( $aF ))
{
if(($aTp->th!="STRING")&&($aF->type!="STRING"))
{
$this->text_error="Can only concatenate STRING expressions";
return 0;
}
$temp=new AELNode( SCEL_CONCAT );
$temp->addSon( $aTp->h );
$temp->addSon( $aF->tree );
$aTp1=new AELAtribs();
$aTp1->h=$temp;
$aTp1->th="STRING";
if($this->auxTp( $aTp1 ))
{
$aTp->s=$aTp1->s;
$aTp->ts=$aTp1->ts;
return 1;
}
}
}
//<Tp>->lambda
elseif(in_array($this->cat, array(LAEL_LOP, LAEL_END, LAEL_CPAR,
LAEL_COMA, LAEL_CBRACE)))
{
$aTp->s=$aTp->h;
$aTp->ts=$aTp->th;
return 1;
}
return 0;
}
function auxF( & $aF )
{
//<F>->!<B>
if($this->cat==LAEL_NOT)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB=new AELAtribs();
if($this->auxB( $aB ))
{
if($aB->type!="BOOL")
{
$this->text_error="Cannot apply a NOT over a string expresion";
return 0;
}
$aF->type="BOOL";
$temp=new AELNode( SCEL_NOT );
$temp->addSon( $aB->tree );
$aF->tree=$temp;
return 1;
}
}
//<F>-><B>
elseif(in_array($this->cat, array(LAEL_VAR, LAEL_LITERAL, LAEL_FUNCTION,
LAEL_OPAR, LAEL_FORALL, LAEL_IF, LAEL_FORMAT,
LAEL_LINK, LAEL_KB, LAEL_COUNT)))
{
$aB=new AELAtribs();
if ($this->auxB( $aB ))
{
$aF->tree=$aB->tree;
$aF->type=$aB->type;
return 1;
}
}
return 0;
}
function auxB( & $aB )
{
//<B>->var
if($this->cat==LAEL_VAR)
{
$aB->tree=new AELNode( SCEL_VAR, $this->text );
list($this->cat, $this->text)=$this->lexa->nextItem();
$aSF=new AELAtribs();
if($this->auxSF( $aSF ))
{
$aB->tree->addSon( $aSF->tree );
$aB->type="STRING";
return 1;
}
}
//<B>->literal
elseif($this->cat==LAEL_LITERAL)
{
$aB->tree=new AELNode( SCEL_LITERAL, $this->text );
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB->type="STRING";
return 1;
}
//<B>->function(<LP>)
elseif($this->cat==LAEL_FUNCTION)
{
$aB->tree=new AELNode( SCEL_FUNCTION, $this->text );
$fname=$this->text;
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->auxLP( $aB ))
{
list($ok, $msg)=$this->udf_ret->validate( $fname, count($aB->tree->sons) );
if(!$ok)
{
$this->text_error=$msg;
return 0;
}
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
//By the time, a function will allways return a STRING value.
// If necessary we could distinguish between STRING or BOOL
// functions
$aB->type="STRING";
return 1;
}
else
$this->text_error="There is a ')' missing";
}
}
else
$this->text_error="Functions must be followed by '('";
}
//<B>->format( <E> )
elseif($this->cat==LAEL_FORMAT)
{
$aB->tree=new AELNode( SCEL_FORMAT );
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
if($aE->type!="STRING")
{
$this->text_error="FORMAT type has to be a must be a STRING";
return 0;
}
if($aE->tree->cat == SCEL_LITERAL)
{
if(in_array( strtoupper($aE->tree->lex), $this->formats_forbidden ))
{
$this->text_error="Recursive format call";
return 0;
}
}
$aB->tree->addSon( $aE->tree );
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB->type="STRING";
return 1;
}
}
}
}
//<B>->link( literal, <LP> )
elseif($this->cat==LAEL_LINK)
{
if($this->notlink)
{
$this->text_error="LINK statements cannot be nested";
return 0;
}
$aB->tree=new AELNode( SCEL_LINK );
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_LITERAL)
{
//Check if the link type exists
//Add the literal as first son of the tree
$aB->tree->addSon(new AELNode( SCEL_LITERAL, $this->text ));
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_COMA)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$this->notlink=1;
$temp=new AELAtribs();
$temp->tree=new AELNode( SCEL_PARAMS );
if($this->auxLP( $temp ))
{
$aB->tree->addSon( $temp->tree );
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB->type="STRING";
if($this->cat==LAEL_OBRACE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
if($aE->type!="STRING")
{
$this->text_error="Actions inside a LINK statement must be STRING";
return 0;
}
$aB->tree->addSon( $aE->tree );
if($this->cat==LAEL_CBRACE)
{
$this->notlink=0;
list($this->cat, $this->text)=$this->lexa->nextItem();
$aEls=new AELAtribs();
if($this->auxEls( $aEls ))
{
$aB->tree->addSon( $aEls->tree );
return 1;
}
}
}
}
else
{
$this->text_error="A '{' was expected";
return 0;
}
}
}
}
else
{
$this->text_error="A ',' was expected";
return 0;
}
}
else
{
$this->text_error="Link type has to be specified by a LITERAL in a LINK call";
return 0;
}
}
else
{
$this->text_error="A '(' was expected after a LINK call";
return 0;
}
}
//<B>->KB(literal, <E>)
elseif($this->cat==LAEL_KB)
{
$aB->tree=new AELNode( SCEL_KB );
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aE=new AELAtribs();
if($this->auxE( $aE))
{
if($aE->type!="STRING")
{
$this->text_error="The key parameter has to be a STRING in a KB call";
return 0;
}
if($this->cat==LAEL_COMA)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_LITERAL)
{
$aB->tree->addSon( new AELNode( SCEL_LITERAL, $this->text) );
$aB->tree->addSon($aE->tree);
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB->type="STRING";
return 1;
}
else
{
$this->text_error="A ')' was expected";
return 0;
}
}
else
{
$this->text_error="KB name has to be specified by a LITERAL in a KB call";
return 0;
}
}
else
{
$this->text_error="A ',' was expected after the key parameter in the KB call";
return 0;
}
}
}
else
{
$this->text_error="A '(' was expected after a KB call";
return 0;
}
}
//<B>->(<E>)
elseif($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->auxE( $aB ))
{
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
return 1;
}
else
$this->text_error="There is a ')' missing";
}
}
//<B>->forall(var<SF>){<E>}
elseif($this->cat==LAEL_FORALL)
{
if($this->notforall)
{
$this->text_error="You cannot use forall into an evaluation zone";
return 0;
}
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_VAR)
{
$aB->tree=new AELNode( SCEL_FORALL, $this->text );
list($this->cat, $this->text)=$this->lexa->nextItem();
$aSF=new AELAtribs();
if($this->auxSF( $aSF ))
{
$aB->tree->addSonNoCheck( $aSF->tree );
$aNi=new AELAtribs();
if($this->auxNi( $aNi ))
{
$aB->tree->addSonNoCheck( $aNi->tree );
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OBRACE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
if($aE->type!="STRING")
{
$this->text_error="FORALL can only be applied over a STRING exression";
return 0;
}
if($this->cat==LAEL_CBRACE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB->tree->addSon( $aE->tree );
$aB->type="STRING";
return 1;
}
}
}
}
}
}
}
else
{
$this->text_error="A VARIABLE expected in the FORALL declaration";
}
}
}
//<B>->if(<E>){<E>}<Els>
elseif($this->cat==LAEL_IF)
{
$aB->tree=new AELNode( SCEL_IF );
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$this->notforall++;
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
if($aE->type!="BOOL")
{
$this->text_error="IF condition must be a LOGIC expression";
return 0;
}
if($this->cat==LAEL_CPAR)
{
$aB->tree->addSon($aE->tree);
$this->notforall--;
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OBRACE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aE1=new AELAtribs();
if($this->auxE( $aE1 ))
{
if($aE1->type!="STRING")
{
$this->text_error="IF can only be applied over a STRING expression";
return 0;
}
if($this->cat==LAEL_CBRACE)
{
$aB->tree->addSon( $aE1->tree );
list($this->cat, $this->text)=$this->lexa->nextItem();
$aEls=new AELAtribs();
if($this->auxEls( $aEls ))
{
$aB->tree->addSon( $aEls->tree );
$aB->type="STRING";
return 1;
}
}
}
}
}
}
}
}
//<B>-> count( var <SF> )
elseif($this->cat==LAEL_COUNT)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_VAR)
{
$temp_var=$this->text;
list($this->cat, $this->text)=$this->lexa->nextItem();
$aSF=new AELAtribs();
if($this->auxSF( $aSF ))
{
if($this->cat==LAEL_CPAR)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aB->tree=new AELNode(SCEL_COUNT, $temp_var);
$aB->tree->addSon( $aSF->tree );
$aB->type="STRING";
return 1;
}
else
{
$this->text_error="A ')' was expected after the COUNT call";
}
}
}
else
{
$this->text_error="A VARIABLE was expected inside the COUNT call";
}
}
else
{
$this->text_error="A '(' expected after COUNT call";
}
}
return 0;
}
function auxNi( & $aNi )
{
//<Ni>->,literal
if($this->cat==LAEL_COMA)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_LITERAL)
{
$aNi->tree=new AELNode( SCEL_LITERAL, $this->text );
list($this->cat, $this->text)=$this->lexa->nextItem();
return 1;
}
else
{
$this->text_error="A LITERAL was expected";
}
}
//<Ni>->lambda
elseif($this->cat==LAEL_CPAR)
{
$aNi->tree=null;
return 1;
}
return 0;
}
function auxSF( & $aSF )
{
//<SF>->.function
if($this->cat==LAEL_DOT)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_FUNCTION)
{
$aSF->tree=new AELNode( SCEL_SUBFIELD, $this->text );
list($this->cat, $this->text)=$this->lexa->nextItem();
return 1;
}
else
{
$this->text_error="You have to specify the subfield";
}
}
//<SF>->lambda
elseif(in_array($this->cat, array( LAEL_COP, LAEL_NOT, LAEL_VAR,
LAEL_LITERAL, LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL, LAEL_IF,
LAEL_LOP, LAEL_END, LAEL_CPAR, LAEL_CBRACE, LAEL_COMA,
LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT, LAEL_CPAR )))
{
$aSF->tree=null;
return 1;
}
return 0;
}
function auxEls( & $aEls )
{
//<Els>->else{ <E> }
if($this->cat==LAEL_ELSE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
if($this->cat==LAEL_OBRACE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
if($aE->type!="STRING")
{
$this->text_error="ELSE can only be applied over a STRING expression";
return 0;
}
$aEls->tree=$aE->tree;
if($this->cat==LAEL_CBRACE)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
return 1;
}
}
}
}
//<Els>->lambda
elseif(in_array($this->cat, array( LAEL_COP, LAEL_NOT, LAEL_VAR,
LAEL_LITERAL, LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL, LAEL_IF,
LAEL_LOP, LAEL_END, LAEL_CPAR, LAEL_CBRACE, LAEL_COMA,
LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT )))
{
$aEls->tree=null;
return 1;
}
return 0;
}
function auxLP( & $aLP )
{
//<LP>-><E><LPp>
if(in_array($this->cat, array(LAEL_NOT, LAEL_VAR, LAEL_LITERAL,
LAEL_FUNCTION, LAEL_OPAR, LAEL_FORALL, LAEL_IF,
LAEL_FORMAT, LAEL_LINK, LAEL_KB, LAEL_COUNT)))
{
$aE=new AELAtribs();
if($this->auxE( $aE ))
{
$aLP->tree->addSon( $aE->tree );
$aLPp=new AELAtribs();
$aLPp->tree=$aLP->tree;
if($this->auxLPp( $aLPp ))
{
$aLP->tree=$aLPp->tree;
return 1;
}
}
}
//<LP>->lambda
elseif($this->cat==LAEL_CPAR)
{
return 1;
}
return 0;
}
function auxLPp( & $aLPp )
{
//<LPp>->,<LP>
if($this->cat==LAEL_COMA)
{
list($this->cat, $this->text)=$this->lexa->nextItem();
$aLP=new AELAtribs();
$aLP->tree=$aLPp->tree;
if($this->auxLP( $aLP ))
{
$aLPp->tree=$aLP->tree;
return 1;
}
}
//<LPp>->lambda
elseif($this->cat==LAEL_CPAR)
{
return 1;
}
}
}//end class: AEvalLan
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: AELExecutor
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AELExecutor {
var $link_res;
function AELExecutor( $create_handlers=1 )
{
$this->link_res=null;
}
function checkCode( $code )
{
$anz=new AEvalLan();
list($ok, $msg)=$anz->parse( $code );
unset($anz);
return array($ok, $msg);
}
function execTree( $tree, $vars )
{
if($tree==null) return array(0, "Empty tree to interpret");
$int=new AELInterpreter( $vars );
$str=$int->interpret( $tree, $vars );
unset($int);
return array( 1, $str );
}
function execCode( $code, $vars )
{
$anz=new AEvalLan();
$int=new AELInterpreter( $vars );
list($ok, $tree)=$anz->parse( $code );
unset($anz);
if(!$ok)
return array($ok, $tree);
$str=$int->interpret( $tree, $vars );
unset($int);
return array( 1, $str );
}
}
?>
diff --git a/modules/bibformat/lib/core/FlexElink.inc.php b/modules/bibformat/lib/core/FlexElink.inc.php
index a890bfb35..23981a6d5 100644
--- a/modules/bibformat/lib/core/FlexElink.inc.php
+++ b/modules/bibformat/lib/core/FlexElink.inc.php
@@ -1,144 +1,144 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//Main class
include(RECORD_SEP);
include(VARIABLE_EXT);
include(PROCESSOR);
class CreateOAIMARCXMLFactory {
function CreateOAIMARCXMLFactory()
{
$this->error="";
}
function error()
{
return $this->error;
}
function & createSeparator( $ifile="" )
{
$sep=new XMLSimpleRecSeparator();
$error=$sep->setIFile( $ifile );
if($error)
{
$this->error=$error;
return "";
}
$sep->setTag("record");
return $sep;
}
function & createExtractor()
{
$ext=new OAIVarExtractor();
return $ext;
}
}
class FlexElink {
function FlexElink()
{
}
function initialise( $itype, $ifile="" )
{
$this->itype=trim(strtoupper($itype));
if($itype=="OAIMARC")
$this->factory=new CreateOAIMARCXMLFactory();
else
return "Not suported input type: $itype";
$this->separator=& $this->factory->createSeparator( $ifile );
if(!$this->separator)
return "Error while creating the Record Separator: ".$this->factory->error();
$this->extractor=& $this->factory->createExtractor();
if(!$this->extractor)
return "Error while creating the Variable Extractor: ".$this->factory->error();
$this->processor=new Processor();
return "";
}
function getRecordResult($otypes, $debug=0)
{
$record=$this->clean($this->separator->getRecord());
//No more records
if($record=="")
return array(-1, "");
//More records
set_time_limit(TIMELIMIT);
$vars=$this->extractor->getVars("DEFAULT", $record);
if($vars==null)
return array(0, $this->extractor->getError());
if($debug)
$vars->debug();
$result="";
foreach($otypes as $otype)
{
if(trim($otype)=="")
continue;
list($ok, $msg)=$this->processor->getOutput( $vars, $otype, $record );
if($ok)
$result.=$msg;
else
return array(0, "Error processing record with otype '$otype':".$msg);
}
return array(1, $result);
}
function getResult( $otype, $itype, $ifile="" )
{
}
function clean($text)
{
$text = str_replace("\016","",$text);
$text = str_replace("\017","",$text);
$text = str_replace("\018","",$text);
$text = str_replace("\019","",$text);
$text = str_replace("\020","",$text);
$text = str_replace("\021","",$text);
$text = str_replace("\022","",$text);
$text = str_replace("\023","",$text);
$text = str_replace("\024","",$text);
$text = str_replace("\025","",$text);
$text = str_replace("\026","",$text);
$text = str_replace("\027","",$text);
$text = str_replace("\028","",$text);
$text = str_replace("\029","",$text);
$text = str_replace("\030","",$text);
$text = str_replace("\031","",$text);
$text = str_replace("\032","",$text);
$text = str_replace("\033","",$text);
$text = str_replace("\034","",$text);
$text = str_replace("\035","",$text);
$text = str_replace("\036","",$text);
$text = str_replace("\037","",$text);
return $text;
}
}
?>
diff --git a/modules/bibformat/lib/core/FormatRetriever.inc.php b/modules/bibformat/lib/core/FormatRetriever.inc.php
index 7cdd7fb9b..9002e4178 100644
--- a/modules/bibformat/lib/core/FormatRetriever.inc.php
+++ b/modules/bibformat/lib/core/FormatRetriever.inc.php
@@ -1,160 +1,160 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: FormatRetriever.inc (flexElink core)
// Classes: FormatRetriever
//
// Requires:
// Included: DB
//==========================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: FormatRetriever
// Purpose:
// Attributes:
// Visible Methods:
// getInstance ----->
// getFormatCode --->
// getParsedFormat ->
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class FormatRetriever {
var $cache; //Contains parsed formats, indexed by their format name
function FormatRetriever()
{
$this->cache=array();
}
/*---------------------------------------------------------------------
Method: getInstance (static)
Description: Gives a reference to an FormatRetriever ensurring that is the
only one that exists. For doing so, the Singleton pattern is followed.
Call always to this method instead of using the constructor
Parameters:
Return value: (FormatRetriever) Reference to the unique FormatRetriever
object
---------------------------------------------------------------------*/
function & getInstance()
{
static $instance;
if(!isset($instance))
{
$instance=new FormatRetriever();
}
return $instance;
}
/*---------------------------------------------------------------------
Method: getFormatCode
Description:
Parameters:
Return value:
---------------------------------------------------------------------*/
function getFormatCode( $fname )
{
$fname=strtoupper(trim($fname));
include(DB);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select value from flxFORMATS where name='".addslashes($fname)."'";
$qh=mysql_query( $qry, $db );
if(mysql_num_rows($qh)<1)
{
return array(0, "Format '$fname' not found");
}
$res=mysql_fetch_array( $qh );
mysql_close($db);
return array(1, $res["value"]);
}
/*---------------------------------------------------------------------
Method: getSerializedFormat
Description:
Parameters:
Return value:
---------------------------------------------------------------------*/
function getSerializedFormat ( $fname )
{
$fname=strtoupper(trim($fname));
if(isset($this->cache[$fname]))
{
return array(1, $this->cache[$fname]);
}
else
{
include(DB);
$db=mysql_pconnect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select serialized from flxFORMATS where name='".addslashes($fname)."'";
$qh=mysql_query( $qry, $db );
if(mysql_num_rows($qh)<1)
{
return array(0, "Format '$fname' not found");
}
$res=mysql_fetch_array( $qh );
$this->cache[$fname]=$res["serialized"];
return array(1, $res["serialized"]);
}
}
/*---------------------------------------------------------------------
Method: getParsedFormat
Description:
Parameters:
Return value:
---------------------------------------------------------------------*/
function getParsedFormat( $fname )
{
$fname=strtoupper(trim($fname));
if($fname=="")
{
return array(0, "Empty format name");
}
//First, check if we have the "compiled" format in local cache
//If the format is not in chache, we should go for it to the
// database, parse it, add compiled result (if succesful) to cache
// and return it
list($ok, $fcode)=$this->getSerializedFormat( $fname );
if($ok)
{
$tree=unserialize($fcode);
if($tree==null)
{
return array(0, "Bad format");
}
return array(1, $tree);
}
}
function applyFormat( $fname, $intvars )
{
}
}
?>
diff --git a/modules/bibformat/lib/core/IntVars.inc.php b/modules/bibformat/lib/core/IntVars.inc.php
index 3cf31e76f..eae469214 100644
--- a/modules/bibformat/lib/core/IntVars.inc.php
+++ b/modules/bibformat/lib/core/IntVars.inc.php
@@ -1,577 +1,577 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: IntVars.inc (flexElink core)
// Classes: IntVarValue
// Requires:
// Included:
//==========================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: IntVarValue
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class IntVarValue {
var $value; //string
var $sfvalues; //array that will contain subfield values for this value;
// key will indicate the sfname, and value will be the string
// value itself
//If a subfield hasn't existed for this value, it won't
// appear as a key in the array
function IntVarValue($value, $sfvalues=null)
{
$this->value=$value;
$this->sfvalues=array();
$this->addSFValues($sfvalues);
}
function hasSF( $sfname )
{
$sfname=strtoupper(trim($sfname));
//return in_array($sfname, array_keys($this->sfvalues));
return isset($this->sfvalues[$sfname]);
}
function addValue( $value )
{
//$this->value.=$value;
$this->value=$value;
}
function addSFValues( $sfvalues )
{
if($sfvalues)
{
foreach($sfvalues as $key=>$val)
{
$this->addSFValue($key, $val);
}
}
}
function addSFValue( $sfname, $sfvalue, $ow=true )
{
$sfname=strtoupper(trim($sfname));
if($ow)
$this->sfvalues[$sfname]=$sfvalue;
else
{
if(trim($this->sfvalues[$sfname])=="")
{
$this->sfvalues[$sfname]=$sfvalue;
}
}
}
function getValue()
{
return $this->value;
}
function getSFValue( $sfname )
{
$sfname=strtoupper(trim($sfname));
//if(!(in_array($sfname, array_keys($this->sfvalues))))
if(!isset($this->sfvalues[$sfname]))
return "";
else
return $this->sfvalues[$sfname];
}
}//end class: IntVarValue
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: IntVar
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class IntVar {
var $name; //string
var $values; //array that contains references to IntVarValue objects which
// each value of the variable
var $ipos;
var $vpos;
var $subfields; //array which will maintain a list of the variable subfields
function IntVar($name)
{
$this->name=strtoupper(trim($name));
$this->values=array();
$this->ipos=0;
$this->vpos=0;
$this->subfields=array();
}
function vreset()
{
$this->vpos=0;
}
function hasValue($num=-1)
{
if($num<0)
$num=$this->vpos;
return ($this->values[$num]==null);
}
function isEmpty()
{
return count($this->values);
}
function inextValue()
{
$this->ipos++;
}
function vnextValue()
{
if($this->vpos>=$this->ipos)
return 0;
$this->vpos++;
return !($this->vpos>=$this->ipos);
}
function vfirstSFValue($sfname)
{
$sfname=strtoupper(trim($sfname));
//if(!in_array($sfname, $this->subfields))
if(!isset($this->subfields[$sfname]))
{
return 0;
}
$this->vpos=0;
while(!$this->values[$this->vpos]->hasSF( $sfname ))
{
$this->vpos++;
if($this->vpos>=$this->ipos)
return 0;
}
return 1;
}
function vnextSFValue( $sfname )
{
$sfname=strtoupper(trim($sfname));
if($this->vpos>=$this->ipos)
return 0;
$this->vpos++;
if($this->vpos>=$this->ipos)
return 0;
while(!$this->values[$this->vpos]->hasSF( $sfname ))
{
$this->vpos++;
if($this->vpos>=$this->ipos)
return 0;
}
return 1;
}
function updateSF( $sfvalues )
{
if($sfvalues)
foreach(array_keys($sfvalues) as $sfname)
{
$sfname=strtoupper(trim($sfname));
//if(!in_array($sfname, $this->subfields))
if(!isset($this->subfields[$sfname]))
{
//array_push($this->subfields, $sfname);
$this->subfields[$sfname]=0;
}
}
}
function newValue( $value, $sfvalues=null)
{
//NOTE: if this function is called after the creation of the variable, it will
// produce the 0 value to be empty
$this->inextValue();
$this->addValue( $value, $sfvalues );
}
function addValue( $value, $sfvalues=null )
{
if(!$this->values[$this->ipos])
{
$this->values[$this->ipos]=new IntVarValue($value, $sfvalues);
}
else
{
$this->values[$this->ipos]->addValue($value);
$this->values[$this->ipos]->addSFValues($sfvalues);
}
$this->updateSF($sfvalues);
}
function getValue( $num=-1 )
{
if($num<0)
$num=$this->vpos;
if($this->values[$num]==null)
return "";
else
{
$temp=$this->values[$num]->getValue();
return $temp;
}
}
function getSFValue( $sfname, $num=-1 )
{
$sfname=strtoupper(trim($sfname));
//if(!in_array($sfname, $this->subfields))
if(!isset($this->subfields[$sfname]))
return "";
if($num<0)
$num=$this->vpos;
if($this->values[$num]==null)
return "";
else
{
return $this->values[$num]->getSFValue( $sfname );
}
}
function addSFValue( $sfname, $sfvalue, $ow=true )
{
$sfname=strtoupper(trim($sfname));
//if(!in_array($sfname, $this->subfields))
if(!isset($this->subfields[$sfname]))
{
$this->subfields[$sfname]=0;
}
if(!$this->values[$this->ipos])
$this->addValue("");
$this->values[$this->ipos]->addSFValue( $sfname, $sfvalue, $ow );
$this->subfields[$sfname]++;
}
function lastValue()
{
if(($this->vpos+1)==$this->ipos)
return 1;
return 0;
}
function firstValue()
{
return(($this->ipos>0)&&($this->vpos==0));
}
function countValues()
{
return count($this->values);
}
function countSFValues( $sfname )
{
$sfname=strtoupper(trim($sfname));
//if(!in_array($sfname, $this->subfields))
if(!isset($this->subfields[$sfname]))
{
return 0;
}
$counter=0;
return $this->subfields[$sfname];
}
}//end class: IntVar
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: Vars
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Vars {
var $list;
function Vars()
{
$this->list=array();
}
function add( $var )
{
if($var!=null)
{
$this->list[$var->name]=$var;
}
}
function remove( $varname )
{
$varname=strtoupper(trim($varname));
//if(in_array($varname, array_keys($this->list)))
//{
$this->list[$varname]=null;
unset($this->list[$varname]);
//}
}
function addVar( $varname )
{
$varname=strtoupper(trim($varname));
//if(!in_array($varname, array_keys($this->list)))
if(!isset($this->list[$varname]))
{
$this->list["$varname"]=new IntVar( $varname );
}
}
function varExist( $varname )
{
$varname=strtoupper(trim($varname));
//return in_array($varname, array_keys($this->list));
return isset($this->list[$varname]);
}
function countValues( $varname, $sf="" )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
if(trim($sf)=="")
{
return $this->list[$varname]->countValues();
}
return $this->list[$varname]->countSFValues( $sf );
}
return 0;
}
function addValue( $name, $value )
{
$temp=explode(".", $name);
$varname=strtoupper(trim($temp[0]));
if(!$this->varExist( $varname ))
{
$this->addVar( $varname );
}
if(count($temp)>1)//add the value to a subfield
{
$sfname=strtoupper(trim($temp[1]));
if($sfname!="")
$this->addSFValue($varname, $sfname, $value);
}
else
{
$this->addSValue($varname, $value);
}
}
function addSValue( $varname, $value, $sfvalues=null )
{
$varname=strtoupper(trim($varname));
//if(!in_array($varname, array_keys($this->list)))
if(!isset($this->list[$varname]))
{
return "";
}
else
{
$this->list[$varname]->addValue( $value, $sfvalues );
}
}
function addSFValue( $varname, $sfname, $sfvalue, $ow=true )
{
$varname=strtoupper(trim($varname));
//if(!in_array($varname, array_keys($this->list)))
if(!isset($this->list[$varname]))
{
return "";
}
else
{
$this->list[$varname]->addSFValue( $sfname, $sfvalue, $ow );
}
}
function inextValue($varname)
{
$varname=strtoupper(trim($varname));
$exists=0;
foreach(array_keys($this->list) as $k)
{
if("$k"==$varname)
{
$exists=1;
break;
}
}
if($exists)
{
$this->list[$varname]->inextValue( );
}
}
function getValue( $varname, $num=-1 )
{
$varname=strtoupper(trim($varname));
foreach(array_keys($this->list) as $k)
{
if(strcmp($varname,$k)==0)
{
return $this->list[$varname]->getValue( $num );
}
}
return "";
}
function getSFValue( $varname, $sfname, $num=-1 )
{
$varname=strtoupper(trim($varname));
if(!isset($this->list[$varname]))
{
return "";
}
else
{
return $this->list[$varname]->getSFValue( $sfname, $num );
}
}
function vreset( $varname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
$this->list[$varname]->vreset();
return 1;
}
return 0;
}
function lastValue( $varname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
return $this->list[$varname]->lastValue();
}
return 1;
}
function firstValue( $varname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
return $this->list[$varname]->firstValue();
}
return 0;
}
function isEmpty( $varname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
return !($this->list[$varname]->isEmpty());
}
else
return 1;
}
function vnextValue( $varname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
return $this->list[$varname]->vnextValue();
}
return 0;
}
function vnextSFValue( $varname, $sfname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
return $this->list[$varname]->vnextSFValue( $sfname );
}
function vfirstSFValue( $varname, $sfname )
{
$varname=strtoupper(trim($varname));
if($this->varExist($varname))
{
$sfname=strtoupper(trim($sfname));
return $this->list[$varname]->vfirstSFValue($sfname);
}
return 0;
}
function debug()
{
print '<table width="100%" border="1">'."\n";
print "<tr>\n";
print "<td>Name</td><td>Values</td><td>Subfield Values</td>\n";
print "</tr>\n";
foreach($this->list as $name=>$var)
{
print "<tr>\n";
print "<td>$name</td>\n";
print '<td><table width="100%">'."\n";
$cads=array();
foreach($var->values as $value)
{
print "<tr><td>".$value->getValue()."</td></tr>\n";
$cad="";
foreach($value->sfvalues as $sfname=>$sfvalue)
{
$cad.=$sfname."=".$sfvalue.",";
}
array_push($cads, $cad);
}
print "</table></td>\n";
print '<td><table width="100%">'."\n";
foreach($cads as $cad)
{
print "<tr><td>".$cad."</td></tr>\n";
}
print "</table></td>\n";
print "</tr>\n";
}
print "</table>";
}
}//end class: Vars
?>
diff --git a/modules/bibformat/lib/core/KBRetriever.inc.php b/modules/bibformat/lib/core/KBRetriever.inc.php
index b1256710b..d26628864 100644
--- a/modules/bibformat/lib/core/KBRetriever.inc.php
+++ b/modules/bibformat/lib/core/KBRetriever.inc.php
@@ -1,129 +1,129 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: KBRetriever.inc (flexElink core)
// Classes: KBRetriever
// Requires:
// Includes: DB
//==========================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: KBRetriever
// Purpose: Encapsulates the retrieving of KB values defined in the FlexElink
// consiguration DB. It implements an internal cache in order to minimize
// database accesses and optimize performace. It follows the Singleton
// pattern for ensuring the existence of a single instance of this class
// Attributes:
// db -----------> Persistent MySQL connection
// cache_tables -> Array for keeping in memory kb name-kb table
// correspondence retrieved from the DB
// cache_values -> Array for keeping in memory key-value correspondence
// for a certain KB and that have been already etrieved from the DB
// Methods:
// getInstance (static) --> returns an instance of this class assuring that
// is unique
// getValue --------------> returns the string value mapped for a given
// key value in a given KB configured inseide the flexElink DB. In
// case the key or KB don't exist, an empty string is retruned
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class KBRetriever
{
var $db;
var $cache_tables;
var $cache_values;
function KBRetriever()
{
srand((float)microtime()*10000000);
$this->cache_tables=array();
$this->cache_values=array();
include( DB );
$this->db=mysql_pconnect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $this->db );
$qry="select kb_name, kb_table
from flxKBS";
$qh=mysql_query($qry, $this->db);
while($row=mysql_fetch_array($qh))
{
list($kb_name, $kb_value)=$row;
$this->cache_tables["$kb_name"]="$kb_value";
}
}
/*---------------------------------------------------------------------
Method: getInstance
Description:
Parameters:
Return value: (KBRetriever)
---------------------------------------------------------------------*/
function & getInstance()
{
static $instance;
if(!isset($instance))
{
$instance=new KBRetriever();
}
return $instance;
}
/*---------------------------------------------------------------------
Method: getValue
Description:
Parameters:
kb_name (String) --> KB identifier in flexElink database from which the
value is going to be extracted
key (String) ------> Key value to search for inside the KB
Return value: (String) Mapped value corresponding to the KB and key values
given
---------------------------------------------------------------------*/
function getValue( $kb_name, $key )
{
if(!$this->db)
return "";
$kb_name=strtoupper(trim($kb_name));
$kb_table=$this->cache_tables[$kb_name];
if(!$kb_table)
{
return "";
}
$value=$this->cache_values["$kb_table##$key"];
if($value=="")
{
$key=addslashes($key);
$qry="select value from $kb_table where vkey='$key'";
$qh=mysql_query($qry, $this->db);
if(mysql_num_rows($qh)<1)
return "";
list($value)=mysql_fetch_array($qh);
if(count($this->cache_values)>100)
{
$k=array_rand($this->cache_values);
unset($this->cache_values["$k"]);
}
$this->cache_values["$kb_table##$key"]=$value;
}
return $value;
}
}
?>
diff --git a/modules/bibformat/lib/core/LinkResolver.inc.php b/modules/bibformat/lib/core/LinkResolver.inc.php
index 05c54f02a..83069be70 100644
--- a/modules/bibformat/lib/core/LinkResolver.inc.php
+++ b/modules/bibformat/lib/core/LinkResolver.inc.php
@@ -1,494 +1,494 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: LinkResolver.inc (flexElink core)
// Classes: LinkResolver
// Requires: AELExecutor, Vars, IntVar
// Included: EXECUTOR, INTVARS, DB
//==========================================================================
include_once(EXECUTOR);
include_once(INTVARS);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: Link
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Link {
var $type;
var $params;
var $conditions;
function Link( $type )
{
include( DB );
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$this->params=array();
$qry="select pname
from flxLINKTYPEPARAMS
where linktype='".addslashes($type)."'
order by ord";
$qh=mysql_query($qry, $db);
while($row=mysql_fetch_array($qh))
{
array_push($this->params, $row[0]);
}
$this->conditions=array();
$qry="select eval_order, el_condition, solvingtype, base_file, base_url
from flxLINKTYPECONDITIONS
where linktype='".$type."'
order by eval_order";
$qh=mysql_query($qry);
while($row=mysql_fetch_array($qh))
{
list($eorder, $ccode, $stype, $file, $url)=$row;
$d=new LinkConditionData();
$d->linktype=$type;
$d->eorder=$eorder;
$d->code=$ccode;
if($stype=="INT")
{
$d->file=$file;
$d->url=$url;
$c=new LinkConditionINT( $d );
}
else
{
$c=new LinkConditionEXT( $d );
}
if($c!=null)
array_push($this->conditions, $c);
}
//mysql_close($db);
}
function check( $par_values )
{
return (count($par_values)==count($this->params));
}
function solve( $par_values )
{
if(count($par_values)!=count($this->params))
{
return array(0, "Incorrect number of parameters");
}
$vars=new Vars();
for($i=0;$i<=count($this->params);$i++)
{
$vars->addValue($this->params[$i], $par_values[$i]);
}
foreach($this->conditions as $cond)
{
list($errcode, $link)=$cond->evaluate($vars);
if($errcode<0) return array(0, "$link");
if($errcode==0) continue;
return array(1, $link);
}
return array(0, "NOT SOLVED");
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkConditionData (non-visible)
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkConditionData{
var $linktype;
var $eorder;
var $code;
var $file;
var $url;
function LinkConditionData(){}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkConditionINT (implements LinkCondition)
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkConditionINT {
var $condition;
var $actions;
var $formats;
var $exec;
var $file_path;
var $url_path;
function LinkConditionINT( $data )
{
if($data==null) return null;
$this->exec=new AELExecutor();
list($ok, $msg)=$this->exec->checkCode( $data->code );
if(!$ok) return null;
$this->condition=$msg;
$this->file_path=$data->file;
$this->url_path=$data->url;
$this->actions=array();
$this->formats=array();
include( DB );
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select f.name, f.text, f.extensions
from flxFILEFORMATS f, flxLINKTYPECONDITIONSFILEFORMATS cf
where cf.linktype='".$data->linktype."'
and cf.eval_order='".$data->eorder."'
and f.name=cf.fname";
$qh=mysql_query($qry, $db);
while($row=mysql_fetch_array($qh))
{
$d=new LinkFileFormatData();
list($d->name, $d->description, $ext)=$row;
$d->extensions=array();
if(trim($ext)!="")
$d->extensions=explode("|", $ext);
$format=new LinkFileFormat( $d );
if($format==null) continue;
array_push($this->formats, $format);
}
$qry="select el_code
from flxLINKTYPECONDITIONSACTIONS
where linktype='".$data->linktype."'
and eval_order=".$data->eorder."
order by apply_order";
$qh=mysql_query($qry, $db);
while($row=mysql_fetch_array($qh))
{
$d=new LinkActionData();
list($d->code)=$row;
$action=new LinkAction($d);
if(!$action) continue;
array_push($this->actions, $action);
}
mysql_close($db);
}
function evaluate( $vars )
{
list($ok, $res)=$this->exec->execTree( $this->condition, $vars );
if(!$ok) return array(-1, "Error evaluating condtion: $res");
if($res=="FALSE") return array(0, "FALSE");
if(count($this->actions)==0) return array(0, "NO ACTIONS");
$v=new IntVar("LINK");
$generated=false;
foreach($this->actions as $action)
{
list($ok, $res)=$action->getResult( $vars );
if(!$ok) return array(-1, "Error evaluating action: $res");
$file=$this->file_path.$res;
$url=$this->url_path.$res;
if(count($this->formats)>0)
{
foreach($this->formats as $format)
{
foreach($format->composeFilePaths( $file, $url ) as $i)
{
list($full_file, $full_url)=$i;
$testfh=@ fopen($full_file, "r");
if($testfh)
{
$generated=true;
fclose($testfh);
$v->addValue($full_url);
$v->addSFValue("url", $full_url);
$v->addSFValue("file", $full_file);
$v->addSFValue("format_id", $format->getName());
$v->addSFValue("format_desc", $format->getDesc());
$v->inextValue();
}
}
}
}
if($generated===true) break;
$testfh=@ fopen($file, "r");
if($testfh)
{
$generated=true;
fclose($testfh);
$v->addValue($url);
$v->addSFValue("url", $url);
$v->addSFValue("file", $url);
break;
}
}
if($generated)
return array(1, $v);
return array(0, "NO LINK");
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkFileFormatData (non-visible)
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkFileFormatData {
var $name;
var $description;
var $extensions;
function LinkFileFormatData(){}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkFileFormat
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkFileFormat {
var $description;
var $name;
var $extensions;
function LinkFileFormat( $data )
{
if($data==null) return null;
$this->name=$data->name;
$this->description=$data->description;
$this->extensions=$data->extensions;
}
function getName()
{
return $this->name;
}
function getDesc()
{
return $this->description;
}
function composeFilePaths( $base_path, $base_url )
{
$res=array();
foreach($this->extensions as $ext)
{
$ext=trim($ext);
if($ext=="") continue;
array_push( $res, array($base_path.".".$ext, $base_url.".".$ext) );
}
return $res;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkConditionEXT (implements LinkCondition)
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkConditionEXT {
var $condition;
var $action;
var $exec;
function LinkConditionEXT( $data )
{
if($data==null) return null;
$this->exec=new AELExecutor();
list($ok, $msg)=$this->exec->checkCode( $data->code );
if(!$ok) return null;
$this->condition=$msg;
include( DB );
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select el_code
from flxLINKTYPECONDITIONSACTIONS
where linktype='".$data->linktype."'
and eval_order=".$data->eorder."
order by apply_order";
$qh=mysql_query($qry, $db);
$d=new LinkActionData();
list($d->code)=mysql_fetch_array($qh);
mysql_close($db);
if(!$d->code) return null;
if(!($this->action=new LinkAction($d))) return null;
}
function evaluate( $vars )
{
list($ok, $res)=$this->exec->execTree( $this->condition, $vars );
if(!$ok) return array(-1, "Error evaluating condtion: $res");
if($res=="FALSE") return array(0, "FALSE");
list($ok, $res)=$this->action->getResult( $vars );
if(!$ok) return array(-1, "Error evaluating action: $res");
$v=new IntVar("LINK");
$v->addValue($res);
$v->addSFValue("url", "$res");
$v->inextValue();
return array(1, $v);
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkActionData (non-visible)
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkActionData {
var $code;
function LinkActionData(){}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkAction
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkAction {
var $action;
var $exec;
function LinkAction($data)
{
if($data==null) return null;
$this->exec=new AELExecutor();
list($ok, $msg)=$this->exec->checkCode( $data->code );
if(!$ok) return null;
$this->action=$msg;
}
function getResult($vars)
{
return $this->exec->execTree( $this->action, $vars );
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: LinkResolver
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class LinkResolver {
var $db;
var $a;
var $links;
function LinkResolver() {
$this->links=array();
}
function & getInstance()
{
static $instance;
if(!isset($instance))
{
$instance=new LinkResolver();
}
return $instance;
}
function getLink($type)
{
$type=strtoupper(trim($type));
if(isset($this->links[$type]))
{
return $this->links[$type];
}
else
{
include( DB );
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select linktype
from flxLINKTYPES
where linktype='$type'";
$qh=mysql_query($qry);
if(mysql_num_rows($qh)!="1") return null;
mysql_close($db);
$link=new Link($type);
if($link==null) return null;
$this->links[$type]=$link;
return $link;
}
}
function destroy()
{
//mysql_close( $this->db );
}
function checkLink( $linktype, $params ) {
$l=$this->getLink( $linktype );
if($l==null) return 0;
return $l->check($params);
}
function solveLink( $linktype, $params ) {
$l=$this->getLink($linktype);
if($l==null) return array(0, "Incorrect link");
list($ok, $res)=$l->solve($params);
if(!$ok) return array(0, $res);
return array(1, $link_url, $res);
}
}//end class
?>
diff --git a/modules/bibformat/lib/core/Makefile.am b/modules/bibformat/lib/core/Makefile.am
index 65856d26f..cef3739ac 100644
--- a/modules/bibformat/lib/core/Makefile.am
+++ b/modules/bibformat/lib/core/Makefile.am
@@ -1,37 +1,37 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
phplibdir = $(libdir)/php/cdsware/bibformat/core
phplib_DATA = AEvalLan.inc.php \
FlexElink.inc.php \
FormatRetriever.inc.php \
IntVars.inc.php \
KBRetriever.inc.php \
LinkResolver.inc.php \
OAISpecExtractor.inc.php \
Processor.inc.php \
RecordSeparator.inc.php \
Timing.inc.php \
TreeNode.inc.php \
UDFRetriever.inc.php
EXTRA_DIST = $(phplib_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/bibformat/lib/core/OAISpecExtractor.inc.php b/modules/bibformat/lib/core/OAISpecExtractor.inc.php
index 6ae5c7f9b..4fe39956c 100644
--- a/modules/bibformat/lib/core/OAISpecExtractor.inc.php
+++ b/modules/bibformat/lib/core/OAISpecExtractor.inc.php
@@ -1,329 +1,329 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: OAISpecExtractor.inc (flexElink core)
// Classes: OAIVarExtractor
// Requires: Vars
// Included: core/IntVars.inc, DB
//==========================================================================
include_once(INTVARS);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: OAIVarExtractor
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class OAIVarExtractor {
var $xml_parser;
var $doc;
var $db;
var $type;
var $errortext;
var $intvars;
var $CFcache;
var $MFcache;
var $SFcache;
function OAIVarExtractor()
{
include( DB );
$this->db=$db=mysql_pconnect( $DB_HOST, $DB_USER, $DB_PASSWD );
if($this->db)
mysql_selectdb( $DB_DB, $this->db );
$this->errortext="";
$this->CFcache=array();
$this->MFcache=array();
$this->SFcache=array();
}
function destroy()
{
}
function getError()
{
return $this->errortext;
}
function inCFcache( $tag )
{
return $this->CFcache["$tag"];
}
function addCFcache($tag, $vars)
{
$this->CFcache["$tag"]=$vars;
}
function inMFcache($id, $i1, $i2)
{
return $this->MFcache["$id::$i1::$i2"];
}
function addMFcache($id, $i1, $i2, $vars)
{
$this->MFcache["$id::$i1::$i2"]=$vars;
}
function inSFcache($varname, $label)
{
return $this->SFcache["$varname::$label"];
}
function addSFcache($varname, $label, $vars)
{
$this->SFcache["$varname::$label"]=$vars;
}
function getVarfromCF( $tag )
{
$vars=$this->inCFcache( $tag );
if($vars!=null)
return $vars;
$tag=addslashes($tag);
$qry="select varname, mvalues from flxXMLMARCEXTRULES where type='".
addslashes($this->type)."' and att_id='$tag'
and ftype='CONTROLFIELD'";
$res=mysql_query($qry, $this->db);
$vars=array();
while($row=mysql_fetch_array($res))
{
array_push( $vars, array($row["varname"], $row["mvalues"]) );
}
$this->addCFcache( $tag, $vars );
return $vars;
}
function getVarfromMF( $id, $i1, $i2 )
{
$vars=$this->inMFcache( $id, $i1, $i2 );
if($vars!=null)
return $vars;
$id=addslashes($id);
$i1=addslashes($i1);
$i2=addslashes($i2);
$qry="select varname, mvalues from flxXMLMARCEXTRULES where type='".
addslashes($this->type)."' and att_id='".addslashes($id).
"' and att_i1='".addslashes($i1)."' and att_i2='".addslashes($i2)."'";
$res=mysql_query($qry, $this->db);
$vars=array();
while($row=mysql_fetch_array($res))
{
array_push( $vars, array($row["varname"], $row["mvalues"]) );
}
$this->addMFcache( $id, $i1, $i2, $vars );
return $vars;
}
function getVarfromSF( $varname, $label )
{
$vars=$this->inSFcache( $varname, $label );
if($vars!=null)
return $vars;
$varname=addslashes($varname);
$label=addslashes($label);
$qry="select sfname from flxXMLMARCEXTRULESUBFIELDS where type='".
addslashes($this->type)."' and varname='".addslashes($varname).
"' and att_label='".addslashes($label)."'";
$res=mysql_query($qry, $this->db);
$vars=array();
while($row=mysql_fetch_array($res))
{
array_push( $vars, $row["sfname"] );
}
$this->addSFcache( $varname, $label, $vars );
return $vars;
}
function getVars( $type, $doc )
{
$this->type=strtoupper(trim($type));
if(!$this->db)
{
$this->errortext="Invalid database resource";
return null;
}
$this->intvars=new Vars();
$this->insideCF=0;
$this->insideMF=0;
$this->insideSF=0;
$this->ignore=0;
$this->doc=$doc;
$this->xml_parser=xml_parser_create();
xml_set_object($this->xml_parser, &$this);
xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, 1);
xml_set_element_handler($this->xml_parser, "startElement", "endElement");
xml_set_character_data_handler($this->xml_parser, "characterData");
if(!xml_parse($this->xml_parser, $doc, 1))
{
$this->errortext=sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($this->xml_parser)),
xml_get_current_line_number($this->xml_parser));
xml_parser_free($this->xml_parser);
return null;
}
xml_parser_free($this->xml_parser);
return $this->intvars;
}
function startElement($parser, $name, $attrs)
{
if($this->ignore>0)
{
$this->ignore++;
return;
}
if($name=="CONTROLFIELD")
{
if($this->insideCF)
{
$this->ignore--;
return;
}
$this->insideCF=1;
$this->tempCF="";
$this->varsCF=$this->getVarfromCF( $attrs["TAG"] );
}
elseif($name=="DATAFIELD")
{
//If we are already processing a VARFIELD element and we find another
// one inside, it's a wrong XML, so we just ignore until the wrong
// element and all it contains is finished
if( ($this->insideMF) || ($this->insideCF) )
{
$this->ignore++;
return;
}
$this->insideMF=1;
$this->tempMF="";
$this->varsMF=$this->getVarfromMF(
$attrs["TAG"], $attrs["IND1"], $attrs["IND2"]);
}
elseif($name=="SUBFIELD")
{
//When we find a SUBFIELD element, we need to check that it's contained
// by a VARFIELD one. It's also a wrong XML if we find another SUBFIELD
// tag inside it
if((!$this->insideMF)||($this->insideSF))
{
$this->ignore++;
return;
}
$this->insideSF=1;
$this->tempSF="";
$this->labelSF=$attrs["CODE"];
}
//For other types of TAGs we don't care, because is supposed that the
// input will be OK
else
{
if($name!="RECORD")
$this->ignore++;
}
}
function endElement($parser, $name)
{
if($this->ignore>0)
{
$this->ignore--;
return;
}
if($name=="CONTROLFIELD")
{
$this->insideCF=0;
if(($this->varsCF!=null)&&(count($this->varsCF)>0))
{
foreach($this->varsCF as $var)
{
list($varname, $mvalues)=$var;
$this->intvars->addValue( $varname, $this->tempCF );
if($mvalues=="S")
$this->intvars->inextValue( $varname );
}
}
}
//As the XML parser will check the validness of the XML, there is no
// possibility to find a closing DATAFIELD before a closing SUBFIELD, so
// we don't need to check it
elseif($name=="DATAFIELD")
{
$this->insideMF=0;
if(($this->varsMF!=null)&&(count($this->varsMF)>0))
{
foreach($this->varsMF as $var)
{
list($varname, $mvalues)=$var;
$this->intvars->addValue( $varname, $this->tempMF );
if($mvalues=="S")
$this->intvars->inextValue( $varname );
}
}
}
elseif($name=="SUBFIELD")
{
$this->insideSF=0;
if(($this->varsMF!=null)&&(count($this->varsMF)>0))
{
foreach($this->varsMF as $var)
{
list($varname, $mvalues)=$var;
$this->intvars->addVar($varname);
$ow=true;
if($mvalues!="S") $ow=false;
$sfs=$this->getVarfromSF( $varname, $this->labelSF );
if(($sfs!=null)&&(count($sfs)>0))
{
foreach($sfs as $sfname)
{
$this->intvars->addSFValue( $varname, $sfname, $this->tempSF, $ow );
}
}
}
}
}
}
function characterData($parser, $data)
{
if($this->ignore>0)
return;
if($this->insideCF)
{
$this->tempCF.=$data;
}
elseif($this->insideMF)
{
if($this->insideSF)
$this->tempSF.=$data;
else
$this->tempMF.=$data;
}
}
}
?>
diff --git a/modules/bibformat/lib/core/Processor.inc.php b/modules/bibformat/lib/core/Processor.inc.php
index 4a8cbe310..7053beff8 100644
--- a/modules/bibformat/lib/core/Processor.inc.php
+++ b/modules/bibformat/lib/core/Processor.inc.php
@@ -1,316 +1,316 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: Processor.inc (flexelink core)
// Classes: Processor
// Requires: AELExecutor, LinkResolver, Node, AVarSpec
// Included: core/AEvalLan.inc
// core/LinkResolver.inc
// core/TreeNode.inc
// core/ASpec.inc
// dbparams.inc
//==========================================================================
include_once( EXECUTOR );
include_once( LINK_RESOLVER );
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class BehaviorData {
var $name;
function BehaviorData(){}
}
class NBehavior {
var $conditions;
function NBehavior( $data )
{
include(DB);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select eval_order, el_condition
from flxBEHAVIORCONDITIONS
where otype='".$data->name."'
order by eval_order";
$qh=mysql_query($qry, $db);
$this->conditions=array();
while($row=mysql_fetch_array($qh))
{
list($eorder, $ccond)=$row;
$d=new BehCondData();
$d->behname=$data->name;
$d->eorder=$eorder;
$d->code=$ccond;
$bc=new BehCondition( $d );
if($bc!=null)
{
array_push($this->conditions, $bc);
}
}
//mysql_close($db);
}
function getResult( $vars, $record="" )
{
foreach($this->conditions as $condition)
{
if($condition==null) continue;
list($errcode, $str)=$condition->evaluate( $vars );
if($errcode<0) return array(0, $str);
if($errcode==1) return array(1, $str);
}
return array(1, "");
}
}
class IBehavior {
var $conditions;
function IBehavior( $data )
{
include(DB);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select eval_order, el_condition
from flxBEHAVIORCONDITIONS
where otype='".$data->name."'
order by eval_order";
$qh=mysql_query($qry, $db);
$this->conditions=array();
while($row=mysql_fetch_array($qh))
{
list($eorder, $ccond)=$row;
$d=new BehCondData();
$d->behname=$data->name;
$d->eorder=$eorder;
$d->code=$ccond;
$bc=new BehCondition( $d );
if($bc!=null)
array_push($this->conditions, $bc);
}
//mysql_close($db);
}
function getResult( $vars, $record="" )
{
$str="";
foreach($this->conditions as $condition)
{
if($condition==null) continue;
list($errcode, $str)=$condition->evaluate( $vars );
if($errcode<0) return array(0, $str);
if($errcode==1) break;
}
$record=trim($record);
$end_tag="</record>";
$result=substr($record, 0, strlen($record)-strlen($end_tag)).$str.$end_tag;
return array(1, $result);
}
}
class BehCondData {
var $behname;
var $eorder;
var $code;
function BehCondData(){}
}
class BehCondition {
var $exec;
var $condition;
var $actions;
function BehCondition( $data )
{
$this->exec=new AELExecutor();
$this->condition=null;
$this->actions=array();
list($ok, $msg)=$this->exec->checkCode( $data->code );
if(!$ok) return null;
$this->condition=$msg;
include( DB );
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select el_code
from flxBEHAVIORCONDITIONSACTIONS
where otype='".$data->behname."'
and eval_order=".$data->eorder."
order by apply_order";
$qh=mysql_query($qry, $db);
while($row=mysql_fetch_array($qh))
{
list($ok, $msg)=$this->exec->checkCode($row[0]);
if($ok)
{
array_push($this->actions, $msg);
}
}
mysql_close($db);
}
function evaluate( $vars )
{
list($ok, $res)=$this->exec->execTree( $this->condition, $vars );
if(!$ok) return array(-1, "Error executing action: $res");
if($res!="TRUE") return array(0, "FALSE");
$str="";
foreach($this->actions as $action)
{
list($ok, $res)=$this->exec->execTree( $action, $vars);
if(!$ok) continue;
$str.=$res;
}
return array(1, $str);
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: Processor
// Purpose: This is a wrapper class for the FlexElink formatting process.
// It allows to apply a certaint pre-configured (in the Fxk config DB)
// behavior with a set of internal variables from a single record, and
// gives back resulting string. There is a (private) method for each
// different type of behavior that the processor has to interpret: NORMAL,
// IENRICH. It's able to apply corresponding method for each behavior type
// (Visible) Atributes: all private
// (Visible) Methods:
// constructor --> initializes processor
// getOutput(intvars, otype, xml_doc*) ----> applies "otype"
// pre-configured behavior from the configuration DB
// with the internal vars "intvars" for obtaining the
// resulting string.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Processor {
var $behaviors;
//---------------------------------------------------------------------------
// Method: CONSTRUCTOR Processor (public)
// Description: Initializes class atributes needed to function. Creates the
// link to the config DB; the instance of the code executor and link
// resolver; sets the link resolver for the code executor(in order to
// enable link resolution on the executor)
// Params:
//---------------------------------------------------------------------------
function Processor()
{
$this->behaviors=array();
}
//---------------------------------------------------------------------------
// Method: DESTRUCTOR destroy (public)
// Description:
// Params:
//---------------------------------------------------------------------------
function destroy()
{
}
function getBehavior( $behname )
{
$behname=strtoupper(trim($behname));
if(trim($behname)=="") return null;
if(isset($this->behaviors[$behname]))
{
return $this->behaviors[$behname];
}
else
{
include( DB );
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $db );
$qry="select type
from flxBEHAVIORS
where name='$behname'";
$qh=mysql_query($qry, $db);
if(mysql_num_rows($qh)!=1)
$res=null;
else
{
list($type)=mysql_fetch_array($qh);
$d=new BehaviorData();
$d->name=$behname;
if($type=="NORMAL")
{
$res=new NBehavior( $d );
}
elseif($type=="IENRICH")
{
$res=new IBehavior( $d );
}
if($res!=null)
{
$this->behaviors[$behname]=$res;
}
}
// mysql_close($db);
return $res;
}
}
//---------------------------------------------------------------------------
// Method: getOutput (public)
// Description: This method takes a behavior identifier as parameter,
// retrieves it from the config DB, checks the type of behavior, applies
// in each case corresponding private method, and gives the result or
// an error if something didn't go well.
// Params:
// intvars -> (Vars) reference to the internal vars collection extracted
// from the record over which the behavior has to be applied
// otype ---> (string) Output type or behavior identifier to apply and
// that has to be pre-configure in the config DB
// xml_doc -> (string) It's optional. In case of specified, it contains the
// XML document of the record being processed (mandatory for
// enriching behavior types)
// Return value: (array) As result a two-element array is given; first value
// is an error code an is 1 when the behavior was correctly applied; in
// this case the second value contains the resulting string. First array
// value can be also 0 when some error occured while applying behavior;
// in this case, the second value will contain a string with the error
// description
//---------------------------------------------------------------------------
function getOutput( $intvars, $otype, $xml_doc="" )
{
$b=$this->getBehavior( $otype );
if($b==null) return array(0, "Undefined output type $otype");
list($ok, $msg)=$b->getResult($intvars, $xml_doc);
if(!$ok) return array(0, "Errors evaluating output type $otype: $msg");
return array(1, $msg);
}
}
?>
diff --git a/modules/bibformat/lib/core/RecordSeparator.inc.php b/modules/bibformat/lib/core/RecordSeparator.inc.php
index fc29aaea3..35cd80019 100644
--- a/modules/bibformat/lib/core/RecordSeparator.inc.php
+++ b/modules/bibformat/lib/core/RecordSeparator.inc.php
@@ -1,135 +1,135 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: RecordSeparator.inc (flexElink core)
// Classes: XMLSimpleRecSeparator
// Requires:
// Included:
//==========================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: XMLSimpleRecSeparator
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//This is the base class for record separation. For each different type
// of input that requires a special record separation, this class can be
// extended keeping the same interface:
// constructor(file="") --> initialize the object and test input file
// accesibility. When file=="" standard input is
// used
// getRecord():array----> returns an array which contains, as first element
// a logic indicating if everything is OK or not and as second
// element a string containing the next record read from the input,
// in case of success, or a error message. When eof is reached ""
// is returned.
//class RecSeparator {
// function RecSeparator( $file="")
// function getRecord()
//}
//Class for separation of XML simple inputs (one tag marks the record)
class XMLSimpleRecSeparator {
var $fh; //Input file handler
var $tag; //XML element tag which marks the record
var $readnext;
function XMLSimpleRecSeparator( $ifile="" )
{
$this->tag="";
}
function setIFile( $ifile="" )
{
$this->readnext="";
//This method doesn't check if the file is correct or not, it should be
// checked outside
if(trim($ifile)=="")
{
$ifile="php://stdin";
}
$this->fh=@fopen($ifile, "r");
if(!$this->fh)
return "Input file handler incorrect";
return "";
}
function setTag( $tag )
{
$this->tag=strtoupper(trim($tag));
}
function getRecord()
{
if($this->tag=="")
return "";
if(!$this->fh)
return "";
//Everything OK. Let's start
$grab=0;//Flag which indicates that the start tag has been found
$record="";//Contains the record string
while(!feof($this->fh))
{
if($this->readnext!="")
{
$line=$this->readnext;
$this->readnext="";
}
else
$line=fgets($this->fh, 1024);
if($grab)
{
//Look if in the line there is the closing tag
if(ereg("(.*</[ \t]*".$this->tag."[^>]*>)(.*)", strtoupper($line), $res))
{
$record.=substr($line, 0, strlen($res[1]));
$this->readnext=substr($line, strlen($res[1]));
break;
}
else
{
$record.=$line;
}
}
else
{
//Look if in the line there is the starting tag
if(ereg("[^<]*(<[ \t]*".$this->tag."[^>]*>.*)", strtoupper($line), $res))
{
$record.=substr($line, strlen($line)-strlen($res[1]));
$grab=1;
}
}
}
if(feof($this->fh)&&($record==""))
{
fclose($this->fh);
}
return $record;
}
}
?>
diff --git a/modules/bibformat/lib/core/Timing.inc.php b/modules/bibformat/lib/core/Timing.inc.php
index 08d443b69..c70951610 100644
--- a/modules/bibformat/lib/core/Timing.inc.php
+++ b/modules/bibformat/lib/core/Timing.inc.php
@@ -1,66 +1,66 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
class Timing {
var $timing_list;
function Timing()
{
$this->timing_list=array();
}
function start( $tname )
{
$tname=strtoupper(trim($tname));
list($sec, $usec)=explode(" ", microtime());
$this->timing_list[$tname]=(float)$sec+(float)$usec;
return $this->timing_list[$tname];
}
function end( $tname )
{
$tname=strtoupper(trim($tname));
if(in_array($tname, array_keys($this->timing_list)))
{
list($sec, $usec)=explode(" ", microtime());
$endts=(float)$sec+(float)$usec;
$this->timing_list[$tname]= $endts-$this->timing_list[$tname];
}
else
{
$this->timing_list[$tname]=-1;
}
return $this->timing_list[$tname];
}
function debug()
{
print "<font size=\"2\" color=\"red\"><u>Timing</u></font><br>";
foreach($this->timing_list as $tsname=>$tsvalue)
{
if($tsvalue>0)
{
print "<font size=\"2\" color=\"red\">[$tsname]=$tsvalue sec</font><br>";
}
}
}
}
?>
diff --git a/modules/bibformat/lib/core/TreeNode.inc.php b/modules/bibformat/lib/core/TreeNode.inc.php
index 191cd7836..ad2154421 100644
--- a/modules/bibformat/lib/core/TreeNode.inc.php
+++ b/modules/bibformat/lib/core/TreeNode.inc.php
@@ -1,320 +1,320 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: TreeNode.inc (flexElink core)
// Classes: Condition
// Atribs
// Node
// Requires:
// Included:
//==========================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: Condition
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Condition {
var $atname;
var $atvalue;
function Condition( $atname, $atvalue="" )
{
$this->atname=$atname;
$this->atvalue=trim($atvalue);
}
function pass( $atname, $atvalue="" )
{
$atvalue=trim($atvalue);
//$atname=strtoupper( trim( $atname ) );
$atname=trim( $atname );
return (($atname==$this->atname) && ($atvalue==$this->atvalue));
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: Atribs
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Atribs {
var $name="";
var $vars;
function Atribs($name, $var="")
{
$this->name=$name;
$this->vars=array();
if($var!="")
$this->addVar($var);
}
function addVar($varname)
{
if(!in_array(trim($varname), array_values($this->vars)))
array_push($this->vars, trim($varname));
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: Node
// Purpose:
// Attributes:
// Methods:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Node {
var $tag; //string contining the tag name
var $vars; //array which contains variable to set up with
// the text of the tag
var $sons; //array which will keep all the references to son nodes
var $parent; //reference to the parent node
var $atribs; //array contianing references to atribute objects
var $conditions; //array containing conditions needed for entering
// this node
function &Node($tagname, & $parent)
{
$this->tag=trim($tagname);
$this->parent= & $parent;
$this->sons=array();
$this->atribs=array();
$this->vars=array();
$this->conditions=array();
return $this;
}
function addAtrib( $name, $intvar)
{
//$atribname=strtoupper(trim($name));
$atribname=trim($name);
$intvar=strtoupper(trim($intvar));
if(!in_array($atribname, array_keys($this->atribs)))
$this->atribs[ $atribname ]=new Atribs( $atribname );
$this->atribs[ $atribname ]->addVar( $intvar );
}
function addCondition( $atname, $atvalue="" )
{
//$atname=strtoupper(trim($atname));
$atname=trim($atname);
//As XML only allows an attribute to appear once in each TAG,
// the condition list with more than one attrib that has the same
// name, won't make sense, so the criteria for looking if a
// condition is already inserted is looking for the attrib name.
//In case various attrib values are specified for one attribute name,
// the first one will remain
if(!in_array($atname, array_keys($this->conditions)))
$this->conditions[ $atname ]=new Condition( $atname, $atvalue );
}
function & son( $name, $conditions=null )
{
$idx=0;
while($idx<=(count($this->sons)-1))
{
$temp=& $this->sons[$idx];
if($temp->matchId( $name, $conditions ))
{
return $temp;
}
$idx++;
}
return null;
}
function & atrib($name)
{
//return ($this->atribs[strtoupper(trim($name))]);
return ($this->atribs[trim($name)]);
}
function matchId ( $tagname, $conditions=null )
{
//$tagname=trim(strtoupper($tagname));
$tagname=trim($tagname);
//First let's see if tag names match
if ( $tagname!=$this->tag ) return 0;
if ( $conditions==null )
$conditions=array();
$acond=array();
foreach($conditions as $key=>$value)
{
//$acond[strtoupper($key)]=$value;
$acond[$key]=$value;
}
//Then let's check if it has same conditions
if($this->tag==$tagname)
{
//Then we have to see if the node has exactly the same conditions
foreach($acond as $key=>$value)
{
if (!($this->hasCondition($key, $value))) return 0;
}
//Now we need to check if the node condition is in the parameter
foreach($this->conditions as $cond)
{
if (!(in_array($cond->atname, array_keys($acond))))
return 0;
if (!($cond->pass($cond->atname, $acond[$cond->atname])))
return 0;
}
}
return 1;
}
function addSon( $tagname, $conditions=null )
{
//$tag=strtoupper(trim($tagname));
$tag=trim($tagname);
if($conditions==null)
$conditions=array();
if(!$this->hasSon( $tagname, $conditions ))
{
$temp = & new Node( $tag, $this );
foreach($conditions as $key=>$value)
$temp->addCondition($key, $value);
array_push($this->sons, & $temp);
}
}
function addVariable( $varname )
{
if(!in_array( trim($varname), $this->vars))
array_push($this->vars, trim($varname));
}
function hasSon( $tagname, $conditions=null )
{
//There could be more than one son with the same tagname
foreach($this->sons as $temp)
{
if($temp->matchId( $tagname, $conditions))
return 1;
}
return 0;
}
function hasVariables()
{
return (count($this->vars)>0);
}
function hasAtribs()
{
return (count($this->atribs));
}
function hasAtrib( $atname )
{
//$atname=strtoupper(trim($atname));
$atname=trim($atname);
return in_array($atname, array_keys($this->atribs));
}
function hasCondition( $atname, $atvalue="" )
{
//$atname=strtoupper(trim($atname));
$atname=trim($atname);
if(in_array($atname, array_keys($this->conditions)))
if(!$atvalue)
return 1;
else
return ($this->conditions[$atname]->pass($atname, $atvalue));
return 0;
}
function & descend( $tag, $cond )
{
foreach($this->sons as $key=>$temp)
{
//if(strtoupper(trim($tag))==$temp->tag)
if(trim($tag)==$temp->tag)
{
if($temp->passConditions( $cond ))
{
return $temp;
}
}
}
return null;
}
function passConditions( $a )
{ //This method tells if the node pass the conditions according with the
// assoc array which is passed as parameter. This array will contain
// the atribute names as indexes, and the atribute values as values.
//To pass the conditions means that all the conditions in the node have
// be present in the array parameter
//If there is no condition in the node, is passed
if (!$this->conditions)
return 1;
//If there is any condition in the node but not in the parameter is
// not passed
if (($this->conditions) && (!$a))
return 0;
//Any other case, we'll have to compare individually
foreach($this->conditions as $atname=>$atvalue)
{
if (!in_array($atname, array_keys( $a )))
{
return 0;
}
if (!$atvalue->pass( $atname, $a[ $atname ]))
{
return 0;
}
}
return 1;
}
function output()
{
print "Actual node: ".$this->tag."(".$this->parent->tag.")<br>";
print "Sons: ".array2str(array_keys($this->sons))."<br>";
print "Variables: ".array2str(array_values($this->vars))."<br>";
print "Atribs: ".array2str(array_keys($this->atribs))."<br>";
print "Conditions: ".array2str(array_keys($this->conditions))."<br>";
reset($this->sons);
while(current($this->sons)){
$temp=current($this->sons);
$temp->output();
next($this->sons);
}
}
}
//----------------------------------------------------------------------
?>
diff --git a/modules/bibformat/lib/core/UDFRetriever.inc.php b/modules/bibformat/lib/core/UDFRetriever.inc.php
index b6e992023..80f19992c 100644
--- a/modules/bibformat/lib/core/UDFRetriever.inc.php
+++ b/modules/bibformat/lib/core/UDFRetriever.inc.php
@@ -1,192 +1,192 @@
<?
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//==========================================================================
// File: UDFRetriever.inc (flexElink core)
// Classes: UDFRetriever
// Requires:
// Included: DB
//==========================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Class: UDFRetriever
// Purpose: Retrieves UDFs from the database providing services for validating
// and getting the reults of an existing one. All the UDF database access
// is encapsulated here; besides, it implements an internal cache which is
// trasparent to clients and that minimizes DB accesses. It follows the
// Singleton pattern so it will only be one instance of this class.
// Attributes:
// cache --> Array that implements an internal cache for keeping UDFs
// retrieved from the DB (minimizes DB acceses)
// db -----> Persistent MySQL connection
// Visible methods:
// getInstance (static)--> returns an instance of the class ensurring
// that is unique
// validate -----> cheks that the UDF with the given name exists and has
// the number of parameters indicated.
// execute ------> evaluates the UDF with the parameter values given and
// returns the result if the execution was succesful
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class UDFRetriever {
var $cache;
var $db;
function UDFRetriever()
{
$this->cache=array();
include( DB );
$this->db=mysql_pconnect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB, $this->db );
}
function destroy()
{
//mysql_close( $this->db );
}
/*---------------------------------------------------------------------
Method: getInstance (static)
Description: Gives a reference to an UDFRetriever ensurring that is the only
one that exists. For doing so, the Singleton pattern is followed. Call
always to this method instead of using the constructor
Parameters:
Return value: (UDFRetriever) Reference to the unique UDFRetriever object
---------------------------------------------------------------------*/
function & getInstance()
{
static $instance;
if(!isset($instance))
{
$instance=new UDFRetriever();
}
return $instance;
}
/*---------------------------------------------------------------------
Method: validate
Description: Checks if a UDF is defined in the FlexElink configuration and
if the number of parameters is correct for it
Parameters:
udf_name (String) ---------> identifier of the UDF
udf_param_count (Integer) -> number of parameters of the UDF
Return value: (Array) Contains two values:
1) The first one is <=0 if the validation wasn't OK, and any other
value in case of succesful validation
2) The second one contains a text explaining why the validation wasn't
possible. (It's not meaningful when the validation is OK)
---------------------------------------------------------------------*/
function validate( $udf_name, $udf_param_count)
{
if(!$this->db)
return array(0, "Couldn't connect to database");
$udf_name=strtoupper(trim($udf_name));
//Check if the function is in cache
if(in_array($udf_name, array_keys($this->cache)))
{
if($udf_param_count==count($this->cache[$udf_name][0]))
{
return array(1, $this->cache[$udf_name]);
}
return array(0, "Function '$udf_name' error: wrong number of parameters");
}
else
{
//If the function is not cached we have to look for it on the DB
$qry="select code from flxUDFS where fname='".addslashes($udf_name)."'";
$qh=mysql_query( $qry, $this->db );
if(mysql_num_rows($qh)>0)
{
$row=mysql_fetch_array($qh);
$code=$row["code"];
$qry="select pname from flxUDFPARAMS
where fname='".addslashes($udf_name)."'
order by ord";
$qh=mysql_query($qry, $this->db);
$params=array();
while($row=mysql_fetch_array($qh))
{
array_push($params, $row["pname"]);
}
if(count($params)==$udf_param_count)
{
//Add to cache
$this->cache[$udf_name]=array($params, $code);
return array(1, $this->cache[$udf_name]);
}
return array(0, "Function '$udf_name' error: wrong number of parameters");
}
}
return array(0, "Function '$udf_name' not found");
}
/*---------------------------------------------------------------------
Method: execute
Description: Gives the result of evaluating the UDF with the parameter values
indicated.
Parameters:
name (String) --> UDF identifier
param_values (Array) --> Contains the parameter values with which the
UDF has to be executed. The order is important because the
values will be assigned to parameters in the order they come
in the array to the order they where defined in the UDF.
last (Bool) -----------> Value of the a special variable to be used
inside the UDF code (LAST_ITERATION)
first (Bool) ----------> Value of the a special variable to be used
inside the UDF code (FIRST_ITERATION)
Return value: (Array) Contains two values:
1) The first one is <=0 if it occured any problem during execution, any
other value in case of success
2) The second one contains a text explaining why the execution wasn't
possible. (It's not meaningful when it is OK)
---------------------------------------------------------------------*/
function execute( $name, $param_values, $last, $first )
{
list($ok, $udf)=$this->validate( $name, count($param_values) );
if(!$ok)
return array(0, $udf);
$excode="\$LAST_ITERATION=$last;";
$excode.="\$FIRST_ITERATION=$first;";
list($param_names, $code)=$udf;
$counter=0;
foreach($param_names as $pname)
{
//$val=addslashes($param_values[$counter]);
$val=str_replace("\\", "\\\\", $param_values[$counter]);
$val=str_replace("\"", "\\\"", $val);
$val=str_replace("\$", "\\\$", $val);
$excode.='$'."$pname=\"".$val."\";\n";
$counter++;
}
$excode.=$code;
$res=eval($excode);
return array(1, $res);
}
}//end class:
?>
diff --git a/modules/bibformat/web/Makefile.am b/modules/bibformat/web/Makefile.am
index e95a705bd..fffc67dfd 100644
--- a/modules/bibformat/web/Makefile.am
+++ b/modules/bibformat/web/Makefile.am
@@ -1,33 +1,33 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
webdir=$(WEBDIR)/bibformat
FILESWML=$(wildcard $(srcdir)/*.wml)
web_DATA=$(FILESWML:$(srcdir)/%.wml=%)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(wildcard *.php) *~ *.tmp
%.php: %.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdspage.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibformat/web/admin/BEH_ACTION_add.php.wml b/modules/bibformat/web/admin/BEH_ACTION_add.php.wml
index 8027f082d..62e083c05 100644
--- a/modules/bibformat/web/admin/BEH_ACTION_add.php.wml
+++ b/modules/bibformat/web/admin/BEH_ACTION_add.php.wml
@@ -1,171 +1,171 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_ACTION_add.php (flexElink WI)
// Description: Displays necessary controls to define a new behavior action
// or adds a defined behavior action to the DB if all the parameters are
// set
// POST parameters:
// otype --> (required) Behavior label the action corresponds to
// eorder -> (required) Evaluation order of the condition the actions
// corresponds to
// process -> (optional) If defined (value not relevant) the script adds
// the action to the DB; if not it displays options for defining it
// code ----> (optional) Action's EL code
// locator -> (optional) Not relevant
// aorder --> (optional) Action application order inside its corresponding
// condition; if i isn't specified, the script will look for the
// last one in the database for that condition
// Notes: If an action is succesfully added to the DB it refreshes the caller
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
print "<b>Output type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$otype=trim(strtoupper($otype));
if( (!isset($eorder)) or (trim($eorder)=="") )
{
print "<b>Condition evaluation order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if(!isset($process))
{
?>
<form action="BEH_ACTION_add.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
Add new action for condition '<? echo $otype." -- ".$eorder;?>'</font>
</td>
</tr>
<tr>
<td>Apply order: </td>
<td><input type="text" name="aorder"></td>
</tr>
<tr>
<td>Locator(only IENRICH types): </td>
<td><textarea name="locator" cols="80" rows="2"></textarea></td>
</tr>
<tr>
<td>EL Code: </td>
<td><textarea name="code" cols="80" rows="9"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit"></td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="otype" value="<?echo $otype;?>">
<input type="hidden" name="eorder" value="<?echo $eorder;?>">
</form>
<?
}
else
{
if( (!isset($code)) )
$code="";
else
{
$temp_code=$code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code );
if(!$ok)
{
print "Code incorrect: <b>$msg</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
}
if( (!isset($locator)) )
$locator="";
if(!get_magic_quotes_gpc())
{
$code=addslashes($code);
$locator=addslashes($locator);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or errormsg("Couldn't connect to mySQL");
mysql_selectdb( $DB_DB );
if( (!isset($aorder)) or (trim($aorder)=="") )
{
$qry="select max(apply_order)+1
from flxBEHAVIORCONDITIONSACTIONS
where otype='$otype'
and eval_order='$eorder'";
$res=mysql_query( $qry );
$aorder=mysql_fetch_array( $res );
$aorder=$aorder[0];
if($aorder==null)
{
$aorder=0;
}
}
$qry="insert into flxBEHAVIORCONDITIONSACTIONS
(otype, eval_order, apply_order, locator, el_code)
values ('$otype', '$eorder', '$aorder', '$locator', '$code')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new action:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/BEH_ACTION_del.php.wml b/modules/bibformat/web/admin/BEH_ACTION_del.php.wml
index 6793b6ee5..9c8b5a5c9 100644
--- a/modules/bibformat/web/admin/BEH_ACTION_del.php.wml
+++ b/modules/bibformat/web/admin/BEH_ACTION_del.php.wml
@@ -1,83 +1,83 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_ACTION_del.php (flexElink WI)
// Description: Delete an existing new behavior action from the DB
// POST parameters:
// otype --> (required) Behavior label the action corresponds to
// eorder -> (required) Evaluation order of the condition the actions
// corresponds to
// aorder --> (required) Action application order inside its corresponding
// condition.
// Notes: If the deletion is succesful it redirects the browser to the
// showing of the
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
errorpage("<b>Output type name</b> hasn't been specified");
exit;
}
$otype=strtoupper(trim($otype));
if( (!isset($eorder)) or (trim($eorder)=="") )
{
errorpage("<b>Condition evaluation order</b> hasn't been specified");
exit;
}
if( (!isset($aorder)) or (trim($aorder)=="") )
{
errorpage("<b>Action evaluation order</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxBEHAVIORCONDITIONSACTIONS
where otype='$otype'
and eval_order='$eorder'
and apply_order='$aorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete action:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: BEH_OTYPE_showone.php?otype=$otype");
?>
diff --git a/modules/bibformat/web/admin/BEH_ACTION_edit.php.wml b/modules/bibformat/web/admin/BEH_ACTION_edit.php.wml
index fc0714ca5..a11287183 100644
--- a/modules/bibformat/web/admin/BEH_ACTION_edit.php.wml
+++ b/modules/bibformat/web/admin/BEH_ACTION_edit.php.wml
@@ -1,233 +1,233 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_ACTION_edit.php (flexElink WI)
// Description: Allows to edit a single behavior action from the DB and apply
// changes in the action's data to the DB
// POST parameters:
// otype --> (required) Behavior label the action corresponds to
// eorder -> (required) Evaluation order of the condition the actions
// corresponds to
// process -> (optional) If defined (value not relevant) the script updates
// action's in the DB; if not it displays options for modifiying it
// aorder --> (required if process is not defined) Action application order
// inside its corresponding condition. When process is set, it
// contains the new order for this action; if it's empty, the
// script will look for the last apply order of the actions for
// the corresponding condition.
// original_aorder --> (required if process is defined) Original action
// application order inside its corresponding condition.
// code ----> (optional) Action's EL code
// locator -> (optional) Not relevant
// Notes: If the update of the action is succesful it closes the current i
// browser and refreshes the caller one
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
print "<b>Output type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$otype=trim(strtoupper($otype));
if( (!isset($eorder)) or (trim($eorder)=="") )
{
print "<b>Condition evaluation order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if(!isset($process))
{
if( (!isset($aorder)) or (trim($aorder)=="") )
{
print "<b>Action apply order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$qry="select locator, el_code
from flxBEHAVIORCONDITIONSACTIONS
where otype='$otype'
and eval_order=$eorder
and apply_order=$aorder";
$qh=mysql_query( $qry );
list($locator, $code)=mysql_fetch_array( $qh );
?>
<form action="BEH_ACTION_edit.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
Modifying action '<? echo $otype." -- ".$eorder." -- ".$aorder;?>'</font>
</td>
</tr>
<tr>
<td>Apply order: </td>
<td><input type="text" name="aorder" value="<?echo $aorder;?>"></td>
</tr>
<tr>
<td>Locator(only IENRICH types): </td>
<td><textarea name="locator" cols="80" rows="2"><?echo $locator?></textarea></td>
</tr>
<tr>
<td>EL Code: </td>
<td><textarea name="code" cols="80" rows="9"><?echo $code;?></textarea></td>
</tr>
<tr>
<td colspan="2" align="center">
<input class="formbutton" type="submit" value="UPDATE" name="btnUpd">
<input class="formbutton" type="submit" value="UPDATE&CLOSE" name="btnUpdClose">
</td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="otype" value="<?echo $otype;?>">
<input type="hidden" name="eorder" value="<?echo $eorder;?>">
<input type="hidden" name="original_aorder" value="<?echo $aorder;?>">
</form>
<?
}
else
{
if( (!isset($original_aorder)) or (trim($original_aorder)=="") )
{
print "<b>Action orginal apply order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if( (!isset($code)) )
$code="";
else
{
$temp_code=$code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code );
if(!$ok)
{
print "Code incorrect: <b>$msg</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
}
if( (!isset($locator)) )
$locator="";
if(!get_magic_quotes_gpc())
{
$code=addslashes($code);
$locator=addslashes($locator);
}
if( (!isset($aorder)) or (trim($aorder)=="") )
{
$qry="select max(apply_order)+1
from flxBEHAVIORCONDITIONSACTIONS
where otype='$otype'
and eval_order='$eorder'";
$res=mysql_query( $qry );
$aorder=mysql_fetch_array( $res );
$aorder=$aorder[0];
if($aorder==null)
{
$aorder=0;
}
}
if($aorder==$original_aorder)
{
$qry="update flxBEHAVIORCONDITIONSACTIONS
set locator='$locator',
el_code='$code'
where otype='$otype'
and eval_order='$eorder'
and apply_order='$aorder'";
if(!mysql_query( $qry ))
{
print "Impossible to update action: ".mysql_error()."<hr> <a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close( $db );
exit;
}
}
else
{
$qry="delete from flxBEHAVIORCONDITIONSACTIONS
where otype='$otype'
and eval_order='$eorder'
and apply_order='$original_aorder'";
if(!mysql_query( $qry ))
{
print "Impossible to delete old action: ".mysql_error()."<hr> <a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close( $db );
exit;
}
$qry="insert into flxBEHAVIORCONDITIONSACTIONS
(otype, eval_order, apply_order, locator, el_code)
values ('$otype', '$eorder', '$aorder', '$locator', '$code')";
if(!mysql_query( $qry ))
{
print "Impossible to insert new action: ".mysql_error()."<hr> <a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close( $db );
exit;
}
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
<?
if(isset($btnUpd))
print "window.location=\"BEH_ACTION_edit.php?otype=$otype&eorder=$eorder&aorder=$aorder\";";
else
print "window.close();";
?>
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/BEH_COND_add.php.wml b/modules/bibformat/web/admin/BEH_COND_add.php.wml
index 01acb4081..fdb416b01 100644
--- a/modules/bibformat/web/admin/BEH_COND_add.php.wml
+++ b/modules/bibformat/web/admin/BEH_COND_add.php.wml
@@ -1,153 +1,153 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_COND_add.php (flexElink WI)
// Description: Displays necessary controls to define a new behaviour condition
// or adds a defined behavior condition (by the values passed as
// parameters) to the DB
// POST parameters:
// otype --> (required) Behavior label the condition corresponds to
// process -> (optional) If defined (value not relevant) the script adds
// the condition to the DB.
// eorder -> (optional) Evaluation order of the condition inside the owner
// behaviour. If this parameter is not set, the script will look
// for the last evaluation order value inside the corresponding
// behaviour
// code ----> (optional) Action's EL code
// Notes: If an action is succesfully added to the DB it closes the current
// browser and refreshes the opener one
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
print "<b>Output type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$otype=trim(strtoupper($otype));
if(!isset($process))
{
?>
<form action="BEH_COND_add.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
Add new condition for output type'<? echo $otype;?>'</font>
</td>
</tr>
<tr>
<td>Evaluation order: </td>
<td><input type="text" name="eorder"></td>
</tr>
<tr>
<td>EL Code: </td>
<td><textarea name="code" cols="80" rows="9"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit"></td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="otype" value="<?echo $otype;?>">
</form>
<?
}
else
{
if( (!isset($code)) )
$code="";
else
{
$temp_code=$code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code );
if(!$ok)
{
print "Condition code incorrect: <b>$msg</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
}
if(!get_magic_quotes_gpc())
$code=addslashes($code);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
if( (!isset($eorder)) or (trim($eorder)=="") )
{
$qry="select max(eval_order)+1
from flxBEHAVIORCONDITIONS
where otype='$otype'";
$res=mysql_query( $qry );
$order=mysql_fetch_array( $res );
$order=$order[0];
if($order==null)
{
$order=0;
}
}
$qry="insert into flxBEHAVIORCONDITIONS (otype, eval_order, el_condition)
values ('$otype', '$order', '$code')";
if(!mysql_query( $qry ))
{
print "Impossible to insert new condition:<br> ".mysql_error();
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.history.go(-1);\">[Go Back]</a>";
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/BEH_COND_del.php.wml b/modules/bibformat/web/admin/BEH_COND_del.php.wml
index fe264fb2e..060685b1e 100644
--- a/modules/bibformat/web/admin/BEH_COND_del.php.wml
+++ b/modules/bibformat/web/admin/BEH_COND_del.php.wml
@@ -1,79 +1,79 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_COND_del.php (flexElink WI)
// Description: Deletes a given condition (and its depending items) from the DB
// POST parameters:
// otype --> (required) Behaviour label the condition corresponds to
// eorder -> (required) Evaluation order of the condition
// Notes: If the condition is succesfully deleted from the DB it redirects
// the current browser to the detailed display of the corresponding
// behaviour
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
errorpage("<b>Output type name</b> hasn't been specified");
exit;
}
$otype=strtoupper(trim($otype));
if( (!isset($eorder)) or (trim($eorder)=="") )
{
errorpage("<b>Condition evaluation order</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxBEHAVIORCONDITIONSACTIONS
where otype='$otype' and eval_order='$eorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete actions related to this condition:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxBEHAVIORCONDITIONS
where otype='$otype' and eval_order='$eorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete condition:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("Location: BEH_OTYPE_showone.php?otype=$otype");
?>
diff --git a/modules/bibformat/web/admin/BEH_COND_edit.php.wml b/modules/bibformat/web/admin/BEH_COND_edit.php.wml
index 7f650778a..c0a937c0f 100644
--- a/modules/bibformat/web/admin/BEH_COND_edit.php.wml
+++ b/modules/bibformat/web/admin/BEH_COND_edit.php.wml
@@ -1,197 +1,197 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_COND_edit.php (flexElink WI)
// Description: Allows to modify a condition data and updates changes in
// the configuration DB
// POST parameters:
// otype --> (required) Behavior label the condition corresponds to
// process -> (optional) If defined (value not relevant) the script updates
// condition data in the DB with the new values passed as
// parameters
// eorder -> (required if process is not set) Evaluation order of the
// condition inside the owner behaviour. If this parameter is not
// set, the script will look for the last evaluation order value
// inside the corresponding behaviour
// old_eorder -> (required if process is set) Original evaluation order of
// the condition to be modified
// code ----> (optional) Action's EL code
// Notes: If an action is succesfully added to the DB it closes the current
// browser and refreshes the opener one
// Requires: DB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
if( (!isset($otype)) or (trim($otype)=="") )
{
print "<b>Output type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$otype=trim(strtoupper($otype));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
if(!isset($process))
{
if( (!isset($eorder)) or (trim($eorder)=="") )
{
print "<b>Condition evaluation order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$qry="select el_condition
from flxBEHAVIORCONDITIONS
where otype='$otype'
and eval_order='$eorder'";
$qh=mysql_query($qry, $db);
list($code)=mysql_fetch_array($qh);
mysql_close($db);
?>
<form action="BEH_COND_edit.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
Editing condition <?echo $eorder;?> for output type'<? echo $otype;?>'</font>
</td>
</tr>
<tr>
<td>Evaluation order: </td>
<td><input type="text" name="eorder" value="<?echo $eorder;?>"></td>
</tr>
<tr>
<td>EL Code: </td>
<td><textarea name="code" cols="80" rows="9"><?echo $code;?></textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit"></td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="otype" value="<?echo $otype;?>">
<input type="hidden" name="old_eorder" value="<?echo $eorder;?>">
</form>
<?
}
else
{
if( (!isset($old_eorder)) or (trim($old_eorder)=="") )
{
print "<b>Condition original evaluation order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if( (!isset($code)) )
$code="";
else
{
$temp_code=$code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code );
if(!$ok)
{
print "Condition code incorrect: <b>$msg</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
}
if(!get_magic_quotes_gpc())
$code=addslashes($code);
if( (!isset($eorder)) or (trim($eorder)=="") )
{
$qry="select max(eval_order)+1
from flxBEHAVIORCONDITIONS
where otype='$otype'
and eval_order<>$old_eorder";
$res=mysql_query( $qry );
$order=mysql_fetch_array( $res );
$eorder=$order[0];
if($eorder==null)
{
$eorder=0;
}
}
if($eorder!=$old_eorder)
{
$qry="update flxBEHAVIORCONDITIONSACTIONS
set eval_order='$eorder'
where otype='$otype'
and eval_order='$old_eorder'";
if(!mysql_query( $qry ))
{
print "Impossible to update actions related to this condition:<br> ".mysql_error();
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.history.go(-1);\">[Go Back]</a>";
mysql_close( $db );
exit;
}
}
$qry="update flxBEHAVIORCONDITIONS
set eval_order='$eorder',
el_condition='$code'
where otype='$otype'
and eval_order='$old_eorder'";
if(!mysql_query( $qry ))
{
print "Impossible to insert update condition:<br> ".mysql_error();
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.history.go(-1);\">[Go Back]</a>";
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/BEH_OTYPE_add.php.wml b/modules/bibformat/web/admin/BEH_OTYPE_add.php.wml
index 49ec593e7..e0e18a523 100644
--- a/modules/bibformat/web/admin/BEH_OTYPE_add.php.wml
+++ b/modules/bibformat/web/admin/BEH_OTYPE_add.php.wml
@@ -1,84 +1,84 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_OTYPE_add.php (flexElink WI)
// Description: Adds a new behaviour to the DB from the data passed as
// parameteres
// POST parameters:
// otype --> (required) Behaviour label the action corresponds to
// type ---> (required, possible values: NORMAL, IENRICH) Behaviour type.
// doc ----> (optional) Documentation describing the behaviour
// Notes: If the behaviour is succesfully added to the DB it redirects the
// browser to the behaviour list display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
errorpage("<b>Output type name</b> hasn't been specified");
exit;
}
$otype=strtoupper(trim($otype));
if( (!isset($type)) or (trim($type)=="") )
$type="";
$type=strtoupper(trim($type));
if(!in_array($type, array( "NORMAL", "IENRICH" )))
{
errorpage("<b>Behavior type</b> incorrect!!");
exit;
}
if( !isset($doc) )
$doc="";
$doc=strtoupper(trim($doc));
if(!get_magic_quotes_gpc())
{
$doc=addslashes($doc);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or
errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="insert into flxBEHAVIORS(name, type, doc)
values ('$otype', '$type', '$doc')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new output type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: BEH_display.php");
?>
diff --git a/modules/bibformat/web/admin/BEH_OTYPE_del.php.wml b/modules/bibformat/web/admin/BEH_OTYPE_del.php.wml
index ee37919e7..dfb884fcf 100644
--- a/modules/bibformat/web/admin/BEH_OTYPE_del.php.wml
+++ b/modules/bibformat/web/admin/BEH_OTYPE_del.php.wml
@@ -1,92 +1,92 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_OTYPE_del.php (flexElink WI)
// Description: Deletes an existing behaviour (and all the items that depend
// on them) from the DB
// parameteres
// POST parameters:
// otype --> (required) Behaviour label the action corresponds to
// Notes: If the behaviour is succesfully deleted from the DB it closes the
// current browser and refreshes the opener one
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
if( (!isset($otype)) or (trim($otype)=="") )
{
errorpage("<b>Output type name</b> hasn't been specified");
exit;
}
$otype=strtoupper(trim($otype));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or
errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxBEHAVIORCONDITIONSACTIONS where otype='$otype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete actions related to this output type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxBEHAVIORCONDITIONS where otype='$otype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete conditions related to this output type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxBEHAVIORS where name='$otype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete output type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
diff --git a/modules/bibformat/web/admin/BEH_OTYPE_edit.php.wml b/modules/bibformat/web/admin/BEH_OTYPE_edit.php.wml
index a8b921952..9f421e963 100644
--- a/modules/bibformat/web/admin/BEH_OTYPE_edit.php.wml
+++ b/modules/bibformat/web/admin/BEH_OTYPE_edit.php.wml
@@ -1,186 +1,186 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_OTYPE_edit.php (flexElink WI)
// Description: Allows to modify a behavior's data and updates it, according
// with the made changes, in the DB
// POST parameters:
// otype --> (required) Behavior label
// otype_orig -> (optional) If defined the script updates the data passed
// parameters in the DB. When defined, it contains the DB label(the
// original one as it can be changed) of the behaviour to be
// modified
// type ---> (required if otype_orig is set, possible values: NORMAL,
// IENRICH) Behaviour type.
// doc ----> (optional) Documentation describing the behaviour
// Notes: If the behaviour data is succesfully updated in the DB it redirects
// the current browser to the detailed display of the updated behaviour
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
include(FUNCTION_LIB);
if((!isset($otype))||(trim($otype)==""))
{
print "<b>ERROR</b>: Output type label hasn't been specified!!<hr>";
print "<a align=\"center\" href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
if(get_magic_quotes_gpc())
{
$otype=stripslashes($otype);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if(isset($otype_orig))
{
$otype=trim(strtoupper($otype));
$otype_orig=trim(strtoupper($otype_orig));
if(!isset($type))
{
$type="NORMAL";
}
else
{
$type=strtoupper(trim($type));
}
if(($type!="NORMAL")&&($type!="IENRICH"))
{
print "Incorrect value for <b>type</b>";
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
exit;
}
if(!isset($doc))
{
$doc="";
}
if(!get_magic_quotes_gpc())
{
$type=addslashes($type);
$doc=addslashes($doc);
$otype=addslashes($otype);
$otype_orig=addslashes($otype_orig);
}
if($otype!=$otype_orig)
{
$qry="update flxBEHAVIORCONDITIONSACTIONS
set otype='$otype'
where otype='$otype_orig'";
if(!mysql_query($qry))
{
print "Impossible to update actions for output type '$otype_orig': ".mysql_error();
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
$qry="update flxBEHAVIORCONDITIONS
set otype='$otype'
where otype='$otype_orig'";
if(!mysql_query($qry))
{
print "Impossible to update conditions for output type '$otype_orig': ".mysql_error();
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
}
$qry="update flxBEHAVIORS
set name='$otype',
type='$type',
doc='$doc'
where name='$otype_orig'";
if(!mysql_query($qry))
{
print "Impossible to update output type '$otype_orig': ".mysql_error();
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
if($errors!="")
{
print $errors;
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
header("location: BEH_OTYPE_showone.php?otype=$otype");
exit;
}
//-----------------------------------------------------------------
$qry="select type, doc
from flxBEHAVIORS
where name='".addslashes($otype)."'";
$qh=mysql_query($qry, $db);
list($type, $doc)=mysql_fetch_row($qh);
?>
<form action="BEH_OTYPE_edit.php" method="POST">
<table width="100%" bgcolor="#CCCCCC" border="1">
<tr bgcolor="#0000FF" align="center">
<td colspan="2"><font size="6" color="white">Modifying output type '<?echo $otype;?>'</font></td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF" width="15%"><b>Name</b></td>
<td><input type="text" name="otype" value="<?echo $otype;?>"</td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF" width="15%"><b>Type</b></td>
<td><select name="type">
<option value="NORMAL"<?if($type=="NORMAL") echo " selected";?>>Normal</option>
<option value="IENRICH"<?if($type=="IENRICH") echo " selected";?>>Input Enrich</option>
</select>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF"><b>Documentation</b></td>
<td><textarea name="doc" cols="65" rows="5"><?echo $doc;?></textarea></td>
</tr>
<tr align="center">
<td colspan="2">
<input type="button" value="CANCEL" onClick="JavaScript:window.history.go(-1)">
<input class="formbutton" type="submit" value="UPDATE">
<input type="hidden" name="otype_orig" value="<?echo $otype;?>">
</td>
</tr>
</table>
</form>
<?
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml b/modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml
index ef7c7758e..1350f5671 100644
--- a/modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml
+++ b/modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml
@@ -1,162 +1,162 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_OTYPE_showone.php (flexElink WI)
// Description: Shows the complete structure for a given behaviour. It presents
// the behavior data, conditions and actions; it also allows its management
// POST parameters:
// otype --> (required) Behavior label that identifies the behavior to be
// shown
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(FUNCTION_LIB);
?>
<script language="javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=420,witdh=320,scrollbars,resizable")
}
//-->
</script>
<?
if((!isset($otype))||(trim($otype)==""))
{
print "<b>ERROR</b>: Behavior label hasn't been specified!!<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$otype=trim(strtoupper($otype));
if(get_magic_quotes_gpc())
{
$otype=stripslashes($otype);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="select type, doc
from flxBEHAVIORS
where name='".addslashes($otype)."'";
$qh=mysql_query($qry, $db);
list($type, $doc)=mysql_fetch_row($qh);
?>
<table bgcolor="#CCCCCC" border="1">
<tr bgcolor="#0000FF" align="center">
<td colspan="2"><font size="6" color="white">Details of output type '<?echo $otype;?>'</font></td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF" width="15%"><b>Type</b></td>
<td><?echo $type;?></td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF"><b>Documentation</b></td>
<td><?echo str_replace("\n", "<br>", $doc);?></td>
</tr>
</table>
<table cellspacing="0" bgcolor="#CCCCCC" cellpadding="4" border="0">
<tr align="center">
<td><a href="JavaScript:openwindowlink('BEH_COND_add.php?otype=<? print urlencode($otype);?>', 'BEHRADDC<? echo $linktype;?>')">[Add condition]</a></td>
<td><a href="BEH_OTYPE_edit.php?otype=<?print urlencode($otype);?>">[Modify]</a></td>
<td><a href="BEH_OTYPE_del.php?otype=<?echo urlencode($otype);?>">[Delete]</a></td>
</tr>
</table>
<?
$qry="select eval_order, el_condition
from flxBEHAVIORCONDITIONS
where otype='".addslashes($otype)."'
order by eval_order";
$qh=mysql_query($qry, $db);
if(mysql_num_rows($qh)>=1)
{
?>
<table bgcolor="#CCCCCC" border="1">
<tr bgcolor="#0000FF" align="center">
<td colspan="4"><font color="white"><b>CONDITIONS</b></font></td>
</tr>
<?
while($row=mysql_fetch_array($qh))
{
list($eorder, $condition)=$row;
?>
<tr bgcolor="#33CCFF">
<td align="center"><b><?echo $eorder;?></b></td>
<td width="95%" colspan="3"><b><?echo text2HTML($condition);?></b></td>
</tr>
<?
$qry_ac="select apply_order, el_code
from flxBEHAVIORCONDITIONSACTIONS
where otype='".addslashes($otype)."'
and eval_order=$eorder
order by apply_order";
$qh_ac=mysql_query($qry_ac, $db);
while($row_ac=mysql_fetch_array($qh_ac))
{
list($aorder, $action)=$row_ac;
?>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF"><font size="2"><b>Action (<?echo $aorder;?>)</b></font></td>
<td><?echo text2HTML($action);?></td>
<td><font size="2"><a href="JavaScript:openwindowlink('BEH_ACTION_edit.php?otype=<?echo urlencode($otype);?>&eorder=<?echo $eorder;?>&aorder=<?echo $aorder;?>', 'BEHCAE<? echo "$otype$eorder$aorder";?>')">[Modify]</a></td>
<td><font size="2"><a href="BEH_ACTION_del.php?otype=<?echo urlencode($otype);?>&eorder=<?echo $eorder;?>&aorder=<?echo $aorder;?>">[Delete]</a></td>
</tr>
<?
}
?>
<tr bgcolor="#CCCCCC" align="center">
<td colspan="4"><font size="2">
<a href="JavaScript:openwindowlink('BEH_ACTION_add.php?otype=<?echo urlencode($otype);?>&eorder=<?echo $eorder;?>', 'BEHCAADD<?echo "$otype$eorder$aorder";?>')">[Add Action]</a>
<a href="JavaScript:openwindowlink('BEH_COND_edit.php?otype=<?echo urlencode($otype)?>&eorder=<?echo $eorder;?>', 'BEHCEDIT<?echo "$otype$eorder";?>')">[Modify]</a>
<a href="BEH_COND_del.php?otype=<?echo urlencode($otype);?>&eorder=<?echo $eorder?>">[Delete]</a>
</font>
</td>
</tr>
<?
}
print "</table>";
}
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/BEH_display.php.wml b/modules/bibformat/web/admin/BEH_display.php.wml
index db4193a84..808d0c4bf 100644
--- a/modules/bibformat/web/admin/BEH_display.php.wml
+++ b/modules/bibformat/web/admin/BEH_display.php.wml
@@ -1,136 +1,136 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Behaviours" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BEH_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: BEH_display.php (flexElink WI)
// Description: Shows a list of the existing behaviors in the DB, and allows to
// access to their details or to add new ones
// POST parameters:
// Notes:
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(HEADER);
?>
<p>Define one or more output BibFormat behaviours. These are then
passed as parameters to the BibFormat modules while executing
formatting.
<em>Example:</em> You can tell BibFormat that is has to enrich the
incoming metadata file by the created format, or that it only has to
print the format out.
<p>
<script type="text/javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=720,witdh=320,scrollbars,resizable")
}
//-->
</script>
<?
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or
errormsg("Couldn't connect to mySQL");
mysql_selectdb( $DB_DB ) or
errormsg(sprintf("Couldn't connect into database %s", $DB_DB));
$qry_otypes="select name, type, doc from flxBEHAVIORS order by name";
$qh_otypes=mysql_query( $qry_otypes );
?>
<table border="1">
<tr bgcolor="#0000FF" align="center">
<td><font color="white"><b>Name</b></font></td>
<td><font color="white"><b>Type</b></font></td>
<td><font color="white"><b>Documentation</b></font></td>
<td colspan="2"></td>
</tr>
<?
while($row=mysql_fetch_array( $qh_otypes ))
{
list($otype, $type, $doc)=$row;
?>
<tr bgcolor="#FFFFFF">
<td bgcolor="#33CCFF"><b><?echo $otype?></b></td>
<td><?echo $type;?></td>
<td><font size="2"><?echo $doc;?>&nbsp;</font></td>
<td><a href="JavaScript:openwindowlink( 'BEH_OTYPE_showone.php?otype=<?print urlencode($otype);?>', 'OC<?print urlencode($otype);?>')"><font size="2">[Details]</font></a></td>
</tr>
<?
}
print "</table>";
?>
<form action="BEH_OTYPE_add.php" method="POST">
<table>
<tr>
<td bgcolor="#0000FF" colspan="2">
<font color="#FFFFFF"><strong>Add new OUPUT TYPE</strong></font>
</td>
</tr>
<tr>
<td width="30%" align="right">
Output Type Name
</td>
<td>
<input type="text" name="otype">
</td>
</tr>
<tr>
<td width="30%" align="right">
Behavior Type
</td>
<td>
<select name="type">
<option value="NORMAL">Normal</option>
<option value="IENRICH">Input Enrich</option>
</select>
</td>
</tr>
<tr>
<td width="30%" align="right">Documentation</td>
<td><textarea name="doc" cols="65" rows="5"></textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit" value="Add output type"></td>
</tr>
</table>
</form>
<?
mysql_close( $db );
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/BIBREFORMAT_display.php.wml b/modules/bibformat/web/admin/BIBREFORMAT_display.php.wml
index 1381a4918..35f3a6717 100644
--- a/modules/bibformat/web/admin/BIBREFORMAT_display.php.wml
+++ b/modules/bibformat/web/admin/BIBREFORMAT_display.php.wml
@@ -1,101 +1,101 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<? include('localconf.inc.php');
?>
#include "cdspage.wml" \
title="Reformat Records" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="BIBREFORMAT_display"
<?
include("security.inc.php");
?>
<p>After you updated your <a href="BEH_display.php">Behaviours</a> or <a
href="FORMAT_display.php">Formats</a> and other <a
href="LINK_display.php">Link Rules</a> you may be using in your
formats, you may want to reformat records again. This is where
BibReformat comes handy.
<p>You can run BibReformat from the command line. It understands many
arguments, e.g.:
<blockquote>
<pre>
Usage: bibreformat [options]
-u, --user=USER User name to submit the task as, password needed.
-h, --help Print this help.
-V, --version Print version information.
-v, --verbose=LEVEL Verbose level (0=min,1=normal,9=max).
-s, --sleeptime=SLEEP Time after which to repeat tasks (no)
-t, --time=DATE Moment for the task to be active (now).
-a, --all All records
-c, --collection Select records by collection
-f, --field Select records by field.
-p, --pattern Select records by pattern.
-o, --format Specify output format to be (re-)created. (default HB)
-n, --noprocess Count records to be processed only (no processing done)
Example: bibreformat -n Show how many records are to be bibreformated.
</pre>
</blockquote>
For example, to reformat all records in HB (=HTML brief) format, you'd launch:
<blockquote>
<pre>
$ bibreformat -a -oHB
</pre>
</blockquote>
and you watch the progress of the process via <code>bibsched</code>.
<p>Note that BibReformat understands <code>-p</code>, <code>-f</code>,
and <code>-c</code> arguments that enable you to easily reformat only
the records you need. For example, to reformat the Pictures
collection, launch:
<blockquote>
<pre>
$ bibreformat -cPictures -oHB,HD,HP
</pre>
</blockquote>
or to reformat HD (=HTML detailed) format for records #10 to #20, you
launch:
<blockquote>
<pre>
$ bibreformat -p"recid:10->20" -oHD
</pre>
</blockquote>
<p>Last but not least, if you launch bibreformat without arguments:
<blockquote>
<pre>
$ bibreformat
</pre>
</blockquote>
it will process all the records that have been modified since the last
run of BibReformat, as well as all newly inputted records. This is
suitable for running BibReformat in a periodical daemon mode via
BibSched. See our <a href="<WEBURL>/admin/howto/run.html">HOWTO Run
Your CDSware Installation</a> guide for more information.
diff --git a/modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml b/modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml
index ee39335b6..b16d96c89 100644
--- a/modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml
+++ b/modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml
@@ -1,30 +1,30 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Reformat Records" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="bibformat"
<?
include("security.inc.php");
?>
See <a href="BIBREFORMAT_display.php">Reformat Records</a>.
diff --git a/modules/bibformat/web/admin/BIBREFORMAT_process.php.wml b/modules/bibformat/web/admin/BIBREFORMAT_process.php.wml
index f6c614c37..7b8dd003e 100644
--- a/modules/bibformat/web/admin/BIBREFORMAT_process.php.wml
+++ b/modules/bibformat/web/admin/BIBREFORMAT_process.php.wml
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<? include('localconf.inc.php');
?>
#include "config.wml"
#include "configbis.wml"
<?
include("security.inc.php");
?>
See <a href="BIBREFORMAT_display.php">Reformat Records</a>.
diff --git a/modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml b/modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml
index ee39335b6..b16d96c89 100644
--- a/modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml
+++ b/modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml
@@ -1,30 +1,30 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Reformat Records" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="bibformat"
<?
include("security.inc.php");
?>
See <a href="BIBREFORMAT_display.php">Reformat Records</a>.
diff --git a/modules/bibformat/web/admin/FORMAT_add.php.wml b/modules/bibformat/web/admin/FORMAT_add.php.wml
index 60d3845d9..bd3db9db0 100644
--- a/modules/bibformat/web/admin/FORMAT_add.php.wml
+++ b/modules/bibformat/web/admin/FORMAT_add.php.wml
@@ -1,95 +1,95 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: FORMAT_add.php (flexElink WI)
// Description: Adds a new format to the DB. It will only add the format if the
// EL code is syntactically correct and it's "interpretable". It serializes
// the EL code into the corresponding semantic structure and stores it
// in the DB for optimization (no need to re-compile afterwards)
// POST parameters:
// fname --> (required) Name (id) of the format to be added
// doc ----> (optional) Description of the purpose of the format
// code ---> (optional) Format's EL code
// Notes: If the format is succesfully added to the DB it redirects the current
// browser to the format display list
// Requires: DB, ERROR, EXECUTOR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($fname)) or (trim($fname)=="") )
{
errorpage("<b>Format name</b> hasn't been specified");
exit;
}
if(!isset($doc))
$doc="";
if(!isset($code))
$code="";
else
{
$temp_code=$code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code, array($fname) );
if(!$ok)
{
errorpage("Code incorrect: <b>$msg</b>");
exit;
}
$ser=addslashes(serialize($msg));
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
if(!get_magic_quotes_gpc())
{
$doc=addslashes($doc);
}
$qry="insert into flxFORMATS (name, value, doc, serialized)
values ('$fname', '$code', '$doc', '$ser')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new format:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: FORMAT_display.php");
?>
diff --git a/modules/bibformat/web/admin/FORMAT_del.php.wml b/modules/bibformat/web/admin/FORMAT_del.php.wml
index 539c06ca7..aad8daf06 100644
--- a/modules/bibformat/web/admin/FORMAT_del.php.wml
+++ b/modules/bibformat/web/admin/FORMAT_del.php.wml
@@ -1,66 +1,66 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: FORMAT_del.php (flexElink WI)
// Description: Deletes a certain format from the DB.
// POST parameters:
// fname --> (required) Name (id) of the format to be deleted
// Notes: If the behaviour is succesfully added to the DB it redirects the
// browser to the behaviour list display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($fname)) or (trim($fname)=="") )
{
errorpage("<b>Format name</b> hasn't been specified");
exit;
}
$fname=strtoupper(trim($fname));
if(!get_magic_quotes_gpc())
{
$fname=addslashes($fname);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxFORMATS
where name='$fname'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete format:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: FORMAT_display.php");
?>
diff --git a/modules/bibformat/web/admin/FORMAT_display.php.wml b/modules/bibformat/web/admin/FORMAT_display.php.wml
index 64a6a681c..3aa919100 100644
--- a/modules/bibformat/web/admin/FORMAT_display.php.wml
+++ b/modules/bibformat/web/admin/FORMAT_display.php.wml
@@ -1,139 +1,139 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Formats" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="FORMAT_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: FORMAT_display.php (flexElink WI)
// Description: Shows a list of the existing formats in the DB, and allows to
// access to their details, add or delete
// POST parameters:
// Notes:
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(HEADER);
?>
<p>Define the output formats, i.e. how to create the output out of
internal BibFormat variables that were extracted in a previous step.
This is the functionality you would want to configure most of the
time. It may reuse formats, user defined functions, knowledge bases,
etc.
<em>Example:</em> You can tell that authors should be printed in
italic, that if there are more than 10 authors only the first three
should be printed, etc.
<p>
<script language="javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=700,witdh=120,scrollbars,resizable")
}
//-->
</script>
<?
$cBorder="#CCCCCC";
$cHeaders="#9999FF";
$cCells="#CCFFFF";
$cImpCells="#FFFFFFF0";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or errormsg("Couldn't conn
ect to mySQL");
mysql_selectdb( $DB_DB ) or errormsg(sprintf("Couldn't connect into database %
s", $DB_DB));
$qry_format="select name, doc from flxFORMATS order by name";
$res_format=mysql_query( $qry_format );
print '<table cellpadding="4" cellspacing="0">';
$color="";
while($format=mysql_fetch_array($res_format))
{
list($name, $doc)=$format;
if($color==$cCells)
$color="#FFFFFF";
else
$color=$cCells;
$doc=str_replace("\n", "<br>", $doc);
#$doc=str_replace(" ", "&nbsp;", $doc);
print "<tr bgcolor=\"$color\">";
print "<td><b>$name</b></td>";
print "<td><font size=\"2\">$doc&nbsp;</font></td>";
print "<td><a href=\"JavaScript:openwindowlink( 'FORMAT_showone.php?fname=".urlencode($name)."', 'FE' )\"><font size=\"2\">[Code]</font></a></td>";
print "<td><a href=\"JavaScript:openwindowlink( 'FORMAT_edit.php?fname=".urlencode($name)."', 'FM' )\"><font size=\"2\">[Modify]</font></a></td>";
print "<td><a href=\"FORMAT_del.php?fname=".urlencode($name)."\"><font size=\"2\">[Delete]</font></a></td>";
print "</tr>";
print "<tr>";
print "<td colspan=\"3\">".str_replace("\n", "<br>", htmlspecialchars($code))."</td>";
print "</tr>";
}
print "</table>";
mysql_close( $db );
?>
<hr><br>
<form action="FORMAT_add.php" method="POST">
<table>
<tr>
<td bgcolor="#000000" colspan="2">
<font color="#FFFFFF">Add new FORMAT</font>
</td>
</tr>
<tr>
<td>Format Name</td>
<td><input type="text" name="fname"></td>
</tr>
<tr>
<td>Format documentation</td>
<td><textarea name="doc" cols="65" rows="5"></textarea><td>
</tr>
<tr>
<td>EL Code</td>
<td><textarea name="code" cols="65" rows="20"></textarea><td>
</tr>
<tr>
<td align="center" colspan="2"><input class="formbutton" type="submit" value="Add"></td>
</tr>
</table>
</form>
<?
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/FORMAT_edit.php.wml b/modules/bibformat/web/admin/FORMAT_edit.php.wml
index 57657e651..b05448ab1 100644
--- a/modules/bibformat/web/admin/FORMAT_edit.php.wml
+++ b/modules/bibformat/web/admin/FORMAT_edit.php.wml
@@ -1,171 +1,171 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: FORMAT_edit.php (flexElink WI)
// Description: Allows to modify format data and updates the changes in the DB.
// It will only update the format data if the EL code is syntactically
// correct and it's "interpretable". It serializes the EL code into the
// corresponding semantic structure and stores it in the DB for
// optimization (no need to re-compile afterwards)
// POST parameters:
// fname --> (required) Name (id) of the format to be modified
// process -> (optional) When is set, the script updates the format data
// in the DB with the parameter values
// fname_orig -> (required if process is set) Original name of the format
// to be updated (the name format can be changed)
// doc ----> (optional) Description of the purpose of the format
// code ---> (optional) Format's EL code
// Notes: If the format is succesfully updated in the DB it closes the current
// browser and refreshes the opener one
// Requires: DB, ERROR, EXECUTOR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($fname)) or (trim($fname)=="") )
{
print "<b>Format name</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
//--------DISPLAY
if(!isset($process))
{
$qry="select value, doc from flxFORMATS where name='$fname'";
$qh=mysql_query( $qry );
if(mysql_num_rows( $qh )<1)
{
print "<b>Format</b> not found";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$row=mysql_fetch_array($qh);
list($code, $doc)=$row;
$code = str_replace("&nbsp;","&amp;nbsp;",$code);
?>
<form action="FORMAT_edit.php" method="POST">
<table witdth="100%" bgcolor="#CCCCCC" cellpadding="4" cellspacing="4">
<tr align="center">
<td bgcolor="#CCCCFF">
<font size="4">
Editing format <b>'<? echo $fname;?>'</b></font>
</td>
</tr>
<td bgcolor="#FFFFFF">
<b>Format Name</b> <input name="fname" value="<?echo $fname;?>">
</td>
<tr>
<td align="center" bgcolor="#FFFFFF">
<b>Documentation</b><br>
<textarea name="doc" cols="100" rows="5"><?echo $doc;?></textarea>
</td>
</tr>
<tr>
<td align="center" bgcolor="#FFFFFF">
<b>EL Code</b><br>
<textarea name="code" cols="100" rows="25"><?echo $code;?></textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input class="formbutton" type="submit" value="UPDATE" name="btnUpd">
<input class="formbutton" type="submit" value="UPDATE&CLOSE" name="btnUpdClose">
</td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="fname_orig" value="<?echo $fname;?>">
</form>
<?
}
else
{
if( (!isset($code)) )
$code="";
else
{
$temp_code=$code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code, array( $fname ) );
if(!$ok)
{
print "Code incorrect: <b>$msg</b><hr> <a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
else
{
$serialized=addslashes(serialize($msg));
}
}
if(!isset($doc))
{
$doc="";
}
if(!get_magic_quotes_gpc())
{
$fname=addslashes($fname);
$code=addslashes($code);
$doc=addslashes($doc);
}
$qry="update flxFORMATS
set name='$fname',
value='$code',
doc='$doc',
serialized='$serialized'
where name='$fname_orig'";
if(!mysql_query( $qry ))
{
print "Impossible to update format: <b>$fname</b><br>".mysql_error()."<hr> <a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
<?
if(isset($btnUpd))
print "window.location=\"FORMAT_edit.php?fname=$fname\";";
else
print "window.close();";
?>
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/FORMAT_showone.php.wml b/modules/bibformat/web/admin/FORMAT_showone.php.wml
index 958b66f9e..757a74b2d 100644
--- a/modules/bibformat/web/admin/FORMAT_showone.php.wml
+++ b/modules/bibformat/web/admin/FORMAT_showone.php.wml
@@ -1,89 +1,89 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: BEH_showone.php (flexElink WI)
// Description: Shows the details for a given format (code and documentation).
// POST parameters:
// fname --> (required) Name (id) of the format to be shown
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
include(FUNCTION_LIB);
if( (!isset($fname)) or (trim($fname)=="") )
{
errorpage("<b>Format name</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
$qry="select value, doc from flxFORMATS where name='$fname'";
$res=mysql_query( $qry );
list($code, $doc) =mysql_fetch_array( $res );
$code=text2HTML($code);
$doc=str_replace("\n","<br>",$doc);
$doc=str_replace(" ","&nbsp;",$doc);
?>
<html>
<head>
<title>Format <?print $fname;?></title>
</head>
<body>
<table width="100%" bgcolor="#808080">
<tr align="center">
<td colspan="2" bgcolor="#66CCFF">
<font size="4">Details of format <b>'<? echo $fname;?>'</b></font>
</td>
</tr>
<tr>
<td width="15%" valign="middle" bgcolor="#CCFFFF">
<b>Documentation</b>
</td>
<td bgcolor="#FFFFFFFF">
<font size="2"><?print $doc; ?></font>
</td>
</tr>
<tr>
<td width="15%" valign="middle" bgcolor="#CCFFFF">
<b>EL Code</b>
</td>
<td bgcolor="#FFFFFFFF">
<?print $code;?>
</td>
</tr>
</table>
</html>
<?
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/KB_VALUE_add.php.wml b/modules/bibformat/web/admin/KB_VALUE_add.php.wml
index 4fee6ad44..30204f202 100644
--- a/modules/bibformat/web/admin/KB_VALUE_add.php.wml
+++ b/modules/bibformat/web/admin/KB_VALUE_add.php.wml
@@ -1,81 +1,81 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: KB_VALUE_add.php (flexElink WI)
// Description: Adds a new pair key-value to the DB table which corresponds to
// the indicated KB.
// POST parameters:
// name --> (required) Name (id) of the KB to which the value will be added
// key ---> (required) Key value to be added
// value -> (required) Value that maps the indicated key
// Notes: If the KB is succesfully added to the DB it redirects the current
// browser to the indicated KB display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($kb_name)) or (trim($kb_name)=="") )
{
errorpage("<b>KB name</b> hasn't been specified");
exit;
}
if( (!isset($key)) or (trim($key)=="") )
{
errorpage("<b>KB entry key</b> hasn't been specified");
exit;
}
if( (!isset($value)) or (trim($value)=="") )
{
errorpage("<b>KB entry value</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$kb_name=strtoupper(trim($kb_name));
$qry="select kb_table from flxKBS where kb_name='$kb_name'";
$res=mysql_query( $qry, $db );
list($kb_table)=mysql_fetch_array( $res );
$qry="insert into $kb_table(vkey, value)
values ('$key', '$value')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new KB entry:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: KB_showone.php?name=".urlencode($kb_name));
?>
diff --git a/modules/bibformat/web/admin/KB_VALUE_del.php.wml b/modules/bibformat/web/admin/KB_VALUE_del.php.wml
index 3f0d4bb1c..34c8dd23e 100644
--- a/modules/bibformat/web/admin/KB_VALUE_del.php.wml
+++ b/modules/bibformat/web/admin/KB_VALUE_del.php.wml
@@ -1,73 +1,73 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: KB_del.php (flexElink WI)
// Description: Deletes a pair key-value from the DB table of the indicated KB.
// POST parameters:
// name --> (required) Name (id) of the KB from which the key-value has to
// be deleted
// key ---> (required) Key value to be deleted (the mapping value is also
// deleted)
// Notes: If the KB is succesfully added to the DB it redirects the current
// browser to the indicated KB display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($kb_name)) or (trim($kb_name)=="") )
{
errorpage("<b>KB name</b> hasn't been specified");
exit;
}
if( (!isset($key)) or (trim($key)=="") )
{
errorpage("<b>KB entry key</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$kb_name=strtoupper(trim($kb_name));
$qry="select kb_table from flxKBS where kb_name='$kb_name'";
$res=mysql_query( $qry, $db );
list($kb_table)=mysql_fetch_array( $res );
$qry="delete from $kb_table where vkey='$key'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete KB entry:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: KB_showone.php?name=".urlencode($kb_name));
?>
diff --git a/modules/bibformat/web/admin/KB_add.php.wml b/modules/bibformat/web/admin/KB_add.php.wml
index f09ef9c97..81e3ac317 100644
--- a/modules/bibformat/web/admin/KB_add.php.wml
+++ b/modules/bibformat/web/admin/KB_add.php.wml
@@ -1,96 +1,96 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: KB_add.php (flexElink WI)
// Description: Adds a new KB to the DB. It also creates a table in the
// configuration DB that will keep the KB values.
// POST parameters:
// name --> (required) Name (id) of the KB to be added
// table -> (optional) DB table name; if it is not provided (normal i
// situation), the script will generate it automatically ensuring
// that is unique in this DB
// doc ----> (optional) Description of the purpose of the KB
// Notes: If the KB is succesfully added to the DB it redirects the current
// browser to the KB display list
// Requires: DB, ERROR, EXECUTOR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($name)) or (trim($name)=="") )
{
errorpage("<b>KB name</b> hasn't been specified");
exit;
}
if( !isset($table) )
$table="";
if( !isset($doc) )
$doc="";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL");
mysql_selectdb( $DB_DB );
$name=trim(strtoupper($name));
$table=trim(strtoupper($table));
if($table=="")
{
$table="flxKB$name";
}
$qry="create table $table(
vkey varchar(255) not null,
value text default '',
primary key(vkey))";
if(!mysql_query( $qry ))
{
errorpage("Impossible to create KB table:<br> ".mysql_error());
mysql_close( $db );
exit;
}
if(!get_magic_quotes_gpc())
{
$doc=addslashes($doc);
}
$qry="insert into flxKBS(kb_name, kb_table, doc)
values ('$name', '$table', '$doc')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new KB:<br> ".mysql_error());
$qry="drop table $table";
mysql_query( $qry );
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: KB_display.php");
?>
diff --git a/modules/bibformat/web/admin/KB_del.php.wml b/modules/bibformat/web/admin/KB_del.php.wml
index 8ab62dca4..6deaa1188 100644
--- a/modules/bibformat/web/admin/KB_del.php.wml
+++ b/modules/bibformat/web/admin/KB_del.php.wml
@@ -1,74 +1,74 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: KB_del.php (flexElink WI)
// Description: Deletes an existing KB from the DB. It also deletes its
// corresponding DB table.
// POST parameters:
// name --> (required) Name (id) of the KB to be added
// Notes: If the KB is succesfully added to the DB it redirects the current
// browser to the KB display list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($name)) or (trim($name)=="") )
{
errorpage("<b>KB name</b> hasn't been specified");
exit;
}
$name=strtoupper(trim($name));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="select kb_table from flxKBS where kb_name='$name'";
$qh=mysql_query($qry, $db);
list($table)=mysql_fetch_array($qh);
$qry="delete from flxKBS
where kb_name='$name'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete KB:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="drop table $table";
if(!mysql_query( $qry ))
{
errorpage("KB entry deleted but not table:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: KB_display.php");
?>
diff --git a/modules/bibformat/web/admin/KB_display.php.wml b/modules/bibformat/web/admin/KB_display.php.wml
index 6ce58b257..0c7b237d0 100644
--- a/modules/bibformat/web/admin/KB_display.php.wml
+++ b/modules/bibformat/web/admin/KB_display.php.wml
@@ -1,138 +1,138 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Knowledge Bases (KBs)" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="KB_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: KB_display.php (flexElink WI)
// Description: Shows a list of the existing KBs in the DB, and allows to
// access to their list of values, add new ones or delete existing ones
// POST parameters:
// Notes:
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(HEADER);
?>
<p>Define one or more knowledge bases that enables you to transform
various forms of input data values into the unique standard form on
the output.
<em>Example:</em> You can tell that <em>Phys Rev D</em> and
<em>Physical Review D</em> are both the same journal and that these
names should be standardized to <em>Phys Rev : D</em>.<p>
<script language="javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=320,witdh=320,scrollbars,resizable")
}
//-->
</script>
<?
$cBorder="#CCCCCC";
$cHeaders="#FFCC33";
$cCells="#FFFFFF";
$cImpCells="#FFCC99";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="select kb_name, kb_table, doc from flxKBS order by kb_name";
$res=mysql_query( $qry, $db );
print '<table bgcolor="'.$cBorder.'" border="1">';
print "<tr bgcolor=\"$cHeaders\">";
print "<td align=\"center\"><b>KB name</b></td>";
print "<td align=\"center\"><b>Table name</b></td>";
print "<td align=\"center\"><b>Documentation</b></td>";
print "<td colspan=\"3\">&nbsp;</td>";
print "</tr>";
while($row=mysql_fetch_array($res))
{
list($kb_name, $kb_table, $doc)=$row;
$doc=str_replace("\n", "<br>", $doc);
#$doc=str_replace(" ", "&nbsp;", $doc);
print "<tr bgcolor=\"$cCells\">";
print "<td bgcolor=\"$cImpCells\">
<strong>$kb_name</strong>
</td>";
print "<td>$kb_table</td>";
print "<td><font size=\"2\">$doc&nbsp;</font></td>";
print "<td><font size=\"2\">
<a href=\"JavaScript:openwindowlink( 'KB_showone.php?name=".urlencode($kb_name)."', 'KBSv$kb_name' )\">[Values]</a></font></td>";
print "<td><font size=\"2\">
<a href=\"JavaScript:openwindowlink( 'KB_edit.php?name=".urlencode($kb_name)."', 'KBSe$kb_name' )\">[Modify]</a></font></td>";
print "<td><font size=\"2\">
<a href=\"KB_del.php?name=".urlencode($kb_name)."\">[Delete]</a>
</font></td>";
print "</tr>";
}
print "</table>";
mysql_close( $db );
?>
<br>
<form action="KB_add.php" method="POST">
<table>
<tr>
<td bgcolor="#000000" colspan="2">
<font color="#FFFFFF">Add new KNOWLEDGE BASE</font>
</td>
</tr>
<tr>
<td align="right">Knowledge base name</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td align="right">Knowledge base table name (normally leave it blank)</td>
<td><input type="text" name="table"></td>
</tr>
<tr>
<td align="right">KB documentation</td>
<td><textarea name="doc" cols="50" rows="5"></textarea><td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit" value="Add"></td>
</tr>
</table>
</form>
<?
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/KB_edit.php.wml b/modules/bibformat/web/admin/KB_edit.php.wml
index 1d17115e5..411994722 100644
--- a/modules/bibformat/web/admin/KB_edit.php.wml
+++ b/modules/bibformat/web/admin/KB_edit.php.wml
@@ -1,129 +1,129 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: KB_edit.php (flexElink WI)
// Description: Allows to modify KB data and updates the changes in the DB.
// DB table is not available for modifcation
// POST parameters:
// name --> (required) Name (id) of the KB to be modified
// process -> (optional) When is set, the script updates the KB data
// in the DB with the parameter values
// name_orig -> (required if process is set) Original name of the KB
// to be updated (the KB format may be changed)
// doc ----> (optional) Description of the purpose of the KB
// Notes: If the KB is succesfully updated in the DB it closes the current
// browser and refreshes the opener one
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($name)) or (trim($name)=="") )
{
print "<b>KB name</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$name=trim(strtoupper($name));
//--------DISPLAY
if(!isset($process))
{
$qry="select kb_table, doc from flxKBS where kb_name='$name'";
$qh=mysql_query( $qry );
if(mysql_num_rows( $qh )<1)
{
print "<b>KB '$name'</b> not found";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$row=mysql_fetch_array($qh);
list($table, $doc)=$row;
?>
<form action="KB_edit.php" method="POST">
<table witdth="100%" bgcolor="#CCCCCC" cellpadding="4" cellspacing="4">
<tr align="center">
<td bgcolor="#FFCC99" colspan="2">
<font size="4">
Editing KB <b>'<? echo $name;?>'</b></font>
</td>
</tr>
<td bgcolor="#FFFFFF">
<b>KB Name</b> <input name="name" value="<?echo $name;?>">
</td>
<td bgcolor="#FFFFFF">
<b>Table name: </b><? echo $table;?>
</td>
<tr>
<td align="center" bgcolor="#FFFFFF" colspan="2">
<b>Documentation</b><br>
<textarea name="doc" cols="100" rows="5"><?echo $doc;?></textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit" value="UPDATE"></td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="name_orig" value="<?echo $name;?>">
</form>
<?
}
else
{
if( (!isset($doc)) )
$doc="";
if(!get_magic_quotes_gpc())
{
$doc=addslashes($doc);
}
$qry="update flxKBS
set kb_name='$name',
doc='$doc'
where kb_name='$name_orig'";
if(!mysql_query( $qry ))
{
print "Impossible to update KB '$name_orig': ".mysql_error();
print "<hr><a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit();
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/KB_showone.php.wml b/modules/bibformat/web/admin/KB_showone.php.wml
index 853ddda19..7a6549209 100644
--- a/modules/bibformat/web/admin/KB_showone.php.wml
+++ b/modules/bibformat/web/admin/KB_showone.php.wml
@@ -1,98 +1,98 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: KB_showone.php (flexElink WI)
// Description: Shows the list of values for a given KB (it also shows complete
// KB reated data: documentation, DB table name). It allows to add or
// delete values to the displayed KB
// POST parameters:
// name --> (required) Name (id) of the KB to be shown
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($name)) or (trim($name)=="") )
{
errorpage("<b>KB name</b> hasn't been specified");
exit;
}
$cBorder="#CCCCCC";
$cHeaders="#FFCC33";
$cCells="#FFFFFF";
$cImpCells="#FFCC99";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="select kb_table, doc from flxKBS where kb_name='$name'";
$res=mysql_query( $qry, $db );
list($table, $doc)=mysql_fetch_array( $res );
$doc=str_replace("\n", "<br>", $doc);
$doc=str_replace(" ", "&nbsp;", $doc);
$qry="select vkey, value from $table order by vkey";
$res=mysql_query( $qry, $db );
print "<form action=\"KB_VALUE_add.php\" method=\"POST\">";
print "<input type=\"hidden\" name=\"kb_name\" value=\"$name\">";
print '<table bgcolor="'.$cBorder.'" width="100%" border="1">';
print "<tr bgcolor=\"$cHeaders\">";
print "<td colspan=\"3\" align=\"center\"><font size=\"4\">Values of KB <b>'$name'</b> ".mysql_num_rows($res)." values</font></td>";
print "</tr>";
print "<tr>";
print "<td bgcolor=\"$cImpCells\"><b>Table Name</b></td>";
print "<td colspan=\"2\" bgcolor=\"$cCells\">$table</td>";
print "</tr>";
print "<tr>";
print "<td bgcolor=\"$cImpCells\"><b>Documentation</b></td>";
print "<td colspan=\"2\" bgcolor=\"$cCells\"><font size=\"2\">$doc</font></td>";
print "</tr>";
print "<tr bgcolor=\"#CCCCCC\">";
print "<td bgcolor=\"$cImpCells\" colspan=\"3\" align=\"center\">ADD <b>VALUE</b>:
<i>Key</i> <input type=\"text\" name=\"key\">
<i>Value</i> <input type=\"text\" name=\"value\">
<input class=\"formbutton\" type=\"submit\" value=\"Add value\">
</td>";
print "</tr>";
while($row=mysql_fetch_array($res))
{
list($key, $value)=$row;
print "<tr bgcolor=\"$cCells\">";
print "<td width=\"50%\">$key</td>";
print "<td width=\"50%\">$value</td>";
print "<td align=\"center\"><a href=\"KB_VALUE_del.php?kb_name=".urlencode($name)."&key=".urlencode($key)."\"><font size=\"2\">[Delete]</font></a></td>";
print "</tr>";
}
print "</table>";
print "</form>";
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/LINK_ACTION_add_edit.php.wml b/modules/bibformat/web/admin/LINK_ACTION_add_edit.php.wml
index f24fe54bf..1bb93679f 100644
--- a/modules/bibformat/web/admin/LINK_ACTION_add_edit.php.wml
+++ b/modules/bibformat/web/admin/LINK_ACTION_add_edit.php.wml
@@ -1,221 +1,221 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_ACTION_add_edit.php (flexElink WI)
// Description: Adds a new action to an existing link condtion or allows to
// modify the data of an existing action of a link condition.
// POST parameters:
// linktype --> (required) Name (id) of the link definition which the
// action's condition belongs (or will belong) to
// eorder ----> (required) Action's condition evaluation order number for
// the given link definition
// action ----> (optional, possible values: ADD, EDIT) Determines which
// operations wants to be performed: adding a new action or
// editing an existing one. When is set, the update or insert is
// made in the DB; if not, the needed controls for the adding or
// modifying are displayed
// aorder ---> (required if action is EDIT) Apply order of the
// cation inside the corresponding link condition. When adding,
// if this parameter is not set the script will look for the last
// apply order number assigned in this link action
// el_code -> (optional) Action's EL code
// Notes: If the condition is succesfully added to the DB it closes the current
// browser and refreshes the opener one
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($linktype)) or (trim($linktype)=="") )
{
print "<b>Link type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if( (!isset($eorder)) or (trim($eorder)=="") )
{
print "<b>Link condition evaluation order</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if(get_magic_quotes_gpc())
$linktype=stripslashes($linktype);
$linktype=trim(strtoupper($linktype));
if(!isset($action))
{
$action="ADD";
if( (isset($aorder)) or (trim($aorder)!="") )
{
$action="EDIT";
}
else
{
$aorder="";
}
$el_code="";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if($action=="EDIT")
{
$qry="select el_code
from flxLINKTYPECONDITIONSACTIONS
where linktype='$linktype'
and eval_order='$eorder'
and apply_order=$aorder";
$qh=mysql_query($qry);
if(mysql_num_rows($qh)<=0)
{
print "<b>Action not found</b>";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
mysql_close($db);
exit;
}
list($el_code)=mysql_fetch_array($qh);
}
mysql_close($db);
?>
<form action="LINK_ACTION_add_edit.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
<? echo $action; ?> action for linktype '
<? echo $linktype;?> - <?echo $eorder;?>'</font>
</td>
</tr>
<tr>
<td>Apply order: </td>
<td><input type="text" name="<?
if($action=="EDIT")
print "";
else
print "aorder";?>" value="<?echo $aorder;?>"></td>
</tr>
<tr>
<td>Action EL Code: </td>
<td><textarea name="el_code" cols="80" rows="15"><?echo $el_code;?></textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit"></td>
</tr>
</table>
<input type="hidden" name="linktype" value="<?echo $linktype;?>">
<input type="hidden" name="eorder" value="<?echo $eorder;?>">
<input type="hidden" name="process" value="oo">
<input type="hidden" name="action" value="<?echo $action;?>">
<?if($action=="EDIT"){
print "<input type=\"hidden\" name=\"aorder\" value=\"$aorder\">";
}?>
</form>
<?
}
else
{
if( (!isset($el_code)) )
$el_code="";
else
{
$temp_code=$el_code;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code );
if(!$ok)
{
print "Action code incorrect: <b>$msg</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if( (!isset($aorder)) or (trim($aorder)==""))
{
$qry="select max(apply_order)+1
from flxLINKTYPECONDITIONSACTIONS
where linktype='$linktype'
and eval_order=$eorder";
$qh=mysql_query($qry, $db);
list($aorder)=mysql_fetch_array( $qh );
if($aorder==null)
$aorder=0;
}
if(!get_magic_quotes_gpc())
{
$el_code=addslashes($el_code);
}
$qry="";
if($action=="ADD")
{
$qry="insert into flxLINKTYPECONDITIONSACTIONS
(linktype, eval_order, apply_order, el_code)
values
('$linktype', '$eorder', '$aorder', '$el_code')";
}
elseif($action=="EDIT")
{
$qry="update flxLINKTYPECONDITIONSACTIONS
set linktype='$linktype',
eval_order='$eorder',
apply_order='$aorder',
el_code='$el_code'
where linktype='$linktype'
and eval_order='$eorder'
and apply_order='$aorder'";
}
if(!mysql_query( $qry ))
{
print "Impossible to $action action:<br> ".mysql_error()."<br>".
"<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close($db);
exit;
}
mysql_close($db);
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/LINK_ACTION_del.php.wml b/modules/bibformat/web/admin/LINK_ACTION_del.php.wml
index a5ca5cf8d..507e23a81 100644
--- a/modules/bibformat/web/admin/LINK_ACTION_del.php.wml
+++ b/modules/bibformat/web/admin/LINK_ACTION_del.php.wml
@@ -1,77 +1,77 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_ACTION_del.php (flexElink WI)
// Description: Deletes an existing action of a certain condition for a given
// link definition from the DB.
// POST parameters:
// linktype --> (required) Name (id) of the link definition the condition
// belongs to
// eorder ----> (required) Action's condition evaluation order number for
// the given link definition
// aorder ----> (required) Action's apply order number inside the given
// condition
// Notes: If the action is succesfully added to the DB the current browser is
// redirectred to the link detailed definition display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($linktype)) or (trim($linktype)=="") )
{
errorpage("<b>Link type</b> hasn't been specified");
exit();
}
if( (!isset($eorder)) or (trim($eorder)=="") )
{
errorpage("<b>Evaluation order</b> hasn't been specified");
exit();
}
if( (!isset($aorder)) or (trim($aorder)=="") )
{
errorpage("<b>Apply order</b> hasn't been specified");
exit();
}
$linktype=strtoupper(trim($linktype));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="delete from flxLINKTYPECONDITIONSACTIONS
where linktype='$linktype'
and eval_order='$eorder'
and apply_order='$aorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete action:<br> ".mysql_error());
}
mysql_close( $db );
header("location: LINK_showone.php?linktype=".urlencode($linktype));
?>
diff --git a/modules/bibformat/web/admin/LINK_COND_add_edit.php.wml b/modules/bibformat/web/admin/LINK_COND_add_edit.php.wml
index c48675576..90052820e 100644
--- a/modules/bibformat/web/admin/LINK_COND_add_edit.php.wml
+++ b/modules/bibformat/web/admin/LINK_COND_add_edit.php.wml
@@ -1,309 +1,309 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_COND_add_edit.php (flexElink WI)
// Description: Adds a new condition to an existing link or allows to modify
// the data of an existing condition of a link.
// POST parameters:
// linktype --> (required) Name (id) of the link definition which the
// condition belongs (or will belong) to
// action ----> (optional, possible values: ADD, EDIT) Determines which
// operations wants to be performed: adding a new condition or
// editing an existing one. When is set, the update or insert is
// made in the DB; if not, the needed controls for the adding or
// modifying are displayed
// eorder ---> (required if action is EDIT) Evalutation order of the
// condition inside the corresponding link definition. When adding,
// if this parameter is not set the script will look for the last
// evaluation order number assigned in this link definition
// stype ----> (optional, allowed values: EXT, INT) Condition solving type;
// if it isn't specified is put to the default value (EXT)
// el_condition -> (optional) Condition's EL code
// bfile ----> (optional) Base file path for internal link solving
// burl -----> (optional) Base url path for internal link solving
// formats --> (optional) List of file formats ids separated by "|"
// Notes: If the condition is succesfully added to the DB it closes the current
// browser and refreshes the opener one
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($linktype)) or (trim($linktype)=="") )
{
print "<b>Link type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if(get_magic_quotes_gpc())
$linktype=stripslashes($linktype);
$linktype=trim(strtoupper($linktype));
if(!isset($action))
{
$action="ADD";
if( (isset($eorder)) or (trim($eorder)!="") )
{
$action="EDIT";
}
else
{
$eorder="";
}
$el_condition="";
$formats="";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if($action=="EDIT")
{
$qry="select el_condition, solvingtype,
base_file, base_url
from flxLINKTYPECONDITIONS
where linktype='$linktype'
and eval_order='$eorder'";
$qh=mysql_query($qry);
if(mysql_num_rows($qh)<=0)
{
print "<b>Condition not found</b>";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
mysql_close($db);
exit;
}
list($el_condition, $stype, $bfile, $burl)=mysql_fetch_array($qh);
$qry="select f.name
from flxLINKTYPECONDITIONSFILEFORMATS cf, flxFILEFORMATS f
where cf.linktype='$linktype'
and cf.eval_order='$eorder'
and f.name=cf.fname";
$qh=mysql_query($qry);
$formats="";
while($row=mysql_fetch_array($qh))
{
$f=$row[0];
$formats.="$f | ";
}
}
else //Add action
{
$qry="select solvingtype, base_file, base_url
from flxLINKTYPES
where linktype='".addslashes($linktype)."'";
$qh=mysql_query($qry, $db);
list($stype, $bfile, $burl)=mysql_fetch_array($qh);
}
mysql_close($db);
?>
<form action="LINK_COND_add_edit.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
<? echo $action; ?> condition for linktype '
<? echo $linktype;?>'</font>
</td>
</tr>
<tr>
<td>Evaluation order: </td>
<td><input type="text" name="<?
if($action=="EDIT")
print "";
else
print "eorder";?>" value="<?echo $eorder;?>"></td>
</tr>
<tr>
<td>Condition EL Code: </td>
<td><textarea name="el_condition" cols="80" rows="2"><?echo $el_condition;?></textarea></td>
</tr>
<tr>
<td>Solving type</td>
<td><select name="stype">
<option value="EXT"
<?if($stype=="EXT") echo "selected";?>>External</option>
<option value="INT"
<?if($stype=="INT") echo "selected";?>>Internal</option>
</select>
</td>
</tr>
<tr>
<td>Base file path</td>
<td><input type="text" name="bfile" value="<? echo $bfile; ?>" size="107"></td>
</tr>
<tr>
<td>Base url</td>
<td><input type="text" name="burl" value="<? echo $burl; ?>" size="107"></td>
</tr>
<tr>
<td>Associated file formats</td>
<td><input type="text" name="formats" size="107" value="<?echo $formats;?>"></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit"></td>
</tr>
</table>
<input type="hidden" name="linktype" value="<?echo $linktype;?>">
<input type="hidden" name="process" value="oo">
<input type="hidden" name="action" value="<?echo $action;?>">
<?if($action=="EDIT"){
print "<input type=\"hidden\" name=\"eorder\" value=\"$eorder\">";
}?>
</form>
<?
}
else
{
if( (!isset($el_condition)) )
$el_condition="";
else
{
$temp_code=$el_condition;
if(get_magic_quotes_gpc())
$temp_code=stripslashes($temp_code);
include(EXECUTOR);
$a=new AELExecutor();
list($ok, $msg)=$a->checkCode( $temp_code );
if(!$ok)
{
print "Condition code incorrect: <b>$msg</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if( (!isset($eorder)) or (trim($eorder)==""))
{
$qry="select max(eval_order)+1 from flxLINKTYPECONDITIONS
where linktype='$linktype'";
$qh=mysql_query($qry, $db);
list($eorder)=mysql_fetch_array( $qh );
if($eorder==null)
$eorder=0;
}
if(!isset($formats))
{
$formats="";
}
if(!get_magic_quotes_gpc())
{
$el_condition=addslashes($el_condition);
$bfile=addslashes($bfile);
$burl=addslashes($burl);
}
$qry="";
if($action=="ADD")
{
$qry="insert into flxLINKTYPECONDITIONS
(linktype, eval_order, el_condition,
solvingtype, base_file, base_url)
values
('$linktype', '$eorder', '$el_condition',
'$stype', '$bfile', '$burl')";
}
elseif($action=="EDIT")
{
$qry="update flxLINKTYPECONDITIONS
set linktype='$linktype',
eval_order='$eorder',
el_condition='$el_condition',
solvingtype='$stype',
base_file='$bfile',
base_url='$burl'
where linktype='$linktype'
and eval_order='$eorder'";
}
if(!mysql_query( $qry ))
{
print "Impossible to $action condition:<br> ".mysql_error()."<br>".
"<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close($db);
exit;
}
$qry="delete from flxLINKTYPECONDITIONSFILEFORMATS
where linktype='$linktype'
and eval_order='$eorder'";
if(!mysql_query( $qry ))
{
print "Impossible to update associated formats<br> ".mysql_error().
"<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close($db);
exit;
}
$f=split("\|", $formats);
$errors="";
foreach($f as $format)
{
$format=strtoupper(trim($format));
if($format=="")
continue;
$qry="select name
from flxFILEFORMATS
where name='$format'";
$qh=mysql_query($qry);
if(mysql_num_rows($qh)<1)
{
$errors.="Format '$format' doesn't exist, couldn't associate<hr>";
continue;
}
$qry="insert into flxLINKTYPECONDITIONSFILEFORMATS(linktype, eval_order, fname)
values ('$linktype', '$eorder', '$format')";
if(!mysql_query( $qry ))
{
$errors.="Couldn't associate format '$format'<br> ".mysql_error();
}
}
if($errors!="")
{
print "Record succesfully updated but ERRORS found associating formats:<br> <b>$errors</b><hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
mysql_close($db);
exit;
}
mysql_close($db);
?>
<script language="JavaScript">
opener.location.reload(false);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/LINK_COND_del.php.wml b/modules/bibformat/web/admin/LINK_COND_del.php.wml
index e3acf3d53..fd38918f2 100644
--- a/modules/bibformat/web/admin/LINK_COND_del.php.wml
+++ b/modules/bibformat/web/admin/LINK_COND_del.php.wml
@@ -1,92 +1,92 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_COND_del.php (flexElink WI)
// Description: Deletes an existing condition(and all its depending
// items) for a given link definition from the DB.
// POST parameters:
// linktype --> (required) Name (id) of the link definition the condition
// belongs to
// eorder ----> (required) Condition evaluation order number for the given
// link definition
// Notes: If the format is succesfully added to the DB the current browser is
// redirectred to the link detailed definition display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($linktype)) or (trim($linktype)=="") )
{
errorpage("<b>Link type</b> hasn't been specified");
exit();
}
if( (!isset($eorder)) or (trim($eorder)=="") )
{
errorpage("<b>Evaluation order</b> hasn't been specified");
exit();
}
$linktype=strtoupper(trim($linktype));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxLINKTYPECONDITIONSACTIONS
where linktype='$linktype'
and eval_order='$eorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete actions related to this condition:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxLINKTYPECONDITIONSFILEFORMATS
where linktype='$linktype'
and eval_order='$eorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete formats related to this condition:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxLINKTYPECONDITIONS
where linktype='$linktype' and eval_order='$eorder'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete conditions related to this link type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: LINK_showone.php?linktype=".urlencode($linktype));
?>
diff --git a/modules/bibformat/web/admin/LINK_FORMAT_add.php.wml b/modules/bibformat/web/admin/LINK_FORMAT_add.php.wml
index 0f57d9d74..63fdb21c0 100644
--- a/modules/bibformat/web/admin/LINK_FORMAT_add.php.wml
+++ b/modules/bibformat/web/admin/LINK_FORMAT_add.php.wml
@@ -1,74 +1,74 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($name)) or (trim($name)=="") )
{
errorpage("<b>File format name</b> hasn't been specified");
exit;
}
if( (!isset($text)))
{
$text="";
}
if( (!isset($extensions)))
{
$extensions="";
}
if(get_magic_quotes_gpc())
{
$extensions=stripslashes($extensions);
$text=stripslashes($text);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$name=trim(strtoupper($name));
if(!get_magic_quotes_gpc())
{
$extensions=addslashes($extensions);
$text=addslashes($text);
}
$qry="insert into flxFILEFORMATS (name, text, extensions)
values ('$name', '$text', '$extensions')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new file format:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: LINK_FORMAT_display.php");
?>
diff --git a/modules/bibformat/web/admin/LINK_FORMAT_del.php.wml b/modules/bibformat/web/admin/LINK_FORMAT_del.php.wml
index 5901b0a40..40fac239f 100644
--- a/modules/bibformat/web/admin/LINK_FORMAT_del.php.wml
+++ b/modules/bibformat/web/admin/LINK_FORMAT_del.php.wml
@@ -1,56 +1,56 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($name)) or (trim($name)=="") )
{
errorpage("<b>Format file name</b> hasn't been specified");
exit;
}
$name=strtoupper(trim($name));
if(!get_magic_quotes_gpc())
{
$name=addslashes($name);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxFILEFORMATS
where name='$name'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete file format:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: LINK_FORMAT_display.php");
?>
diff --git a/modules/bibformat/web/admin/LINK_FORMAT_display.php.wml b/modules/bibformat/web/admin/LINK_FORMAT_display.php.wml
index 0f7061dc8..c726b0637 100644
--- a/modules/bibformat/web/admin/LINK_FORMAT_display.php.wml
+++ b/modules/bibformat/web/admin/LINK_FORMAT_display.php.wml
@@ -1,118 +1,118 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="File Formats" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="LINK_FORMAT_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
include(DB);
include(ERROR);
include(HEADER);
?>
<p>Define file format types based on file extensions. This will be
used when proposing various fulltext services.
<em>Example:</em> You can tell that <code>*.pdf</code> files will
be treated as PDF files. <p>
<script type="text/javascript">
<!---
function openwindowlink( addr )
{
newwin=window.open( addr, "Mywindow", "height=620,witdh=520,scrollbars,resizable")
}
//-->
</script>
<?
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or errormsg("Couldn't conn
ect to mySQL");
mysql_selectdb( $DB_DB ) or errormsg(sprintf("Couldn't connect into database %
s", $DB_DB));
$qry="select name, text, extensions
from flxFILEFORMATS
order by name";
$res=mysql_query( $qry, $db );
print '<table border="1">';
print "<tr align=\"center\" bgcolor=\"#00CCFF\">";
print "<td><b>Format Id</b></td>";
print "<td><b>Format Description</b></td>";
print "<td><b>File Extensions</b></td>";
print "<td colspan=\"2\"></td>";
print "</tr>";
while($format=mysql_fetch_array($res))
{
list($name, $text, $ext)=$format;
print "<tr>";
print "<td>$name</td>";
print "<td>$text</td>";
print "<td>$ext</td>";
print "<td><a href=\"JavaScript:openwindowlink( '.php?' )\">[Modify]</a></td>";
print "<td><a href=\"LINK_FORMAT_del.php?name=$name\">[Delete]</a></td>";
print "</tr>";
}
print "</table>";
mysql_close( $db );
?>
<hr><br>
<form action="LINK_FORMAT_add.php" method="POST">
<table>
<tr>
<td bgcolor="#000000" colspan="2">
<font color="#FFFFFF">Add new File FORMAT</font>
</td>
</tr>
<tr>
<td>Format Name</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>Format Description</td>
<td><input type="text" name="text" size="60"></td>
</tr>
<tr>
<td>File Extensions</td>
<td><textarea name="extensions" cols="65" rows="5"></textarea><td>
</tr>
<tr>
<td colspan="2"><input class="formbutton" type="submit" value="Add"></td>
</tr>
</table>
</form>
<?
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/LINK_add.php.wml b/modules/bibformat/web/admin/LINK_add.php.wml
index 2b9f0b3da..e70fbc7c0 100644
--- a/modules/bibformat/web/admin/LINK_add.php.wml
+++ b/modules/bibformat/web/admin/LINK_add.php.wml
@@ -1,119 +1,119 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_add.php (flexElink WI)
// Description: Adds a new link definition to the DB.
// POST parameters:
// linktype --> (required) Name (id) of the link definition to be added
// params ----> (optional) List of parameters that the link will accept;
// they have to be separated with "," and the order in which they
// are specified is the order the values will have to be passed
// when solving the link
// stype ----> (optional, allowed values: EXT, INT) Link solving type; if
// it isn't specified is put to the default value (EXT)
// bfile ----> (optional) Base file path for internal link solving
// burl -----> (optional) Base url path for internal link solving
// Notes: If the format is succesfully added to the DB it redirects the current
// browser to the link display list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($linktype)) or (trim($linktype)=="") )
{
errorpage("<b>Link Type</b> hasn't been specified");
exit;
}
$linktype=trim(strtoupper($linktype));
if( !isset($params) )
{
$params="";
}
if(!isset($stype))
{
$stype="EXT";
}
else
{
$stype=strtoupper(trim($stype));
}
if(($stype!="EXT")&&($stype!="INT"))
{
errorpage("Incorrect value for <b>solving type</b>");
exit;
}
if(!isset($bfile))
$bfile="";
if(!isset($burl))
$burl="";
if(!get_magic_quotes_gpc())
{
$stype=addslashes($stype);
$bfile=addslashes($bfile);
$burl=addslashes($burl);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="insert into flxLINKTYPES(linktype, check_exists,
solvingtype, base_file, base_url)
values('$linktype', '$check', '$stype', '$bfile', '$burl')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
if(trim($params)!="")
{
$params=split(",", $params);
$order=0;
foreach($params as $param)
{
$param=trim(strtoupper($param));
$qry="insert into flxLINKTYPEPARAMS values('$linktype', '$param', $order)";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert parameter '$param':<br> ".mysql_error());
mysql_close( $db );
exit;
}
$order++;
}
}
mysql_close( $db );
header("location: LINK_display.php");
?>
diff --git a/modules/bibformat/web/admin/LINK_del.php.wml b/modules/bibformat/web/admin/LINK_del.php.wml
index d267636fc..6a26a6e49 100644
--- a/modules/bibformat/web/admin/LINK_del.php.wml
+++ b/modules/bibformat/web/admin/LINK_del.php.wml
@@ -1,95 +1,95 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_del.php (flexElink WI)
// Description: Deletes an existing link definition (and all its depending
// items) from the DB.
// POST parameters:
// linktype --> (required) Name (id) of the link definition to be deleted
// Notes: If the format is succesfully added to the DB the current browser is
// closed and the opener one is refreshed
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($linktype)) or (trim($linktype)=="") )
{
errorpage("<b>Link type</b> hasn't been specified");
exit;
}
$linktype=strtoupper(trim($linktype));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="delete from flxLINKTYPECONDITIONSACTIONS where linktype='$linktype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete actions related to this link type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxLINKTYPECONDITIONSFILEFORMATS where linktype='$linktype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete formats related to this link type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxLINKTYPECONDITIONS where linktype='$linktype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete conditions related to this link type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxLINKTYPEPARAMS where linktype='$linktype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete parameters related to this link type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxLINKTYPES where linktype='$linktype'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete link type:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(true);
window.close();
</script>
diff --git a/modules/bibformat/web/admin/LINK_display.php.wml b/modules/bibformat/web/admin/LINK_display.php.wml
index 730426420..0dada7fc0 100644
--- a/modules/bibformat/web/admin/LINK_display.php.wml
+++ b/modules/bibformat/web/admin/LINK_display.php.wml
@@ -1,166 +1,166 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Link Rules" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="LINK_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: LINK_display.php (flexElink WI)
// Description: Shows a list of the existing links and their parameters, and
// allows to access to their details or add new link definitions
// POST parameters:
// Notes:
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(HEADER);
?>
<p>Define rules for automated creation of URI links from mapped
internal variables.
<em>Example:</em> You can tell a rule how to create a link to
People database out of the <code>$100.a</code> internal variable
repesenting author's name. (The <code>$100.a</code> variable was mapped
in the previous step, see the Extraction Rules.)<p>
<script type="text/javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=620,witdh=320,scrollbars,resizable")
}
//-->
</script>
<?
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="select linktype
from flxLINKTYPES
order by linktype";
$qh=mysql_query($qry);
print '<table bgcolor="#CCCCCC" border="1">';
print "<tr align=\"center\" bgcolor=\"#33CC00\">";
print "<td><b>Link type label</b></td>";
print "<td><b>Parameters</b></td>";
print "<td>&nbsp;</td>";
print "</tr>";
while($row=mysql_fetch_array($qh))
{
list($linktype)=$row;
$qry_par="select pname
from flxLINKTYPEPARAMS
where linktype='".addslashes($linktype)."'
order by ord";
$qh_par=mysql_query($qry_par);
$pars="";
while($row=mysql_fetch_array($qh_par))
{
$pars.=$row[0].",";
}
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\"><b>$linktype</b></td>";
print "<td>$pars</td>";
print "<td align=\"center\">
<a href=\"JavaScript:openwindowlink('LINK_showone.php?linktype=$linktype', 'LRSHOW$linktype')\">
<font size=\"2\">[Details]</font></a></td>";
print "</tr>";
}
print "</table>";
mysql_close( $db );
?>
<form action="LINK_add.php" method="POST">
<table>
<tr>
<td bgcolor="#000000" colspan="2">
<font color="#FFFFFF">Add new Link Type</font>
</td>
</tr>
<tr>
<td width="30%" align="right">
Name
</td>
<td>
<input type="text" name="linktype">
</td>
</tr>
<tr>
<td width="30%" align="right">
Params
</td>
<td>
<input type="text" name="params">
</td>
</tr>
<tr>
<td width="30%" align="right">
Solving type
</td>
<td>
<select name="stype">
<option value="EXT">External</option>
<option value="INT">Internal</option>
</select>
</td>
</tr>
<tr>
<td width="30%" align="right">
Base file path
</td>
<td>
<input type="text" name="bfile" size="80">
</td>
</tr>
<tr>
<td width="30%" align="right">
Base url
</td>
<td>
<input type="text" name="burl" size="80">
</td>
</tr>
<tr>
<td colspan="2">
<input class="formbutton" type="submit" value="Add">
</td>
</tr>
</table>
</form>
<?
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/LINK_edit.php.wml b/modules/bibformat/web/admin/LINK_edit.php.wml
index da6c6f5e8..9b1f6ceba 100644
--- a/modules/bibformat/web/admin/LINK_edit.php.wml
+++ b/modules/bibformat/web/admin/LINK_edit.php.wml
@@ -1,221 +1,221 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_edit.php (flexElink WI)
// Description: Allows to modify the data of an existing link definition by
// the user.
// POST parameters:
// linktype --> (required) Name (id) of the link definition to be modified
// linktype_orig -> (optional) Contains the original name (name in the DB)
// of the link definition which has to be modified. When this
// parameter is set, the update in the DB is done with the
// parameter values received by the script.
// params ----> (optional) List of parameters that the link will accept;
// they have to be separated with "," and the order in which they
// are specified is the order the values will have to be passed
// when solving the link
// stype ----> (optional, allowed values: EXT, INT) Link solving type; if
// it isn't specified is put to the default value (EXT)
// bfile ----> (optional) Base file path for internal link solving
// burl -----> (optional) Base url path for internal link solving
// Notes: If the format is succesfully added to the DB it redirects the current
// browser to the link detailed definition display
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
include(FUNCTION_LIB);
if((!isset($linktype))||(trim($linktype)==""))
{
print "<b>ERROR</b>: Link type label hasn't been specified!!<hr>";
print "<a align=\"center\" href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
if(get_magic_quotes_gpc())
{
$linktype=stripslashes($linktype);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
if(isset($linktype_orig))
{
if(get_magic_quotes_gpc())
{
$linktype_orig=stripslashes($linktype_orig);
}
$linktype=trim(strtoupper($linktype));
$linktype_orig=trim(strtoupper($linktype_orig));
if( !isset($params) )
{
$params="";
}
if(!isset($stype))
{
$stype="EXT";
}
else
{
$stype=strtoupper(trim($stype));
}
if(($stype!="EXT")&&($stype!="INT"))
{
print "Incorrect value for <b>solving type</b>";
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
exit;
}
if(!isset($bfile))
$bfile="";
if(!isset($burl))
$burl="";
if(!get_magic_quotes_gpc())
{
$stype=addslashes($stype);
$bfile=addslashes($bfile);
$burl=addslashes($burl);
}
$qry="delete from flxLINKTYPEPARAMS
where linktype='$linktype'";
if(!mysql_query($qry))
{
print "Impossible to delete old link params for '$linktype': ".
mysql_error();
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
$qry="update flxLINKTYPES
set solvingtype='$stype',
base_file='$bfile',
base_url='$burl'
where linktype='$linktype'";
if(!mysql_query($qry))
{
print "Impossible to update link type '$linktype': ".mysql_error();
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
if(trim($params)!="")
{
$params=split(",", $params);
$order=0;
foreach($params as $param)
{
if(trim($param)=="")
continue;
$param=trim(strtoupper($param));
$qry="insert into flxLINKTYPEPARAMS
values('$linktype', '$param', $order)";
$errors="";
if(!mysql_query( $qry ))
{
$errors.="Impossible to insert parameter '$param':<br> ".
mysql_error()."<br><br>";
}
$order++;
}
if($errors!="")
{
print $errors;
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Back]</a>";
mysql_close( $db );
exit;
}
}
header("location: LINK_showone.php?linktype=$linktype");
exit;
}
$qry="select solvingtype, base_file, base_url
from flxLINKTYPES
where linktype='".addslashes($linktype)."'";
$qh=mysql_query($qry);
print "<form action=\"\" method=\"POST\">";
print '<table width="100%" bgcolor="#CCCCCC" border="1">';
print "<tr bgcolor=\"#33CC00\" align=\"center\">";
print "<td colspan=\"2\"><font size=\"6\">Modifying link type '$linktype'</font></td>";
print "</tr>";
list($stype, $bfile, $burl)=mysql_fetch_row($qh);
$qry_par="select pname
from flxLINKTYPEPARAMS
where linktype='".addslashes($linktype)."'
order by ord";
$qh_par=mysql_query($qry_par);
$pars="";
while($row=mysql_fetch_array($qh_par))
{
$pars.=$row[0].",";
}
?>
<tr bgcolor="#FFFFFF">
<td bgcolor="#CCFFCC" width="15%"><b>Parameters</b></td>
<td><input type="text" name="params" value="<?echo $pars;?>" size="70"></td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#CCFFCC"><b>Solving type</b></td>
<td><select name="stype">
<option value="EXT" <?if($stype=="EXT") echo "selected";?>>
External
</option>
<option value="INT" <?if($stype=="INT") echo "selected";?>>
Internal
</option>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#CCFFCC"><b>Base file path</b></td>
<td><input type="text" name="bfile" size="100" value="<?echo $bfile;?>"></td>
</tr>
<tr bgcolor="#FFFFFF">
<td bgcolor="#CCFFCC"><b>Base url</b></td>
<td><input type="text" name="burl" size="100" value="<?echo $burl;?>"></td>
</tr>
<tr align="center">
<td colspan="2">
<input type="button" value="CANCEL" onClick="JavaScript:window.history.go(-1)">
<input class="formbutton" type="submit" value="UPDATE">
<input type="hidden" name="linktype" value="<?echo $linktype;?>">
<input type="hidden" name="linktype_orig" value="<?echo $linktype;?>">
</td>
</tr>
</table>
</form>
<?
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/LINK_showone.php.wml b/modules/bibformat/web/admin/LINK_showone.php.wml
index 1efd8b3cd..8aae0dad6 100644
--- a/modules/bibformat/web/admin/LINK_showone.php.wml
+++ b/modules/bibformat/web/admin/LINK_showone.php.wml
@@ -1,212 +1,212 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: LINK_add.php (flexElink WI)
// Description: Show the details of a link definition which is in the DB. It
// shows link definition data (parameters, type, base paths) and
// corresponding link condtions with their actions. It allows to perform
// management operations (delete, add, modifiy) over all the items diplayed
// POST parameters:
// linktype --> (required) Name (id) of the link definition to be shown
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
include(FUNCTION_LIB);
?>
<script language="javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=420,witdh=320,scrollbars,resizable")
}
//-->
</script>
<?
if((!isset($linktype))||(trim($linktype)==""))
{
print "<b>ERROR</b>: Link type label hasn't been specified!!<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
if(get_magic_quotes_gpc())
{
$linktype=stripslashes($linktype);
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="select solvingtype, base_file, base_url
from flxLINKTYPES
where linktype='".addslashes($linktype)."'";
$qh=mysql_query($qry);
print '<table width="100%" bgcolor="#CCCCCC" border="1">';
print "<tr bgcolor=\"#33CC00\" align=\"center\">";
print "<td colspan=\"2\"><font size=\"6\">Details of link type '$linktype'</font></td>";
print "</tr>";
list($stype, $bfile, $burl)=mysql_fetch_row($qh);
$qry_par="select pname
from flxLINKTYPEPARAMS
where linktype='".addslashes($linktype)."'
order by ord";
$qh_par=mysql_query($qry_par);
$pars="";
while($row=mysql_fetch_array($qh_par))
{
$pars.=$row[0].",";
}
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\" width=\"15%\"><b>Parameters</b></td>";
print "<td>$pars</td>";
print "</tr>";
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\"><b>Solving type</b></td>";
$temp="Internal";
if($stype=="EXT")
{
$temp="External";
}
print "<td>$temp</td>";
print "</tr>";
if($stype=="INT")
{
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\"><b>Base file path</b></td>";
print "<td>$bfile</td>";
print "</tr>";
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\"><b>Base url</b></td>";
print "<td>$burl</td>";
print "</tr>";
}
print "</table>";
print '<table width="100%" cellspacing="0" bgcolor="#CCCCCC" cellpadding="4" border="0">';
print "<tr align=\"center\">";
print "<td>
<a href=\"JavaScript:openwindowlink('LINK_COND_add_edit.php?linktype=".urlencode($linktype)."', 'LRADDC$linktype')\">[Add condition]</a></td>";
print "<td><a href=\"LINK_edit.php?linktype=".urlencode($linktype)."\">[Modify]</a></td>";
print "<td><a href=\"LINK_del.php?linktype=".urlencode($linktype)."\">[Delete]</a></td>";
print "</tr>";
print "</table>";
$qry="select eval_order, el_condition, el_action,
solvingtype, base_file, base_url
from flxLINKTYPECONDITIONS
where linktype='".addslashes($linktype)."'
order by eval_order";
$qh=mysql_query($qry, $db);
if(mysql_num_rows($qh)>=1)
{
print '<table width="100%" bgcolor="#CCCCCC" border="1">';
print "<tr bgcolor=\"#33CC00\" align=\"center\">";
print "<td colspan=\"4\"><b>CONDITIONS</b></td>";
print "</tr>";
while($row=mysql_fetch_array($qh))
{
print "<tr bgcolor=\"#CCFFCC\" align=\"center\">";
print "<td><font size=\"2\"><b>Evaluation Order</b></font></td>";
print "<td width=\"100%\"><font size=\"2\"><b>Condition EL Code</b></font></td>";
print "<td><font size=\"2\"><b>Solve type</b></font></td>";
print "<td><font size=\"2\"><b>Formats</b></font></td>";
print "</tr>";
list($eorder, $condition, $action, $stype, $bfile, $burl)=$row;
$qry_fmts="select f.name
from flxLINKTYPECONDITIONSFILEFORMATS cf, flxFILEFORMATS f
where cf.linktype='".addslashes($linktype)."'
and cf.eval_order='$eorder'
and f.name=cf.fname";
$qh_fmts=mysql_query($qry_fmts, $db);
$fmts="";
while($fmt=mysql_fetch_array($qh_fmts))
{
$fmts.=$fmt[0]."<br>";
}
print "<tr bgcolor=\"#FFFFFF\">";
print "<td align=\"center\">$eorder</td>";
print "<td>".text2HTML($condition)."</td>";
print "<td>$stype</td>";
print "<td>$fmts</td>";
print "</tr>";
if($stype=="INT")
{
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\"><font size=\"2\"><b>Base FILE</b></font></td>";
print "<td colspan=\"4\">$bfile</td>";
print "</tr>";
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\"><font size=\"2\"><b>Base URL</b></font></td>";
print "<td colspan=\"4\">$burl</td>";
print "</tr>";
}
$qry_ac="select apply_order, el_code
from flxLINKTYPECONDITIONSACTIONS
where linktype='".addslashes($linktype)."'
and eval_order=$eorder
order by apply_order";
$qh_ac=mysql_query($qry_ac, $db);
while($row_ac=mysql_fetch_array($qh_ac))
{
list($aorder, $action)=$row_ac;
print "<tr bgcolor=\"#FFFFFF\">";
print "<td bgcolor=\"#CCFFCC\">
<font size=\"2\"><b>Action ($aorder)</b></font></td>";
print "<td>".text2HTML($action)."</td>";
print "<td><font size=\"2\">
<a href=\"JavaScript:openwindowlink('LINK_ACTION_add_edit.php?linktype=".urlencode($linktype)."&eorder=$eorder&aorder=$aorder', 'LCAE$linktype$eorder$aorder')\">[Modify]</a></td>";
print "<td><font size=\"2\">
<a href=\"LINK_ACTION_del.php?linktype=".urlencode($linktype)."&eorder=$eorder&aorder=$aorder\">[Delete]</a></td>";
print "</tr>";
}
print "<tr bgcolor=\"#CCCCCC\" align=\"center\">";
print "<td colspan=\"5\">
<font size=\"2\">
<a href=\"JavaScript:openwindowlink('LINK_ACTION_add_edit.php?linktype=".urlencode($linktype)."&eorder=$eorder', 'LCAADD$linktype$eorder$aorder')\">[Add Action]</a>
<a href=\"JavaScript:openwindowlink('LINK_COND_add_edit.php?linktype=".urlencode($linktype)."&eorder=$eorder', 'LCEDIT$linktype$eorder')\">[Modify]</a>
<a href=\"LINK_COND_del.php?linktype=".urlencode($linktype)."&eorder=$eorder\">[Delete]</a>
</font>
</td>";
print "</tr>";
}
print "</table>";
}
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/Makefile.am b/modules/bibformat/web/admin/Makefile.am
index cd518c3a5..c556d6646 100644
--- a/modules/bibformat/web/admin/Makefile.am
+++ b/modules/bibformat/web/admin/Makefile.am
@@ -1,37 +1,37 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webdir=$(WEBDIR)/admin/bibformat
FILESWML=$(wildcard $(srcdir)/*.wml)
web_DATA=$(FILESWML:$(srcdir)/%.wml=%)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(wildcard *.php) *~ *.tmp
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.php: %.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml \
$(top_srcdir)/config/cdspage.wml $(top_srcdir)/config/cdsnavbar.wml $(MO)
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
for lang in en; do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.php" ; \
done
diff --git a/modules/bibformat/web/admin/OAIER_SF_add.php.wml b/modules/bibformat/web/admin/OAIER_SF_add.php.wml
index fa8d1bc23..21fc8387f 100644
--- a/modules/bibformat/web/admin/OAIER_SF_add.php.wml
+++ b/modules/bibformat/web/admin/OAIER_SF_add.php.wml
@@ -1,144 +1,144 @@
# $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Extraction Rules" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="OAIER_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: OAIER_SF_add.php (flexElink WI)
// Description: Adds a new field and its ER to the DB for a defined variable.
// POST parameters:
// type -----> (required) Input type the variable belongs to
// varname --> (required) Internal variable name the field is going to be
// added to
// process --> (optional) When is set, it adds the field and its ER to
// the DB according to the values specified via the parameters
// sfname ---> (required when process is set) Name of the field to be
// added
// label ---> (optional) subfield element attribute LABEL value
// Notes: If the field-ER is succesfully added to the DB the current browser
// is closed and the opener one is refreshed
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
if( (!isset($type)) or (trim($type)=="") )
{
print "<b>Input type</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$otype=trim(strtoupper($otype));
if( (!isset($varname)) or (trim($varname)=="") )
{
print "<b>Variable name</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$varname=trim(strtoupper($varname));
if(!isset($process))
{
?>
<form action="OAIER_SF_add.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="black">
<font color="white" align="center">
Add new subfield to variable'<? echo "$type - $varname";?>'</font>
</td>
</tr>
<tr>
<td>Subfield name: </td>
<td><input type="text" name="sfname"></td>
</tr>
<tr>
<td>Attribute "label" value: </td>
<td><input type="text" name="label"></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit"></td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="type" value="<?echo $type;?>">
<input type="hidden" name="varname" value="<?echo $varname;?>">
</form>
<?
}
else
{
if( (!isset($sfname)) or (trim($sfname)=="") )
{
outWarning( "<b>Subfield name</b> hasn't been specified");
print "</td></tr></table>";
exit;
}
$sfname=trim(strtoupper($sfname));
if( (!isset($label)) or (trim($label)=="") )
{
outWarning( "<b>Attribute 'label' value</b> hasn't been specified");
print "</td></tr></table>";
exit;
}
$label=trim($label);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$qry="insert into flxXMLMARCEXTRULESUBFIELDS(type, varname, sfname, att_label)
values ('$type', '$varname', '$sfname', '$label')";
if(!mysql_query( $qry ))
{
print "Impossible to insert new subfield rule:<br> ".mysql_error();
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.history.go(-1);\">[Go Back]</a>";
mysql_close( $db );
exit;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(true);
window.close();
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/OAIER_SF_del.php.wml b/modules/bibformat/web/admin/OAIER_SF_del.php.wml
index 6849c4c20..13b55cc3a 100644
--- a/modules/bibformat/web/admin/OAIER_SF_del.php.wml
+++ b/modules/bibformat/web/admin/OAIER_SF_del.php.wml
@@ -1,81 +1,81 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: OAIER_SF_del.php (flexElink WI)
// Description: Deletes an existing field and its corresponding ER from the
// configuration DB for the specified variable.
// POST parameters:
// type -----> (required) Input type the ER belongs to
// varname --> (required) Internal variable name the field to be deleted
// belongs to
// sfname ---> (required) Field name to be deleted
// Notes: If the variable-ER is succesfully deleted from the DB the current
// browser is redirected to the OAI extraction rules list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($type)) or (trim($type)=="") )
{
errorpage("<b>Type of the rule</b> hasn't been specified");
exit;
}
$type=strtoupper(trim($type));
if( (!isset($varname)) or (trim($varname)=="") )
{
errorpage("<b>Variable name</b> hasn't been specified");
exit;
}
$varname=strtoupper(trim($varname));
if( (!isset($sfname)) or (trim($sfname)=="") )
{
errorpage("<b>Subfield name</b> hasn't been specified");
exit;
}
$sfname=strtoupper(trim($sfname));
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry="delete from flxXMLMARCEXTRULESUBFIELDS
where type='$type'
and varname='$varname'
and sfname='$sfname'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete variable subfields:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: OAIER_display.php");
?>
diff --git a/modules/bibformat/web/admin/OAIER_add.php.wml b/modules/bibformat/web/admin/OAIER_add.php.wml
index 4422f1657..ca4b3cfc8 100644
--- a/modules/bibformat/web/admin/OAIER_add.php.wml
+++ b/modules/bibformat/web/admin/OAIER_add.php.wml
@@ -1,94 +1,94 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
<protect>## $Id$</protect>
//==========================================================================
// File: OAIER_add.php (flexElink WI)
// Description: Adds a new variable and the corresponding ER to the
// configuration DB.
// POST parameters:
// type -----> (required) Input type the ER belongs to
// varname --> (required) Internal variable name
// att_id ---> (optional) varfield element attribute ID value
// att_i1 ---> (optional) varfield element attribute I1 value (only
// relevant if ftype=DATAFIELD)
// att_i2 ---> (optional) varfield element attribute I2 value (only
// relevant if ftype=DATAFIELD)
// ftype ----> (required) field type (DATAFIELD, CONTROLFIELD), default
// value DATAFIELD
// Notes: If the variable-ER is succesfully added to the DB the current browser
// is redirected to the OAI extraction rules list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($type)) or (!trim($type)) )
{
errorpage("Rule <b>type</b> hasn't been specified");
exit;
}
if( (!isset($varname)) or (!trim($varname)) )
{
errorpage("Rule <b>varname</b> hasn't been specified");
exit;
}
if( (!isset($ftype))||(($ftype!="DATAFIELD")&&($ftype!="CONTROLFIELD")) )
$ftype="DATAFIELD";
if(!isset($att_id))
$att_id="";
if(!isset($att_i1))
$att_i1="";
if(!isset($att_i2))
$att_i2="";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$type=trim(strtoupper($type));
$varname=trim(strtoupper($varname));
$att_id=trim($att_id);
$att_i1=trim($att_i1);
$att_i2=trim($att_i2);
$qry="insert into flxXMLMARCEXTRULES(type, varname, att_id, att_i1, att_i2, ftype)
values ('$type', '$varname', '$att_id', '$att_i1', '$att_i2', '$ftype')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new rule:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: OAIER_display.php");
?>
diff --git a/modules/bibformat/web/admin/OAIER_del.php.wml b/modules/bibformat/web/admin/OAIER_del.php.wml
index 6200f4b80..2833cf474 100644
--- a/modules/bibformat/web/admin/OAIER_del.php.wml
+++ b/modules/bibformat/web/admin/OAIER_del.php.wml
@@ -1,83 +1,83 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
<protect>## $Id$</protect>
//==========================================================================
// File: OAIER_del.php (flexElink WI)
// Description: Deletes an existing variable and the corresponding ER from the
// configuration DB.
// POST parameters:
// type -----> (required) Input type the ER belongs to
// varname --> (required) Internal variable name to be deleted
// Notes: If the variable-ER is succesfully deleted from the DB the current
// browser is redirected to the OAI extraction rules list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($type)) or (trim($type)=="") )
{
errorpage("<b>Type of the rule</b> hasn't been specified");
exit;
}
if( (!isset($varname)) or (trim($varname)=="") )
{
errorpage("<b>Variable name</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$type=trim(strtoupper($type));
$varname=trim(strtoupper($varname));
$qry="delete from flxXMLMARCEXTRULESUBFIELDS
where type='$type'
and varname='$varname'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete variable subfields:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxXMLMARCEXTRULES
where type='$type'
and varname='$varname'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete rule:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: OAIER_display.php");
?>
diff --git a/modules/bibformat/web/admin/OAIER_display.php.wml b/modules/bibformat/web/admin/OAIER_display.php.wml
index 7f81928a5..1768af37f 100644
--- a/modules/bibformat/web/admin/OAIER_display.php.wml
+++ b/modules/bibformat/web/admin/OAIER_display.php.wml
@@ -1,227 +1,227 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Extraction Rules" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="OAIER_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: OAIER_display.php (flexElink WI)
// Description: Shows a list of defined internal variables and their
// corresponding extraction rules (ER); it also shows fields of each
// variable. Besides, it provides access to management operations
// POST parameters:
// Notes:
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(HEADER);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$qry_rules="select *
from flxXMLMARCEXTRULES
order by type, varname";
$res=mysql_query( $qry_rules, $db );
$old_type="";
?>
<p>Define how the metadata tags from input are mapped into internal
BibFormat variable names. The variable names can afterwards be used
in formatting and linking rules.
<em>Example:</em> You can tell that <code>100 $a</code> field
should be mapped into <code>$100.a</code> internal variable that you
could use later.<p>
<script language="javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=320,witdh=320,scrollbars,resizable")
}
//-->
</script>
<?
print '<table cellspacing="0" cellpadding="4">';
$color1="#FFFFFF";
$color2="#66CCCC";
while($row=mysql_fetch_array($res))
{
list($type, $varname, $att_id, $att_i1, $att_i2, $mvalues, $ftype)=$row;
if(($old_type=="") or ($type!=$old_type))
{
print "\t<tr>\n";
print "\t\t<td colspan=\"6\" align=\"center\" bgcolor=\"#000000\"><b><font size=\"5\" color=\"#FFFFFF\">$type</font></b></td>\n";
print "\t</tr>\n";
print "\t<tr align=\"center\" bgcolor=\"#CCCCCC\">\n";
print "\t\t<td><b>Varname</b></td>\n";
print "\t\t<td><b>Mapping Tag</b></td>\n";
print "\t\t<td><b>Allow multiple values</b></td>\n";
print "\t\t<td colspan=\"3\">&nbsp;</td>\n";
print "\t</tr>\n";
$old_type=$type;
$color=$color2;
}
if($color==$color1)
$color=$color2;
else
$color=$color1;
print "\t<tr bgcolor=\"$color\" align=\"center\">\n";
print "\t\t<td><b>$varname</b></td>\n";
if($ftype=="DATAFIELD")
{
print "\t\t<td>".htmlspecialchars("<datafield tag=\"$att_id\" ind1=\"$att_i1\" ind2=\"$att_i2\">")."</td>\n";
}
else
{
print "\t\t<td>".htmlspecialchars("<controlfield tag=\"$att_id\">")."</td>\n";
}
if($mvalues=="S")
print "\t\t<td>Yes</td>\n";
else
print "\t\t<td><font color=\"red\">No</font></td>\n";
print "\t\t<td><a href=\"\"><font size=\"2\">[Modify]</font></a></td>\n";
if($ftype=="DATAFIELD")
{
print "\t\t<td><a href=\"JavaScript:openwindowlink('OAIER_SF_add.php?type=$type&varname=$varname', 'OAIERSFADD$type$varname')\"><font size=\"2\">[Add Subfield]</font></a></td>\n";
}
else
{
print "\t\t<td>&nbsp;</td>";
}
print "\t\t<td><a href=\"OAIER_del.php?type=".urlencode($type)."&varname=".urlencode($varname)."\"><font size=\"2\">[Delete]</font></a></td>\n";
print "\t</tr>\n";
if($ftype!="DATAFIELD") continue;
$qry_sf="select sfname, att_label from flxXMLMARCEXTRULESUBFIELDS where type='$type'
and varname='$varname' order by sfname";
$res_sf=mysql_query($qry_sf);
if(mysql_num_rows($res_sf)>=1)
{
print "\t<tr align=\"center\" bgcolor=\"$color\">\n";
print "\t\t<td colspan=\"6\">\n";
print "\t\t\t".'<table width="50%" bgcolor="#CCCCCC" cellspacing="1">'."\n";
print "\t\t\t\t<tr>\n";
print "\t\t\t\t\t<td colspan=\"4\" align=\"center\">";
print "<font size=\"2\"><b>SUBFIELDS</b></font>";
print "</td>\n";
print "\t\t\t\t</tr>\n";
print "\t\t\t\t<tr align=\"center\">\n";
print "\t\t\t\t\t<td><font size=\"2\">SF Name</font></td>\n";
print "\t\t\t\t\t<td><font size=\"2\">Mapping Tag</font></td>\n";
print "\t\t\t\t\t<td colspan=\"2\">&nbsp;</td>\n";
print "\t\t\t\t</tr>\n";
while($row_sf=mysql_fetch_array($res_sf))
{
list($sfname, $att_label)=$row_sf;
print "\t\t\t\t<tr align=\"center\" bgcolor=\"$color\">\n";
print "\t\t\t\t\t<td>$sfname</td>\n";
print "\t\t\t\t\t<td>".htmlspecialchars("<subfield code=\"$att_label\">")."</td>\n";
print "\t\t\t\t\t<td><a href=\"\"><font size=\"2\">[Modify]</font></a></td>\n";
print "\t\t\t\t\t<td><a href=\"OAIER_SF_del.php?type=".urlencode($type)."&varname=".urlencode($varname)."&sfname=".urlencode($sfname)."\"><font size=\"2\">[Delete]</font></a></td>\n";
print "\t\t\t\t</tr>\n";
}
print "\t\t\t</table>\n";
print "\t\t</td>\n";
print "\t</tr>\n";
}
while($row_sf=mysql_fetch_array($res_sf))
{
print "<tr bgcolor=\"$color\">";
print "<td><font size=\"2\"><strong>$sfname</strong></font></td>";
print "<td><font size=\"2\">$att_label</font></td>";
print "<td colspan=\"3\"></td>";
print "<td><a href=\"\"><font size=\"2\">[Delete]</font></a>";
print "</tr>";
}
}
print "</table>";
?>
<hr>
<form action="OAIER_add.php" method="POST">
<table>
<tr>
<td colspan="2" bgcolor="#000000"><font size="5" color="#FFFFFF">Add new Extraction Rule</font></td>
</tr>
<tr>
<td align="right">Type</td>
<td><input type="text" name="type"></td>
</tr>
<tr>
<td align="right">Variable name</td>
<td><input type="text" name="varname"></td>
</tr>
<tr>
<td align="right">Field Type</td>
<td><select name="ftype">
<option value="DATAFIELD">datafield</option>
<option value="CONTROLFIELD">controlfield</option>
</select>
</td>
</tr>
<tr>
<td align="right">Attribute TAG value</td>
<td><input type="text" name="att_id"></td>
</tr>
<tr>
<td align="right">Attribute IND1 value<br><font size="1">(only for datafield)</font></td>
<td><input type="text" name="att_i1"></td>
</tr>
<tr>
<td align="right">Attribute IND2 value<br><font size="1">(only for datafield)</font></td>
<td><input type="text" name="att_i2"></td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit" value="Add rule"></td>
</tr>
</table>
</form>
<?
mysql_close( $db );
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/UDF_add.php.wml b/modules/bibformat/web/admin/UDF_add.php.wml
index 25838853e..04e40d44b 100644
--- a/modules/bibformat/web/admin/UDF_add.php.wml
+++ b/modules/bibformat/web/admin/UDF_add.php.wml
@@ -1,105 +1,105 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: UDF_add.php (flexElink WI)
// Description: Adds a new UDF definition to the DB. It also stores the
// UDF's parameters.
// POST parameters:
// fname --> (required) Name (id) of the UDF to be added
// params -> (required) Contains the UDF param list. UDF parameters are
// separated by using ","
// doc ----> (optional) Description of the purpose of the UDF
// code ---> (optional) UDF's PHP code
// Notes: If the UDF is succesfully added to the DB it redirects the current
// browser to the UDF display list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($fname)) or (trim($fname)=="") )
{
errorpage("<b>Function name</b> hasn't been specified");
exit;
}
if(!isset($params))
{
errorpage("<b>Params</b> hasn't been specified");
exit;
}
if(!isset($code))
$code="";
if(!isset($doc))
$doc="";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
$rtype=trim(strtoupper($rtype));
if(!get_magic_quotes_gpc())
{
$code=addslashes($code);
$doc=addslashes($doc);
}
$qry="insert into flxUDFS (fname, rtype, code, doc)
values ('$fname', '$rtype', '$code', '$doc')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert new UDF:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$pars=explode(",", trim($params));
$counter=0;
foreach($pars as $parname)
{
$parname=trim($parname);
if($parname=="")
continue;
$qry="insert into flxUDFPARAMS(fname, pname, ord)
values('$fname', '$parname', '$counter')";
if(!mysql_query( $qry ))
{
errorpage("Impossible to insert UDF parameter '$parname':<br> ".mysql_error());
mysql_close( $db );
exit;
}
$counter++;
}
mysql_close( $db );
header("location: UDF_display.php");
?>
diff --git a/modules/bibformat/web/admin/UDF_del.php.wml b/modules/bibformat/web/admin/UDF_del.php.wml
index a83678cd4..2e9c779d1 100644
--- a/modules/bibformat/web/admin/UDF_del.php.wml
+++ b/modules/bibformat/web/admin/UDF_del.php.wml
@@ -1,72 +1,72 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: UDF_delete.php (flexElink WI)
// Description: Deletes an existing UDF from the DB.
// POST parameters:
// fname --> (required) Name (id) of the UDF to be deleted
// Notes: If the UDF is succesfully added to the DB it redirects the current
// browser to the UDF display list
// Requires: DB, ERROR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($fname)) or (trim($fname)=="") )
{
errorpage("<b>Function name</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
$qry="delete from flxUDFS
where fname='$fname'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete function:<br> ".mysql_error());
mysql_close( $db );
exit;
}
$qry="delete from flxUDFPARAMS
where fname='$fname'";
if(!mysql_query( $qry ))
{
errorpage("Impossible to delete function parameters:<br> ".mysql_error());
mysql_close( $db );
exit;
}
mysql_close( $db );
header("location: UDF_display.php");
?>
diff --git a/modules/bibformat/web/admin/UDF_display.php.wml b/modules/bibformat/web/admin/UDF_display.php.wml
index 0e1452b8a..74125d628 100644
--- a/modules/bibformat/web/admin/UDF_display.php.wml
+++ b/modules/bibformat/web/admin/UDF_display.php.wml
@@ -1,146 +1,146 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="User Defined Functions (UDFs)" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="UDF_display"
<?
include("security.inc.php");
<protect>## $Id$</protect>
//==========================================================================
// File: UDF_display.php (flexElink WI)
// Description: Shows a list of the existing UDFs and their parameters, and
// allows to access to their details, add or delete
// POST parameters:
// Notes:
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include(DB);
include(ERROR);
include(FUNCTION_LIB);
include(HEADER);
?>
<p>Define your own functions that you can reuse when creating your
own output formats. This enables you to do complex formatting without
ever touching the BibFormat core code.
<em>Example:</em> You can define a function how to match and
extract email addresses out of a text file.<p>
<script language="javascript">
<!---
function openwindowlink( addr, name )
{
window.open( addr, "Window"+name, "height=560,witdh=220,scrollbars,resizable" )
}
//-->
</script>
<?
$cBorder="#CCCCCC";
$cHeaders="#FFFFFFCC";
$cCells="#FFFFFFFF";
$cImpCells="#FFFFFFF0";
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD ) or errormsg("Couldn't conn
ect to mySQL");
mysql_selectdb( $DB_DB ) or errormsg(sprintf("Couldn't connect into database %
s", $DB_DB));
$qry_func="select fname, rtype, doc from flxUDFS order by fname";
$res_func=mysql_query( $qry_func );
print '<table border="1" bgcolor="'.$cBorder.'">'."\n";
print "<tr align=\"center\">\n
<td bgcolor=\"$cHeaders\"><B>Function name</b></td>\n";
print "<td bgcolor=\"$cHeaders\"><b>Params</b></td>\n";
print "<td bgcolor=\"$cHeaders\"><b>Description</b></td>\n";
print "<td bgcolor=\"$cHeaders\" colspan=\"3\">&nbsp;</td>\n";
while($func=mysql_fetch_array($res_func))
{
list($fname, $rtype, $doc)=$func;
$doc=str_replace("\n", "<br>", $doc);
#$doc=str_replace(" ", "&nbsp;", $doc);
print "<tr>";
print "<td bgcolor=\"$cImpCells\"><b>$fname</b></td>\n";
$qry_par="select pname from flxUDFPARAMS where fname='$fname' order by ord";
$pars="";
$res_par=mysql_query( $qry_par );
while($par=mysql_fetch_array( $res_par ))
{
$par=$par["pname"];
$pars.=$par."<br>";
}
print "<td valign=\"top\" bgcolor=\"$cCells\">$pars&nbsp;</td>\n";
print "<td bgcolor=\"$cCells\"><font size=\"2\">$doc&nbsp;</font></td>\n";
print "<td align=\"center\" bgcolor=\"$cCells\"><a href=\"JavaScript:openwindowlink( 'UDF_showone.php?fname=$fname', 'UDFC$fname' )\"><font size=\"2\">[Code]</font></a></td>\n";
print "<td align=\"center\" bgcolor=\"$cCells\"><a href=\"JavaScript:openwindowlink( 'UDF_edit.php?fname=$fname', 'UDFM$fname' )\"><font size=\"2\">[Modify]</font></a></td>\n";
print "<td align=\"center\" bgcolor=\"$cCells\"><a href=\"UDF_del.php?fname=$fname\"><font size=\"2\">[Delete]</font></a></td>\n";
print "</tr>";
}
print "</table>\n";
mysql_close( $db );
?>
<br>
<form action="UDF_add.php" method="POST">
<table>
<tr>
<td bgcolor="#000000" colspan="2">
<font color="#FFFFFF">Add new function</font>
</td>
</tr>
<tr>
<td>Function Name</td>
<td><input type="text" name="fname"></td>
</tr>
<tr>
<td>Params</td>
<td><input type="text" name="params" size="40"></td>
</tr>
<tr>
<td>PHP Code</td>
<td><textarea name="code" cols="65" rows="20"></textarea><td>
</tr>
<tr>
<td>UDF documentation</td>
<td><textarea name="doc" cols="65" rows="10"></textarea><td>
</tr>
<tr>
<td colspan="2" align="center"><input class="formbutton" type="submit" value="Add"></td>
</tr>
</table>
</form>
<?
include(FOOTER);
?>
diff --git a/modules/bibformat/web/admin/UDF_edit.php.wml b/modules/bibformat/web/admin/UDF_edit.php.wml
index 73873c444..e88331031 100644
--- a/modules/bibformat/web/admin/UDF_edit.php.wml
+++ b/modules/bibformat/web/admin/UDF_edit.php.wml
@@ -1,197 +1,197 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: UDF_edit.php (flexElink WI)
// Description: Allows to modify UDF data and updates the changes in the DB.
// POST parameters:
// fname --> (required) Name (id) of the UDF to be modified
// process -> (optional) When is set, the script updates the UDF data
// in the DB with the parameter values
// params -> (optional) Contains the UDF param list. UDF parameters are
// separated by using ","
// fname_orig -> (required if process is set) Original name of the UDF
// to be updated (the UDF name can be changed)
// doc ----> (optional) Description of the purpose of the UDF
// code ---> (optional) UDF's PHP code
// Notes: If the format is succesfully updated in the DB it closes the current
// browser and refreshes the opener one
// Requires: DB, ERROR, EXECUTOR
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
if( (!isset($fname)) or (trim($fname)=="") )
{
print "<b>Function name</b> hasn't been specified";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
//-------DISPLAY
if(!isset($process))
{
$qry="select code, doc
from flxUDFS
where fname='$fname'";
$qh=mysql_query( $qry );
if(mysql_num_rows( $qh )<1)
{
print "<b>Function</b> not found";
print "<hr>";
print "<a align=\"center\" href=\"JavaScript:window.close();\">[Close]</a>";
exit;
}
$row=mysql_fetch_array($qh);
list($code, $doc)=$row;
$qry="select pname
from flxUDFPARAMS
where fname='$fname'
order by ord";
$qh=mysql_query($qry, $db);
$params="";
while($row=mysql_fetch_array($qh))
{
$params.=$row[0].",";
}
$params=substr($params, 0, strlen($params)-1);
?>
<form action="UDF_edit.php" method="POST">
<table width="100%" bgcolor="#808080">
<tr align="center">
<td colspan="2" bgcolor="#FFFFFFCC">
<font size="4">Editing udf <b>'<? echo $fname;?>'</b></font>
</td>
</tr>
<tr bgcolor="#FFFFFFFF">
<td width="50%"><b>Function Name</b> <input type="text" name="fname" value="<?echo $fname;?>"></td>
<td width="50%"><b>Params</b> <input type="text" name="params" size="60" value="<?echo $params;?>"></td>
</tr>
<tr bgcolor="#FFFFFFFF" align="center">
<td colspan="2">
<br><b>Documentation</b><br>
<textarea name="doc" cols="100" rows="5"><?echo $doc;?></textarea>
</td>
</tr>
<tr align="center" bgcolor="#FFFFFFFF">
<td colspan="2" >
<br><b>PHP Code</b><br>
<textarea name="code" cols="100" rows="15"><?echo $code;?></textarea><br><br>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input class="formbutton" type="submit" value="UPDATE" name="btnUpd">
<input class="formbutton" type="submit" value="UPDATE&CLOSE" name="btnUpdClose">
</td>
</tr>
</table>
<input type="hidden" name="process" value="oo">
<input type="hidden" name="fname_orig" value="<?echo $fname;?>">
</form>
<?
}
else
{
if(!isset($fname_orig) || (trim($fname_orig)==""))
{
print "Original function name incorrect or not found<hr>
<a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit;
}
if( (!isset($code)) )
$code="";
if( (!isset($doc)) )
$doc="";
if( (!isset($params)) )
$params="";
if(!get_magic_quotes_gpc())
{
$doc=addslashes($doc);
$code=addslashes($code);
}
$qry="update flxUDFS
set fname='$fname',
code='$code',
doc='$doc'
where fname='$fname_orig'";
if(!mysql_query( $qry ))
{
print "Impossible to update udf '$fname_orig':<br> ".mysql_error();
print "<hr><a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit();
}
$qry="delete from flxUDFPARAMS where fname='$fname_orig'";
if(!mysql_query( $qry ))
{
print "Function was updated but couldn't update udf params:<br> ".mysql_error();
print "<hr><a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit();
}
$params=explode(",", $params);
$count=0;
foreach($params as $param)
{
$param=trim($param);
if($param=="") continue;
$qry="insert into flxUDFPARAMS(fname, pname, ord)
values('$fname', '$param', $count)";
if(!mysql_query( $qry ))
{
print "Function parameter '$param' couldn't be inserted:<br> ".mysql_error();
print "<hr><a href=\"JavaScript:window.history.go(-1)\">[Go Back]</a>";
exit();
}
$count++;
}
mysql_close( $db );
?>
<script language="JavaScript">
opener.location.reload(false);
<?
if(isset($btnUpd))
print "window.location=\"UDF_edit.php?fname=$fname\";";
else
print "window.close();";
?>
</script>
<?
}
?>
diff --git a/modules/bibformat/web/admin/UDF_showone.php.wml b/modules/bibformat/web/admin/UDF_showone.php.wml
index de42caab3..9391dafd8 100644
--- a/modules/bibformat/web/admin/UDF_showone.php.wml
+++ b/modules/bibformat/web/admin/UDF_showone.php.wml
@@ -1,124 +1,124 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: UDF_showone.php (flexElink WI)
// Description: Shows the details for a given UDF (parameters, code and
// documentation) and allows to test the PHP for user-entered parameter
// values
// POST parameters:
// fname --> (required) Name (id) of the UDF to be shown
// Requires: DB, ERROR, FUNCTION_LIB
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(DB);
include(ERROR);
include(FUNCTION_LIB);
if( (!isset($fname)) or (trim($fname)=="") )
{
errorpage("<b>Function</b> hasn't been specified");
exit;
}
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD )
or errormsg("Couldn't connect to mySQL") or exit;
mysql_selectdb( $DB_DB );
$fname=trim(strtoupper($fname));
$qry="select rtype, code, doc from flxUDFS where fname='$fname'";
$res=mysql_query( $qry );
list($rtype, $code, $doc) =mysql_fetch_array( $res );
$code=text2HTML($code);
$doc=str_replace("\n","<br>",$doc);
$doc=str_replace(" ","&nbsp;",$doc);
$qry="select pname from flxUDFPARAMS where fname='$fname' order by ord";
$pars="";
$res=mysql_query( $qry );
$allpars=array();
while($par=mysql_fetch_array( $res ))
{
$par=$par["pname"];
$pars.=$par.", ";
array_push($allpars, $par);
}
$pars=substr( $pars, 0, strlen($pars)-2 );
?>
<html>
<head>
<title>PHP Code for <?print $fname;?></title>
</head>
<body>
<table width="100%" bgcolor="#808080">
<tr align="center">
<td colspan="2" bgcolor="#FFFFFFCC">
<font size="4">Details of UDF <b>'<? echo $fname;?>'</b></font>
</td>
</tr>
<tr>
<td width="15%" bgcolor="#FFFFFFF0"><b>Parameters</b></td>
<td bgcolor="#FFFFFFFF"><? print $pars; ?></td>
</tr>
<tr>
<td width="15%" valign="middle" bgcolor="#FFFFFFF0"><b>Documentation</b></td>
<td bgcolor="#FFFFFFFF"><font size="2"><?print $doc; ?></font></td>
</tr>
<tr>
<td width="15%" valign="middle" bgcolor="#FFFFFFF0"><b>PHP Code</b></td>
<td bgcolor="#FFFFFFFF"><?print $code;?></td>
</tr>
</table>
<br>
<form action="UDF_testcode.php" method="POST">
<input type="hidden" name="fname" value="<?print $fname?>">
<table width="70%" align="center">
<tr>
<td bgcolor="#000000" align="center" colspan="2">
<font color="white">Test this function</font>
</td>
</tr>
<?
foreach($allpars as $pname)
{
print "<tr><td><i>$pname</i> value</td>";
print "<td><input type=\"text\" name=\"$pname\"></td></tr>";
}
?>
<tr>
<td colspan="2" align="center">
<input class="formbutton" type="submit" value="Test">
</td>
</tr>
</table>
</form>
</body>
</html>
<?
mysql_close( $db );
?>
diff --git a/modules/bibformat/web/admin/UDF_testcode.php.wml b/modules/bibformat/web/admin/UDF_testcode.php.wml
index 7cfdaddb3..dee919996 100644
--- a/modules/bibformat/web/admin/UDF_testcode.php.wml
+++ b/modules/bibformat/web/admin/UDF_testcode.php.wml
@@ -1,74 +1,74 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
//==========================================================================
// File: UDF_testcode.php (flexElink WI)
// Description: Allows to test a UDF for a given set of parameter values.
// Parameter values have to be specified in the correct order and the
// parameter name is not relevant (only the order and the value). It
// shows a web page with the result of executing the UDF with those
// parameter values
// POST parameters:
// fname ---> (required) Name (id) of the UDF to be tested
// <param> -> (optional, multiple) Parameter value, they have to come in
// the same order as the UDF definition specifies
// Requires: ERROR, UDF_RETRIEVER
// Author: Hector.Sanchez@cern.ch
//==========================================================================
include("localconf.inc.php");
include(ERROR);
include(UDF_RETRIEVER);
if(!isset($fname) || (trim($fname)==""))
{
errorpage("Function not set!!");
}
global $HTTP_POST_VARS;
$pars=array();
foreach($HTTP_POST_VARS as $var=>$value)
{
if(get_magic_quotes_gpc())
$value=stripslashes($value);
if($var!="fname")
array_push($pars, $value);
}
print_r($pars);
$ret=new UDFRetriever();
list($ecode, $emsg)=$ret->execute( $fname, $pars, 0, 0);
$ret->destroy();
if($ecode)
{
print "Result:<br><h2>$emsg</h2>";
}
else
{
print "ERROR!! $emsg";
}
print "<hr>";
print "<a href=\"JavaScript:window.history.go(-1)\">[Go back]</a>";
?>
diff --git a/modules/bibformat/web/admin/error.inc.php.wml b/modules/bibformat/web/admin/error.inc.php.wml
index bc5372b7f..4458d10d9 100644
--- a/modules/bibformat/web/admin/error.inc.php.wml
+++ b/modules/bibformat/web/admin/error.inc.php.wml
@@ -1,38 +1,38 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
function errormsg( $msg )
{
print "<h1>Error:</h1><br>";
print "<i>$msg</i>";
print "</td></tr></table>";
exit;
}
function errorpage( $msg )
{
include("header.inc.php");
print "<h1>Error:</h1><br>";
print "<i>$msg</i>";
include("footer.inc.php");
}
?>
diff --git a/modules/bibformat/web/admin/footer.inc.php.wml b/modules/bibformat/web/admin/footer.inc.php.wml
index 3213fe627..6bd0f0e76 100644
--- a/modules/bibformat/web/admin/footer.inc.php.wml
+++ b/modules/bibformat/web/admin/footer.inc.php.wml
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
?>
diff --git a/modules/bibformat/web/admin/header.inc.php.wml b/modules/bibformat/web/admin/header.inc.php.wml
index 2aa6116d0..4091e6574 100644
--- a/modules/bibformat/web/admin/header.inc.php.wml
+++ b/modules/bibformat/web/admin/header.inc.php.wml
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
?>
diff --git a/modules/bibformat/web/admin/index.php.wml b/modules/bibformat/web/admin/index.php.wml
index 001bc1e80..a181b08d0 100644
--- a/modules/bibformat/web/admin/index.php.wml
+++ b/modules/bibformat/web/admin/index.php.wml
@@ -1,208 +1,208 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="BibFormat Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibformat"
<?
include("security.inc.php");
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
?>
<p>The BibFormat admin interface enables you to specify how the
bibliographic data is presented to the end user in the search
interface and search results pages. For example, you may specify that
titles should be printed in bold font, the abstract in small italic,
etc. Moreover, the BibFormat is not only a simple bibliographic data
<em>output formatter</em>, but also an automated <em>link
constructor</em>. For example, from the information on journal name
and pages, it may automatically create links to publisher's site based
on some configuration rules.
<h2>Configuring BibFormat</h2>
<p>By default, a simple HTML format based on the most common fields
(title, author, abstract, keywords, fulltext link, etc) is defined.
You certainly want to define your own ouput formats in case you have a
specific metadata structure.
<p>Here is a short guide of what you can configure:
<blockquote>
<dl>
<dt><a href="BEH_display.php">Behaviours</a>
<dd>Define one or more output BibFormat behaviours. These are then
passed as parameters to the BibFormat modules while executing
formatting.
<br><em>Example:</em> You can tell BibFormat that is has to enrich the
incoming metadata file by the created format, or that it only has to
print the format out.
<dt><a href="OAIER_display.php">Extraction Rules</a>
<dd>Define how the metadata tags from input are mapped into internal
BibFormat variable names. The variable names can afterwards be used
in formatting and linking rules.
<br><em>Example:</em> You can tell that <code>100 $a</code> field
should be mapped into <code>$100.a</code> internal variable that you
could use later.
<dt><a href="LINK_display.php">Link Rules</a>
<dd>Define rules for automated creation of URI links from mapped
internal variables.
<br><em>Example:</em> You can tell a rule how to create a link to
People database out of the <code>$100.a</code> internal variable
repesenting author's name. (The <code>$100.a</code> variable was mapped
in the previous step, see the Extraction Rules.)
<dt><a href="LINK_FORMAT_display.php">File Formats</a>
<dd>Define file format types based on file extensions. This will be
used when proposing various fulltext services.
<br><em>Example:</em> You can tell that <code>*.pdf</code> files will
be treated as PDF files.
<dt><a href="UDF_display.php">User Defined Functions (UDFs)</a>
<dd>Define your own functions that you can reuse when creating your
own output formats. This enables you to do complex formatting without
ever touching the BibFormat core code.
<br><em>Example:</em> You can define a function how to match and
extract email addresses out of a text file.
<dt><a href="FORMAT_display.php">Formats</a>
<dd>Define the output formats, i.e. how to create the output out of
internal BibFormat variables that were extracted in a previous step.
This is the functionality you would want to configure most of the
time. It may reuse formats, user defined functions, knowledge bases,
etc.
<br><em>Example:</em> You can tell that authors should be printed in
italic, that if there are more than 10 authors only the first three
should be printed, etc.
<dt><a href="KB_display.php">Knowledge Bases (KBs)</a>
<dd>Define one or more knowledge bases that enables you to transform
various forms of input data values into the unique standard form on
the output.
<br><em>Example:</em> You can tell that <em>Phys Rev D</em> and
<em>Physical Review D</em> are both the same journal and that these
names should be standardized to <em>Phys Rev : D</em>.
<dt><a href="test.php">Execution Test</a>
<dd>Enables you to test your formats on your sample data file. Useful
when debugging newly created formats.
</dl>
</blockquote>
<p>To learn more on BibFormat configuration, you can consult the <a
href="guide.html">BibFormat Admin Guide</a>.</small>
<h2>Running BibFormat</h2>
<h3>From the Web interface</h3>
<p>
Run <a href="BIBREFORMAT_display.php">Reformat Records</a> tool.
This tool permits you to update stored formats for bibliographic records.
<br>
It should normally be used after configuring BibFormat's
<a href="BEH_display.php">Behaviours</a> and
<a href="FORMAT_display.php">Formats</a>.
When these are ready, you can choose to rebuild formats for selected
collections or you can manually enter a search query and the web interface
will accomplish all necessary formatting steps.
<br>
<i>Example:</i> You can request Photo collections to have their HTML
brief formats rebuilt, or you can reformat all the records written by Ellis.
<h3>From the command-line interface</h3>
<p>Consider having an XML MARC data file that is to be uploaded into
the CDSware. (For example, it might have been harvested from other
sources and processed via <a href="../bibconvert/">BibConvert</a>.)
Having configured BibFormat and its default output type behaviour, you
would then run this file throught BibFormat as follows:
<blockquote>
<pre>
$ bibformat < /tmp/sample.xml > /tmp/sample_with_fmt.xml
<pre>
</blockquote>
that would create default HTML formats and would "enrich" the input
XML data file by this format. (You would then continue the upload
procedure by calling successively <a
href="../bibupload/">BibUpload</a> and <a
href="../bibwords/">BibWords</a>.)
<p>Now consider a different situation. You would like to add a new
possible format, say "HTML portfolio" and "HTML captions" in order to
nicely format multiple photographs in one page. Let us suppose that
these two formats are called <code>hp</code> and <code>hc</code> and
are already loaded in the <code>collection_format</code> table.
(TODO: describe how this is done via WebAdmin.) You would then
proceed as follows: firstly, you would prepare the corresponding <a
href="BEH_display.php">output behaviours</a> called <code>HP</code>
and <code>HC</code> (TODO: note the uppercase!) that would not enrich
the input file but that would produce an XML file with only
<code>001</code> and <code>FMT</code> tags. (This is in order not to
update the bibliographic information but the formats only.) You would
also prepare corresponding <a href="FORMAT_display.php">formats</a>
at the same time. Secondly, you would launch the formatting as
follows:
<blockquote>
<pre>
$ bibformat otype=HP,HC < /tmp/sample.xml > /tmp/sample_fmts_only.xml
<pre>
</blockquote>
that should give you an XML file containing only 001 and FMT tags.
Finally, you would upload the formats:
<blockquote>
<pre>
$ bibupload < /tmp/sample_fmts_only.xml
<pre>
</blockquote>
and that's it. The new formats should now appear in <a
href="<WEBURL>">WebSearch</a>.
diff --git a/modules/bibformat/web/admin/localconf.inc.php.wml b/modules/bibformat/web/admin/localconf.inc.php.wml
index 439d9efff..8959e325f 100644
--- a/modules/bibformat/web/admin/localconf.inc.php.wml
+++ b/modules/bibformat/web/admin/localconf.inc.php.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
include("<LIBDIR>/php/cdsware/bibformat/common/global.inc.php");
include("<LIBDIR>/php/cdsware/errors/errorHandling.php");
include("<WEBDIR>/sessinit.inc.php");
define(ERROR, WEBCONF_DIR."/error.inc.php");
define(HEADER, WEBCONF_DIR."/header.inc.php");
define(FOOTER, WEBCONF_DIR."/footer.inc.php");
?>
diff --git a/modules/bibformat/web/admin/security.inc.php.wml b/modules/bibformat/web/admin/security.inc.php.wml
index 737c23486..40779125d 100644
--- a/modules/bibformat/web/admin/security.inc.php.wml
+++ b/modules/bibformat/web/admin/security.inc.php.wml
@@ -1,40 +1,40 @@
<?
/*********************************************************************
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
1211 Geneva 23 - Switzerland
<cds.support@cern.ch>
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************/
/*********************Authentication*******************************/
##if ($uid_email == "guest")
##{
## outWarning('You seem to be guest. Please <a href="'.$WEBURL.'/youraccount.py/login?referer='.$WEBURL.$PHP_SELF.'">login</a> first.');
## print "</td></tr></table>";
## exit;
##}
$auth = acc_authorize_action($uid, "cfgbibformat");
if($auth[0] != 0)
{
outWarning($auth[1]);
print "</td></tr></table>";
exit;
}
?>
diff --git a/modules/bibformat/web/admin/test.php.wml b/modules/bibformat/web/admin/test.php.wml
index 328477288..a0c1fcf08 100644
--- a/modules/bibformat/web/admin/test.php.wml
+++ b/modules/bibformat/web/admin/test.php.wml
@@ -1,189 +1,189 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
include("localconf.inc.php");
?>
#include "cdspage.wml" \
title="Execution Test" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibformat/>BibFormat Admin</a>" \
navbar_name="admin" \
navbar_select="test"
<?
include("security.inc.php");
<protect>## $Id$</protect>
include(DB);
$db=mysql_connect( $DB_HOST, $DB_USER, $DB_PASSWD );
mysql_selectdb( $DB_DB );
//---DISPLAY
if(!isset($process))
{
include(HEADER);
$qry="select distinct(type) from flxXMLMARCEXTRULES";
$qh=mysql_query($qry, $db);
$itype_opts="";
while($row=mysql_fetch_array($qh))
{
$itype_opts.="<option value=\"".$row[0]."\">".$row[0]."</option>";
}
$qry="select name from flxBEHAVIORS";
$qh=mysql_query($qry, $db);
$otype_opts="";
while($row=mysql_fetch_array($qh))
{
$otype_opts.="<option value=\"".$row[0]."\">".$row[0]."</option>";
}
?>
<p>Enables you to test your formats on your sample data file. Useful
when debugging newly created formats.
<p align="center">
<table width="60%" border=1>
<tr>
<td>
<font size="2">From this page you'll be able to launch BibFormat over a file which contains bibliographic MARC21 XML
</font>
</td>
</tr>
</table>
</p>
<br>
<p align="center">
<form action="test.php" method="POST">
<table>
<tr>
<td bgcolor="#FFFFCC">
<b>XML File (URL)</b>
</td>
<td>
<input type="text" name="file" size="50">
</td>
</tr>
<tr>
<td bgcolor="#FFFFCC">
<b>Input Type</b>
</td>
<td align="left">
<select name="itype"><?echo $itype_opts;?></select>
</td>
</tr>
<tr>
<td bgcolor="#FFFFCC">
<b>Output Type</b>
</td>
<td align="left">
<select name="otype"><?echo $otype_opts;?></select>
</td>
</tr>
<tr>
<td colspan="2" align="left">
<input type="checkbox" name="debug" checked>
<font size="2">Print debug information</font>
</td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="hidden" name="process" value="oo">
<input class="formbutton" type="submit" value="LAUNCH!!">
</td>
</tr>
</table>
</form>
</p>
<?
include(FOOTER);
}
//---PROCESS
else
{
include_once(ERROR);
if( (!isset($file)) || (trim($file)=="") )
{
outWarning("The <b>XML file</b> hasn't been specified");
print "</td></tr></table>";
mysql_close($db);
exit;
}
if( (!isset($itype)) || (trim($itype)=="") )
{
outWarning("The <b>input type</b> hasn't been specified");
print "</td></tr></table>";
mysql_close($db);
exit;
}
if( (!isset($otype)) || (trim($otype)=="") )
{
outWarning("The <b>ouput type</b> hasn't been specified");
print "</td></tr></table>";
mysql_close($db);
exit;
}
$qry="select type from flxBEHAVIORS where name='$otype'";
$qh=mysql_query($qry, $db);
$modeshow="NORMAL";
list($modeshow)=mysql_fetch_array($qh);
include_once(MAIN);
include_once(CORE_DIR."Timing.inc.php");
$timing=new Timing();
$fxk=new FlexElink();
$error=$fxk->initialise("OAIMARC", $file);
if($error)
{
errorpage("Error initialising: $error");
exit;
}
$code=0;
while(1)
{
$timing->start("TOTAL");
list($code, $res)=$fxk->getRecordResult(array($otype), $debug);
$timing->end("TOTAL");
if($code<0) break;
if($code==0)
{
print "ERROR: $res<br>";
}
else
{
if(isset($debug)&&($modeshow=="NORMAL"))
print "<br>".text2HTML($res)."<br><hr><br>";
if($modeshow=="IENRICH")
print text2HTML($res)."<br>";
else
print $res."<br>";
}
$timing->debug();
print "<hr><hr>";
}
}
?>
diff --git a/modules/bibformat/web/bibformat.php.wml b/modules/bibformat/web/bibformat.php.wml
index cdd435dde..f805f95ab 100644
--- a/modules/bibformat/web/bibformat.php.wml
+++ b/modules/bibformat/web/bibformat.php.wml
@@ -1,100 +1,100 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
include("<LIBDIR>/php/cdsware/bibformat/common/global.inc.php");
include_once(MAIN);
include_once(CORE_DIR."/Timing.inc.php");
define(DEFAULT_ITYPE, "DEFAULT");
define(DEFAULT_OTYPE, "FULL");
$itype=DEFAULT_ITYPE;
if(!isset($id))
{
print "Not id specified!!";
exit;
}
$id=trim($id);
if(isset($otype) && trim($otype)!="")
{
$otype=strtoupper(trim($otype));
}
else
{
$otype=DEFAULT_OTYPE;
}
$t=new Timing();
$t->start("TOTAL");
$t->start("GetRecord method");
$file="<WEBURL>/search.py?id=$id&of=xm";
$fxk=new FlexElink();
$error=$fxk->initialise("OAIMARC", $file);
$t->end("GetRecord method");
if($error)
{
print "Error initialising: $error";
exit;
}
$t->start("FlexElink processing");
list($code, $res)=$fxk->getRecordResult(array($otype));
if($code>0)
$record=$res;
else
$err=$res;
print eval("?>$record<?");
$t->end("FlexElink processing");
if($err!="")
{
print "--------------------------------------------------------\n";
print "Errors processing record\n";
print "$err\n";
print "--------------------------------------------------------\n";
}
$t->end("TOTAL");
if(isset($timing))
{
print $t->debug();
}
?>
diff --git a/modules/bibharvest/Makefile.am b/modules/bibharvest/Makefile.am
index 02ad7f15c..cc3f271a0 100644
--- a/modules/bibharvest/Makefile.am
+++ b/modules/bibharvest/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
cachedir = $(localstatedir)/cache/RTdata
cache_DATA =
SUBDIRS = bin doc lib web
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/bibharvest/bin/Makefile.am b/modules/bibharvest/bin/Makefile.am
index 850d38e46..0c62fc089 100644
--- a/modules/bibharvest/bin/Makefile.am
+++ b/modules/bibharvest/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibharvest oaiharvest oaiarchive
EXTRA_DIST = bibharvest.in oaiharvest.in oaiarchive.in
CLEANFILES = *~ *.tmp bibharvestc oaiarchivec
diff --git a/modules/bibharvest/bin/bibharvest.in b/modules/bibharvest/bin/bibharvest.in
index 243ed026c..081f28114 100644
--- a/modules/bibharvest/bin/bibharvest.in
+++ b/modules/bibharvest/bin/bibharvest.in
@@ -1,272 +1,272 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware OAI harvestor."""
__version__ = "$Id$"
try:
import httplib
import urllib
import sys
import re
import string
import getopt
import time
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
try:
from cdsware.config import adminemail, version, cdsname
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
http_response_status_code = {
"000" : "Unknown",
"100" : "Continue",
"200" : "OK",
"302" : "Redirect",
"403" : "Forbidden",
"404" : "Not Found",
"500" : "Error",
"503" : "Service Unavailable"
}
def http_param_resume(http_param_dict,resumptionToken):
"Change parameter dictionary for harvest resumption"
http_param = {
'verb' : http_param_dict['verb'],
'resumptionToken' : resumptionToken
}
return http_param
def http_request_parameters(http_param_dict, method="POST"):
"Assembly http request parameters for http method used"
params = ""
if method == "GET":
for key in http_param_dict.keys():
if params:
params = "%s&" % (params)
if key:
params = "%s%s=%s" % (params, key, http_param_dict[key])
elif method == "POST":
http_param = {}
for key in http_param_dict.keys():
if http_param_dict[key]:
http_param[key] = http_param_dict[key]
params = urllib.urlencode(http_param)
return params
def OAI_Session(server, script, http_param_dict ,method="POST",output="", stylesheet=""):
"Handle OAi session"
sys.stderr.write("Starting the harvesting session at %s" % time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
sys.stderr.write("%s - %s\n" % (server, http_request_parameters(http_param_dict)))
a = OAI_Request(server, script, http_request_parameters(http_param_dict, method), method)
rt_obj = re.search('>.*</resumptionToken>',a)
i = 0
while rt_obj != None and rt_obj !="":
if output:
write_file( "%s.%07d" % (output,i), a)
else:
sys.stdout.write(a)
i = i + 1
time.sleep(1)
http_param_dict = http_param_resume(http_param_dict,rt_obj.group()[1:-18])
a = OAI_Request(server, script, http_request_parameters(http_param_dict, method), method)
rt_obj = re.search('>.*</resumptionToken>',a)
if output:
write_file("%s.%07d" % (output,i),a)
else:
sys.stdout.write(a)
def write_file(filename="harvest",a=""):
"Writes a to filename"
f = open(filename,"w")
f.write(a)
f.close()
def help():
"Print out info"
print "\n bibharvest -fhimoprsuv baseURL\n"
print " -h print this help"
print " -V print version number"
print " -o<outputfilename> specify output file"
print " -v<verb> OAI verb to be executed"
print " -m<method> http method (default POST)"
print " -p<metadataPrefix> metadata format"
print " -i<identifier> OAI identifier"
print " -s<set> OAI set"
print " -r<resuptionToken> Resume previous harvest"
print " -f<from> from date (datestamp)"
print " -u<until> until date (datestamp)\n"
def OAI_Request(server, script, params, method="POST"):
"Handle OAi request"
headers = {"Content-type":"application/x-www-form-urlencoded", "Accept":"text/xml", "From": adminemail, "User-Agent":"CDSware %s" % version}
i = 0
while i < 10:
i = i + 1
conn = httplib.HTTPConnection(server)
if method == "GET":
conn.putrequest(method,script + "?" + params)
conn.putheader("Content-type","application/x-www-form-urlencoded")
conn.putheader("Accept","text/xml")
conn.putheader("From", adminemail)
conn.putheader("User-Agent", cdsname)
conn.endheaders()
elif method == "POST":
conn.request("POST", script, params, headers)
response = conn.getresponse()
status = "%d" % response.status
if http_response_status_code.has_key(status):
sys.stderr.write("%s(%s) : %s : %s\n" % (status, http_response_status_code[status], response.reason, params))
else:
sys.stderr.write("%s(%s) : %s : %s\n" % (status, http_response_status_code['000'], response.reason, params))
if response.status == 200:
i = 10
data = response.read()
conn.close()
return data
elif response.status == 503:
sys.stderr.write("Retry in %d seconds...\n" % string.atoi(response.getheader("Retry-After","%d" % (i*i))))
time.sleep(string.atoi(response.getheader("Retry-After","%d" % (i*i))))
elif response.status == 302:
sys.stderr.write("Redirecting...\n")
server = response.getheader("Location").split("/")[2]
script = "/" + string.join(response.getheader("Location").split("/")[3:],"/")
else:
sys.stderr.write("Retry in 10 seconds...\n")
time.sleep(10)
sys.stderr.write("Harvesting interrupted (after 10 attempts) at %s: %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime())),params)
sys.exit(1)
def main():
"Main"
try:
opts, args = getopt.getopt(sys.argv[1:],"hVo:v:m:p:i:s:f:u:r:x:",
[
"help",
"version",
"output",
"verb",
"method",
"metadataPrefix",
"identifier",
"set",
"from",
"until",
"resumptionToken"
]
)
except getopt.error:
help()
sys.exit(1)
http_param_dict = {}
method = "POST"
output = ""
stylesheet = ""
# get options and arguments
for opt, opt_value in opts:
if opt == "-v":
http_param_dict['verb'] = opt_value
elif opt == "-m":
if opt_value == "GET" or opt_value == "POST":
method = opt_value
elif opt == "-p":
http_param_dict['metadataPrefix'] = opt_value
elif opt == "-i":
http_param_dict['identifier'] = opt_value
elif opt == "-s":
http_param_dict['set'] = opt_value
elif opt == "-f":
http_param_dict['from'] = opt_value
elif opt == "-u":
http_param_dict['until'] = opt_value
elif opt == "-r":
http_param_dict['resumptionToken'] = opt_value
elif opt == "-o":
output = opt_value
elif opt == "-x":
stylesheet = opt_value
elif opt in ["-V", "--version"]:
print __version__
sys.exit(0)
else:
help()
sys.exit()
if len(args) > 0:
server = args[0].split("/")[2]
script = "/" + string.join(args[0].split("/")[3:],"/")
OAI_Session(server, script, http_param_dict, method, output, stylesheet)
sys.stderr.write("Harvesting successfully completed at: %s\n\n" % time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
else:
help()
sys.exit()
if __name__ == '__main__':
main()
diff --git a/modules/bibharvest/bin/oaiharvest.in b/modules/bibharvest/bin/oaiharvest.in
index 82cfdc8f2..2bcd16c3e 100644
--- a/modules/bibharvest/bin/oaiharvest.in
+++ b/modules/bibharvest/bin/oaiharvest.in
@@ -1,53 +1,53 @@
#!/usr/bin/python2.3
## -*- mode: python; coding: utf-8; -*-
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibHarvest Admin Task.
It launches bibharvest periodically by reading table oaiHARVEST.
Usage: oaiharvest %s [options]
Examples:
oaiharvest -r arxiv -s 24h
oaiharvest -r pubmed -d 2005-05-05:2005-05-10 -t 10m
Specific options:
-r, --repository=NAME name of the OAI repository to be harvested (default=all)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat task (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h, 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
"""
try:
import sys
from cdsware.oaiharvestlib import main
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
main()
diff --git a/modules/bibharvest/doc/Makefile.am b/modules/bibharvest/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibharvest/doc/Makefile.am
+++ b/modules/bibharvest/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibharvest/doc/admin/Makefile.am b/modules/bibharvest/doc/admin/Makefile.am
index d75b59d70..9103c6710 100644
--- a/modules/bibharvest/doc/admin/Makefile.am
+++ b/modules/bibharvest/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/bibharvest
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibharvest/doc/admin/guide.html.wml b/modules/bibharvest/doc/admin/guide.html.wml
index acf6edce7..146246c2e 100644
--- a/modules/bibharvest/doc/admin/guide.html.wml
+++ b/modules/bibharvest/doc/admin/guide.html.wml
@@ -1,171 +1,171 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibHarvest Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibharvest/>BibHarvest Admin</a>" \
navbar_name="admin" \
navbar_select="bibharvest-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">Overview</a></strong><br>
<strong>2. <a href="#2">OAI Data Harvesting</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1 <a href="#2.1">One time harvesting</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 <a href="#2.2">Periodical harvesting</a><br>
<strong>3. <a href="#3">OAI Data Providing</a></strong><br>
<a name="1"></a><h2>1. Overview</h2>
The BibHarvest module handles metadata gathering and delivery between OAI-compliant repositories. Metadata exchange is performed on top of the OAI-PMH, the Open Archives Initiative's Protocol for Metadata Harvesting.
The BibHarvest Admin Interface can be used to set up a database of OAI sources and determine the periodicity of harvesting.
<br>
<a name="2"></a><h2>2. OAI Data Harvesting</h2>
<a name="2.1"></a><h3>2.1 One-time harvesting</h3>
<p>To harvest records from an OAI compliant repository, run the
<code>bibharvest</code> command-line tool. For example:
<blockquote>
<pre>
$ bibharvest -vListRecords -f2004-04-01 -u2004-04-02 -pmarcxml -o/tmp/z.xml \\
http://cdsweb.cern.ch/oai2d.py
</pre>
</blockquote>
<p>For further help with the command-line harvesting tool, run
<code>bibharvest --help</code>.
<a name="2.2"></a><h3>2.2 Periodical harvesting</h3>
<p>In order to periodically harvest metadata from one or several repositories, it is possible to organize OAI sources through the BibHarvest Admin Interface.
The interface allows the administrator to add new repositories as well as edit and delete existing ones.
Once the database has been set up thorugh the BibHarvest Admin Interface, run the oaiharvest command-line tool to run periodical harvesting</p>
<a name="2.2.1"></a><h4>2.2.1. Bibharvest Admin Interface</h3>
<b>Add OAI sources</b><br>
<p>The first step requires the administrator to enter the baseURL of the OAI repository. This is done for validation purposes - i.e. to check that the baseURL actually points to an OAI-compliant repository.
(Note: the validation simply performs an 'Identify' query to the baseURL and parses the reply with crucial tags such as <code>OAI-PMH</code> and <code>Identify</code>).
<br>Once the baseURL is validated, the administrator is required to fill into the following fields:
<br><ul>
<li><strong>Source name</strong>: this will be the (alphanumeric) name used to refer to this OAI repository.<br><br>
<li><strong>Metadata prefix</strong>: upon validation the baseURL is checked for the available metadata formats. The administator can choose the desired format to harvest metadata in.<br><br>
<li><strong>Frequency</strong>: how often do you intend to harvest from this repository? (Note: selecting "never" excludes this source from automatic periodical harvesting)<br><br>
<li><strong>Starting date</strong>: on your first harvesting session, do you intend to harvest the whole repository (from beginning) or only newly added material (from today)? (WARNING: harvesting large collections of material may take very long!)<br><br>
<li><strong>Postprocess</strong>: how is the harvested material be dealt with after harvesting?
<ul><li>h: harvest only - metadata will be gathered and saved locally<li>h-u: harvest and upload - metadata will be automatically queued for upload (this is useful when harvested metadata is already in marcxml format)<li>h-c: harvest and convert - harvested metadata will be converted and saved locally<li>h-c-u: harvest, convert and upload - harvested metadata will be converted and queued for upload - this is useful when harvested metadata is in a format different from marcxml (e.g. oai_dc)</ul><br>
<li><strong>BibConvert configuration file</strong>: if postprocess involves conversion, the full path to a BibConvert configuration file is needed.
This file determines how the metadata conversion will take place (e.g. oai_dc to marcxml).
In order to ensure that the configuration file performs the desired conversion, please test it in advance and follow the instruction contained in the <a href="../bibconvert/guide.html">BibConvert Admin Guide</a>.
Please note that some conversion parameters previously input at the command line can now be handled by the BibConvert Configuration Language (namely record separator, file header and file footer). Please consult the <a href="../bibconvert/guide.html">BibConvert Admin Guide</a> for more information on this.
This allows fully automatised harvesting and conversion (and possibly upload) of records provided a valid, functioning, BibConvert template is provided.
</ul>
<br>
<b>Edit and delete OAI sources</b><br>
<p>Once a source has been added to the database, it will be visible in the overview page, as shown below</p>
<div class="pagebody">
<table class="admin_wvar_nomargin" summary="">
<tr>
<th class="adminheader">name</th>
<th class="adminheader">baseURL</th>
<th class="adminheader">metadataprefix</th>
<th class="adminheader">frequency</th>
<th class="adminheader">bibconvertfile</th>
<th class="adminheader">postprocess</th>
<th class="adminheader">actions</th>
</tr>
<tr>
<td class="admintdright">cdsweb</td>
<td class="admintdleft">http://cdsweb.cern.ch/oai2d.py</td>
<td class="admintdleft">marcxml</td>
<td class="admintdleft">daily</td>
<td class="admintdleft">NULL</td>
<td class="admintdleft">h-u</td>
<td class="admintdleft">edit / delete</td>
<td rowspan="4" style="vertical-align: bottom">
</td>
</tr>
</table>
</div>
<p>At this point it will be possible to edit the definition of this source by clicking on the appropriate action button. All the fields described in 2.2.1 can be modified (except for the Starting date).
There is no more validation at this stage, hence, please take extra care when editing important fields such as baseurl and metadataprefix.
<br>
OAI repositories can be removed from the database by clicking on the appropriate action button in the overview page.
</p>
<a name="2.2.2"></a><h4>2.2.2 oaiharvest commmand-line tool</h3>
<p>Once administrators have set up their desired OAI repositories in the database through the Admin Interface they can invoke <code>oaiharvest</code> to start up periodical harvesting.<br>
<br>
<b>Oaiharvest usage</b>
<blockquote>
<pre>
oaiharvest [options]
Specific options:
-r, --repository=REPOS_ONE,"REPOS TWO" name of the OAI repositories to be harvested (default=all)
-d, --dates=yyyy-mm-dd:yyyy-mm-dd harvest repositories between specified dates (overrides repositories' last updated timestamps)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat tasks (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h , 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
</pre>
</blockquote>
<code>oaiharvest</code> performs a number of operations on the repositories listed in the database. By default <code>oaiharvest</code> considers all repositories, one by one (this gets overridden when <code>--repository</code> argument is passed).
<br> For each repository that is considered, <code>oaiharvest</code> behaves according to the arguments passed at the command line:
<ul>
<li> If the <code>--dates</code> argument is not passed, it checks whether an update from the repository is needed (Note: the update status is calculated based on the time of the last harvesting and the frequency chosen by the administrator).
<ul>
<li>If an update is needed, it launches <code>bibharvest</code> and harvests all the metadata that the repository has added since the data of the last update. When the update is finished, the last update value is set to the current time and date.
<li>If an update is not needed, the source is skipped.
</ul>
<li> If the <code>--dates</code> argument is passed, it simply harvests the metadata of the repository from/until the given dates. The last update date is left unchanged.
<li> Finally, it performs the operations indicated in the postprocess mode, i.e. convert and/or upload the harvested metadata.
</ul>
<br>
<b>Oaiharvest usage examples</b><br>
<p>In most cases, administrators will want <code>oaiharvest</code> to run in the background, i.e. run in sleep mode and wake up periodically (e.g. every 24 hours) to check whether updates are needed, e.g. <code>oaiharvest -s 24h</code><br>
<p>In other cases, administrators may want to perform periodical harvesting only on specific sources, e.g. <code>oaiharvest -r cdsweb -s 12h</code><br>
<p>Another option is that administrators may want to harvest from certain repositories within two specific dates. This will be regarded as a one-off operation and will not affect the last update value of the source, e.g. <code>oaiharvest -r cdsweb -d 2005-05-05:2005-05-30</code><br>
<br>
<a name="3"></a><h2>3. OAI Data Providing</h2>
FIXME. (See config.wml for OAI tags.)
diff --git a/modules/bibharvest/doc/admin/index.html.wml b/modules/bibharvest/doc/admin/index.html.wml
index 84510fd68..38b111f58 100644
--- a/modules/bibharvest/doc/admin/index.html.wml
+++ b/modules/bibharvest/doc/admin/index.html.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibHarvest Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibharvest"
<p>
This is the gate to the admin area for BibHarvest. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/bibharvest/">login</a> to enter.
</p>
<dl>
<dt><a href="bibharvestadmin.py">BibHarvest Admin Interface</a></dt>
<dd>Configure your OAI sources and harvesting periodicity.</dd>
</dl>
<dl>
<dt><a href="guide.html">BibHarvest Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running BibHarvest.</dd>
</dl>
diff --git a/modules/bibharvest/lib/Makefile.am b/modules/bibharvest/lib/Makefile.am
index 140c0029e..a0396b661 100644
--- a/modules/bibharvest/lib/Makefile.am
+++ b/modules/bibharvest/lib/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = oai_repository.py oai_repository_config.py oai_repository_tests.py \
bibharvestadminlib.py bibharvest_templates.py oaiharvestlib.py \
oaiarchive_engine.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibharvest/lib/bibharvest_templates.py b/modules/bibharvest/lib/bibharvest_templates.py
index 075425d96..467b58040 100644
--- a/modules/bibharvest/lib/bibharvest_templates.py
+++ b/modules/bibharvest/lib/bibharvest_templates.py
@@ -1,229 +1,229 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import urllib
import time
import cgi
import gettext
import traceback
import sre
import urllib
import sys
from cdsware.config import *
from cdsware.messages import gettext_set_language, language_list_long
class Template:
def tmpl_getnavtrail(self, ln, previous):
"""Get the navigation trail
- 'previous' *string* - The previous navtrail"""
_ = gettext_set_language(ln)
navtrail = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/bibharvest/">BibHarvest Admin</a> """ % (weburl, weburl)
navtrail = navtrail + previous
return navtrail
def tmpl_draw_titlebar(self, ln, weburl, title, guideurl, extraname="", extraurl=""):
"""Draws an html title bar
- 'title' *string* - The name of the titlebar
- 'weburl' *string* - The general weburl root for this admin section (e.g. admin/bibharvest/guide.html#mi )
- 'guideurl' *string* - The relative url of the guide relative to this section
- 'extraname' *string* - The name of an extra function
- 'extraurl' *string* - The relative url to an extra function
"""
_ = gettext_set_language(ln)
guidetitle = _("See Guide")
titlebar = """ <table class="admin_wvar_nomargin"><th class="adminheader">"""
titlebar += """%s&nbsp;&nbsp&nbsp;<small>[<a title="%s" href="%s/%s">?</a>]</small>""" % (title, guidetitle, weburl, guideurl)
if extraname and extraurl:
titlebar += """&nbsp;&nbsp&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp&nbsp;<small>[<a href="%s/%s">%s</a>]</small>""" % (weburl, extraurl, extraname)
titlebar += """</th></table>"""
return titlebar
def tmpl_draw_subtitle(self, ln, weburl, title, subtitle, guideurl):
"""Draws an html title bar
- 'title' *string* - The name of the titlebar
- 'subtitle' *string* - The header name of the subtitle
- 'weburl' *string* - The general weburl root for this admin section (e.g. admin/bibharvest/guide.html#mi )
- 'guideurl' *string* - The relative url of the guide relative to this section
"""
_ = gettext_set_language(ln)
guidetitle = _("See Guide")
titlebar = """<a name="%s">""" % title
titlebar += """ </a>%s&nbsp&nbsp&nbsp<small>""" % subtitle
titlebar += """ [<a title="%s" href="%s/%s">?</a>]</small>""" % (guidetitle, weburl, guideurl)
return titlebar
def tmpl_link_with_args(self, ln, weburl, funcurl, title, args):
"""Draws an html title bar
- 'weburl' *string* - The general weburl root for this admin section (e.g. admin/bibharvest/guide.html#mi )
- 'funcurl' *string* - The relative url to this section
- 'title' *string* - The name of the link
- 'args' *list* - The list of arguments to be appended to the url in the form [name, value]
"""
_ = gettext_set_language(ln)
initurl = '<a href="' + weburl + '/' + funcurl
endurl = '" title="' + title + '">' + title + '</a>'
noargs = len(args)
if noargs==0:
# there are no arguments, close link and return
return initurl + endurl
else:
# we have args. list them in the link, then close it and return it
argsurl = '?'
count = 1
for arg in args:
if count != noargs:
argsurl += arg[0] + '=' + arg[1] + '&amp;'
else:
argsurl += arg[0] + '=' + arg[1]
count = count + 1
return initurl+argsurl+endurl
def tmpl_output_numbersources(self, ln, numbersources):
"""Get the navigation trail
- 'number of sources' *int* - The number of sources in the database"""
_ = gettext_set_language(ln)
present = _("OAI sources currently present in the database")
notpresent = _("No OAI sources currently present in the database")
if (numbersources>0):
output = """&nbsp;&nbsp&nbsp;&nbsp;<strong><span class="info">%s %s</span></strong><br><br>""" % (numbersources, present)
return output
else:
output = """&nbsp;&nbsp&nbsp;&nbsp;<strong><span class="warning">%s</span></strong><br><br>""" % notpresent
return output
def tmpl_output_schedule(self, ln, schtime, schstatus):
_ = gettext_set_language(ln)
msg_next = _("Next oaiharvest task")
msg_sched = _("scheduled time:")
msg_cur = _("current status:")
msg_notask = _("No oaiharvest task currently scheduled")
if schtime and schstatus:
output = """&nbsp;&nbsp&nbsp;&nbsp;<strong>%s<br>
&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp&nbsp;&nbsp; - %s %s <br>
&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp&nbsp;&nbsp; - %s %s </strong><br><br>""" % (msg_next, msg_sched, schtime, msg_cur, schstatus)
return output
else:
output = """&nbsp;&nbsp&nbsp;&nbsp;<strong><span class="warning">%s</span></strong><br><br>""" % msg_notask
return output
def tmpl_admin_w200_text(self, ln, title, name, value):
"""Draws an html w200 text box
- 'title' *string* - The name of the textbox
- 'name' *string* - The name of the value in the textbox
- 'value' *string* - The value in the textbox"""
_ = gettext_set_language(ln)
text = """<span class="adminlabel">%s""" % title
text += """</span><input class="admin_w200" type="text" name="%s" value="%s" /><br>""" % (cgi.escape(name,1), cgi.escape(value, 1))
return text
def tmpl_admin_w200_select(self, ln, title, name, valuenil, values, lastval=""):
"""Draws an html w200 drop-down box
- 'title' *string* - The name of the dd box
- 'name' *string* - The name of the value in the dd box
- 'value' *list* - The values in the textbox"""
_ = gettext_set_language(ln)
text = """<span class="adminlabel">%s""" % title
text += """</span><select name="%s" class="admin_w200">""" % name
text += """<option value="">%s</option>""" % valuenil
try:
for val in values:
intval = int(lastval)
if intval==int(val[0]): ## retrieve and display last value inputted into drop-down box
text += """<option value="%s" %s>%s</option>""" % (val[0], 'selected="selected"', str(val[1]))
else:
text += """<option value="%s">%s</option>""" % (val[0], str(val[1]))
text += """</select><br>"""
except StandardError, e:
for val in values:
if lastval==val[0]:
text += """<option value="%s" %s>%s</option>""" % (val[0], 'selected="selected"', str(val[1]))
else:
text += """<option value="%s">%s</option>""" % (val[0], str(val[1]))
text += """</select><br>"""
return text
### deprecated ###
# def tmpl_print_src_add_tips(self):
# """Outputs some tips for source adding and editing"""
# text = """<br>
# <small><strong>Frequency</strong>: how often do you intend to harvest from this repository?</small><br><br>
# <small><strong>Starting date</strong>: do you intend to harvest the whole repository (from beginning) or only newly added material (from today)? <strong>WARNING</strong>: harvesting large collections of material may take very long!</small><br><br>
# <small><strong>Postprocess</strong>: how is the harvested material be dealt with after harvesting?
# <ul><li>h: harvest only<li>h-c: harvest and convert<li>h-c-u: harvest, convert and upload</ul></small>
# <small><strong>BibConvert configuration file</strong>: if postprocess involves conversion, please include full path to a configuration file</small>
# """
# return text
### deprecated ###
# def tmpl_print_src_edit_tips(self):
# """Outputs some tips for source adding and editing"""
# text = """<br>
# <small><strong>Frequency</strong>: how often do you intend to harvest from this repository?</small><br><br>
# <small><strong>Postprocess</strong>: how is the harvested material be dealt with after harvesting?
# <ul><li>h: harvest only<li>h-c: harvest and convert<li>h-c-u: harvest, convert and upload</ul></small>
# <small><strong>BibConvert configuration file</strong>: if postprocess involves conversion, please include full path to a configuration file</small>
# """
# return text
### deprecated ###
# def tmpl_print_validate_tips(self):
# """Outputs some tips for source validation"""
# text = """<br><small><strong>Validate</strong>: to check that the baseURL of the repository is OAI-compliant</small>"""
# return text
def tmpl_print_info(self, ln, infotext):
"""Outputs some info"""
_ = gettext_set_language(ln)
text = """<br><b><span class="info">%s</span></b>""" % infotext
return text
def tmpl_print_warning(self, ln, warntext):
"""Outputs some info"""
_ = gettext_set_language(ln)
text = """<span class="warning">%s</span>""" % warntext
return text
def tmpl_print_brs(self, ln, howmany):
"""Outputs some <br>s"""
_ = gettext_set_language(ln)
text = ""
while howmany>>0:
text += """<br>"""
howmany = howmany - 1
return text
def tmpl_output_validate_info(self, ln, outcome, base):
"""Prints a message to say whether source was validated or not
- 'outcome' *int* - 0=success, 1=fail
- 'base' *string* - baseurl"""
_ = gettext_set_language(ln)
msg_success = _("successfully validated!")
msg_nosuccess = _("does not seem to be a OAI-compliant baseURL...")
if (outcome==0):
output = """<BR><span class="info">baseURL <strong>%s</strong> %s</span>""" % (base, msg_success)
return output
else:
output = """<BR><span class="info">baseURL <strong>%s</strong> %s</span>""" % (base, msg_nosuccess)
return output
diff --git a/modules/bibharvest/lib/bibharvestadminlib.py b/modules/bibharvest/lib/bibharvestadminlib.py
index 4c5217743..8c550ce95 100644
--- a/modules/bibharvest/lib/bibharvestadminlib.py
+++ b/modules/bibharvest/lib/bibharvestadminlib.py
@@ -1,440 +1,440 @@
## $Id$
## Administrator interface for BibIndex
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Bibharvest Administrator Interface."""
import cgi
import re
import MySQLdb
import Numeric
import os, sys, string
import ConfigParser
import time
import random
import urllib
import sre
from mod_python import apache
from cdsware.bibrankadminlib import write_outcome,modify_translations,get_def_name,get_i8n_name,get_name,get_rnk_nametypes,get_languages,check_user,is_adminuser,adderrorbox,addadminbox,tupletotable,tupletotable_onlyselected,addcheckboxes,createhiddenform,serialize_via_numeric_array_dumps,serialize_via_numeric_array_compr,serialize_via_numeric_array_escape,serialize_via_numeric_array,deserialize_via_numeric_array,serialize_via_marshal,deserialize_via_marshal
from cdsware.dbquery import run_sql
from cdsware.config import *
from cdsware.webpage import page, pageheaderonly, pagefooteronly
from cdsware.webuser import getUid, get_email
import cdsware.template
bibharvest_templates = cdsware.template.load('bibharvest')
tmppath = tmpdir + '/bibharvestadmin.' + str(os.getpid())
guideurl = "admin/bibharvest/guide.html"
freqs = [[0, "never"], [24, "daily"], [168, "weekly"], [720, "monthly"] ]
posts = [["h", "harvest only (h)"], ["h-c", "harvest and convert (h-c)"], ["h-u", "harvest and upload (h-u)"], ["h-c-u", "harvest, convert and upload (h-c-u)"]]
dates = [[0, "from beginning"], [1, "from today"]]
__version__ = "$Id$"
def getnavtrail(previous = ''):
"""Get the navtrail"""
return bibharvest_templates.tmpl_getnavtrail(previous = previous, ln = cdslang)
def perform_request_index(ln=cdslang):
"""start area for administering harvesting from OAI repositories"""
titlebar = bibharvest_templates.tmpl_draw_titlebar(ln = cdslang, weburl = weburl, title = "Overview of sources", guideurl = guideurl, extraname = "add new OAI source" , extraurl = "admin/bibharvest/bibharvestadmin.py/addsource" )
titlebar2 = bibharvest_templates.tmpl_draw_titlebar(ln = cdslang, weburl = weburl, title = "Harvesting status", guideurl = guideurl)
header = ['name', 'baseURL', 'metadataprefix', 'frequency', 'bibconvertfile', 'postprocess', 'actions']
header2 = ['name', 'last update']
oai_src = get_oai_src()
upd_status = get_update_status()
sources = []
for (oai_src_id,oai_src_name,oai_src_baseurl,oai_src_prefix,oai_src_frequency,oai_src_config,oai_src_post) in oai_src:
namelinked_args = []
namelinked_args.append(["oai_src_id", str(oai_src_id)])
namelinked_args.append(["ln", ln])
namelinked = bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/editsource", title = oai_src_name, args = namelinked_args)
freq = "Not Set"
if oai_src_frequency==0: freq = "never"
elif oai_src_frequency==24: freq = "daily"
elif oai_src_frequency==168: freq = "weekly"
elif oai_src_frequency==720: freq = "monthly"
editACTION = bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/editsource", title = "edit", args = namelinked_args)
delACTION = bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/delsource", title = "delete", args = namelinked_args)
action = editACTION + " / " + delACTION
sources.append([namelinked,oai_src_baseurl,oai_src_prefix,freq,oai_src_config,oai_src_post, action])
updates = []
for (upd_name, upd_status) in upd_status:
if not upd_status:
upd_status = bibharvest_templates.tmpl_print_warning(cdslang, "Never harvested")
else: #cut away leading zeros
upd_status = sre.sub(r'\.[0-9]+$', '', str(upd_status))
updates.append([upd_name, upd_status])
(schtime, schstatus) = get_next_schedule()
if schtime:
schtime = sre.sub(r'\.[0-9]+$', '', str(schtime))
output = titlebar
output += bibharvest_templates.tmpl_output_numbersources(cdslang, get_tot_oai_src())
output += tupletotable(header=header, tuple=sources)
output += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += titlebar2
output += bibharvest_templates.tmpl_output_schedule(cdslang, schtime, str(schstatus))
output += tupletotable(header=header2, tuple=updates)
return output
def perform_request_editsource(oai_src_id, oai_src_name='', oai_src_baseurl='', oai_src_prefix='', oai_src_frequency='', oai_src_config='', oai_src_post='',ln=cdslang, confirm=-1):
"""creates html form to edit a OAI source. this method is calling other methods which again is calling this and sending back the output of the method.
confirm - determines the validation status of the data input into the form"""
output = ""
subtitle = bibharvest_templates.tmpl_draw_subtitle(ln = cdslang, weburl = weburl, title = "edit source", subtitle = "Edit OAI source", guideurl = guideurl)
if confirm in [-1, "-1"]:
oai_src = get_oai_src(oai_src_id)
oai_src_name = oai_src[0][1]
oai_src_baseurl = oai_src[0][2]
oai_src_prefix = oai_src[0][3]
oai_src_frequency = oai_src[0][4]
oai_src_config = oai_src[0][5]
oai_src_post = oai_src[0][6]
text = bibharvest_templates.tmpl_print_brs(cdslang, 1)
text += bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Source name", name = "oai_src_name", value = oai_src_name)
text += bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Base URL", name = "oai_src_baseurl", value = oai_src_baseurl)
text += bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Metadata prefix", name = "oai_src_prefix", value = oai_src_prefix)
text += bibharvest_templates.tmpl_admin_w200_select(ln = cdslang, title = "Frequency", name = "oai_src_frequency", valuenil = "- select frequency -" , values = freqs, lastval = oai_src_frequency)
text += bibharvest_templates.tmpl_admin_w200_select(ln = cdslang, title = "Postprocess", name = "oai_src_post", valuenil = "- select mode -" , values = posts, lastval = oai_src_post)
text += bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Bibconvert configuration file", name = "oai_src_config", value = oai_src_config)
text += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += createhiddenform(action="editsource#1",
text=text,
button="Modify",
oai_src_id=oai_src_id,
ln=ln,
confirm=1)
if confirm in [1, "1"] and not oai_src_name:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a name for the source.")
elif confirm in [1, "1"] and not oai_src_prefix:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a metadata prefix.")
elif confirm in [1, "1"] and not oai_src_baseurl:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a base url.")
elif confirm in [1, "1"] and not oai_src_frequency:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please choose a frequency of harvesting")
elif confirm in [1, "1"] and not oai_src_post:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please choose a postprocess mode")
elif confirm in [1, "1"] and (oai_src_post=="h-c" or oai_src_post=="h-c-u") and (not oai_src_config or validatefile(oai_src_config)!=0):
output += bibharvest_templates.tmpl_print_info(cdslang, "You selected a postprocess mode which involves conversion.")
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a valid full path to a bibConvert config file or change postprocess mode.")
elif oai_src_id > -1 and confirm in [1, "1"]:
if not oai_src_frequency:
oai_src_frequency = 0
if not oai_src_config:
oai_src_config = "NULL"
if not oai_src_post:
oai_src_post = "h"
res = modify_oai_src(oai_src_id, oai_src_name, oai_src_baseurl, oai_src_prefix, oai_src_frequency, oai_src_config, oai_src_post)
output += write_outcome(res)
lnargs = [["ln", ln]]
output += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/index", title = "Go back to the OAI sources overview", args = lnargs )
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle, body)
def perform_request_addsource(oai_src_name, oai_src_baseurl='', oai_src_prefix='', oai_src_frequency='', oai_src_lastrun='', oai_src_config='', oai_src_post='', ln=cdslang, confirm=-1):
"""creates html form to add a new source"""
subtitle = bibharvest_templates.tmpl_draw_subtitle(ln = cdslang, weburl = weburl, title = "add source", subtitle = "Add new OAI source", guideurl = guideurl)
output = ""
if confirm <= -1:
text = bibharvest_templates.tmpl_print_brs(cdslang, 1)
text += bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Enter the base url", name = "oai_src_baseurl", value = oai_src_baseurl)
output = createhiddenform(action="addsource",
text=text,
ln=ln,
button="Validate",
confirm=0)
if confirm not in ["-1", -1] and validate(oai_src_baseurl)==1:
lnargs = [["ln", ln]]
output += bibharvest_templates.tmpl_output_validate_info(cdslang, 1, str(oai_src_baseurl))
output += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/addsource", title = "Try again", args = [])
output += bibharvest_templates.tmpl_print_brs(cdslang, 1)
output += """or"""
output += bibharvest_templates.tmpl_print_brs(cdslang, 1)
output += bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/index", title = "Go back to the OAI sources overview", args = lnargs)
if confirm not in ["-1", -1] and validate(oai_src_baseurl)==0:
output += bibharvest_templates.tmpl_output_validate_info(cdslang, 0, str(oai_src_baseurl))
output += bibharvest_templates.tmpl_print_brs(cdslang, 2)
text = bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Source name", name = "oai_src_name", value = oai_src_name)
metadatas = findMetadataFormats(oai_src_baseurl)
prefixes = []
for value in metadatas:
prefixes.append([value, str(value)])
text += bibharvest_templates.tmpl_admin_w200_select(ln = cdslang, title = "Metadata prefix", name = "oai_src_prefix", valuenil = "- select prefix -" , values = prefixes, lastval = oai_src_prefix)
text += bibharvest_templates.tmpl_admin_w200_select(ln = cdslang, title = "Frequency", name = "oai_src_frequency", valuenil = "- select frequency -" , values = freqs, lastval = oai_src_frequency)
text += bibharvest_templates.tmpl_admin_w200_select(ln = cdslang, title = "Starting date", name = "oai_src_lastrun", valuenil = "- select a date -" , values = dates, lastval = oai_src_lastrun)
text += bibharvest_templates.tmpl_admin_w200_select(ln = cdslang, title = "Postprocess", name = "oai_src_post", valuenil = "- select mode -" , values = posts, lastval = oai_src_post)
text += bibharvest_templates.tmpl_admin_w200_text(ln = cdslang, title = "Bibconvert configuration file", name = "oai_src_config", value = oai_src_config)
text += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += createhiddenform(action="addsource#1",
text=text,
button="Add OAI Source",
oai_src_baseurl=oai_src_baseurl,
ln=ln,
confirm=1)
if confirm in [1, "1"] and not oai_src_name:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a name for the source.")
elif confirm in [1, "1"] and not oai_src_prefix:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a metadata prefix.")
elif confirm in [1, "1"] and not oai_src_frequency:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please choose a frequency of harvesting")
elif confirm in [1, "1"] and not oai_src_lastrun:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please choose the harvesting starting date")
elif confirm in [1, "1"] and not oai_src_post:
output += bibharvest_templates.tmpl_print_info(cdslang, "Please choose a postprocess mode")
elif confirm in [1, "1"] and (oai_src_post=="h-c" or oai_src_post=="h-c-u") and (not oai_src_config or validatefile(oai_src_config)!=0):
output += bibharvest_templates.tmpl_print_info(cdslang, "You selected a postprocess mode which involves conversion.")
output += bibharvest_templates.tmpl_print_info(cdslang, "Please enter a valid full path to a bibConvert config file or change postprocess mode.")
elif oai_src_name and confirm in [1, "1"]:
if not oai_src_frequency:
oai_src_frequency = 0
if not oai_src_lastrun:
oai_src_lastrun = 1
if not oai_src_config:
oai_src_config = "NULL"
if not oai_src_post:
oai_src_post = "h"
res = add_oai_src(oai_src_name, oai_src_baseurl, oai_src_prefix, oai_src_frequency, oai_src_lastrun, oai_src_config, oai_src_post)
output += write_outcome(res)
lnargs = [["ln", ln]]
output += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/index", title = "Go back to the OAI sources overview", args = lnargs )
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle, body)
def perform_request_delsource(oai_src_id, ln=cdslang, callback='yes', confirm=0):
"""creates html form to delete a source
"""
if oai_src_id:
oai_src = get_oai_src(oai_src_id)
namesrc = (oai_src[0][1])
pagetitle = """Delete OAI source: %s""" % namesrc
subtitle = bibharvest_templates.tmpl_draw_subtitle(ln = cdslang, weburl = weburl, title = "delete source", subtitle = pagetitle, guideurl = guideurl)
output = ""
if confirm in ["0", 0]:
if oai_src:
question = """Do you want to delete the OAI source '%s' and all its definitions?""" % namesrc
text = bibharvest_templates.tmpl_print_info(cdslang, question)
text += bibharvest_templates.tmpl_print_brs(cdslang, 3)
output += createhiddenform(action="delsource#5",
text=text,
button="Confirm",
oai_src_id=oai_src_id,
confirm=1)
else:
return bibharvest_templates.tmpl_print_info(cdslang, "Source specified does not exist.")
elif confirm in ["1", 1]:
res = delete_oai_src(oai_src_id)
if res[0] == 1:
output += bibharvest_templates.tmpl_print_info(cdslang, "Source removed.")
output += bibharvest_templates.tmpl_print_brs(cdslang, 1)
output += write_outcome(res)
else:
output += write_outcome(res)
lnargs = [["ln", ln]]
output += bibharvest_templates.tmpl_print_brs(cdslang, 2)
output += bibharvest_templates.tmpl_link_with_args(ln = cdslang, weburl = weburl, funcurl = "admin/bibharvest/bibharvestadmin.py/index", title = "Go back to the OAI sources overview", args = lnargs )
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle, body)
##################################################################
### Here the functions to retrieve, modify, delete and add sources
##################################################################
def get_oai_src(oai_src_id=''):
"""Returns a row parameters for a given id"""
sql = "SELECT id,name,baseurl,metadataprefix,frequency,bibconvertcfgfile,postprocess FROM oaiHARVEST"
try:
if oai_src_id:
sql += " WHERE id=%s" % oai_src_id
sql += " ORDER BY id asc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def modify_oai_src(oai_src_id, oai_src_name, oai_src_baseurl, oai_src_prefix, oai_src_frequency, oai_src_config, oai_src_post):
"""Modifies a row's parameters"""
try:
sql = "UPDATE oaiHARVEST SET name='%s' WHERE id=%s" % (MySQLdb.escape_string(oai_src_name), oai_src_id)
res = run_sql(sql)
sql = "UPDATE oaiHARVEST SET baseurl='%s' WHERE id=%s" % (MySQLdb.escape_string(oai_src_baseurl), oai_src_id)
res = run_sql(sql)
sql = "UPDATE oaiHARVEST SET metadataprefix='%s' WHERE id=%s" % (MySQLdb.escape_string(oai_src_prefix), oai_src_id)
res = run_sql(sql)
sql = "UPDATE oaiHARVEST SET frequency='%s' WHERE id=%s" % (MySQLdb.escape_string(oai_src_frequency), oai_src_id)
res = run_sql(sql)
sql = "UPDATE oaiHARVEST SET bibconvertcfgfile='%s' WHERE id=%s" % (MySQLdb.escape_string(oai_src_config), oai_src_id)
res = run_sql(sql)
sql = "UPDATE oaiHARVEST SET postprocess='%s' WHERE id=%s" % (MySQLdb.escape_string(oai_src_post), oai_src_id)
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def add_oai_src(oai_src_name, oai_src_baseurl, oai_src_prefix, oai_src_frequency, oai_src_lastrun, oai_src_config, oai_src_post):
"""Adds a new row to the database with the given parameters"""
try:
if oai_src_lastrun in [0, "0"]: lastrun_mode = 'NULL'
else:
lastrun_mode = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# lastrun_mode = "'"+lastrun_mode+"'"
sql = "insert into oaiHARVEST values (0, '%s', '%s', NULL, NULL, '%s', '%s', '%s', '%s', '%s')" % (MySQLdb.escape_string(oai_src_baseurl), MySQLdb.escape_string(oai_src_prefix), MySQLdb.escape_string(oai_src_config), MySQLdb.escape_string(oai_src_name), MySQLdb.escape_string(lastrun_mode), MySQLdb.escape_string(oai_src_frequency), MySQLdb.escape_string(oai_src_post))
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def delete_oai_src(oai_src_id):
"""Deletes a row from the database according to its id"""
try:
res = run_sql("DELETE FROM oaiHARVEST WHERE id=%s" % oai_src_id)
return (1, "")
except StandardError, e:
return (0, e)
def get_tot_oai_src():
"""Returns number of rows in the database"""
try:
sql = "select count(*) FROM oaiHARVEST"
res = run_sql(sql)
return res[0][0]
except StandardError, e:
return ""
def get_update_status():
"""Returns a table showing a list of all rows and their LastUpdate status"""
try:
sql = "select name,lastrun from oaiHARVEST order by lastrun desc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_next_schedule():
"""Returns the next scheduled oaiharvestrun tasks"""
try:
sql = "select runtime,status from schTASK where proc='oaiharvest' and runtime > now() ORDER by runtime limit 1"
res = run_sql(sql)
if len(res)>>0:
return res[0]
else:
return ("", "")
except StandardError, e:
return ("","")
def validate(oai_src_baseurl):
"""This function validates a baseURL by opening its URL and 'greping' for the <OAI-PMH> and <Identify> tags:
0 = okay
1 = baseURL non existing
"""
try:
url = oai_src_baseurl + "?verb=Identify"
urllib.urlretrieve(url, tmppath)
grepOUT1 = os.popen('grep -iwc "<identify>" '+tmppath).read()
grepOUT2 = os.popen('grep -iwc "<OAI-PMH" '+tmppath).read()
if int(grepOUT1) >> 0 and int(grepOUT2) >> 0:
#print "Valid!"
return 0
else:
#print "Not valid!"
return 1
except StandardError, e:
return 1
def validatefile(oai_src_config):
"""This function checks whether teh given path to text file exists or not
0 = okay
1 = file non existing
"""
try:
ftmp = open(oai_src_config, 'r')
cfgstr= ftmp.read()
ftmp.close()
if cfgstr!="":
#print "Valid!"
return 0
else:
#print "Not valid!"
return 1
except StandardError, e:
return 1
def findMetadataFormats(oai_src_baseurl):
"""This function finds the Metadata formats offered by a OAI repository by analysing the output of verb=ListMetadataFormats"""
url = oai_src_baseurl + "?verb=ListMetadataFormats"
urllib.urlretrieve(url, tmppath)
formats = []
ftmp = open(tmppath, 'r')
xmlstr= ftmp.read()
ftmp.close()
chunks = xmlstr.split('<metadataPrefix>')
count = 0 # first chunk is invalid
for chunk in chunks:
if count!=0:
formats.append(chunk.split('</metadataPrefix>')[0])
count = count + 1
return formats
diff --git a/modules/bibharvest/lib/oai_repository.py b/modules/bibharvest/lib/oai_repository.py
index fecdc84cb..f2addec13 100644
--- a/modules/bibharvest/lib/oai_repository.py
+++ b/modules/bibharvest/lib/oai_repository.py
@@ -1,894 +1,894 @@
## $Id$
## OAI interface for CDSware/MySQL written in Python compliant with OAI-PMH2.0
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""OAI interface for CDSware/MySQL written in Python compliant with OAI-PMH2.0"""
import cPickle
import string
from string import split
import os
import re
import urllib
import sys
import time
import md5
from cdsware.oai_repository_config import *
from cdsware.config import *
from cdsware.dbquery import run_sql
verbs = {
"Identify" : [""],
"ListSets" : ["resumptionToken"],
"ListMetadataFormats" : ["resumptionToken"],
"ListRecords" : ["resumptionToken"],
"ListIdentifiers" : ["resumptionToken"],
"GetRecord" : [""]
}
params = {
"verb" : ["Identify","ListIdentifiers","ListSets","ListMetadataFormats","ListRecords","GetRecord"],
"metadataPrefix" : ["","oai_dc","marcxml"],
"from" :[""],
"until":[""],
"set" :[""],
"identifier": [""]
}
def encode_for_xml(strxml):
"Encode special chars in string for XML-compliancy."
if strxml == None:
return strxml
else:
strxml = string.replace(strxml, '&', '&amp;')
strxml = string.replace(strxml, '<', '&lt;')
return strxml
def escape_space(strxml):
"Encode special chars in string for URL-compliancy."
strxml = string.replace(strxml, ' ', '%20')
return strxml
def encode_for_url(strxml):
"Encode special chars in string for URL-compliancy."
strxml = string.replace(strxml, '%', '%25')
strxml = string.replace(strxml, ' ', '%20')
strxml = string.replace(strxml, '?', '%3F')
strxml = string.replace(strxml, '#', '%23')
strxml = string.replace(strxml, '=', '%3D')
strxml = string.replace(strxml, '&', '%26')
strxml = string.replace(strxml, '/', '%2F')
strxml = string.replace(strxml, ':', '%3A')
strxml = string.replace(strxml, ';', '%3B')
strxml = string.replace(strxml, '+', '%2B')
return strxml
def oai_header(args, verb):
"Print OAI header"
out = ""
out = out + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n"
out = out + "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n"
out = out + " <responseDate>" + oaigetresponsedate() + "</responseDate>\n"
if verb:
out = out + " <request verb=\"%s\">%s</request>\n" % (verb, oaigetrequesturl(args))
out = out + " <%s>\n" % verb
else:
out = out + " <request>%s</request>\n" % (oaigetrequesturl(args))
return out
def oai_footer(verb):
"Print OAI footer"
out = ""
if verb:
out = "%s </%s>\n" % (out, verb)
out = out + "</OAI-PMH>\n"
return out
def oai_error_header(args, verb):
"Print OAI header"
out = ""
### out = "Content-Type: text/xml\n\n"
out = out + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n"
out = out + "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n"
out = out + " <responseDate>" + oaigetresponsedate() + "</responseDate>\n"
out = out + " <request verb=\"%s\">%s</request>\n" % (verb, oaigetrequesturl(args))
return out
def oai_error_footer(verb):
"Print OAI footer"
out = verb
out = "</OAI-PMH>\n"
return out
def get_field(sysno, field):
"Gets list of field 'field' for the record with 'sysno' system number."
out = []
digit = field[0:2]
bibbx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag='%s'" % (bibbx, bibx, sysno, field)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def utc_to_localtime(date):
"Convert UTC to localtime"
ldate = date.split("T")[0]
ltime = date.split("T")[1]
lhour = ltime.split(":")[0]
lminute = ltime.split(":")[1]
lsec = ltime.split(":")[2]
lyear = ldate.split("-")[0]
lmonth = ldate.split("-")[1]
lday = ldate.split("-")[2]
timetoconvert = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.mktime((string.atoi(lyear), string.atoi(lmonth), string.atoi(lday), string.atoi(lhour), string.atoi(lminute), string.atoi(lsec[:-1]), 0, 0, -1)) - time.timezone + (time.daylight)*3600))
return timetoconvert
def localtime_to_utc(date):
"Convert localtime to UTC"
ldate = date.split(" ")[0]
ltime = date.split(" ")[1]
lhour = ltime.split(":")[0]
lminute = ltime.split(":")[1]
lsec = ltime.split(":")[2]
lyear = ldate.split("-")[0]
lmonth = ldate.split("-")[1]
lday = ldate.split("-")[2]
timetoconvert = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(time.mktime((string.atoi(lyear), string.atoi(lmonth), string.atoi(lday), string.atoi(lhour), string.atoi(lminute), string.atoi(lsec), 0, 0, -1))))
return timetoconvert
def get_creation_date(sysno):
"Returns the creation date of the record 'sysno'."
out = ""
res = run_sql("SELECT DATE_FORMAT(creation_date, '%%Y-%%m-%%d %%H:%%i:%%s') FROM bibrec WHERE id=%s", (sysno,), 1)
if res[0][0]:
out = localtime_to_utc(res[0][0])
return out
def get_modification_date(sysno):
"Returns the date of last modification for the record 'sysno'."
out = ""
res = run_sql("SELECT DATE_FORMAT(modification_date,'%%Y-%%m-%%d %%H:%%i:%%s') FROM bibrec WHERE id=%s", (sysno,), 1)
if res[0][0]:
out = localtime_to_utc(res[0][0])
return out
def get_earliest_datestamp():
"Get earliest datestamp in the database"
out = ""
res = run_sql("SELECT MIN(DATE_FORMAT(creation_date,'%%Y-%%m-%%d %%H:%%i:%%s')) FROM bibrec", (), 1)
if res[0][0]:
out = localtime_to_utc(res[0][0])
return out
def check_date(date, dtime="T00:00:00Z"):
"Check if the date has a correct format"
if(re.sub("[0123456789\-:TZ]", "", date) == ""):
if len(date) == 10:
date = date + dtime
if len(date) == 20:
date = utc_to_localtime(date)
else:
date = ""
else:
date = ""
return date
def record_exists(sysno):
"Returns 1 if record with SYSNO 'sysno' exists. Returns 0 otherwise."
out = 0
query = "SELECT id FROM bibrec WHERE id='%s'" % (sysno)
res = run_sql(query)
for row in res:
if row[0] != "":
out = 1
return out
def print_record(sysno, format='marcxml'):
"Prints record 'sysno' formatted accoding to 'format'."
out = ""
# sanity check:
if not record_exists(sysno):
return
if (format == "dc") or (format == "oai_dc"):
format = "xd"
# print record opening tags:
out = out + " <record>\n"
if is_deleted(sysno) and oaideleted != "no":
out = out + " <header status=\"deleted\">\n"
else:
out = out + " <header>\n"
for ident in get_field(sysno, oaiidfield):
out = "%s <identifier>%s</identifier>\n" % (out, escape_space(ident))
out = "%s <datestamp>%s</datestamp>\n" % (out, get_modification_date(sysno))
for set in get_field(sysno, oaisetfield):
out = "%s <setSpec>%s</setSpec>\n" % (out, set)
out = out + " </header>\n"
if is_deleted(sysno) and oaideleted != "no":
pass
else:
out = out + " <metadata>\n"
if format == "marcxml":
out = out + " <marc:record xmlns:marc=\"http://www.loc.gov/MARC21/slim\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd\" type=\"Bibliographic\">"
out = out + " <marc:leader>00000coc 2200000uu 4500</marc:leader>"
## MARC21 and XML formats, possibley OAI -- they are not in "bibfmt" table; so fetch all the data from "bibXXx" tables:
if format == "marcxml":
out = "%s <marc:controlfield tag=\"001\">%d</marc:controlfield>\n" % (out, int(sysno))
for digit1 in range(0, 10):
for digit2 in range(0, 10):
bibbx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
query = "SELECT b.tag,b.value,bb.field_number FROM %s AS b, %s AS bb "\
"WHERE bb.id_bibrec='%s' AND b.id=bb.id_bibxxx AND b.tag LIKE '%s%%' "\
"ORDER BY bb.field_number, b.tag ASC" % (bibbx, bibx, sysno, str(digit1)+str(digit2))
res = run_sql(query)
field_number_old = -999
field_old = ""
for row in res:
field, value, field_number = row[0], row[1], row[2]
ind1, ind2 = field[3], field[4]
if ind1 == "_":
ind1 = " "
if ind2 == "_":
ind2 = " "
# print field tag
if field_number != field_number_old or field[:-1] != field_old[:-1]:
if format == "marcxml":
if field_number_old != -999:
if field_old[0:2] == "00":
out = out + " </marc:controlfield>\n"
else:
out = out + " </marc:datafield>\n"
if field[0:2] == "00":
out = "%s <marc:controlfield tag=\"%s\">\n" % (out, encode_for_xml(field[0:3]))
else:
out = "%s <marc:datafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">\n" % (out, encode_for_xml(field[0:3]), encode_for_xml(ind1).lower(), encode_for_xml(ind2).lower())
field_number_old = field_number
field_old = field
# print subfield value
if format == "marcxml":
value = encode_for_xml(value)
if(field[0:2] == "00"):
out = "%s %s\n" % (out, value)
else:
out = "%s <marc:subfield code=\"%s\">%s</marc:subfield>\n" % (out, encode_for_xml(field[-1:]), value)
# fetch next subfield
# all fields/subfields printed in this run, so close the tag:
if (format == "marcxml") and field_number_old != -999:
if field_old[0:2] == "00":
out = out + " </marc:controlfield>\n"
else:
out = out + " </marc:datafield>\n"
out = out + " </marc:record>\n"
elif format == "xd":
# XML Dublin Core format, possibly OAI -- select only some bibXXx fields:
out = out + " <oaidc:dc xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:oaidc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n"
for field_ in get_field(sysno, "041__a"):
out = "%s <dc:language>%s</dc:language>\n" % (out, field_)
for field_ in get_field(sysno, "100__a"):
out = "%s <dc:creator>%s</dc:creator>\n" % (out, encode_for_xml(field_))
for field_ in get_field(sysno, "700__a"):
out = "%s <dc:creator>%s</dc:creator>\n" % (out, encode_for_xml(field_))
for field_ in get_field(sysno, "245__a"):
out = "%s <dc:title>%s</dc:title>\n" % (out, encode_for_xml(field_))
for field_ in get_field(sysno, "111__a"):
out = "%s <dc:title>%s</dc:title>\n" % (out, encode_for_xml(field_))
for field_ in get_field(sysno, "65017a"):
out = "%s <dc:subject>%s</dc:subject>\n" % (out, encode_for_xml(field_))
for field_ in get_field(sysno, "8564_u"):
out = "%s <dc:identifier>%s</dc:identifier>\n" % (out, encode_for_xml(escape_space(field_)))
for field_ in get_field(sysno, "520__a"):
out = "%s <dc:description>%s</dc:description>\n" % (out, encode_for_xml(field_))
date = get_creation_date(sysno)
out = "%s <dc:date>%s</dc:date>\n" % (out, date)
out = out + " </oaidc:dc>\n"
# print record closing tags:
out = out + " </metadata>\n"
out = out + " </record>\n"
return out
def oailistmetadataformats(args):
"Generates response to oailistmetadataformats verb."
arg = parse_args(args)
out = ""
flag = 1 # list or not depending on identifier
if arg['identifier'] != "":
flag = 0
sysno = oaigetsysno(arg['identifier'])
if record_exists(sysno):
flag = 1
else:
out = out + oai_error("idDoesNotExist","invalid record Identifier")
out = oai_error_header(args, "ListMetadataFormats") + out + oai_error_footer("ListMetadataFormats")
return out
if flag:
out = out + " <metadataFormat>\n"
out = out + " <metadataPrefix>oai_dc</metadataPrefix>\n"
out = out + " <schema>http://www.openarchives.org/OAI/1.1/dc.xsd</schema>\n"
out = out + " <metadataNamespace>http://purl.org/dc/elements/1.1/</metadataNamespace>\n"
out = out + " </metadataFormat>\n"
out = out + " <metadataFormat>\n"
out = out + " <metadataPrefix>marcxml</metadataPrefix>\n"
out = out + " <schema>http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd</schema>\n"
out = out + " <metadataNamespace>http://www.loc.gov/MARC21/slim</metadataNamespace>\n"
out = out + " </metadataFormat>\n"
out = oai_header(args, "ListMetadataFormats") + out + oai_footer("ListMetadataFormats")
return out
def oailistrecords(args):
"Generates response to oailistrecords verb."
arg = parse_args(args)
out = ""
sysnos = []
sysno = []
# check if the resumptionToken did not expire
if arg['resumptionToken']:
filename = "%s/RTdata/%s" % (cachedir, arg['resumptionToken'])
if os.path.exists(filename) == 0:
out = oai_error("badResumptionToken", "ResumptionToken expired")
out = oai_error_header(args, "ListRecords") + out + oai_error_footer("ListRecords")
return out
if arg['resumptionToken'] != "":
sysnos = oaicacheout(arg['resumptionToken'])
arg['metadataPrefix'] = sysnos.pop()
else:
sysnos = oaigetsysnolist(arg['set'], arg['from'], arg['until'])
if len(sysnos) == 0: # noRecordsMatch error
out = out + oai_error("noRecordsMatch", "no records correspond to the request")
out = oai_error_header(args, "ListRecords") + out + oai_error_footer("ListRecords")
return out
i = 0
for sysno_ in sysnos:
if sysno_:
i = i + 1
if i > nb_records_in_resume: # cache or write?
if i == nb_records_in_resume + 1: # resumptionToken?
arg['resumptionToken'] = oaigenresumptionToken()
extdate = oaigetresponsedate(oai_rt_expire)
if extdate:
out = "%s <resumptionToken expirationDate=\"%s\">%s</resumptionToken>\n" % (out, extdate, arg['resumptionToken'])
else:
out = "%s <resumptionToken>%s</resumptionToken>\n" % (out, arg['resumptionToken'])
sysno.append(sysno_)
else:
out = out + print_record(sysno_, arg['metadataPrefix'])
if i > nb_records_in_resume:
oaicacheclean()
sysno.append(arg['metadataPrefix'])
oaicachein(arg['resumptionToken'], sysno)
out = oai_header(args, "ListRecords") + out + oai_footer("ListRecords")
return out
def oailistsets(args):
"Lists available sets for OAI metadata harvesting."
out = ""
# note: no flow control in ListSets
sets = get_sets()
for set_ in sets:
out = out + " <set>\n"
out = "%s <setSpec>%s</setSpec>\n" % (out, set_[0])
out = "%s <setName>%s</setName>\n" % (out, set_[1])
if set_[2]:
out = "%s <setDescription>%s</setDescription>\n" % (out, set_[2])
out = out + " </set>\n"
out = oai_header(args, "ListSets") + out + oai_footer("ListSets")
return out
def oaigetrecord(args):
"""Returns record 'identifier' according to 'metadataPrefix' format for OAI metadata harvesting."""
arg = parse_args(args)
out = ""
sysno = oaigetsysno(arg['identifier'])
if record_exists(sysno):
datestamp = get_modification_date(sysno)
out = out + print_record(sysno, arg['metadataPrefix'])
else:
out = out + oai_error("idDoesNotExist", "invalid record Identifier")
out = oai_error_header(args, "GetRecord") + out + oai_error_footer("GetRecord")
return out
out = oai_header(args, "GetRecord") + out + oai_footer("GetRecord")
return out
def oailistidentifiers(args):
"Prints OAI response to the ListIdentifiers verb."
arg = parse_args(args)
out = ""
sysno = []
sysnos = []
if arg['resumptionToken']:
filename = "%s/RTdata/%s" % (cachedir, arg['resumptionToken'])
if os.path.exists(filename) == 0:
out = out + oai_error("badResumptionToken", "ResumptionToken expired")
out = oai_error_header(args, "ListIdentifiers") + out + oai_error_footer("ListIdentifiers")
return out
if arg['resumptionToken']:
sysnos = oaicacheout(arg['resumptionToken'])
else:
sysnos = oaigetsysnolist(arg['set'], arg['from'], arg['until'])
if len(sysnos) == 0: # noRecordsMatch error
out = out + oai_error("noRecordsMatch", "no records correspond to the request")
out = oai_error_header(args, "ListIdentifiers") + out + oai_error_footer("ListIdentifiers")
return out
i = 0
for sysno_ in sysnos:
if sysno_:
i = i + 1
if i > nb_identifiers_in_resume: # cache or write?
if i == nb_identifiers_in_resume + 1: # resumptionToken?
arg['resumptionToken'] = oaigenresumptionToken()
extdate = oaigetresponsedate(oai_rt_expire)
if extdate:
out = "%s <resumptionToken expirationDate=\"%s\">%s</resumptionToken>\n" % (out, extdate, arg['resumptionToken'])
else:
out = "%s <resumptionToken>%s</resumptionToken>\n" % (out, arg['resumptionToken'])
sysno.append(sysno_)
else:
for ident in get_field(sysno_, oaiidfield):
if is_deleted(sysno_) and oaideleted != "no":
out = out + " <header status=\"deleted\">\n"
else:
out = out + " <header>\n"
out = "%s <identifier>%s</identifier>\n" % (out, escape_space(ident))
out = "%s <datestamp>%s</datestamp>\n" % (out, get_modification_date(oaigetsysno(ident)))
for set in get_field(sysno_, oaisetfield):
out = "%s <setSpec>%s</setSpec>\n" % (out, set)
out = out + " </header>\n"
if i > nb_identifiers_in_resume:
oaicacheclean() # clean cache from expired resumptionTokens
oaicachein(arg['resumptionToken'], sysno)
out = oai_header(args, "ListIdentifiers") + out + oai_footer("ListIdentifiers")
return out
def oaiidentify(args):
"Generates response to oaiidentify verb."
out = ""
repositoryname = " <repositoryName>" + cdsname + "</repositoryName>\n"
baseurl = " <baseURL>%s/oai2d.py/</baseURL>\n" % weburl
protocolversion = " <protocolVersion>2.0</protocolVersion>\n"
adminemail = " <adminEmail>%s</adminEmail>\n" % supportemail
earliestdst = " <earliestDatestamp>%s</earliestDatestamp>\n" % get_earliest_datestamp()
deletedrecord = " <deletedRecord>%s</deletedRecord>\n" % oaideleted
repositoryidentifier = "%s" % oaiidprefix
sampleidentifier = oaisampleidentifier
identifydescription = oaiidentifydescription + "\n"
out = out + repositoryname
out = out + baseurl
out = out + protocolversion
out = out + adminemail
out = out + earliestdst
out = out + deletedrecord
out = out + " <granularity>YYYY-MM-DDThh:mm:ssZ</granularity>\n"
# print " <compression></compression>\n"
out = out + oaiidentifydescription
out = oai_header(args, "Identify") + out + oai_footer("Identify")
return out
def oaigetrequesturl(args):
"Generates requesturl tag for OAI."
# re_amp = re.compile('&')
requesturl = weburl + "/" + "oai2d.py/"# + "?" + re_amp.sub("&amp;", args)
return requesturl
def oaigetresponsedate(delay=0):
"Generates responseDate tag for OAI."
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(time.time() + delay))
def oai_error(code, msg):
"OAI error occured"
return "<error code=\"%s\">%s</error>\n" % (code, msg)
def oaigetsysno(identifier):
"Returns the first MySQL BIB ID for the OAI identifier 'identifier', if it exists."
sysno = None
if identifier:
query = "SELECT DISTINCT(bb.id_bibrec) FROM bib%sx AS bx, bibrec_bib%sx AS bb WHERE bx.tag='%s' AND bb.id_bibxxx=bx.id AND bx.value='%s'" % (oaiidfield[0:2], oaiidfield[0:2], oaiidfield, identifier)
res = run_sql(query)
for row in res:
sysno = row[0]
return sysno
def oaigetsysnolist(set, fromdate, untildate):
"Returns list of system numbers for the OAI set 'set', modified from 'date_from' until 'date_until'."
out_dict = {} # dict to hold list of out sysnos as its keys
if set:
query = "SELECT DISTINCT bibx.id_bibrec FROM bib%sx AS bx LEFT JOIN bibrec_bib%sx AS bibx ON bx.id=bibx.id_bibxxx LEFT JOIN bibrec AS b ON b.id=bibx.id_bibrec WHERE bx.tag='%s' AND bx.value='%s'" % (oaiidfield[0:2], oaiidfield[0:2], oaisetfield, set)
else:
query = "SELECT DISTINCT bibx.id_bibrec FROM bib%sx AS bx LEFT JOIN bibrec_bib%sx AS bibx ON bx.id=bibx.id_bibxxx LEFT JOIN bibrec AS b ON b.id=bibx.id_bibrec WHERE bx.tag='%s'" % (oaiidfield[0:2], oaiidfield[0:2], oaiidfield)
if untildate:
query = query + " AND b.modification_date <= '%s'" % untildate
if fromdate:
query = query + " AND b.modification_date >= '%s'" % fromdate
res = run_sql(query)
for row in res:
out_dict[row[0]] = 1
return out_dict.keys()
def is_deleted(recid):
"Check if record with recid has been deleted. Return 1 if deleted."
query = "select a.id from bibrec as a left join bibrec_bib98x as b on a.id=b.id_bibrec left join bib98x as c on b.id_bibxxx=c.id where c.value='DELETED' and a.id=%s" % recid
res = run_sql(query)
for item in res:
if item == None:
return 0
else:
return 1
def oaigenresumptionToken():
"Generates unique ID for resumption token management."
return md5.new(str(time.time())).hexdigest()
def oaicachein(resumptionToken, sysnos):
"Stores or adds sysnos in cache. Input is a string of sysnos separated by commas."
filename = "%s/RTdata/%s" % (cachedir, resumptionToken)
fil = open(filename, "w")
cPickle.dump(sysnos, fil)
fil.close()
return 1
def oaicacheout(resumptionToken):
"Restores string of comma-separated system numbers from cache."
sysnos = []
filename = "%s/RTdata/%s" % (cachedir, resumptionToken)
if oaicachestatus(resumptionToken):
fil = open(filename, "r")
sysnos = cPickle.load(fil)
fil.close()
else:
return 0
return sysnos
def oaicacheclean():
"Removes cached resumptionTokens older than specified"
directory = "%s/RTdata" % cachedir
files = os.listdir(directory)
for file_ in files:
filename = directory + "/" + file_
# cache entry expires when not modified during a specified period of time
if ((time.time() - os.path.getmtime(filename)) > oai_rt_expire):
os.remove(filename)
return 1
def oaicachestatus(resumptionToken):
"Checks cache status. Returns 0 for empty, 1 for full."
filename = "%s/RTdata/%s" % (cachedir, resumptionToken)
if os.path.exists(filename):
if os.path.getsize(filename) > 0:
return 1
else:
return 0
else:
return 0
def get_sets():
"Returns list of sets."
out = []
row = ['', '']
query = "SELECT setSpec,setName,setDescription FROM oaiARCHIVE"
res = run_sql(query)
for row in res:
row_bis = [row[0], row[1], row[2]]
out.append(row_bis)
return out
def parse_args(args=""):
"Parse input args"
out_args = {
"verb" : "",
"metadataPrefix" : "",
"from" : "",
"until" : "",
"set" : "",
"identifier" : "",
"resumptionToken" : ""
}
if args == "" or args == None:
pass
else:
list_of_arguments = args.split('&')
for item in list_of_arguments:
keyvalue = item.split('=')
if len(keyvalue) == 2:
if (out_args.has_key(keyvalue[0])):
if(out_args[keyvalue[0]] != ""):
out_args[keyvalue[0]] = "Error"
else:
out_args[keyvalue[0]] = urllib.unquote(keyvalue[1])
else:
out_args[keyvalue[0]] = urllib.unquote(keyvalue[1])
else:
out_args['verb'] = ""
return out_args
def check_args(arguments):
"Check OAI arguments"
out_args = {
"verb" : "",
"metadataPrefix" : "",
"from" : "",
"until" : "",
"set" : "",
"identifier" : "",
"resumptionToken" : ""
}
out = ""
## principal argument required
#
#
if verbs.has_key(arguments['verb']):
pass
else:
out = out + oai_error("badVerb", "Illegal OAI verb")
## defined args
#
#
for param in arguments.keys():
if out_args.has_key(param):
pass
else:
out = out + oai_error("badArgument", "The request includes illegal arguments")
## unique args
#
#
for param in arguments.keys():
if (arguments[param] == "Error"):
out = out + oai_error("badArgument", "The request includes illegal arguments")
## resumptionToken exclusive
#
#
if ((arguments['from'] != "" or arguments['until'] != "" or arguments['metadataPrefix'] != "" or arguments['identifier'] != "" or arguments['set'] != "") and arguments['resumptionToken'] != ""):
out = out + oai_error("badArgument", "The request includes illegal arguments")
## datestamp formats
#
#
if arguments['from'] != "" and arguments['from'] != "":
from_length = len(arguments['from'])
if check_date(arguments['from'], "T00:00:00Z") == "":
out = out + oai_error("badArgument", "Bad datestamp format in from")
else:
from_length = 0
if arguments['until'] != "" and arguments['until'] != "":
until_length = len(arguments['until'])
if check_date(arguments['until'], "T23:59:59Z") == "":
out = out + oai_error("badArgument", "Bad datestamp format in until")
else:
until_length = 0
if from_length != 0:
if until_length != 0:
if from_length != until_length:
out = out + oai_error("badArgument", "Bad datestamp format")
if arguments['from'] != "" and arguments['until'] != "" and arguments['from'] > arguments['until']:
out = out + oai_error("badArgument", "Wrong date")
## Identify exclusive
#
#
if (arguments['verb'] =="Identify" and (arguments['metadataPrefix'] != "" or arguments['identifier'] != "" or arguments['set'] != "" or arguments['from'] != "" or arguments['until'] != "" or arguments['resumptionToken'] != "")):
out = out + oai_error("badArgument", "The request includes illegal arguments")
## parameters for GetRecord
#
#
if arguments['verb'] =="GetRecord" and arguments['identifier'] == "":
out = out + oai_error("badArgument", "Record identifier missing")
if arguments['verb'] =="GetRecord" and arguments['metadataPrefix'] == "":
out = out + oai_error("badArgument", "Missing metadataPrefix")
## parameters for ListRecords and ListIdentifiers
#
#
if (arguments['verb'] =="ListRecords" or arguments['verb'] =="ListIdentifiers") and (arguments['metadataPrefix'] == "" and arguments['resumptionToken'] == ""):
out = out + oai_error("badArgument", "Missing metadataPrefix")
## Metadata prefix defined
#
#
if arguments.has_key('metadataPrefix'):
if ((arguments['metadataPrefix'] in params['metadataPrefix']) or (params['metadataPrefix'] == "")):
pass
else:
out = out + oai_error("badArgument", "Missing metadataPrefix")
return out
diff --git a/modules/bibharvest/lib/oai_repository_config.py b/modules/bibharvest/lib/oai_repository_config.py
index e93ae0fd4..5e2bbf593 100644
--- a/modules/bibharvest/lib/oai_repository_config.py
+++ b/modules/bibharvest/lib/oai_repository_config.py
@@ -1,31 +1,31 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""OAI repository config"""
from cdsware.config import oaiidprefix, \
oaisampleidentifier, \
oaiidentifydescription, \
oaiidfield, \
oaisetfield, \
oaideleted, \
oai_rt_expire, \
oai_sleep, \
nb_records_in_resume
diff --git a/modules/bibharvest/lib/oai_repository_tests.py b/modules/bibharvest/lib/oai_repository_tests.py
index 9cf9c3ebb..768497582 100644
--- a/modules/bibharvest/lib/oai_repository_tests.py
+++ b/modules/bibharvest/lib/oai_repository_tests.py
@@ -1,81 +1,81 @@
# -*- coding: utf-8 -*-
##
## $Id$
## CDSware OAI repository unit tests.
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the oai repository."""
__version__ = "$Id$"
import unittest
import re
from cdsware import oai_repository
class TestVerbs(unittest.TestCase):
"""Test for OAI verb functionality."""
def test_verbs(self):
"""bibharvest oai repository - testing verbs"""
self.assertNotEqual(None, re.search("Identify", oai_repository.oaiidentify("")))
self.assertNotEqual(None, re.search("ListIdentifiers", oai_repository.oailistidentifiers("")))
self.assertNotEqual(None, re.search("ListRecords", oai_repository.oailistrecords("")))
self.assertNotEqual(None, re.search("ListMetadataFormats", oai_repository.oailistmetadataformats("")))
self.assertNotEqual(None, re.search("ListSets", oai_repository.oailistsets("")))
self.assertNotEqual(None, re.search("GetRecord", oai_repository.oaigetrecord("")))
class TestErrorCodes(unittest.TestCase):
"""Test for handling OAI error codes."""
def test_issue_error_identify(self):
"""bibharvest oai repository - testing error codes"""
self.assertNotEqual(None, re.search("badVerb", oai_repository.check_args(oai_repository.parse_args("junk"))))
self.assertNotEqual(None, re.search("badVerb", oai_repository.check_args(oai_repository.parse_args("verb=IllegalVerb"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=Identify&test=test"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListIdentifiers&metadataPrefix=oai_dc&from=some_random_date&until=some_random_date"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListIdentifiers&metadataPrefix=oai_dc&from=2001-01-01&until=2002-01-01T00:00:00Z"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListIdentifiers"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListIdentifiers&metadataPrefix=illegal_mdp"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListIdentifiers&metadataPrefix=oai_dc&metadataPrefix=oai_dc"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListRecords&metadataPrefix=oai_dc&set=really_wrong_set&from=some_random_date&until=some_random_date"))))
self.assertNotEqual(None, re.search("badArgument", oai_repository.check_args(oai_repository.parse_args("verb=ListRecords"))))
class TestEncodings(unittest.TestCase):
"""Test for OAI response encodings."""
def test_encoding(self):
"""bibharvest oai repository - testing encodings"""
self.assertEqual("&lt;&amp;>", oai_repository.encode_for_xml("<&>"))
self.assertEqual("%20", oai_repository.escape_space(" "))
self.assertEqual("%25%20%3F%23%3D%26%2F%3A%3B%2B", oai_repository.encode_for_url("% ?#=&/:;+"))
def create_test_suite():
"""Return test suite for the oai repository."""
return unittest.TestSuite((unittest.makeSuite(TestVerbs, 'test'),
unittest.makeSuite(TestErrorCodes, 'test'),
unittest.makeSuite(TestEncodings, 'test')))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibharvest/lib/oaiharvestlib.py b/modules/bibharvest/lib/oaiharvestlib.py
index 06808998a..374a41f41 100644
--- a/modules/bibharvest/lib/oaiharvestlib.py
+++ b/modules/bibharvest/lib/oaiharvestlib.py
@@ -1,629 +1,629 @@
# -*- coding: utf-8 -*-
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
oaiharvest implementation. See oaiharvest executable for entry point.
"""
__version__ = "$Id$"
from marshal import loads,dumps
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import Numeric
import signal
import traceback
import calendar
from cdsware.config import *
from cdsware.bibindex_engine_config import *
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
## precompile some often-used regexp for speed reasons:
sre_subfields = sre.compile('\$\$\w');
sre_html = sre.compile("(?s)<[^>]*>|&#?\w+;")
sre_datetime_shift = sre.compile("([-\+]{0,1})([\d]+)([dhms])")
tmpHARVESTpath = tmpdir + '/oaiharvest'
def write_message(msg, stream=sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr)."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
def usage(code, msg=''):
"Prints usage for this module."
if msg:
sys.stderr.write("Error: %s.\n" % msg)
usagetext = """ Usage: oaiharvest [options]
Examples:
oaiharvest -r arxiv -s 24h
oaiharvest -r pubmed -d 2005-05-05:2005-05-10 -t 10m
Specific options:
-r, --repository=REPOS_ONE,"REPOS TWO" name of the OAI repositories to be harvested (default=all)
-d, --dates=yyyy-mm-dd:yyyy-mm-dd harvest repositories between specified dates (overrides repositories' last updated timestamps)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat tasks (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h , 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
"""
sys.stderr.write(usagetext)
sys.exit(code)
def authenticate(user, header="oaiharvest Task Submission", action="runoaiharvest"):
"""Authenticate the user against the user database.
Check for its password, if it exists.
Check for action access rights.
Return user name upon authorization success,
do system exit upon authorization failure.
"""
print header
print "=" * len(header)
if user == "":
print >> sys.stdout, "\rUsername: ",
user = string.strip(string.lower(sys.stdin.readline()))
else:
print >> sys.stdout, "\rUsername: ", user
## first check user pw:
res = run_sql("select id,password from user where email=%s", (user,), 1)
if not res:
print "Sorry, %s does not exist." % user
sys.exit(1)
else:
(uid_db, password_db) = res[0]
if password_db:
password_entered = getpass.getpass()
if password_db == password_entered:
pass
else:
print "Sorry, wrong credentials for %s." % user
sys.exit(1)
## secondly check authorization for the action:
(auth_code, auth_message) = acc_authorize_action(uid_db, action)
if auth_code != 0:
print auth_message
sys.exit(1)
return user
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = sre_datetime_shift.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def task_run(row):
"""Run the harvesting task. The row argument is the Bibharvest task
queue row, containing if, arguments, etc.
Return 1 in case of success and 0 in case of failure.
"""
global options, task_id
reposlist = []
datelist = []
dateflag = 0
# read from SQL row:
task_id = row[0]
task_proc = row[1]
options = loads(row[6])
task_status = row[7]
# sanity check:
if task_proc != "oaiharvest":
write_message("The task #%d does not seem to be a oaiharvest task." % task_id, sys.stderr)
return 0
if task_status != "WAITING":
write_message("The task #%d is %s. I expected WAITING." % (task_id, task_status), sys.stderr)
return 0
# we can run the task now:
if options["verbose"]:
write_message("Task #%d started." % task_id)
task_starting_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
task_update_status("RUNNING")
# install signal handlers
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
### go ahead: build up the reposlist
if options["repository"] != None:
### user requests harvesting from selected repositories
write_message("harvesting from selected repositories")
for reposname in options["repository"]:
row = get_row_from_reposname(reposname)
if row==[]:
write_message("source name " + reposname + " is not valid")
continue
else:
reposlist.append(get_row_from_reposname(reposname))
else:
### user requests harvesting from all repositories
write_message("harvesting from all repositories in the database")
reposlist = get_all_rows_from_db()
### go ahead: check if user requested from-until harvesting
if options["dates"]:
### for each repos simply perform a from-until date harvesting... no need to update anything
dateflag = 1
for element in options["dates"]:
datelist.append(element)
for repos in reposlist:
postmode = str(repos[0][9])
if postmode=="h" or postmode=="h-c" or postmode=="h-u" or postmode=="h-c-u":
harvestpath = tmpdir + "/oaiharvest" + str(os.getpid())
if dateflag == 1:
res = call_bibharvest(prefix=repos[0][2], baseurl=repos[0][1], harvestpath=harvestpath, fro=str(datelist[0]), until=str(datelist[1]))
if res==0 :
write_message("source " + str(repos[0][6]) + " was harvested from " + str(datelist[0]) + " to " + str(datelist[1]))
else :
write_message("an error occurred while harvesting from source " + str(repos[0][6]) + " for the dates chosen")
continue
elif dateflag != 1 and repos[0][7] == None and repos[0][8] != 0:
write_message("source " + str(repos[0][6]) + " was never harvested before - harvesting whole repository")
res = call_bibharvest(prefix=repos[0][2], baseurl=repos[0][1], harvestpath=harvestpath)
if res==0 :
update_lastrun(repos[0][0])
else :
write_message("an error occurred while harvesting from source " + str(repos[0][6]))
continue
elif dateflag != 1 and repos[0][8] != 0:
### check that update is actually needed, i.e. lastrun+frequency>today
timenow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
lastrundate = sre.sub(r'\.[0-9]+$', '', str(repos[0][7])) # remove trailing .00
timeinsec = int(repos[0][8])*60*60
updatedue = add_timestamp_and_timelag(lastrundate, timeinsec)
proceed = compare_timestamps_with_tolerance(updatedue, timenow)
if proceed==0 or proceed==-1 : #update needed!
write_message("source " + str(repos[0][6]) + " is going to be updated")
fromdate = str(repos[0][7])
fromdate = fromdate.split()[0] # get rid of time of the day for the moment
res = call_bibharvest(prefix=repos[0][2], baseurl=repos[0][1], harvestpath=harvestpath, fro=fromdate)
if res==0 :
update_lastrun(repos[0][0])
else :
write_message("an error occurred while harvesting from source " + str(repos[0][6]))
continue
else:
write_message("source " + str(repos[0][6]) + " does not need updating")
continue
elif dateflag != 1 and repos[0][8] == 0:
write_message("source " + str(repos[0][6]) + " has frequency set to 'Never' so it will not be updated")
continue
if postmode=="h-u":
res = call_bibupload(convertpath=harvestpath)
if res==0 :
write_message("material harvested from source " + str(repos[0][6]) + " was successfully uploaded")
else :
write_message("an error occurred while uploading harvest from " + str(repos[0][6]))
continue
if postmode=="h-c" or postmode=="h-c-u":
convertpath = tmpdir + "/bibconvertrun" + str(os.getpid())
res = call_bibconvert(config=str(repos[0][5]), harvestpath=harvestpath, convertpath=convertpath)
if res==0 :
write_message("material harvested from source " + str(repos[0][6]) + " was successfully converted")
else :
write_message("an error occurred while converting from " + str(repos[0][6]))
continue
if postmode=="h-c-u":
res = call_bibupload(convertpath=convertpath)
if res==0 :
write_message("material harvested from source " + str(repos[0][6]) + " was successfully uploaded")
else :
write_message("an error occurred while uploading harvest from " + str(repos[0][6]))
continue
elif postmode not in ["h", "h-c", "h-u", "h-c-u"] : ### this should not happen
write_message("invalid postprocess mode: " + postmode + " skipping repository")
continue
task_update_status("DONE")
if options["verbose"]:
write_message("Task #%d finished." % task_id)
return 1
def add_timestamp_and_timelag(timestamp,
timelag):
""" Adds a time lag in seconds to a given date (timestamp). Returns the resulting date. """
# remove any trailing .00 in timestamp:
timestamp = sre.sub(r'\.[0-9]+$', '', timestamp)
# first convert timestamp to Unix epoch seconds:
timestamp_seconds = calendar.timegm(time.strptime(timestamp, "%Y-%m-%d %H:%M:%S"))
# now add them:
result_seconds = timestamp_seconds + timelag
result = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(result_seconds))
return result
def update_lastrun(index):
""" A method that updates the lastrun of a repository successfully harvested """
try:
today = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
sql = 'UPDATE oaiHARVEST SET lastrun="%s" WHERE id=%s' % (today, index)
res = run_sql(sql)
return 1
except StandardError, e:
return (0,e)
def call_bibharvest(prefix, baseurl, harvestpath, fro="", until=""):
""" A method that calls bibharvest and writes harvested output to disk """
try:
command = '%s/bibharvest -o %s -v ListRecords -p %s ' % (bindir, harvestpath, prefix)
if fro!="":
command += '-f %s ' % fro
if until!="":
command += '-u %s ' % until
command += baseurl
print "Start harvesting"
#print command
ret = os.system(command)
print "Harvesting finished, merging files"
harvestdir, filename = os.path.split(harvestpath)
#print "get files"
files = os.listdir(harvestdir)
#print "sort file"
files.sort()
#print "open dest file"
hf = file(harvestpath, 'w')
for f in files:
if f[:len(filename)] == filename:
print "processing file %s"%f
rf = file(os.path.join(harvestdir, f), 'r')
hf.write(rf.read())
hf.write("\n")
rf.close()
#os.remove(os.path.join(harvestdir, f))
hf.close()
print "Files merged"
return 0
except StandardError, e:
return (0,e)
def call_bibconvert(config, harvestpath, convertpath):
""" A method that reads from a file and converts according to a BibConvert Configuration file. Converted output is returned """
command = """%s/bibconvert -c %s < %s > %s """ % (bindir, config, harvestpath, convertpath)
stdout = os.popen(command)
return 0
def call_bibupload(convertpath):
""" A method that uploads a file to the database - calls bibUpload """
command = '%s/bibupload -i %s ' % (bindir, convertpath)
p=os.system(command)
return p
def get_row_from_reposname(reposname):
""" Returns all information about a row (OAI source) from the source name """
try:
sql = 'select * from oaiHARVEST where name="%s"' % MySQLdb.escape_string(reposname)
res = run_sql(sql)
reposdata = []
for element in res:
reposdata.append(element)
return reposdata
except StandardError, e:
return (0,e)
def get_all_rows_from_db():
""" This method retrieves the full database of repositories and returns a list containing (in exact order):
| id | baseurl | metadataprefix | arguments | comment | bibconvertcfgfile | name | lastrun | frequency | postprocess |
"""
try:
reposlist = []
sql = """select id from oaiHARVEST"""
idlist = run_sql(sql)
for index in idlist:
sql = """select * from oaiHARVEST where id=%s""" % index
reposelements = run_sql(sql)
repos = []
for element in reposelements:
repos.append(element)
reposlist.append(repos)
return reposlist
except StandardError, e:
return (0,e)
def compare_timestamps_with_tolerance(timestamp1,
timestamp2,
tolerance=0):
"""Compare two timestamps TIMESTAMP1 and TIMESTAMP2, of the form
'2005-03-31 17:37:26'. Optionally receives a TOLERANCE argument
(in seconds). Return -1 if TIMESTAMP1 is less than TIMESTAMP2
minus TOLERANCE, 0 if they are equal within TOLERANCE limit,
and 1 if TIMESTAMP1 is greater than TIMESTAMP2 plus TOLERANCE.
"""
# remove any trailing .00 in timestamps:
timestamp1 = sre.sub(r'\.[0-9]+$', '', timestamp1)
timestamp2 = sre.sub(r'\.[0-9]+$', '', timestamp2)
# first convert timestamps to Unix epoch seconds:
timestamp1_seconds = calendar.timegm(time.strptime(timestamp1, "%Y-%m-%d %H:%M:%S"))
timestamp2_seconds = calendar.timegm(time.strptime(timestamp2, "%Y-%m-%d %H:%M:%S"))
# now compare them:
if timestamp1_seconds < timestamp2_seconds - tolerance:
return -1
elif timestamp1_seconds > timestamp2_seconds + tolerance:
return 1
else:
return 0
def command_line():
global options
long_flags =["repository=", "dates="
"user=","sleeptime=","time=",
"help", "version", "verbose="]
short_flags ="r:d:u:s:t:hVv:"
format_string = "%Y-%m-%d %H:%M:%S"
repositories = None
dates = None
sleeptime = ""
try:
opts, args = getopt.getopt(sys.argv[1:], short_flags, long_flags)
except getopt.GetoptError, err:
write_message(err, sys.stderr)
usage(1)
if args:
usage(1)
options={"sleeptime":0, "verbose":1, "repository":0, "dates":0}
sched_time = time.strftime(format_string)
user = ""
# Check for key options
try:
for opt in opts:
if opt == ("-h","") or opt == ("--help",""):
usage(1)
elif opt == ("-V","") or opt == ("--version",""):
print __version__
sys.exit(1)
elif opt[0] in ["--verbose", "-v"]:
options["verbose"] = int(opt[1])
elif opt[0] in [ "-r", "--repository" ]:
repositories = opt[1]
elif opt[0] in [ "-d", "--dates" ]:
dates = opt[1]
elif opt[0] in [ "-u", "--user"]:
user = opt[1]
elif opt[0] in [ "-s", "--sleeptime" ]:
get_datetime(opt[1]) # see if it is a valid shift
sleeptime= opt[1]
elif opt[0] in [ "-t", "--time" ]:
sched_time= get_datetime(opt[1])
else: usage(1)
except StandardError, e:
write_message(e, sys.stderr)
sys.exit(1)
options["repository"]=get_repository_names(repositories)
if dates != None:
options["dates"]=get_dates(dates)
if dates != None and options["dates"]==None:
write_message("Date format not valid. Quitting task...")
sys.exit(1)
user = authenticate(user)
if options["verbose"] >= 9:
print ""
write_message("storing task options %s\n" % options)
new_task_id = run_sql("""INSERT INTO schTASK (proc,user,runtime,sleeptime,arguments,status)
VALUES ('oaiharvest',%s,%s,%s,%s,'WAITING')""",
(user, sched_time, sleeptime, dumps(options)))
print "Task #%d was successfully scheduled for execution." % new_task_id
return
def get_dates(dates):
""" A method to validate and process the dates input by the user at the command line """
twodates = []
if dates:
datestring = string.split(dates, ":")
if len(datestring)==2:
for date in datestring:
### perform some checks on the date format
datechunks = string.split(date, "-")
if len(datechunks)==3:
try:
if int(datechunks[0]) and int(datechunks[1]) and int(datechunks[2]):
twodates.append(date)
except StandardError, e:
write_message("Dates have invalid format, not 'yyyy-mm-dd:yyyy-mm-dd'")
twodates=None
return twodates
else:
write_message("Dates have invalid format, not 'yyyy-mm-dd:yyyy-mm-dd'")
twodates=None
return twodates
## final check.. date1 must me smaller than date2
date1 = str(twodates[0]) + " 01:00:00"
date2 = str(twodates[1]) + " 01:00:00"
if compare_timestamps_with_tolerance(date1, date2)!=-1:
write_message("First date must be before second date.")
twodates=None
return twodates
else:
write_message("Dates have invalid format, not 'yyyy-mm-dd:yyyy-mm-dd'")
twodates=None
else:
twodates=None
return twodates
def get_repository_names(repositories):
""" A method to validate and process the repository names input by the user at the command line """
repository_names = []
if repositories:
names = string.split(repositories, ",")
for name in names:
### take into account both single word names and multiple word names (which get wrapped around "" or '')
quote = "'"
doublequote = '"'
if name.find(quote)==0 and name.find(quote)==len(name):
name = name.split(quote)[1]
if name.find(doublequote)==0 and name.find(doublequote)==len(name):
name = name.split(doublequote)[1]
repository_names.append(name)
else:
repository_names=None
return repository_names
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("stopping...")
task_update_status("STOPPING")
errcode = 0
try:
task_sig_stop_commands()
write_message("stopped")
task_update_status("STOPPED")
except StandardError, err:
write_message("Error during stopping! %e" % err)
task_update_status("STOPPINGFAILED")
errcode = 1
sys.exit(errcode)
def task_sig_stop_commands():
"""Do all the commands necessary to stop the task before quitting.
Useful for task_sig_stop() handler.
"""
write_message("stopping commands started")
for table in wordTables:
table.put_into_db()
write_message("stopping commands ended")
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task progress to %s." % msg)
return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, task_id))
def task_update_status(val):
"""Updates state information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task status to %s." % val)
return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, task_id))
def main():
"""Reads arguments and either runs the task, or starts user-interface (command line)."""
if len(sys.argv) == 2:
try:
id = int(sys.argv[1])
except StandardError, err:
command_line()
sys.exit()
res = run_sql("SELECT * FROM schTASK WHERE id='%d'" % (id), None, 1)
if not res:
write_message("Selected task not found.", sys.stderr)
sys.exit(1)
try:
if not task_run(res[0]):
write_message("Error occurred. Exiting.", sys.stderr)
except StandardError, e:
write_message("Unexpected error occurred: %s." % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
write_message("Exiting.")
task_update_status("ERROR")
else:
command_line()
diff --git a/modules/bibharvest/web/Makefile.am b/modules/bibharvest/web/Makefile.am
index e89fc6501..896f9ac37 100644
--- a/modules/bibharvest/web/Makefile.am
+++ b/modules/bibharvest/web/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
webappdir = $(WEBDIR)
webapp_DATA = oai2d.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/bibharvest/web/admin/Makefile.am b/modules/bibharvest/web/admin/Makefile.am
index c59c3e1e3..50806e138 100644
--- a/modules/bibharvest/web/admin/Makefile.am
+++ b/modules/bibharvest/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/bibharvest
webapp_DATA = bibharvestadmin.py
EXTRA_DIST = bibharvestadmin.py
CLEANFILES = *~ *.tmp
diff --git a/modules/bibharvest/web/admin/bibharvestadmin.py b/modules/bibharvest/web/admin/bibharvestadmin.py
index eeaa39109..0195a5be4 100644
--- a/modules/bibharvest/web/admin/bibharvestadmin.py
+++ b/modules/bibharvest/web/admin/bibharvestadmin.py
@@ -1,160 +1,160 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibHarvest Administrator Interface."""
__lastupdated__ = """$Date$"""
import sys
import cdsware.bibharvestadminlib as bhc
from cdsware.webpage import page, create_error_box
from cdsware.config import weburl,cdslang
from cdsware.webuser import getUid, page_not_authorized
__version__ = "$Id$"
def index(req, ln=cdslang):
navtrail_previous_links = bhc.getnavtrail()
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bhc.check_user(uid,'cfgbibharvest')
if not auth[0]:
return page(title="BibHarvest Admin Interface",
body=bhc.perform_request_index(ln),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__,
urlargs=req.args)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def editsource(req, oai_src_id, oai_src_name='', oai_src_baseurl='', oai_src_prefix='', oai_src_frequency='', oai_src_config='', oai_src_post='', ln=cdslang, mtype='', callback='yes', confirm=-1):
navtrail_previous_links = bhc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibharvest/bibharvestadmin.py">BibHarvest Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bhc.check_user(uid,'cfgbibharvest')
if not auth[0]:
return page(title="Edit OAI Source",
body=bhc.perform_request_editsource(oai_src_id=oai_src_id,
oai_src_name=oai_src_name,
oai_src_baseurl=oai_src_baseurl,
oai_src_prefix=oai_src_prefix,
oai_src_frequency=oai_src_frequency,
oai_src_config=oai_src_config,
oai_src_post=oai_src_post,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifysource(req, oai_src_id, oai_src_name, oai_src_baseurl='', oai_src_prefix='', oai_src_frequency='', oai_src_config='', oai_src_post='', ln=cdslang, mtype='', callback='yes', confirm=-1):
navtrail_previous_links = bhc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibharvest/bibharvestadmin.py">BibHarvest Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bhc.check_user(uid,'cfgbibharvest')
if not auth[0]:
return page(title="Edit OAI Source",
body=bhc.perform_request_modifysource(oai_src_id=oai_src_id,
oai_src_name=oai_src_name,
oai_src_baseurl=oai_src_baseurl,
oai_src_prefix=oai_src_prefix,
oai_src_frequency=oai_src_frequency,
oai_src_config=oai_src_config,
oai_src_post=oai_src_post,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addsource(req, ln=cdslang, oai_src_name='', oai_src_baseurl ='', oai_src_prefix='', oai_src_frequency='', oai_src_lastrun='', oai_src_config='', oai_src_post='', confirm=-1):
navtrail_previous_links = bhc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibharvest/bibharvestadmin.py">BibHarvest Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bhc.check_user(uid,'cfgbibharvest')
if not auth[0]:
return page(title="Add new OAI Source",
body=bhc.perform_request_addsource(oai_src_name=oai_src_name,
oai_src_baseurl=oai_src_baseurl,
oai_src_prefix=oai_src_prefix,
oai_src_frequency=oai_src_frequency,
oai_src_lastrun=oai_src_lastrun,
oai_src_config=oai_src_config,
oai_src_post=oai_src_post,
ln=cdslang,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def delsource(req, oai_src_id, ln=cdslang, confirm=0):
navtrail_previous_links = bhc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibharvest/bibharvestadmin.py">BibHarvest Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bhc.check_user(uid,'cfgbibharvest')
if not auth[0]:
return page(title="Delete OAI Source",
body=bhc.perform_request_delsource(oai_src_id=oai_src_id,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
diff --git a/modules/bibharvest/web/oai2d.py b/modules/bibharvest/web/oai2d.py
index d1b658960..060cfa8ed 100644
--- a/modules/bibharvest/web/oai2d.py
+++ b/modules/bibharvest/web/oai2d.py
@@ -1,128 +1,128 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""OAI interface for CDSware/MySQL written in Python compliant with OAI-PMH2.0"""
__lastupdated__ = """$Date$"""
__version__ = "$Id$"
import os
import sys
import urllib
import time
from mod_python import apache
from cdsware.dbquery import run_sql
from cdsware.oai_repository_config import *
from cdsware import oai_repository
from cdsware.config import cachedir
def index (req):
"OAI repository interface"
## check availability
if os.path.exists("%s/RTdata/RTdata" % cachedir):
time_gap = int(time.time() - os.path.getmtime("%s/RTdata/RTdata" % cachedir))
if(time_gap < oai_sleep):
req.err_headers_out["Status-Code"] = "503"
req.err_headers_out["Retry-After"] = "%d" % (oai_sleep - time_gap)
req.status = apache.HTTP_SERVICE_UNAVAILABLE
return "Retry after %d seconds" % (oai_sleep - time_gap)
command = "touch %s/RTdata/RTdata" % cachedir
os.system(command)
## parse input parameters
args = ""
if req.method == "GET":
args = req.args
elif req.method == "POST":
params = {}
for key in req.form.keys():
params[key] = req.form[key]
args = urllib.urlencode(params)
arg = oai_repository.parse_args(args)
## check request for OAI compliancy
oai_error = oai_repository.check_args(arg)
## create OAI response
req.content_type = "text/xml"
req.send_http_header()
if oai_error == "":
## OAI Identify
if arg['verb'] == "Identify":
req.write(oai_repository.oaiidentify(args))
## OAI ListSets
elif arg['verb'] == "ListSets":
req.write(oai_repository.oailistsets(args))
## OAI ListIdentifiers
elif arg['verb'] == "ListIdentifiers":
req.write(oai_repository.oailistidentifiers(args))
## OAI ListRecords
elif arg['verb'] == "ListRecords":
req.write(oai_repository.oailistrecords(args))
## OAI GetRecord
elif arg['verb'] == "GetRecord":
req.write(oai_repository.oaigetrecord(args))
## OAI ListMetadataFormats
elif arg['verb'] == "ListMetadataFormats":
req.write(oai_repository.oailistmetadataformats(args))
## Unknown verb
else:
req.write(oai_repository.oai_error("badVerb","Illegal OAI verb"))
## OAI error
else:
req.write(oai_repository.oai_header(args,""))
req.write(oai_error)
req.write(oai_repository.oai_footer(""))
return "\n"
diff --git a/modules/bibindex/Makefile.am b/modules/bibindex/Makefile.am
index 36564d9cc..e6cf5387a 100644
--- a/modules/bibindex/Makefile.am
+++ b/modules/bibindex/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc lib web
CLEANFILES = *~
diff --git a/modules/bibindex/bin/Makefile.am b/modules/bibindex/bin/Makefile.am
index 2402d4949..fa9b333f2 100644
--- a/modules/bibindex/bin/Makefile.am
+++ b/modules/bibindex/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibindex bibstat
EXTRA_DIST = bibindex.in bibstat.in
CLEANFILES = *~ *.tmp
diff --git a/modules/bibindex/bin/bibindex.in b/modules/bibindex/bin/bibindex.in
index 1f075da55..06485750e 100644
--- a/modules/bibindex/bin/bibindex.in
+++ b/modules/bibindex/bin/bibindex.in
@@ -1,68 +1,68 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
BibIndex bibliographic data, reference and fulltext indexing utility.
Usage: bibindex %s [options]
Examples:
bibindex -a -i 234-250,293,300-500 -u admin@cdsware
bibindex -a -w author,fulltext -M 8192 -v3
bibindex -d -m +4d -A on --flush=10000
Indexing options:
-a, --add add or update words for selected records
-d, --del delete words for selected records
-i, --id=low[-high] select according to record recID.
-m, --modified=from[,to] select according to modification date
-c, --collection=c1[,c2] select according to collection
Repairing options:
-k, --check check consistency for all records in the table(s)
-r, --repair try to repair all records in the table(s)
Specific options:
-w, --windex=w1[,w2] word/phrase indexes to consider (all)
-M, --maxmem=XXX maximum memory usage in kB (no limit)
-f, --flush=NNN full consistent table flush after NNN records (10000)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat task (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h, 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
"""
try:
from cdsware.bibindex_engine import main
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
main()
diff --git a/modules/bibindex/bin/bibstat.in b/modules/bibindex/bin/bibstat.in
index f69f129a9..74200ed15 100644
--- a/modules/bibindex/bin/bibstat.in
+++ b/modules/bibindex/bin/bibstat.in
@@ -1,107 +1,107 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
BibStat reports some interesting numbers on CDSware bibliographic record set.
"""
__version__ = "$Id$"
## import interesting modules:
try:
import sys
from cdsware.dbquery import run_sql
from marshal import loads,dumps
from zlib import compress,decompress
from string import split,translate,lower,upper
import getopt
import string
import os
import re
import time
import urllib
import signal
import threading
import unicodedata
import traceback
import cStringIO
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
def report_table_status(tablename):
"""Report stats for the table TABLENAME."""
out = ""
res = run_sql("SHOW TABLE STATUS LIKE %s", (tablename,))
for row in res:
out += "%14s %17d %17d %17d" % (row[0], row[3], row[5], row[7]) # Name, Rows, Data_length, Max_data_length
return out
def report_on_all_bibliographic_tables():
"""Report stats for all the interesting bibliographic tables."""
print "%14s %17s %17s %17s" % ("TABLE", "ROWS", "DATA SIZE", "INDEX SIZE")
print "============== ================= ================= ================="
for i in range(0,10):
for j in range(0,10):
print report_table_status("bib%1d%1dx" % (i, j))
print report_table_status("bibrec_bib%1d%1dx" % (i, j))
for i in range(0,11):
print report_table_status("idxWORD%02dF" % i)
print report_table_status("idxWORD%02dR" % i)
for i in range(0,11):
print report_table_status("idxPHRASE%02dF" % i)
print report_table_status("idxPHRASE%02dR" % i)
return
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.exit(exitcode)
def main():
"""Report stats on the CDSware bibliographic tables."""
try:
opts, args = getopt.getopt(sys.argv[1:], "hV", ["help", "version"])
except getopt.GetoptError, err:
usage(1, err)
if opts:
for opt in opts:
if opt[0] in ["-h", "--help"]:
usage(0)
elif opt[0] in ["-V", "--version"]:
print __version__
sys.exit(0)
else:
usage(1)
else:
report_on_all_bibliographic_tables()
if __name__ == "__main__":
main()
diff --git a/modules/bibindex/doc/Makefile.am b/modules/bibindex/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibindex/doc/Makefile.am
+++ b/modules/bibindex/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibindex/doc/admin/Makefile.am b/modules/bibindex/doc/admin/Makefile.am
index fee622777..535679b11 100644
--- a/modules/bibindex/doc/admin/Makefile.am
+++ b/modules/bibindex/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/bibindex
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibindex/doc/admin/guide.html.wml b/modules/bibindex/doc/admin/guide.html.wml
index 8ec8a9a12..e0ae682dd 100644
--- a/modules/bibindex/doc/admin/guide.html.wml
+++ b/modules/bibindex/doc/admin/guide.html.wml
@@ -1,228 +1,228 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibIndex Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibindex/>BibIndex Admin</a>" \
navbar_name="admin" \
navbar_select="bibindex-admin-guide"
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
WARNING: BIBINDEX ADMIN GUIDE IS UNDER DEVELOPMENT
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
BibIndex Admin Guide is not yet completed. Most of admin-level
functionality for BibIndex exists only in commandline mode. We
are in the process of developing both the guide as well as the
web admin interface. If you are interested in seeing some
specific things implemented with high priority, please contact us
at <SUPPORTEMAIL>. Thanks for your interest!
</td>
</tr>
</tbody>
</table>
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1.<a href="#1">Overview</a></strong></br>
<strong>2. <a href="#2">Configure Metadata Tags and Fields</a></strong></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1 <a href="#2.1">Configure Physical MARC Tags</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 <a href="#2.2">Configure Logical Fields</a></br>
<strong>3. <a href="#3">Configure Word/Phrase Indexes</a></strong></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1 <a href="#3.1">Define New Index</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2 <a href="#3.2">Configure Word-Breaking Procedure</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.3 <a href="#3.3">Configure Stopwords List</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.4 <a href="#3.4">Configure Stemming</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.5 <a href="#3.5">Configure Word Length</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6 <a href="#3.6">Configure Removal of HTML Code</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.7 <a href="#3.7">Configure Accent Stripping</a></br>
<strong>4. <a href="#4">Run BibIndex Daemon</a></strong></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1 <a href="#4.1">Run BibIndex daemon</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2 <a href="#4.2">Checking and repairing indexes</a></br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.3 <a href="#4.3">Reindexing</a></br>
<a name="1"></a><h2>1. Overview</h2>
<a name="2"></a><h2>2. Configure Metadata Tags and Fields</h2>
<a name="2.1"></a><h3>2.1 Configure Physical MARC Tags</h3>
<a name="2.2"></a><h3>2.2 Configure Logical Fields</h3>
<a name="3"></a><h2>3. Configure Word/Phrase Indexes</h2>
<a name="3.1"></a><h3>3.1 Define New Index</h3>
<p>To define a new index you must first give the index a internal
name. An empty index is then created by preparing the database tables.
<p>Before the index can be used for searching, the fields that should be
included in the index must be selected.
<p>When desired to fill the index based on the fields selected, you can
schedule the update by running <b>bibindex -w indexname</b> together
with other desired parameters.
<a name="3.2"></a><h3>3.2 Configure Word-Breaking Procedure</h3>
<p>Can be configured by changing
<b>cfg_bibindex_chars_alphanumeric_separators</b> and
<b>cfg_bibindex_chars_punctuation</b> in the general config file.
<p>How the words are broken up defines what is added to the index. Should
only "director-general" be added, or should "director", "general" and
"director-general" be added? The index can vary between 300 000 and 3
000 000 terms based the policy for breaking words.
<a name="3.3"></a><h3>3.3 Configure Stopwords List</h3>
<p>BibIndex supports stopword removal by not adding words which exists in
a given stopword list to the index. Stopword removal makes the index
smaller by removing much used words.
<p>Which stopword list that should be used can be configured in the
general config file file by changing the value of the variable
cfg_bibindex_path_to_stopwords_file. If no stopword list should be
used, the value should be 0.
<a name="3.4"></a><h3>3.4 Configure stemming</h3>
<p>The BibIndex indexer supports stemming, removing the ending of
words thus creating a smaller indexer. For example, using english, the
word "information" will be stemmed to "inform", "looking", "looks",
"looked" will be stemmed to "look", thus giving more hits to each
word.
<p>Currently only one stemmer is supported, so the stemmer to use
should be selected based on the most used language. All searches will
also be stemmed based on the same language. For documents in other
languages, there will be no difference if stemmer is used or not.
<p>The Stemmer currently supported, supports the following languages:
French, English, Norwegian, Swedish, German, Italian and Portugese.
<p>If another than the default stemmer should be used, the file
<b>bibindex_engine_stemmer.py</b> must be changed to support the
desired stemmers interface.
<p>To change the default language to use for the stemmer, change the
variable <b>cfg_bibindex_stemmer_default_language</b> in the general
config file. To disable use of stemmer, set the value to empty
string.
<a name="3.5"></a><h3>3.5 Configure Word Length</h3>
<p>By setting the value of <b>cfg_bibindex_min_word_length</b> in the
general config file higher than 0, only words with the number of
characters higher than this will be added to the index.
<a name="3.6"></a><h3>3.6 Configure Removal of HTML Code</h3>
<p>By setting the value of <b>cfg_bibindex_remove_html_markup</b> in
the general config file, the indexer may try to remove all HTML code
from documents before indexing, and index only the text left. (HTML
code is defined as everything between '<' and '>' in a text.)
<a name="3.7"></a><h3>3.7 Configure Accent Stripping</h3>
<a name="4"></a><h2>4. Run BibIndex Daemon</h2>
<a name="4.1"></a><h3>4.1 Run BibIndex daemon</h3>
To index your newly created or modified documents, bibindex must be
run periodically via bibsched. This is achieved by the sleep option
(-s) to bibindex. For more information please see <a
href="../howto/run.html">HOWTO Run</a> admin guide.
<a name="4.2"></a><h3>4.2 Checking and repairing indexes</h3>
Upon each indexing run, bibindex checks and reports any
inconsistencies in the indexes. You can also manually check for the
index corruption yourself by using the check (-k) option to bibindex.
<p>If a problem is found during the check, bibindex hints you to run
repairing (-r). If you run it, then during repair bibindex tries to
correct problems automatically by its own means. Usually it succeeds.
<p>When the automatic repairing does not succeed though, then manual
intervention is required. The easiest thing to get the indexes back
to shape are commands like: (assuming the problem is with the index ID
1):
<blockquote>
<pre>
$ echo "DELETE FROM idxWORD01R WHERE type='TEMPORARY' or type='FUTURE';" | \
/path/to/cdsware/bin/dbexec
</pre>
</blockquote>
to leave only the 'CURRENT' reverse index. After that you can rerun
the index checking procedure (-k) and, if successful, continue with
the normal web site operation. However, a full reindexing should be
scheduled for the forthcoming night or weekend.
<a name="4.3"></a><h3>4.3 Reindexing</h3>
The procedure of reindexing is taking place into the real indexes that
are also used for searching. Therefore the end users will feel
immediately any change in the indexes. If you need to reindex your
records from scratch (e.g. you would like to increase CFG_MAX_RECID in
config.wml), then the best procedure is the following: wipe out
existing indexes, reindex the collection index only (fast operation),
recreate collection cache, and only after that reindex all the other
indexes (slow operation). This will ensure that the records in your
system will be at least browsable while the indexes are being rebuilt.
The steps to perform are:
<blockquote>
<pre>
$ bibsched # wait for all active tasks to finish, and put the queue into manual mode
$ cd cdsware-0.7.1 # source dir
$ echo "UPDATE collection SET reclist=NULL;" | \
/path/to/cdsware/bin/dbexec # clean collection cache
$ grep WORD ./modules/miscutil/sql/tabbibclean.sql | \
/path/to/cdsware/bin/dbexec # truncate word and rank indexes
$ echo "UPDATE idxINDEX SET last_updated='0000-00-00 00:00:00';" | \
/path/to/cdsware/bin/dbexec # rewind the last indexing time
$ echo "UPDATE rnkMETHOD SET last_updated='0000-00-00 00:00:00';" | \
/path/to/cdsware/bin/dbexec # rewind the last ranking time
$ bibindex -f50000 -wcollection # reindex the collection index (fast)
$ webcoll -f # recreate the collection cache
$ bibsched # run the two above-submitted tasks
$ sudo apachectl restart
$ bibindex -f50000 # reindex other indexes (slow)
$ bibrank -f50000
$ webcoll -f
$ bibsched # run the three above-submitted tasks, and put the queue back in auto mode
$ sudo apachectl restart
</pre>
</blockquote>
In the future CDSware should ideally run indexing into invisible
tables that would be switched against the production ones once the
indexing process is successfully over. For the time being, if
reindexing takes several hours in your installation (e.g. if you have
500,000 records), you may want to mysqlhotcopy your tables and run
reindexing on those copies yourself.
diff --git a/modules/bibindex/doc/admin/index.html.wml b/modules/bibindex/doc/admin/index.html.wml
index ba862b04b..babe47afc 100644
--- a/modules/bibindex/doc/admin/index.html.wml
+++ b/modules/bibindex/doc/admin/index.html.wml
@@ -1,43 +1,43 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibIndex Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibindex"
<p>
This is the gate to the admin area for BibIndex. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/bibindex/">login</a> to enter.
</p>
<dl>
<dt><a href="bibindexadmin.py/index">Manage indexes</a></dt>
<dd>For modifying indexes.</dd>
</dl>
<dl>
<dt><a href="bibindexadmin.py/field">Manage logical fields</a></dt>
<dd>For modifying logical fields.</dd>
</dl>
<dl>
<dt><a href="guide.html">BibIndex Admin Guide</a></dt>
<dd>Everything you want to know about BibIndex administration</dd>
</dl>
diff --git a/modules/bibindex/lib/Makefile.am b/modules/bibindex/lib/Makefile.am
index 38dce04b0..de32f4865 100644
--- a/modules/bibindex/lib/Makefile.am
+++ b/modules/bibindex/lib/Makefile.am
@@ -1,27 +1,27 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = bibindex_engine.py bibindex_engine_config.py bibindex_engine_tests.py \
bibindexadminlib.py bibindex_engine_stemmer.py bibindex_engine_stopwords.py \
bibindex_engine_stemmer_tests.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibindex/lib/bibindex_engine.py b/modules/bibindex/lib/bibindex_engine.py
index 2709de7de..5cdb47707 100644
--- a/modules/bibindex/lib/bibindex_engine.py
+++ b/modules/bibindex/lib/bibindex_engine.py
@@ -1,1672 +1,1672 @@
# -*- coding: utf-8 -*-
##
## $Id$
## BibIndxes bibliographic data, reference and fulltext indexing utility.
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
BibIndex indexing engine implementation. See bibindex executable for entry point.
"""
from marshal import loads,dumps
from zlib import compress,decompress
from string import split,translate,lower,upper
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import Numeric
import urllib
import signal
import tempfile
import unicodedata
import traceback
import cStringIO
from cdsware.config import *
from cdsware.bibindex_engine_config import *
from cdsware.search_engine_config import cfg_max_recID
from cdsware.search_engine import perform_request_search, strip_accents
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.bibindex_engine_stopwords import is_stopword
from cdsware.bibindex_engine_stemmer import stem
## import optional modules:
try:
import psyco
psyco.bind(get_words_from_phrase)
psyco.bind(merge_with_old_recIDs)
psyco.bind(serialize_via_numeric_array)
psyco.bind(serialize_via_marshal)
psyco.bind(deserialize_via_numeric_array)
psyco.bind(deserialize_via_marshal)
except:
pass
## override urllib's default password-asking behaviour:
class MyFancyURLopener(urllib.FancyURLopener):
def prompt_user_passwd(self, host, realm):
# supply some dummy credentials by default
return (cfg_bibindex_urlopener_username, cfg_bibindex_urlopener_password)
def http_error_401(self, url, fp, errcode, errmsg, headers):
# do not bother with protected pages
raise IOError, (999, 'unauthorized access')
return None
urllib._urlopener = MyFancyURLopener()
def write_message(msg, stream=sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr)."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
## precompile some often-used regexp for speed reasons:
sre_subfields = sre.compile('\$\$\w');
sre_html = sre.compile("(?s)<[^>]*>|&#?\w+;")
sre_block_punctuation_begin = sre.compile(r"^"+cfg_bibindex_chars_punctuation+"+")
sre_block_punctuation_end = sre.compile(cfg_bibindex_chars_punctuation+"+$")
sre_punctuation = sre.compile(cfg_bibindex_chars_punctuation)
sre_separators = sre.compile(cfg_bibindex_chars_alphanumeric_separators)
sre_datetime_shift = sre.compile("([-\+]{0,1})([\d]+)([dhms])")
nb_char_in_line = 50 # for verbose pretty printing
chunksize = 1000 # default size of chunks that the records will be treated by
wordTables = []
task_id = -1
base_process_size = 4500 # process base size
options = {} # will hold task options
## Dictionary merging functions
def intersection(dict, dict2):
"Returns intersection of the two dictionaries."
int_dict = {}
if len(dict1) > len(dict2):
for e in dict2:
if dict1.has_key(e):
int_dict[e] = 1
else:
for e in dict1:
if dict2.has_key(e):
int_dict[e] = 1
return int_dict
def union(dict1, dict2):
"Returns union of the two dictionaries."
union_dict = {}
for e in dict1.keys():
union_dict[e] = 1
for e in dict2.keys():
union_dict[e] = 1
return union_dict
def diff(dict1, dict2):
"Returns dict1 - dict2."
diff_dict = {}
for e in dict1.keys():
if not dict2.has_key(e):
diff_dict[e] = 1
return diff_dict
def list_union(list1, list2):
"Returns union of the two lists."
union_dict = {}
for e in list1:
union_dict[e] = 1
for e in list2:
union_dict[e] = 1
return union_dict.keys()
## safety function for killing slow MySQL threads:
def kill_sleepy_mysql_threads(max_threads=cfg_max_mysql_threads, thread_timeout=cfg_mysql_thread_timeout):
"""Check the number of MySQL threads and if there are more than
MAX_THREADS of them, lill all threads that are in a sleeping
state for more than THREAD_TIMEOUT seconds. (This is useful
for working around the the max_connection problem that appears
during indexation in some not-yet-understood cases.) If some
threads are to be killed, write info into the log file.
"""
res = run_sql("SHOW FULL PROCESSLIST")
if len(res) > max_threads:
for row in res:
r_id,r_user,r_host,r_db,r_command,r_time,r_state,r_info = row
if r_command == "Sleep" and int(r_time) > thread_timeout:
run_sql("KILL %s", (r_id,))
if options["verbose"] >= 1:
write_message("WARNING: too many MySQL threads, killing thread %s" % r_id)
return
## MARC-21 tag/field access functions
def get_fieldvalues(recID, tag):
"""Returns list of values of the MARC-21 'tag' fields for the record
'recID'."""
out = []
bibXXx = "bib" + tag[0] + tag[1] + "x"
bibrec_bibXXx = "bibrec_" + bibXXx
query = "SELECT value FROM %s AS b, %s AS bb WHERE bb.id_bibrec=%s AND bb.id_bibxxx=b.id AND tag LIKE '%s'" \
% (bibXXx, bibrec_bibXXx, recID, tag)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def get_associated_subfield_value(recID, tag, value, associated_subfield_code):
"""Return list of ASSOCIATED_SUBFIELD_CODE, if exists, for record
RECID and TAG of value VALUE. Used by fulltext indexer only.
Note: TAG must be 6 characters long (tag+ind1+ind2+sfcode),
otherwise en empty string is returned.
FIXME: what if many tag values have the same value but different
associated_subfield_code? Better use bibrecord library for this.
"""
out = ""
if len(tag) != 6:
return out
bibXXx = "bib" + tag[0] + tag[1] + "x"
bibrec_bibXXx = "bibrec_" + bibXXx
query = """SELECT bb.field_number, b.tag, b.value FROM %s AS b, %s AS bb
WHERE bb.id_bibrec=%s AND bb.id_bibxxx=b.id AND tag LIKE '%s%%'""" % \
(bibXXx, bibrec_bibXXx, recID, tag[:-1])
res = run_sql(query)
field_number = -1
for row in res:
if row[1] == tag and row[2] == value:
field_number = row[0]
if field_number > 0:
for row in res:
if row[0] == field_number and row[1] == tag[:-1] + associated_subfield_code:
out = row[2]
break
return out
def get_field_tags(field):
"""Returns a list of MARC tags for the field code 'field'.
Returns empty list in case of error.
Example: field='author', output=['100__%','700__%']."""
out = []
query = """SELECT t.value FROM tag AS t, field_tag AS ft, field AS f
WHERE f.code='%s' AND ft.id_field=f.id AND t.id=ft.id_tag
ORDER BY ft.score DESC""" % field
res = run_sql(query)
for row in res:
out.append(row[0])
return out
## Fulltext word extraction functions
def get_fulltext_urls_from_html_page(htmlpagebody):
"""Parses htmlpagebody data looking for url_directs referring to
probable fulltexts.
Returns an array of (ext,url_direct) to fulltexts.
Note: it looks for file format extensions as defined by global
'conv_programs'structure.
"""
out = []
for ext in conv_programs.keys():
expr = sre.compile( r"\"(http://[\w]+\.+[\w]+[^\"'><]*\." + \
ext + r")\"")
match = expr.search(htmlpagebody)
if match:
out.append([ext,match.group(1)])
else: # FIXME: workaround for getfile, should use bibdoc tables
expr_getfile = sre.compile(r"\"(http://.*getfile\.py\?.*format=" + ext + r"&version=.*)\"")
match = expr_getfile.search(htmlpagebody)
if match:
out.append([ext,match.group(1)])
return out
def get_words_from_fulltext(url_direct_or_indirect,
separators="[^\w]",
split=string.split,
force_file_extension=None):
"""Returns all the words contained in the document specified by
URL_DIRECT_OR_INDIRECT with the words being split by
SEPARATORS. If FORCE_FILE_EXTENSION is set (e.g. to "pdf",
then treat URL_DIRECT_OR_INDIRECT as a PDF file. (This is
interesting to index Indico for example.) Note also that
URL_DIRECT_OR_INDIRECT may be either a direct URL to the
fulltext file or an URL to a setlink-like page body that
presents the links to be indexed. In the latter case the
URL_DIRECT_OR_INDIRECT is parsed to extract actual direct URLs
to fulltext documents, for all knows file extensions as
specified by global conv_programs config variable.
"""
if cfg_bibindex_fulltext_index_local_files_only and string.find(url_direct_or_indirect, weburl) < 0:
return []
if options["verbose"] >= 2:
write_message("... reading fulltext files from %s started" % url_direct_or_indirect)
fulltext_urls = None
if not force_file_extension:
url_direct = None
fulltext_urls = None
# check for direct link in url
url_direct_or_indirect_ext = lower(split(url_direct_or_indirect,".")[-1])
if url_direct_or_indirect_ext in conv_programs.keys():
fulltext_urls = [(url_direct_or_indirect_ext,url_direct_or_indirect)]
# Indirect url. Try to fetch the real fulltext(s)
if not fulltext_urls:
# read "setlink" data
try:
htmlpagebody = urllib.urlopen(url_direct_or_indirect).read()
except:
sys.stderr.write("Error: Cannot read %s.\n" % url_direct_or_indirect)
return []
fulltext_urls = get_fulltext_urls_from_html_page(htmlpagebody)
if options["verbose"] >= 9:
write_message("... fulltext_urls = %s" % fulltext_urls)
else:
fulltext_urls = [[force_file_extension, url_direct_or_indirect]]
words = {}
# process as many urls as they were found:
for (ext,url_direct) in fulltext_urls:
if options["verbose"] >= 2:
write_message(".... processing %s from %s started" % (ext,url_direct))
# sanity check:
if not url_direct:
break;
# read fulltext file:
try:
url = urllib.urlopen(url_direct)
except:
sys.stderr.write("Error: Cannot read %s.\n" % url_direct)
break # try other fulltext files...
tmp_name = tempfile.mktemp('cdsware.tmp')
tmp_fd = open(tmp_name, "w")
data_chunk = url.read(8*1024)
while data_chunk:
tmp_fd.write(data_chunk)
data_chunk = url.read(8*1024)
tmp_fd.close()
# try all available conversion programs according to their order:
bingo = 0
for conv_program in conv_programs[ext]:
if os.path.exists(conv_program):
# intelligence on how to run various conversion programs:
cmd = "" # wil keep command to run
bingo = 0 # had we success?
if os.path.basename(conv_program) == "pdftotext":
cmd = "%s %s %s.txt" % (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "pstotext":
if ext == "ps.gz":
# is there gzip available?
if os.path.exists(conv_programs_helpers["gz"]):
cmd = "%s -cd %s | %s > %s.txt" \
% (conv_programs_helpers["gz"], tmp_name, conv_program, tmp_name)
else:
cmd = "%s %s > %s.txt" \
% (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "ps2ascii":
if ext == "ps.gz":
# is there gzip available?
if os.path.exists(conv_programs_helpers["gz"]):
cmd = "%s -cd %s | %s > %s.txt"\
% (conv_programs_helpers["gz"], tmp_name,
conv_program, tmp_name)
else:
cmd = "%s %s %s.txt" \
% (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "antiword":
cmd = "%s %s > %s.txt" % (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "catdoc":
cmd = "%s %s > %s.txt" % (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "wvText":
cmd = "%s %s %s.txt" % (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "ppthtml":
# is there html2text available?
if os.path.exists(conv_programs_helpers["html"]):
cmd = "%s %s | %s > %s.txt"\
% (conv_program, tmp_name,
conv_programs_helpers["html"], tmp_name)
else:
cmd = "%s %s > %s.txt" \
% (conv_program, tmp_name, tmp_name)
elif os.path.basename(conv_program) == "xlhtml":
# is there html2text available?
if os.path.exists(conv_programs_helpers["html"]):
cmd = "%s %s | %s > %s.txt" % \
(conv_program, tmp_name,
conv_programs_helpers["html"], tmp_name)
else:
cmd = "%s %s > %s.txt" % \
(conv_program, tmp_name, tmp_name)
else:
sys.stderr.write("Error: Do not know how to handle %s conversion program.\n" % conv_program)
# try to run it:
try:
if options["verbose"] >= 9:
write_message("..... launching %s" % cmd)
errcode = os.system(cmd)
if errcode == 0 and os.path.exists("%s.txt" % tmp_name):
bingo = 1
break # bingo!
else:
write_message("Error while running %s for %s.\n" % (cmd, url_direct), sys.stderr)
except:
write_message("Error running %s for %s.\n" % (cmd, url_direct), sys.stderr)
# were we successful?
if bingo:
tmp_name_txt_file = open("%s.txt" % tmp_name)
for phrase in tmp_name_txt_file.xreadlines():
for word in get_words_from_phrase(phrase):
if not words.has_key(word):
words[word] = 1;
tmp_name_txt_file.close()
else:
if options["verbose"]:
write_message("No conversion success for %s.\n" % (url_direct), sys.stderr)
# delete temp files (they might not exist):
try:
os.unlink(tmp_name)
os.unlink(tmp_name + ".txt")
except StandardError:
write_message("Error: Could not delete file. It didn't exist", sys.stderr)
if options["verbose"] >= 2:
write_message(".... processing %s from %s ended" % (ext,url_direct))
if options["verbose"] >= 2:
write_message("... reading fulltext files from %s ended" % url_direct_or_indirect)
return words.keys()
# tagToFunctions mapping. It offers an indirection level necesary for
# indexing fulltext. The default is get_words_from_phrase
tagToWordsFunctions = {'8564_u':get_words_from_fulltext}
def get_words_from_phrase(phrase, split=string.split):
"""Return list of words found in PHRASE. Note that the phrase is
split into groups depending on the alphanumeric characters and
punctuation characters definition present in the config file.
"""
words = {}
if cfg_bibindex_remove_html_markup and string.find(phrase, "</") > -1:
phrase = sre_html.sub(' ', phrase)
phrase = str.lower(phrase)
# 1st split phrase into blocks according to whitespace
for block in split(strip_accents(phrase)):
# 2nd remove leading/trailing punctuation and add block:
block = sre_block_punctuation_begin.sub("", block)
block = sre_block_punctuation_end.sub("", block)
if block:
block = apply_stemming_and_stopwords_and_length_check(block)
if block:
words[block] = 1
# 3rd break each block into subblocks according to punctuation and add subblocks:
for subblock in sre_punctuation.split(block):
subblock = apply_stemming_and_stopwords_and_length_check(subblock)
if subblock:
words[subblock] = 1
# 4th break each subblock into alphanumeric groups and add groups:
for alphanumeric_group in sre_separators.split(subblock):
alphanumeric_group = apply_stemming_and_stopwords_and_length_check(alphanumeric_group)
if alphanumeric_group:
words[alphanumeric_group] = 1
return words.keys()
def apply_stemming_and_stopwords_and_length_check(word):
"""Return WORD after applying stemming and stopword and length checks.
See the config file in order to influence these.
"""
# stem word, when configured so:
if cfg_bibindex_stemmer_default_language != "":
word = stem(word, cfg_bibindex_stemmer_default_language)
# now check against stopwords:
if is_stopword(word):
return ""
# finally check the word length:
if len(word) < cfg_bibindex_min_word_length:
return ""
return word
def remove_subfields(s):
"Removes subfields from string, e.g. 'foo $$c bar' becomes 'foo bar'."
return sre_subfields.sub(' ', s)
def get_index_id(indexname):
"""Returns the words/phrase index id for INDEXNAME.
Returns empty string in case there is no words table for this index.
Example: field='author', output=4."""
out = 0
query = """SELECT w.id FROM idxINDEX AS w
WHERE w.name='%s' LIMIT 1""" % indexname
res = run_sql(query, None, 1)
if res:
out = res[0][0]
return out
def get_index_tags(indexname):
"""Returns the list of tags that are indexed inside INDEXNAME.
Returns empty list in case there are no tags indexed in this index.
Note: uses get_field_tags() defined before.
Example: field='author', output=['100__%', '700__%']."""
out = []
query = """SELECT f.code FROM idxINDEX AS w, idxINDEX_field AS wf,
field AS f WHERE w.name='%s' AND w.id=wf.id_idxINDEX
AND f.id=wf.id_field""" % indexname
res = run_sql(query)
for row in res:
out.extend(get_field_tags(row[0]))
return out
def get_all_indexes():
"""Returns the list of the names of all defined words indexes.
Returns empty list in case there are no tags indexed in this index.
Example: output=['global', 'author']."""
out = []
query = """SELECT name FROM idxINDEX"""
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def usage(code, msg=''):
"Prints usage for this module."
if msg:
sys.stderr.write("Error: %s.\n" % msg)
print >> sys.stderr, \
""" Usage: %s [options]
Examples:
%s -a -i 234-250,293,300-500 -u admin@cdsware
%s -a -w author,fulltext -M 8192 -v3
%s -d -m +4d -A on --flush=10000
Indexing options:
-a, --add add or update words for selected records
-d, --del delete words for selected records
-i, --id=low[-high] select according to doc recID
-m, --modified=from[,to] select according to modification date
-c, --collection=c1[,c2] select according to collection
Repairing options:
-k, --check check consistency for all records in the table(s)
-r, --repair try to repair all records in the table(s)
Specific options:
-w, --windex=w1[,w2] word/phrase indexes to consider (all)
-M, --maxmem=XXX maximum memory usage in kB (no limit)
-f, --flush=NNN full consistent table flush after NNN records (10000)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat tasks (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h , 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
""" % ((sys.argv[0],) * 4)
sys.exit(code)
def authenticate(user, header="BibIndex Task Submission", action="runbibindex"):
"""Authenticate the user against the user database.
Check for its password, if it exists.
Check for action access rights.
Return user name upon authorization success,
do system exit upon authorization failure.
"""
print header
print "=" * len(header)
if user == "":
print >> sys.stdout, "\rUsername: ",
user = string.strip(string.lower(sys.stdin.readline()))
else:
print >> sys.stdout, "\rUsername: ", user
## first check user pw:
res = run_sql("select id,password from user where email=%s", (user,), 1)
if not res:
print "Sorry, %s does not exist." % user
sys.exit(1)
else:
(uid_db, password_db) = res[0]
if password_db:
password_entered = getpass.getpass()
if password_db == password_entered:
pass
else:
print "Sorry, wrong credentials for %s." % user
sys.exit(1)
## secondly check authorization for the action:
(auth_code, auth_message) = acc_authorize_action(uid_db, action)
if auth_code != 0:
print auth_message
sys.exit(1)
return user
def split_ranges(parse_string):
recIDs = []
ranges = string.split(parse_string, ",")
for range in ranges:
tmp_recIDs = string.split(range, "-")
if len(tmp_recIDs)==1:
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[0])])
else:
if int(tmp_recIDs[0]) > int(tmp_recIDs[1]): # sanity check
tmp = tmp_recIDs[0]
tmp_recIDs[0] = tmp_recIDs[1]
tmp_recIDs[1] = tmp
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[1])])
return recIDs
def get_word_tables(tables):
wordTables = []
if tables:
indexes = string.split(tables, ",")
for index in indexes:
index_id = get_index_id(index)
if index_id:
wordTables.append({"idxWORD%02dF" % index_id: \
get_index_tags(index)})
else:
write_message("Error: There is no %s words table." % index, sys.stderr)
else:
for index in get_all_indexes():
index_id = get_index_id(index)
wordTables.append({"idxWORD%02dF" % index_id: \
get_index_tags(index)})
return wordTables
def get_date_range(var):
"Returns the two dates contained as a low,high tuple"
limits = string.split(var, ",")
if len(limits)==1:
low = get_datetime(limits[0])
return low,None
if len(limits)==2:
low = get_datetime(limits[0])
high = get_datetime(limits[1])
return low,high
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = sre_datetime_shift.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def create_range_list(res):
"""Creates a range list from a recID select query result contained
in res. The result is expected to have ascending numerical order."""
if not res:
return []
row = res[0]
if not row:
return []
else:
range_list = [[row[0],row[0]]]
for row in res[1:]:
id = row[0]
if id == range_list[-1][1] + 1:
range_list[-1][1] = id
else:
range_list.append([id,id])
return range_list
def beautify_range_list(range_list):
"""Returns a non overlapping, maximal range list"""
ret_list = []
for new in range_list:
found = 0
for old in ret_list:
if new[0] <= old[0] <= new[1] + 1 or new[0] - 1 <= old[1] <= new[1]:
old[0] = min(old[0], new[0])
old[1] = max(old[1], new[1])
found = 1
break
if not found:
ret_list.append(new)
return ret_list
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return compress(Numeric.dumps(arr))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(decompress(string))
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(compress(dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return loads(decompress(string))
class WordTable:
"A class to hold the words table."
def __init__(self, tablename, fields_to_index, separators="[^\s]"):
"Creates words table instance."
self.tablename = tablename
self.recIDs_in_mem = []
self.fields_to_index = fields_to_index
self.separators = separators
self.value = {}
def get_field(self, recID, tag):
"""Returns list of values of the MARC-21 'tag' fields for the
record 'recID'."""
out = []
bibXXx = "bib" + tag[0] + tag[1] + "x"
bibrec_bibXXx = "bibrec_" + bibXXx
query = """SELECT value FROM %s AS b, %s AS bb
WHERE bb.id_bibrec=%s AND bb.id_bibxxx=b.id
AND tag LIKE '%s'""" % (bibXXx, bibrec_bibXXx, recID, tag);
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def clean(self):
"Cleans the words table."
self.value={}
def put_into_db(self, mode="normal", split=string.split):
"""Updates the current words table in the corresponding MySQL's
idxFOO table. Mode 'normal' means normal execution,
mode 'emergency' means words index reverting to old state.
"""
if options["verbose"]:
write_message("%s %s wordtable flush started" % (self.tablename,mode))
write_message('...updating %d words into %s started' % \
(len(self.value), self.tablename))
task_update_progress("%s flushed %d/%d words" % (self.tablename, 0, len(self.value)))
self.recIDs_in_mem = beautify_range_list(self.recIDs_in_mem)
if mode == "normal":
for group in self.recIDs_in_mem:
query = """UPDATE %sR SET type='TEMPORARY' WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='CURRENT'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
nb_words_total = len(self.value)
nb_words_report = int(nb_words_total/10)
nb_words_done = 0
for word in self.value.keys():
self.put_word_into_db(word)
nb_words_done += 1
if nb_words_report!=0 and ((nb_words_done % nb_words_report) == 0):
if options["verbose"]:
write_message('......processed %d/%d words' % (nb_words_done, nb_words_total))
task_update_progress("%s flushed %d/%d words" % (self.tablename, nb_words_done, nb_words_total))
if options["verbose"] >= 9:
write_message('...updating %d words into %s ended' % \
(nb_words_total, self.tablename))
if options["verbose"]:
write_message('...updating reverse table %sR started' % self.tablename[:-1])
if mode == "normal":
for group in self.recIDs_in_mem:
query = """UPDATE %sR SET type='CURRENT' WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='FUTURE'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
query = """DELETE FROM %sR WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='TEMPORARY'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
if options["verbose"] >= 9:
write_message('End of updating wordTable into %s' % self.tablename)
elif mode == "emergency":
for group in self.recIDs_in_mem:
query = """UPDATE %sR SET type='CURRENT' WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='TEMPORARY'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
query = """DELETE FROM %sR WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='FUTURE'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
if options["verbose"] >= 9:
write_message('End of emergency flushing wordTable into %s' % self.tablename)
if options["verbose"]:
write_message('...updating reverse table %sR ended' % self.tablename[:-1])
self.clean()
self.recIDs_in_mem = []
if options["verbose"]:
write_message("%s %s wordtable flush ended" % (self.tablename, mode))
task_update_progress("%s flush ended" % (self.tablename))
def load_old_recIDs(self,word):
"""Load existing hitlist for the word from the database index files."""
query = "SELECT hitlist FROM %s WHERE term=%%s" % self.tablename
res = run_sql(query, (word,))
if res:
return deserialize_via_numeric_array(res[0][0])
else:
return None
def merge_with_old_recIDs(self,word,set):
"""Merge the system numbers stored in memory (hash of recIDs with value +1 or -1
according to whether to add/delete them) with those stored in the database index
and received in set universe of recIDs for the given word.
Return 0 in case no change was done to SET, return 1 in case SET was changed.
"""
set_changed_p = 0
for recID,sign in self.value[word].items():
if sign == -1 and set[recID]==1:
# delete recID if existent in set and if marked as to be deleted
set[recID] = 0
set_changed_p = 1
elif set[recID] == 0:
# add recID if not existent in set and if marked as to be added
set[recID] = 1
set_changed_p = 1
return set_changed_p
def put_word_into_db(self, word, split=string.split):
"""Flush a single word to the database and delete it from memory"""
set = self.load_old_recIDs(word)
if set: # merge the word recIDs found in memory:
if self.merge_with_old_recIDs(word,set) == 0:
# nothing to update:
if options["verbose"] >= 9:
write_message("......... unchanged hitlist for ``%s''" % word)
pass
else:
# yes there were some new words:
if options["verbose"] >= 9:
write_message("......... updating hitlist for ``%s''" % word)
run_sql("UPDATE %s SET hitlist=%%s WHERE term=%%s" % self.tablename,
(serialize_via_numeric_array(set), word))
else: # the word is new, will create new set:
set = Numeric.zeros(cfg_max_recID+1, Numeric.Int0)
Numeric.put(set, self.value[word].keys(), 1)
if options["verbose"] >= 9:
write_message("......... inserting hitlist for ``%s''" % word)
run_sql("INSERT INTO %s (term, hitlist) VALUES (%%s, %%s)" % self.tablename,
(word, serialize_via_numeric_array(set)))
if not set: # never store empty words
run_sql("DELETE from %s WHERE term=%%s" % self.tablename,
(word,))
del self.value[word]
def display(self):
"Displays the word table."
keys = self.value.keys()
keys.sort()
for k in keys:
if options["verbose"]:
write_message("%s: %s" % (k, self.value[k]))
def count(self):
"Returns the number of words in the table."
return len(self.value)
def info(self):
"Prints some information on the words table."
if options["verbose"]:
write_message("The words table contains %d words." % self.count())
def lookup_words(self, word=""):
"Lookup word from the words table."
if not word:
done = 0
while not done:
try:
word = raw_input("Enter word: ")
done = 1
except (EOFError, KeyboardInterrupt):
return
if self.value.has_key(word):
if options["verbose"]:
write_message("The word '%s' is found %d times." \
% (word, len(self.value[word])))
else:
if options["verbose"]:
write_message("The word '%s' does not exist in the word file."\
% word)
def update_last_updated(self, starting_time=None):
"""Update last_updated column of the index table in the database.
Puts starting time there so that if the task was interrupted for record download,
the records will be reindexed next time."""
if starting_time is None:
return None
if options["verbose"] >= 9:
write_message("updating last_updated to %s...", starting_time)
return run_sql("UPDATE idxINDEX SET last_updated=%s WHERE id=%s",
(starting_time, self.tablename[-3:-1],))
def add_recIDs(self, recIDs):
"""Fetches records which id in the recIDs range list and adds
them to the wordTable. The recIDs range list is of the form:
[[i1_low,i1_high],[i2_low,i2_high], ..., [iN_low,iN_high]].
"""
global chunksize
flush_count = 0
records_done = 0
records_to_go = 0
for range in recIDs:
records_to_go = records_to_go + range[1] - range[0] + 1
time_started = time.time() # will measure profile time
for range in recIDs:
i_low = range[0]
chunksize_count = 0
while i_low <= range[1]:
# calculate chunk group of recIDs and treat it:
i_high = min(i_low+options["flush"]-flush_count-1,range[1])
i_high = min(i_low+chunksize-chunksize_count-1, i_high)
try:
self.chk_recID_range(i_low, i_high)
except StandardError, e:
write_message("Exception caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
task_update_status("ERROR")
task_sig_stop_commands()
sys.exit(1)
if options["verbose"]:
write_message("%s adding records #%d-#%d started" % \
(self.tablename, i_low, i_high))
if cfg_check_mysql_threads:
kill_sleepy_mysql_threads()
task_update_progress("%s adding recs %d-%d" % (self.tablename, i_low, i_high))
self.del_recID_range(i_low, i_high)
just_processed = self.add_recID_range(i_low, i_high)
flush_count = flush_count + i_high - i_low + 1
chunksize_count = chunksize_count + i_high - i_low + 1
records_done = records_done + just_processed
if options["verbose"]:
write_message("%s adding records #%d-#%d ended " % \
(self.tablename, i_low, i_high))
if chunksize_count >= chunksize:
chunksize_count = 0
# flush if necessary:
if flush_count >= options["flush"]:
self.put_into_db()
self.clean()
if options["verbose"]:
write_message("%s backing up" % (self.tablename))
flush_count = 0
self.log_progress(time_started,records_done,records_to_go)
# iterate:
i_low = i_high + 1
if flush_count > 0:
self.put_into_db()
self.log_progress(time_started,records_done,records_to_go)
def add_recIDs_by_date(self, dates):
"""Add records that were modified between DATES[0] and DATES[1].
If DATES is not set, then add records that were modified since
the last update of the index.
"""
if not dates:
id = self.tablename[-3:-1]
query = """SELECT last_updated FROM idxINDEX WHERE id='%s'
""" % id
res = run_sql(query)
if not res:
return
if not res[0][0]:
dates = ("0000-00-00", None)
else:
dates = (res[0][0], None)
if dates[1] is None:
res = run_sql("""SELECT b.id FROM bibrec AS b
WHERE b.modification_date >= %s ORDER BY b.id ASC""",
(dates[0],))
elif dates[0] is None:
res = run_sql("""SELECT b.id FROM bibrec AS b
WHERE b.modification_date <= %s ORDER BY b.id ASC""",
(dates[1],))
else:
res = run_sql("""SELECT b.id FROM bibrec AS b
WHERE b.modification_date >= %s AND
b.modification_date <= %s ORDER BY b.id ASC""",
(dates[0], dates[1]))
list = create_range_list(res)
if not list:
if options["verbose"]:
write_message( "No new records added. %s is up to date" % self.tablename)
else:
self.add_recIDs(list)
def add_recID_range(self, recID1, recID2):
empty_list_string = serialize_via_marshal([])
wlist = {}
self.recIDs_in_mem.append([recID1,recID2])
# secondly fetch all needed tags:
for tag in self.fields_to_index:
if tag in tagToWordsFunctions.keys():
get_words_function = tagToWordsFunctions[tag]
else:
get_words_function = get_words_from_phrase
bibXXx = "bib" + tag[0] + tag[1] + "x"
bibrec_bibXXx = "bibrec_" + bibXXx
query = """SELECT bb.id_bibrec,b.value FROM %s AS b, %s AS bb
WHERE bb.id_bibrec BETWEEN %d AND %d
AND bb.id_bibxxx=b.id AND tag LIKE '%s'""" % (bibXXx, bibrec_bibXXx, recID1, recID2, tag)
res = run_sql(query)
nb_total_to_read = len(res)
verbose_idx = 0 # for verbose pretty printing
for row in res:
recID,phrase = row
if not wlist.has_key(recID): wlist[recID] = []
if tag == "8564_u":
# Special treatment for fulltext indexing. 8564
# $$u contains URL, and $$y link name. If $$y is
# actually a file name, that is if it ends with
# something like .pdf or .ppt, then $$u is treated
# as direct URL to the PDF file, and is indexed as
# such. This is useful to index Indico files.
# FIXME: this is a quick fix only. We should
# rather download all 856 $$u files and analyze
# content in order to decide how to index them
# (directly for Indico, indirectly for Setlink).
filename = get_associated_subfield_value(recID,'8564_u', phrase, 'y')
filename_extension = lower(split(filename, ".")[-1])
if filename_extension in conv_programs.keys():
new_words = get_words_function(phrase, force_file_extension=filename_extension) # ,self.separators
else:
new_words = get_words_function(phrase) # ,self.separators
else:
new_words = get_words_function(phrase) # ,self.separators
wlist[recID] = list_union(new_words,wlist[recID])
# were there some words for these recIDs found?
if len(wlist) == 0: return 0
recIDs = wlist.keys()
for recID in recIDs:
# was this record marked as deleted?
if "DELETED" in self.get_field(recID, "980__c"):
wlist[recID] = []
if options["verbose"] >= 9:
write_message("... record %d was declared deleted, removing its word list" % recID)
if options["verbose"] >= 9:
write_message("... record %d, termlist: %s" % (recID, wlist[recID]))
# Using cStringIO for speed.
query_factory = cStringIO.StringIO()
qwrite = query_factory.write
qwrite( "INSERT INTO %sR (id_bibrec,termlist,type) VALUES" % self.tablename[:-1])
qwrite( "('" )
qwrite( str(recIDs[0]) )
qwrite( "','" )
qwrite( serialize_via_marshal(wlist[recIDs[0]]) )
qwrite( "','FUTURE')" )
for recID in recIDs[1:]:
qwrite(",('")
qwrite(str(recID))
qwrite("','")
qwrite(serialize_via_marshal(wlist[recID]))
qwrite("','FUTURE')")
query = query_factory.getvalue()
query_factory.close()
run_sql(query)
query_factory = cStringIO.StringIO()
qwrite = query_factory.write
qwrite("INSERT INTO %sR (id_bibrec,termlist,type) VALUES" % self.tablename[:-1])
qwrite("('")
qwrite(str(recIDs[0]))
qwrite("','")
qwrite(serialize_via_marshal(wlist[recIDs[0]]))
qwrite("','CURRENT')")
for recID in recIDs[1:]:
qwrite( ",('" )
qwrite( str(recID) )
qwrite( "','" )
qwrite( empty_list_string )
qwrite( "','CURRENT')" )
query = query_factory.getvalue()
query_factory.close()
try:
run_sql(query)
except MySQLdb.DatabaseError:
# ok, we tried to add an existent record. No problem
pass
put = self.put
for recID in recIDs:
for w in wlist[recID]:
put(recID, w, 1)
return len(recIDs)
def log_progress(self, start, done, todo):
"""Calculate progress and store it.
start: start time,
done: records processed,
todo: total number of records"""
time_elapsed = time.time() - start
# consistency check
if time_elapsed == 0 or done > todo:
return
time_recs_per_min = done/(time_elapsed/60.0)
if options["verbose"]:
write_message("%d records took %.1f seconds to complete.(%1.f recs/min)"\
% (done, time_elapsed, time_recs_per_min))
if time_recs_per_min:
if options["verbose"]:
write_message("Estimated runtime: %.1f minutes" % \
((todo-done)/time_recs_per_min))
def put(self, recID, word, sign):
"Adds/deletes a word to the word list."
try:
word = lower(word[:50])
if self.value.has_key(word):
# the word 'word' exist already: update sign
self.value[word][recID] = sign
else:
self.value[word] = {recID: sign}
except:
write_message("Error: Cannot put word %s with sign %d for recID %s." % (word, sign, recID))
def del_recIDs(self, recIDs):
"""Fetches records which id in the recIDs range list and adds
them to the wordTable. The recIDs range list is of the form:
[[i1_low,i1_high],[i2_low,i2_high], ..., [iN_low,iN_high]].
"""
count = 0
for range in recIDs:
self.del_recID_range(range[0],range[1])
count = count + range[1] - range[0]
self.put_into_db()
def del_recID_range(self, low, high):
"""Deletes records with 'recID' system number between low
and high from memory words index table."""
if options["verbose"] > 2:
write_message("%s fetching existing words for records #%d-#%d started" % \
(self.tablename, low, high))
self.recIDs_in_mem.append([low,high])
query = """SELECT id_bibrec,termlist FROM %sR as bb WHERE bb.id_bibrec
BETWEEN '%d' AND '%d'""" % (self.tablename[:-1], low, high)
recID_rows = run_sql(query)
for recID_row in recID_rows:
recID = recID_row[0]
wlist = deserialize_via_marshal(recID_row[1])
for word in wlist:
self.put(recID, word, -1)
if options["verbose"] > 2:
write_message("%s fetching existing words for records #%d-#%d ended" % \
(self.tablename, low, high))
def report_on_table_consistency(self):
"""Check reverse words index tables (e.g. idxWORD01R) for
interesting states such as 'TEMPORARY' state.
Prints small report (no of words, no of bad words).
"""
# find number of words:
query = """SELECT COUNT(*) FROM %s""" % (self.tablename)
res = run_sql(query, None, 1)
if res:
nb_words = res[0][0]
else:
nb_words = 0
# find number of records:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR""" % (self.tablename[:-1])
res = run_sql(query, None, 1)
if res:
nb_records = res[0][0]
else:
nb_records = 0
# report stats:
if options["verbose"]:
write_message("%s contains %d words from %d records" % (self.tablename, nb_words, nb_records))
# find possible bad states in reverse tables:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR WHERE type <> 'CURRENT'""" % (self.tablename[:-1])
res = run_sql(query)
if res:
nb_bad_records = res[0][0]
else:
nb_bad_records = 999999999
if nb_bad_records:
write_message("EMERGENCY: %s needs to repair %d of %d records" % \
(self.tablename, nb_bad_records, nb_records))
else:
if options["verbose"]:
write_message("%s is in consistent state" % (self.tablename))
return nb_bad_records
def repair(self):
"""Repair the whole table"""
# find possible bad states in reverse tables:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR WHERE type <> 'CURRENT'""" % (self.tablename[:-1])
res = run_sql(query, None, 1)
if res:
nb_bad_records = res[0][0]
else:
nb_bad_records = 0
# find number of records:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR""" % (self.tablename[:-1])
res = run_sql(query)
if res:
nb_records = res[0][0]
else:
nb_records = 0
if nb_bad_records == 0:
return
query = """SELECT id_bibrec FROM %sR WHERE type <> 'CURRENT' ORDER BY id_bibrec""" \
% (self.tablename[:-1])
res = run_sql(query)
recIDs = create_range_list(res)
flush_count = 0
records_done = 0
records_to_go = 0
for range in recIDs:
records_to_go = records_to_go + range[1] - range[0] + 1
time_started = time.time() # will measure profile time
for range in recIDs:
i_low = range[0]
chunksize_count = 0
while i_low <= range[1]:
# calculate chunk group of recIDs and treat it:
i_high = min(i_low+options["flush"]-flush_count-1,range[1])
i_high = min(i_low+chunksize-chunksize_count-1, i_high)
try:
self.fix_recID_range(i_low, i_high)
except StandardError, e:
write_message("Exception caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
task_update_status("ERROR")
task_sig_stop_commands()
sys.exit(1)
flush_count = flush_count + i_high - i_low + 1
chunksize_count = chunksize_count + i_high - i_low + 1
records_done = records_done + i_high - i_low + 1
if chunksize_count >= chunksize:
chunksize_count = 0
# flush if necessary:
if flush_count >= options["flush"]:
self.put_into_db("emergency")
self.clean()
flush_count = 0
self.log_progress(time_started,records_done,records_to_go)
# iterate:
i_low = i_high + 1
if flush_count > 0:
self.put_into_db("emergency")
self.log_progress(time_started,records_done,records_to_go)
write_message("%s inconsistencies repaired." % self.tablename)
def chk_recID_range(self, low, high):
"""Check if the reverse index table is in proper state"""
## check db
query = """SELECT COUNT(*) FROM %sR WHERE type <> 'CURRENT'
AND id_bibrec BETWEEN '%d' AND '%d'""" % (self.tablename[:-1], low, high)
res = run_sql(query, None, 1)
if res[0][0]==0:
if options["verbose"]:
write_message("%s for %d-%d is in consistent state"%(self.tablename,low,high))
return # okay, words table is consistent
## inconsistency detected!
write_message("EMERGENCY: %s inconsistencies detected..." % self.tablename)
write_message("""EMERGENCY: Errors found. You should check consistency of the %s - %sR tables.\nRunning 'bibindex --repair' is recommended.""" \
% (self.tablename, self.tablename[:-1]))
raise StandardError
def fix_recID_range(self, low, high):
"""Try to fix reverse index database consistency (e.g. table idxWORD01R) in the low,high doc-id range.
Possible states for a recID follow:
CUR TMP FUT: very bad things have happened: warn!
CUR TMP : very bad things have happened: warn!
CUR FUT: delete FUT (crash before flushing)
CUR : database is ok
TMP FUT: add TMP to memory and del FUT from memory
flush (revert to old state)
TMP : very bad things have happened: warn!
FUT: very bad things have happended: warn!
"""
state = {}
query = "SELECT id_bibrec,type FROM %sR WHERE id_bibrec BETWEEN '%d' AND '%d'"\
% (self.tablename[:-1], low, high)
res = run_sql(query)
for row in res:
if not state.has_key(row[0]):
state[row[0]]=[]
state[row[0]].append(row[1])
ok = 1 # will hold info on whether we will be able to repair
for recID in state.keys():
if not 'TEMPORARY' in state[recID]:
if 'FUTURE' in state[recID]:
if 'CURRENT' not in state[recID]:
write_message("EMERGENCY: Record %d is in inconsistent state. Can't repair it" % recID)
ok = 0
else:
write_message("EMERGENCY: Inconsistency in record %d detected" % recID)
query = """DELETE FROM %sR
WHERE id_bibrec='%d'""" % (self.tablename[:-1], recID)
run_sql(query)
write_message("EMERGENCY: Inconsistency in record %d repaired." % recID)
else:
if 'FUTURE' in state[recID] and not 'CURRENT' in state[recID]:
self.recIDs_in_mem.append([recID,recID])
# Get the words file
query = """SELECT type,termlist FROM %sR
WHERE id_bibrec='%d'""" % (self.tablename[:-1], recID)
if options["verbose"] >= 9:
write_message(query)
res = run_sql(query)
for row in res:
wlist = deserialize_via_marshal(row[1])
if options["verbose"] >= 9:
write_message("Words are %s " % wlist)
if row[0] == 'TEMPORARY':
sign = 1
else:
sign = -1
for word in wlist:
self.put(recID, word, sign)
else:
write_message("EMERGENCY: %s for %d is in inconsistent state. Couldn't repair it." % (self.tablename, recID))
ok = 0
if not ok:
write_message("""EMERGENCY: Unrepairable errors found. You should check consistency
of the %s - %sR tables. Deleting affected records is
recommended.""" % (self.tablename, self.tablename[:-1]))
raise StandardError
def task_run(row):
"""Run the indexing task. The row argument is the BibSched task
queue row, containing if, arguments, etc.
Return 1 in case of success and 0 in case of failure.
"""
global options, task_id, wordTables, stemmer, stopwords
# read from SQL row:
task_id = row[0]
task_proc = row[1]
options = loads(row[6])
task_status = row[7]
# sanity check:
if task_proc != "bibindex":
write_message("The task #%d does not seem to be a BibIndex task." % task_id, sys.stderr)
return 0
if task_status != "WAITING":
write_message("The task #%d is %s. I expected WAITING." % (task_id, task_status), sys.stderr)
return 0
# we can run the task now:
if options["verbose"]:
write_message("Task #%d started." % task_id)
task_starting_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
task_update_status("RUNNING")
# install signal handlers
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
## go ahead and treat each table :
for table in options["windex"]:
wordTable = WordTable(table.keys()[0], table.values()[0])
wordTable.report_on_table_consistency()
try:
if options["cmd"] == "del":
if options["id"]:
wordTable.del_recIDs(options["id"])
elif options["collection"]:
l_of_colls = string.split(options["collection"], ",")
recIDs = perform_request_search(c=l_of_colls)
recIDs_range = []
for recID in recIDs:
recIDs_range.append([recID,recID])
wordTable.del_recIDs(recIDs_range)
else:
write_message("Missing IDs of records to delete from index %s.", wordTable.tablename,
sys.stderr)
raise StandardError
elif options["cmd"] == "add":
if options["id"]:
wordTable.add_recIDs(options["id"])
elif options["collection"]:
l_of_colls = string.split(options["collection"], ",")
recIDs = perform_request_search(c=l_of_colls)
recIDs_range = []
for recID in recIDs:
recIDs_range.append([recID,recID])
wordTable.add_recIDs(recIDs_range)
else:
wordTable.add_recIDs_by_date(options["modified"])
# only update last_updated if run via automatic mode:
wordTable.update_last_updated(task_starting_time)
elif options["cmd"] == "repair":
wordTable.repair()
else:
write_message("Invalid command found processing %s" % \
wordTable.tablename, sys.stderr)
raise StandardError
except StandardError, e:
write_message("Exception caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
task_update_status("ERROR")
task_sig_stop_commands()
sys.exit(1)
wordTable.report_on_table_consistency()
# We are done. State it in the database, close and quit
task_update_status("DONE")
if options["verbose"]:
write_message("Task #%d finished." % task_id)
return 1
def command_line():
global options
long_flags =["add","del","id=","modified=","collection=", "windex=",
"check","repair","maxmem=", "flush=","user=","sleeptime=",
"time=","help", "version", "verbose="]
short_flags ="adi:m:c:w:krM:f:u:s:t:hVv:"
format_string = "%Y-%m-%d %H:%M:%S"
tables = None
sleeptime = ""
try:
opts, args = getopt.getopt(sys.argv[1:], short_flags, long_flags)
except getopt.GetoptError, err:
write_message(err, sys.stderr)
usage(1)
if args:
usage(1)
options={"cmd":"add", "id":[], "modified":[], "collection":[], "maxmem":0,
"flush":10000, "sleeptime":0, "verbose":1 }
sched_time = time.strftime(format_string)
user = ""
# Check for key options
try:
for opt in opts:
if opt == ("-h","") or opt == ("--help",""):
usage(1)
elif opt == ("-V","") or opt == ("--version",""):
print bibindex_engine_version
sys.exit(1)
elif opt[0] in ["--verbose", "-v"]:
options["verbose"] = int(opt[1])
elif opt == ("-a","") or opt == ("--add",""):
options["cmd"] = "add"
if ("-x","") in opts or ("--del","") in opts:
usage(1)
elif opt == ("-k","") or opt == ("--check",""):
options["cmd"] = "check"
elif opt == ("-r","") or opt == ("--repair",""):
options["cmd"] = "repair"
elif opt == ("-d","") or opt == ("--del",""):
options["cmd"]="del"
elif opt[0] in [ "-i", "--id" ]:
options["id"] = options["id"] + split_ranges(opt[1])
elif opt[0] in [ "-m", "--modified" ]:
options["modified"] = get_date_range(opt[1])
elif opt[0] in [ "-c", "--collection" ]:
options["collection"] = opt[1]
elif opt[0] in [ "-w", "--windex" ]:
tables = opt[1]
elif opt[0] in [ "-M", "--maxmem"]:
options["maxmem"]=int(opt[1])
if options["maxmem"] < base_process_size + 1000:
raise StandardError, "Memory usage should be higher than %d kB" % (base_process_size + 1000)
elif opt[0] in [ "-f", "--flush"]:
options["flush"]=int(opt[1])
elif opt[0] in [ "-u", "--user"]:
user = opt[1]
elif opt[0] in [ "-s", "--sleeptime" ]:
get_datetime(opt[1]) # see if it is a valid shift
sleeptime= opt[1]
elif opt[0] in [ "-t", "--time" ]:
sched_time= get_datetime(opt[1])
else: usage(1)
except StandardError, e:
write_message(e, sys.stderr)
sys.exit(1)
options["windex"]=get_word_tables(tables)
if options["cmd"] == "check":
for table in options["windex"]:
wordTable = WordTable(table.keys()[0], table.values()[0])
wordTable.report_on_table_consistency()
return
user = authenticate(user)
if options["verbose"] >= 9:
print ""
write_message("storing task options %s\n" % options)
new_task_id = run_sql("""INSERT INTO schTASK (proc,user,runtime,sleeptime,arguments,status)
VALUES ('bibindex',%s,%s,%s,%s,'WAITING')""",
(user, sched_time, sleeptime, dumps(options)))
print "Task #%d was successfully scheduled for execution." % new_task_id
return
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("stopping...")
task_update_status("STOPPING")
errcode = 0
try:
task_sig_stop_commands()
write_message("stopped")
task_update_status("STOPPED")
except StandardError, err:
write_message("Error during stopping! %e" % err)
task_update_status("STOPPINGFAILED")
errcode = 1
sys.exit(errcode)
def task_sig_stop_commands():
"""Do all the commands necessary to stop the task before quitting.
Useful for task_sig_stop() handler.
"""
write_message("stopping commands started")
for table in wordTables:
table.put_into_db()
write_message("stopping commands ended")
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task progress to %s." % msg)
return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, task_id))
def task_update_status(val):
"""Updates state information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task status to %s." % val)
return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, task_id))
def test_fulltext_indexing():
"""Tests fulltext indexing programs on PDF, PS, DOC, PPT,
XLS. Prints list of words and word table on the screen. Does not
integrate anything into the database. Useful when debugging
problems with fulltext indexing: call this function instead of main().
"""
options = {}
options["verbose"] = 9
print get_words_from_fulltext("http://doc.cern.ch/cgi-bin/setlink?base=atlnot&categ=Communication&id=com-indet-2002-012") # protected URL
print get_words_from_fulltext("http://doc.cern.ch/cgi-bin/setlink?base=agenda&categ=a00388&id=a00388s2t7") # XLS
print get_words_from_fulltext("http://doc.cern.ch/cgi-bin/setlink?base=agenda&categ=a02883&id=a02883s1t6/transparencies") # PPT
print get_words_from_fulltext("http://doc.cern.ch/cgi-bin/setlink?base=agenda&categ=a99149&id=a99149s1t10/transparencies") # DOC
print get_words_from_fulltext("http://doc.cern.ch/cgi-bin/setlink?base=preprint&categ=cern&id=lhc-project-report-601") # PDF
sys.exit(0)
def test_word_separators(phrase="hep-th/0101001"):
"""Tests word separating policy on various input."""
print "%s:" % phrase
for word in get_words_from_phrase(phrase):
print "\t-> %s" % word
def main():
"""Reads arguments and either runs the task, or starts user-interface (command line)."""
if len(sys.argv) == 2:
try:
id = int(sys.argv[1])
except StandardError, err:
command_line()
sys.exit()
res = run_sql("SELECT * FROM schTASK WHERE id='%d'" % (id), None, 1)
if not res:
write_message("Selected task not found.", sys.stderr)
sys.exit(1)
try:
if not task_run(res[0]):
write_message("Error occurred. Exiting.", sys.stderr)
except StandardError, e:
write_message("Unexpected error occurred: %s." % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
write_message("Exiting.")
task_update_status("ERROR")
else:
command_line()
diff --git a/modules/bibindex/lib/bibindex_engine_config.py b/modules/bibindex/lib/bibindex_engine_config.py
index 5280d07db..568db1093 100644
--- a/modules/bibindex/lib/bibindex_engine_config.py
+++ b/modules/bibindex/lib/bibindex_engine_config.py
@@ -1,66 +1,66 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
BibIndex indexing engine configuration parameters.
"""
## configuration parameters read from the general config file:
from cdsware.config import cfg_bibindex_fulltext_index_local_files_only, \
cfg_bibindex_stemmer_default_language, \
cfg_bibindex_remove_stopwords, \
cfg_bibindex_path_to_stopwords_file, \
cfg_bibindex_chars_alphanumeric_separators, \
cfg_bibindex_chars_punctuation, \
cfg_bibindex_remove_html_markup, \
cfg_bibindex_min_word_length, \
cfg_bibindex_urlopener_username, \
cfg_bibindex_urlopener_password, \
version, \
pdftotext, \
pstotext, \
pstoascii, \
antiword, \
catdoc, \
wvtext, \
ppthtml, \
xlhtml, \
htmltotext, \
gzip
## version number:
bibindex_engine_version = "CDSware/%s bibindex/%s" % (version, version)
## programs used to convert fulltext files to text:
conv_programs = {#"ps": [pstotext,pstoascii], # switched off at the moment, since PDF is faster
#"ps.gz": [pstotext,pstoascii],
"pdf": [pdftotext,pstotext,pstoascii],
"doc": [antiword,catdoc,wvtext],
"ppt": [ppthtml],
"xls": [xlhtml]}
## helper programs used if the above programs convert only to html or other intermediate file formats:
conv_programs_helpers = {"html": htmltotext,
"gz": gzip}
## safety parameters concerning MySQL thread-multiplication problem:
cfg_check_mysql_threads = 0 # to check or not to check the problem?
cfg_max_mysql_threads = 50 # how many threads (connections) we consider as still safe
cfg_mysql_thread_timeout = 20 # we'll kill threads that were sleeping for more than X seconds
diff --git a/modules/bibindex/lib/bibindex_engine_stemmer.py b/modules/bibindex/lib/bibindex_engine_stemmer.py
index 7275fd752..ffd7b0c4a 100644
--- a/modules/bibindex/lib/bibindex_engine_stemmer.py
+++ b/modules/bibindex/lib/bibindex_engine_stemmer.py
@@ -1,49 +1,49 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.bibindex_engine_config import *
def create_stemmers():
"""Create stemmers dictionary for all possible languages."""
languages = {'fr': 'french', 'en': 'english', 'no':'norwegian', 'sv':'swedish', 'de': 'german', 'it':'italian', 'pt':'portuguese'}
stemmers = {}
try:
import Stemmer
for (key, value) in languages.iteritems():
stemmers[key] = Stemmer.Stemmer(value)
except ImportError:
pass # PyStemmer isn't available
return stemmers
stemmers = create_stemmers()
def is_stemmer_available_for_language(lang):
"""Return true if stemmer for language LANG is available.
Return false otherwise.
"""
return stemmers.has_key(lang)
def stem(word, lang=cfg_bibindex_stemmer_default_language):
"""Return WORD stemmed according to language LANG (e.g. 'en')."""
if lang and is_stemmer_available_for_language(lang):
return stemmers[lang].stem(word)
else:
return word
diff --git a/modules/bibindex/lib/bibindex_engine_stemmer_tests.py b/modules/bibindex/lib/bibindex_engine_stemmer_tests.py
index e20fa7a82..aedac170e 100644
--- a/modules/bibindex/lib/bibindex_engine_stemmer_tests.py
+++ b/modules/bibindex/lib/bibindex_engine_stemmer_tests.py
@@ -1,47 +1,47 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the indexing engine."""
__version__ = "$Id$"
import unittest
from cdsware import bibindex_engine_stemmer
class TestStemmer(unittest.TestCase):
"""Test stemming, if available."""
def test_stemmer_none(self):
"""bibindex engine - no stemmer"""
self.assertEqual("information",
bibindex_engine_stemmer.stem("information", None))
def test_stemmer_english(self):
"""bibindex engine - English stemmer"""
self.assertEqual("inform",
bibindex_engine_stemmer.stem("information", "en"))
def create_test_suite():
"""Return test suite for the indexing engine."""
return unittest.TestSuite((unittest.makeSuite(TestStemmer,'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibindex/lib/bibindex_engine_stopwords.py b/modules/bibindex/lib/bibindex_engine_stopwords.py
index 131dea438..01d55e882 100644
--- a/modules/bibindex/lib/bibindex_engine_stopwords.py
+++ b/modules/bibindex/lib/bibindex_engine_stopwords.py
@@ -1,51 +1,51 @@
## $Id$
## BibIndex stopwords facility.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import string
from cdsware.bibindex_engine_config import *
def create_stopwords(filename=cfg_bibindex_path_to_stopwords_file):
"""Create stopword dictionary out of FILENAME."""
try:
filename = open(filename, 'r')
except:
return {}
lines = filename.readlines()
filename.close()
stopdict = {}
for line in lines:
stopdict[string.rstrip(line)] = 1
return stopdict
stopwords = create_stopwords()
def is_stopword(word, force_check=0):
"""Return true if WORD is found among stopwords, false otherwise.
Also, return false if BibIndex wasn't configured to use
stopwords. However, if FORCE_CHECK is set to 1, then do not
pay attention to whether the admin disabled stopwords
functionality, but look up the word anyway. This mode is
useful for ranking.
"""
# note: input word is assumed to be in lowercase
if (cfg_bibindex_remove_stopwords or force_check) and stopwords.has_key(word):
return True
return False
diff --git a/modules/bibindex/lib/bibindex_engine_tests.py b/modules/bibindex/lib/bibindex_engine_tests.py
index aeaa81e4f..cec82ffbd 100644
--- a/modules/bibindex/lib/bibindex_engine_tests.py
+++ b/modules/bibindex/lib/bibindex_engine_tests.py
@@ -1,42 +1,42 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the indexing engine."""
__version__ = "$Id$"
import unittest
from cdsware import bibindex_engine
class TestListSetOperations(unittest.TestCase):
"""Test list set operations."""
def test_list_union(self):
"""bibindex engine - list union"""
self.assertEqual([1,2,3,4], bibindex_engine.list_union([1,2,3],[1,3,4]))
def create_test_suite():
"""Return test suite for the indexing engine."""
return unittest.TestSuite((unittest.makeSuite(TestListSetOperations,'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibindex/lib/bibindexadminlib.py b/modules/bibindex/lib/bibindexadminlib.py
index 17143ef24..274213e91 100644
--- a/modules/bibindex/lib/bibindexadminlib.py
+++ b/modules/bibindex/lib/bibindexadminlib.py
@@ -1,1651 +1,1651 @@
## $Id$
## Administrator interface for BibIndex
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibIndex Administrator Interface."""
import cgi
import re
import MySQLdb
import Numeric
import os
import urllib
import time
import random
from zlib import compress,decompress
from mod_python import apache
from cdsware.bibrankadminlib import write_outcome,modify_translations,get_def_name,get_i8n_name,get_name,get_rnk_nametypes,get_languages,check_user,is_adminuser,adderrorbox,addadminbox,tupletotable,tupletotable_onlyselected,addcheckboxes,createhiddenform,serialize_via_numeric_array_dumps,serialize_via_numeric_array_compr,serialize_via_numeric_array_escape,serialize_via_numeric_array,deserialize_via_numeric_array,serialize_via_marshal,deserialize_via_marshal
from cdsware.dbquery import run_sql
from cdsware.config import *
from cdsware.webpage import page, pageheaderonly, pagefooteronly
from cdsware.webuser import getUid, get_email
from cdsware.search_engine import nice_number
__version__ = "$Id$"
def getnavtrail(previous = ''):
"""Get the navtrail"""
navtrail = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/bibindex/">BibIndex Admin</a> """ % (weburl, weburl)
navtrail = navtrail + previous
return navtrail
def perform_index(ln=cdslang, mtype='', content=''):
"""start area for modifying indexes
mtype - the method that called this method.
content - the output from that method."""
fin_output = """
<table>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/index?ln=%s">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/index?ln=%s&amp;mtype=perform_showindexoverview#1">Overview of indexes</a></small></td>
<td>2.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/index?ln=%s&amp;mtype=perform_editindexes#2">Edit index</a></small></td>
<td>3.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/index?ln=%s&amp;mtype=perform_addindex#3">Add new index</a></small></td>
</tr>
</table>
""" % (weburl, ln, weburl, ln, weburl, ln, weburl, ln)
if mtype == "perform_showindexoverview" and content:
fin_output += content
elif mtype == "perform_showindexoverview" or not mtype:
fin_output += perform_showindexoverview(ln, callback='')
if mtype == "perform_editindexes" and content:
fin_output += content
elif mtype == "perform_editindexes" or not mtype:
fin_output += perform_editindexes(ln, callback='')
if mtype == "perform_addindex" and content:
fin_output += content
elif mtype == "perform_addindex" or not mtype:
fin_output += perform_addindex(ln, callback='')
return addadminbox("<b>Menu</b>", [fin_output])
def perform_field(ln=cdslang, mtype='', content=''):
"""Start area for modifying fields
mtype - the method that called this method.
content - the output from that method."""
fin_output = """
<table>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/field?ln=%s">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/field?ln=%s&amp;mtype=perform_showfieldoverview#1">Overview of logical fields</a></small></td>
<td>2.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/field?ln=%s&amp;mtype=perform_editfields#2">Edit logical field</a></small></td>
<td>3.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/field?ln=%s&amp;mtype=perform_addfield#3">Add new logical field</a></small></td>
</tr>
</table>
""" % (weburl, ln, weburl, ln, weburl, ln, weburl, ln)
if mtype == "perform_editfields" and content:
fin_output += content
elif mtype == "perform_editfields" or not mtype:
fin_output += perform_editfields(ln, callback='')
if mtype == "perform_addfield" and content:
fin_output += content
elif mtype == "perform_addfield" or not mtype:
fin_output += perform_addfield(ln, callback='')
if mtype == "perform_showfieldoverview" and content:
fin_output += content
elif mtype == "perform_showfieldoverview" or not mtype:
fin_output += perform_showfieldoverview(ln, callback='')
return addadminbox("<b>Menu</b>", [fin_output])
def perform_editfield(fldID, ln=cdslang, mtype='', content='', callback='yes', confirm=-1):
"""form to modify a field. this method is calling other methods which again is calling this and sending back the output of the method.
if callback, the method will call perform_editcollection, if not, it will just return its output.
fldID - id of the field
mtype - the method that called this method.
content - the output from that method."""
fld_dict = dict(get_def_name('', "field"))
if fldID in [-1, "-1"]:
return addadminbox("Edit logical field", ["""<b><span class="info">Please go back and select a logical field</span></b>"""])
fin_output = """
<table>
<tr>
<td><b>Menu</b></td>
</tr>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&amp;ln=%s">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&amp;ln=%s&amp;mtype=perform_modifyfield">Modify field code</a></small></td>
<td>2.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&amp;ln=%s&amp;mtype=perform_modifyfieldtranslations">Modify translations</a></small></td>
<td>3.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&amp;ln=%s&amp;mtype=perform_modifyfieldtags">Modify MARC tags</a></small></td>
<td>4.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&amp;ln=%s&amp;mtype=perform_deletefield">Delete field</a></small></td>
</tr><tr>
<td>5.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&amp;ln=%s&amp;mtype=perform_showdetailsfield">Show field usage</a></small></td>
</tr>
</table>
""" % (weburl, fldID, ln, weburl, fldID, ln, weburl, fldID, ln, weburl, fldID, ln, weburl, fldID, ln, weburl, fldID, ln)
if mtype == "perform_modifyfield" and content:
fin_output += content
elif mtype == "perform_modifyfield" or not mtype:
fin_output += perform_modifyfield(fldID, ln, callback='')
if mtype == "perform_modifyfieldtranslations" and content:
fin_output += content
elif mtype == "perform_modifyfieldtranslations" or not mtype:
fin_output += perform_modifyfieldtranslations(fldID, ln, callback='')
if mtype == "perform_modifyfieldtags" and content:
fin_output += content
elif mtype == "perform_modifyfieldtags" or not mtype:
fin_output += perform_modifyfieldtags(fldID, ln, callback='')
if mtype == "perform_deletefield" and content:
fin_output += content
elif mtype == "perform_deletefield" or not mtype:
fin_output += perform_deletefield(fldID, ln, callback='')
return addadminbox("Edit logical field '%s'" % fld_dict[int(fldID)], [fin_output])
def perform_editindex(idxID, ln=cdslang, mtype='', content='', callback='yes', confirm=-1):
"""form to modify a index. this method is calling other methods which again is calling this and sending back the output of the method.
idxID - id of the index
mtype - the method that called this method.
content - the output from that method."""
if idxID in [-1, "-1"]:
return addadminbox("Edit index", ["""<b><span class="info">Please go back and select a index</span></b>"""])
fin_output = """
<table>
<tr>
<td><b>Menu</b></td>
</tr>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s&amp;mtype=perform_modifyindex">Modify index name / descriptor</a></small></td>
<td>2.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s&amp;mtype=perform_modifyindextranslations">Modify translations</a></small></td>
<td>3.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s&amp;mtype=perform_modifyindexfields">Modify index fields</a></small></td>
<td>4.&nbsp;<small><a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s&amp;mtype=perform_deleteindex">Delete index</a></small></td>
</tr>
</table>
""" % (weburl, idxID, ln, weburl, idxID, ln, weburl, idxID, ln, weburl, idxID, ln, weburl, idxID, ln)
if mtype == "perform_modifyindex" and content:
fin_output += content
elif mtype == "perform_modifyindex" or not mtype:
fin_output += perform_modifyindex(idxID, ln, callback='')
if mtype == "perform_modifyindextranslations" and content:
fin_output += content
elif mtype == "perform_modifyindextranslations" or not mtype:
fin_output += perform_modifyindextranslations(idxID, ln, callback='')
if mtype == "perform_modifyindexfields" and content:
fin_output += content
elif mtype == "perform_modifyindexfields" or not mtype:
fin_output += perform_modifyindexfields(idxID, ln, callback='')
if mtype == "perform_deleteindex" and content:
fin_output += content
elif mtype == "perform_deleteindex" or not mtype:
fin_output += perform_deleteindex(idxID, ln, callback='')
return addadminbox("Edit index", [fin_output])
def perform_showindexoverview(ln=cdslang, callback='', confirm=0):
subtitle = """<a name="1"></a>1. Overview of indexes"""
output = """<table cellpadding="3" border="1">"""
output += """<tr><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td></tr>""" % ("ID", "Name", "Fwd.Idx Size", "Rev.Idx Size", "Fwd.Idx Words", "Rev.Idx Records", "Last updated", "Fields", "Translations")
idx = get_idx()
idx_dict = dict(get_def_name('', "idxINDEX"))
for idxID, idxNAME, idxDESC,idxUPD in idx:
table_status_forward = get_table_status('idxWORD%sF' % (idxID < 10 and '0%s' % idxID or idxID))
table_status_reverse = get_table_status('idxWORD%sR' % (idxID < 10 and '0%s' % idxID or idxID))
if str(idxUPD)[-3:] == ".00":
idxUPD = str(idxUPD)[0:-3]
lang = get_lang_list("idxINDEXNAME", "id_idxINDEX", idxID)
idx_fld = get_idx_fld(idxID)
fld = ""
for row in idx_fld:
fld += row[1] + ", "
if fld.endswith(", "):
fld = fld[:-2]
if len(fld) == 0:
fld = """<b><span class="info">None</span></b>"""
date = (idxUPD and idxUPD or """<b><span class="info">Not updated</span></b>""")
if table_status_forward and table_status_reverse:
output += """<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>""" % (idxID, """<a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s" title="%s">%s</A>""" % (weburl, idxID, ln, idxDESC, idx_dict.get(idxID, idxNAME)), "%s MB" % nice_number(table_status_forward[0][5] / 1048576), "%s MB" % nice_number(table_status_reverse[0][5] / 1048576), nice_number(table_status_forward[0][3]), nice_number(table_status_reverse[0][3]), date, fld, lang)
elif not table_status_forward:
output += """<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>""" % (idxID, """<a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s">%s</A>""" % (weburl, idxID, ln, idx_dict.get(idxID, idxNAME)), "Error", "%s MB" % nice_number(table_status_reverse[0][5] / 1048576),"Error", nice_number(table_status_reverse[0][3]), date, "", lang)
elif not table_status_reverse:
output += """<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>""" % (idxID, """<a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&amp;ln=%s">%s</A>""" % (weburl, idxID, ln, idx_dict.get(idxID, idxNAME)), "%s MB" % nice_number(table_status_forward[0][5] / 1048576), "Error", nice_number(table_status_forward[0][3]), "Error", date, "", lang)
output += "</table>"
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(fldID, ln, "perform_showindexoverview", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_editindexes(ln=cdslang, callback='yes', content='', confirm=-1):
"""show a list of indexes that can be edited."""
subtitle = """<a name="2"></a>2. Edit index&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % (weburl)
fin_output = ''
idx = get_idx()
output = ""
if len(idx) > 0:
text = """
<span class="adminlabel">Index name</span>
<select name="idxID" class="admin_w200">
<option value="-1">- Select a index -</option>
"""
for (idxID, idxNAME, idxDESC, idxUPD) in idx:
text += """<option value="%s">%s</option>""" % (idxID, idxNAME)
text += """</select>"""
output += createhiddenform(action="%s/admin/bibindex/bibindexadmin.py/editindex" % weburl,
text=text,
button="Edit",
ln=ln,
confirm=1)
else:
output += """No indexes exists"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(ln, "perform_editindexes", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_editfields(ln=cdslang, callback='yes', content='', confirm=-1):
"""show a list of all logical fields that can be edited."""
subtitle = """<a name="5"></a>5. Edit logical field&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % (weburl)
fin_output = ''
res = get_fld()
output = ""
if len(res) > 0:
text = """
<span class="adminlabel">Field name</span>
<select name="fldID" class="admin_w200">
<option value="-1">- Select a field -</option>
"""
for (fldID, name, code) in res:
text += """<option value="%s">%s</option>""" % (fldID, name)
text += """</select>"""
output += createhiddenform(action="%s/admin/bibindex/bibindexadmin.py/editfield" % weburl,
text=text,
button="Edit",
ln=ln,
confirm=1)
else:
output += """No logical fields exists"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_field(ln, "perform_editfields", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addindex(ln=cdslang, idxNAME='', callback="yes", confirm=-1):
"""form to add a new index.
idxNAME - the name of the new index"""
output = ""
subtitle = """<a name="3"></a>3. Add new index"""
text = """
<span class="adminlabel">Index name</span>
<input class="admin_w200" type="text" name="idxNAME" value="%s" /><br>
""" % idxNAME
output = createhiddenform(action="%s/admin/bibindex/bibindexadmin.py/addindex" % weburl,
text=text,
ln=ln,
button="Add index",
confirm=1)
if idxNAME and confirm in ["1", 1]:
res = add_idx(idxNAME)
output += write_outcome(res) + """<br><a href="%s/admin/bibindex/bibindexadmin.py/editindex?idxID=%s&ln=%s">Configure this index</a>.""" % (weburl, res[1], ln)
elif confirm not in ["-1", -1]:
output += """<b><span class="info">Please give the index a name.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(ln, "perform_addindex", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyindextranslations(idxID, ln=cdslang, sel_type='', trans=[], confirm=-1, callback='yes'):
"""Modify the translations of a index
sel_type - the nametype to modify
trans - the translations in the same order as the languages from get_languages()"""
output = ''
subtitle = ''
cdslangs = get_languages()
if confirm in ["2", 2] and idxID:
finresult = modify_translations(idxID, cdslangs, sel_type, trans, "idxINDEX")
idx_dict = dict(get_def_name('', "idxINDEX"))
if idxID and idx_dict.has_key(int(idxID)):
idxID = int(idxID)
subtitle = """<a name="2"></a>2. Modify translations for index.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % weburl
if type(trans) is str:
trans = [trans]
if sel_type == '':
sel_type = get_idx_nametypes()[0][0]
header = ['Language', 'Translation']
actions = []
types = get_idx_nametypes()
if len(types) > 1:
text = """
<span class="adminlabel">Name type</span>
<select name="sel_type" class="admin_w200">
"""
for (key, value) in types:
text += """<option value="%s" %s>%s""" % (key, key == sel_type and 'selected="selected"' or '', value)
trans_names = get_name(idxID, ln, key, "field")
if trans_names and trans_names[0][0]:
text += ": %s" % trans_names[0][0]
text += "</option>"
text += """</select>"""
output += createhiddenform(action="modifyindextranslations#2",
text=text,
button="Select",
idxID=idxID,
ln=ln,
confirm=0)
if confirm in [-1, "-1", 0, "0"]:
trans = []
for (key, value) in cdslangs:
try:
trans_names = get_name(idxID, key, sel_type, "idxINDEX")
trans.append(trans_names[0][0])
except StandardError, e:
trans.append('')
for nr in range(0,len(cdslangs)):
actions.append(["%s %s" % (cdslangs[nr][1], (cdslangs[nr][0]==cdslang and '<small>(def)</small>' or ''))])
actions[-1].append('<input type="text" name="trans" size="30" value="%s"/>' % trans[nr])
text = tupletotable(header=header, tuple=actions)
output += createhiddenform(action="modifyindextranslations#2",
text=text,
button="Modify",
idxID=idxID,
sel_type=sel_type,
ln=ln,
confirm=2)
if sel_type and len(trans):
if confirm in ["2", 2]:
output += write_outcome(finresult)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editindex(idxID, ln, "perform_modifyindextranslations", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyfieldtranslations(fldID, ln=cdslang, sel_type='', trans=[], confirm=-1, callback='yes'):
"""Modify the translations of a field
sel_type - the nametype to modify
trans - the translations in the same order as the languages from get_languages()"""
output = ''
subtitle = ''
cdslangs = get_languages()
if confirm in ["2", 2] and fldID:
finresult = modify_translations(fldID, cdslangs, sel_type, trans, "field")
fld_dict = dict(get_def_name('', "field"))
if fldID and fld_dict.has_key(int(fldID)):
fldID = int(fldID)
subtitle = """<a name="3"></a>3. Modify translations for logical field '%s'&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % (fld_dict[fldID], weburl)
if type(trans) is str:
trans = [trans]
if sel_type == '':
sel_type = get_fld_nametypes()[0][0]
header = ['Language', 'Translation']
actions = []
types = get_fld_nametypes()
if len(types) > 1:
text = """
<span class="adminlabel">Name type</span>
<select name="sel_type" class="admin_w200">
"""
for (key, value) in types:
text += """<option value="%s" %s>%s""" % (key, key == sel_type and 'selected="selected"' or '', value)
trans_names = get_name(fldID, ln, key, "field")
if trans_names and trans_names[0][0]:
text += ": %s" % trans_names[0][0]
text += "</option>"
text += """</select>"""
output += createhiddenform(action="modifyfieldtranslations#3",
text=text,
button="Select",
fldID=fldID,
ln=ln,
confirm=0)
if confirm in [-1, "-1", 0, "0"]:
trans = []
for (key, value) in cdslangs:
try:
trans_names = get_name(fldID, key, sel_type, "field")
trans.append(trans_names[0][0])
except StandardError, e:
trans.append('')
for nr in range(0,len(cdslangs)):
actions.append(["%s %s" % (cdslangs[nr][1], (cdslangs[nr][0]==cdslang and '<small>(def)</small>' or ''))])
actions[-1].append('<input type="text" name="trans" size="30" value="%s"/>' % trans[nr])
text = tupletotable(header=header, tuple=actions)
output += createhiddenform(action="modifyfieldtranslations#3",
text=text,
button="Modify",
fldID=fldID,
sel_type=sel_type,
ln=ln,
confirm=2)
if sel_type and len(trans):
if confirm in ["2", 2]:
output += write_outcome(finresult)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editfield(fldID, ln, "perform_modifytranslations", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_showdetailsfieldtag(fldID, tagID, ln=cdslang, callback="yes", confirm=-1):
"""form to add a new field.
fldNAME - the name of the new field
code - the field code"""
fld_dict = dict(get_def_name('', "field"))
fldID = int(fldID)
tagname = run_sql("SELECT name from tag where id=%s" % tagID)[0][0]
output = ""
subtitle = """<a name="4.1"></a>Showing details for MARC tag '%s'""" % tagname
output += "<br><b>This MARC tag is used directly in these logical fields:</b>&nbsp;"
fld_tag = get_fld_tags('', tagID)
exist = {}
for (id_field,id_tag, tname, tvalue, score) in fld_tag:
output += "%s, " % fld_dict[int(id_field)]
exist[id_field] = 1
output += "<br><b>This MARC tag is used indirectly in these logical fields:</b>&nbsp;"
tag = run_sql("SELECT value from tag where id=%s" % id_tag)
tag = tag[0][0]
for i in range(0, len(tag) - 1):
res = run_sql("SELECT id_field,id_tag FROM field_tag,tag WHERE tag.id=field_tag.id_tag AND tag.value='%s%%'" % tag[0:i])
for (id_field, id_tag) in res:
output += "%s, " % fld_dict[int(id_field)]
exist[id_field] = 1
res = run_sql("SELECT id_field,id_tag FROM field_tag,tag WHERE tag.id=field_tag.id_tag AND tag.value like '%s'" % tag)
for (id_field, id_tag) in res:
if not exist.has_key(id_field):
output += "%s, " % fld_dict[int(id_field)]
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyfieldtags(fldID, ln, "perform_showdetailsfieldtag", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_showdetailsfield(fldID, ln=cdslang, callback="yes", confirm=-1):
"""form to add a new field.
fldNAME - the name of the new field
code - the field code"""
fld_dict = dict(get_def_name('', "field"))
col_dict = dict(get_def_name('', "collection"))
fldID = int(fldID)
col_fld = get_col_fld('', '', fldID)
sort_types = dict(get_sort_nametypes())
fin_output = ""
subtitle = """<a name="1"></a>5. Show usage for logical field '%s'""" % fld_dict[fldID]
output = "This logical field is used in these collections:<br>"
ltype = ''
exist = {}
for (id_collection, id_field, id_fieldvalue, ftype, score, score_fieldvalue) in col_fld:
if ltype != ftype:
output += "<br><b>%s:&nbsp;</b>" % sort_types[ftype]
ltype = ftype
exist = {}
if not exist.has_key(id_collection):
output += "%s, " % col_dict[int(id_collection)]
exist[id_collection] = 1
if not col_fld:
output = "This field is not used by any collections."
fin_output = addadminbox('Collections', [output])
try:
body = [fin_output, extra]
except NameError:
body = [fin_output]
if callback:
return perform_editfield(ln, "perform_showdetailsfield", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addfield(ln=cdslang, fldNAME='', code='', callback="yes", confirm=-1):
"""form to add a new field.
fldNAME - the name of the new field
code - the field code"""
output = ""
subtitle = """<a name="6"></a>6. Add new logical field"""
code = str.replace(code,' ', '')
text = """
<span class="adminlabel">Field name</span>
<input class="admin_w200" type="text" name="fldNAME" value="%s" /><br>
<span class="adminlabel">Field code</span>
<input class="admin_w200" type="text" name="code" value="%s" /><br>
""" % (fldNAME, code)
output = createhiddenform(action="%s/admin/bibindex/bibindexadmin.py/addfield" % weburl,
text=text,
ln=ln,
button="Add field",
confirm=1)
if fldNAME and code and confirm in ["1", 1]:
res = add_fld(fldNAME, code)
output += write_outcome(res)
elif confirm not in ["-1", -1]:
output += """<b><span class="info">Please give the logical field a name and code.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_field(ln, "perform_addfield", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_deletefield(fldID, ln=cdslang, callback='yes', confirm=0):
"""form to remove a field.
fldID - the field id from table field.
"""
fld_dict = dict(get_def_name('', "field"))
if not fld_dict.has_key(int(fldID)):
return """<b><span class="info">Field does not exist</span></b>"""
subtitle = """<a name="4"></a>4. Delete the logical field '%s'&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % (fld_dict[int(fldID)], weburl)
output = ""
if fldID:
fldID = int(fldID)
if confirm in ["0", 0]:
check = run_sql("SELECT * from idxINDEX_field where id_field=%s" % fldID)
text = ""
if check:
text += """<b><span class="info">This field is used in an index, deletion may cause problems.</span></b><br>"""
text += """Do you want to delete the logical field '%s' and all its relations and definitions.""" % (fld_dict[fldID])
output += createhiddenform(action="deletefield#4",
text=text,
button="Confirm",
fldID=fldID,
confirm=1)
elif confirm in ["1", 1]:
res = delete_fld(fldID)
if res[0] == 1:
return """<br><b><span class="info">Field deleted.</span></b>""" + write_outcome(res)
else:
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editfield(fldID, ln, "perform_deletefield", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_deleteindex(idxID, ln=cdslang, callback='yes', confirm=0):
"""form to delete an index.
idxID - the index id from table idxINDEX.
"""
if idxID:
subtitle = """<a name="4"></a>4. Delete the index.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % weburl
output = ""
if confirm in ["0", 0]:
idx = get_idx(idxID)
if idx:
text = ""
text += """<b><span class="info">By deleting an index, you may also loose any indexed data in the forward and reverse table for this index.</span></b><br>"""
text += """Do you want to delete the index '%s' and all its relations and definitions.""" % (idx[0][1])
output += createhiddenform(action="deleteindex#5",
text=text,
button="Confirm",
idxID=idxID,
confirm=1)
else:
return """<br><b><span class="info">Index specified does not exist.</span></b>"""
elif confirm in ["1", 1]:
res = delete_idx(idxID)
if res[0] == 1:
return """<br><b><span class="info">Index deleted.</span></b>""" + write_outcome(res)
else:
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editindex(idxID, ln, "perform_deleteindex", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_showfieldoverview(ln=cdslang, callback='', confirm=0):
subtitle = """<a name="4"></a>4. Logical fields overview"""
output = """<table cellpadding="3" border="1">"""
output += """<tr><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td></tr>""" % ("Field", "MARC Tags", "Translations")
query = "SELECT id,name FROM field"
res = run_sql(query)
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
for field_id,field_name in res:
query = "SELECT tag.value FROM tag, field_tag WHERE tag.id=field_tag.id_tag AND field_tag.id_field=%d ORDER BY field_tag.score DESC,tag.value ASC" % field_id
res = run_sql(query)
field_tags = ""
for row in res:
field_tags = field_tags + row[0] + ", "
if field_tags.endswith(", "):
field_tags = field_tags[:-2]
if not field_tags:
field_tags = """<b><span class="info">None</span></b>"""
lang = get_lang_list("fieldname", "id_field", field_id)
output += """<tr><td>%s</td><td>%s</td><td>%s</td></tr>""" % ("""<a href="%s/admin/bibindex/bibindexadmin.py/editfield?fldID=%s&ln=%s">%s</A>""" % (weburl, field_id, ln, fld_dict[field_id]), field_tags, lang)
output += "</table>"
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_field(fldID, ln, "perform_showfieldoverview", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyindex(idxID, ln=cdslang, idxNAME='', idxDESC='', callback='yes', confirm=-1):
"""form to modify an index name.
idxID - the index name to change.
idxNAME - new name of index
idxDESC - description of index content"""
subtitle = ""
output = ""
if idxID not in [-1, "-1"]:
subtitle = """<a name="2"></a>1. Modify index name.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % weburl
if confirm in [-1, "-1"]:
idx = get_idx(idxID)
idxNAME = idx[0][1]
idxDESC = idx[0][2]
text = """
<span class="adminlabel">Index name</span>
<input class="admin_w200" type="text" name="idxNAME" value="%s" /><br>
<span class="adminlabel">Index description</span>
<textarea class="admin_w200" name="idxDESC">%s</textarea><br>
""" % (idxNAME, idxDESC)
output += createhiddenform(action="modifyindex#1",
text=text,
button="Modify",
idxID=idxID,
ln=ln,
confirm=1)
if idxID > -1 and idxNAME and confirm in [1, "1"]:
res = modify_idx(idxID, idxNAME, idxDESC)
output += write_outcome(res)
elif confirm in [1, "1"]:
output += """<br><b><span class="info">Please give a name for the index.</span></b>"""
else:
output = """No index to modify."""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editindex(idxID, ln, "perform_modifyindex", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyfield(fldID, ln=cdslang, code='', callback='yes', confirm=-1):
"""form to modify a field.
fldID - the field to change."""
subtitle = ""
output = ""
fld_dict = dict(get_def_name('', "field"))
if fldID not in [-1, "-1"]:
if confirm in [-1, "-1"]:
res = get_fld(fldID)
code = res[0][2]
else:
code = str.replace("%s" % code, " ", "")
fldID = int(fldID)
subtitle = """<a name="2"></a>1. Modify field code for logical field '%s'&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % (fld_dict[int(fldID)], weburl)
text = """
<span class="adminlabel">Field code</span>
<input class="admin_w200" type="text" name="code" value="%s" /><br>
""" % code
output += createhiddenform(action="modifyfield#2",
text=text,
button="Modify",
fldID=fldID,
ln=ln,
confirm=1)
if fldID > -1 and confirm in [1, "1"]:
fldID = int(fldID)
res = modify_fld(fldID, code)
output += write_outcome(res)
else:
output = """No field to modify.
"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editfield(fldID, ln, "perform_modifyfield", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyindexfields(idxID, ln=cdslang, callback='yes', content='', confirm=-1):
"""Modify which logical fields to use in this index.."""
output = ''
subtitle = """<a name="3"></a>3. Modify index fields.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % weburl
output = """<dl>
<dt>Menu</dt>
<dd><a href="%s/admin/bibindex/bibindexadmin.py/addindexfield?idxID=%s&amp;ln=%s#3.1">Add field to index</a></dd>
<dd><a href="%s/admin/bibindex/bibindexadmin.py/field?ln=%s">Manage fields</a></dd>
</dl>
""" % (weburl, idxID, ln, weburl, ln)
header = ['Field', '']
actions = []
idx_fld = get_idx_fld(idxID)
if len(idx_fld) > 0:
for (idxID, idxNAME,fldID, fldNAME, regexp_punct, regexp_alpha_sep) in idx_fld:
actions.append([fldNAME])
for col in [(('Remove','removeindexfield'),)]:
actions[-1].append('<a href="%s/admin/bibindex/bibindexadmin.py/%s?idxID=%s&amp;fldID=%s&amp;ln=%s#3.1">%s</a>' % (weburl, col[0][1], idxID, fldID, ln, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/bibindex/bibindexadmin.py/%s?fldID=%s&amp;flID=%s&amp;ln=%s#4.1">%s</a>' % (weburl, function, idxID, fldID, ln, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No index fields exists"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editindex(idxID, ln, "perform_modifyindexfields", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyfieldtags(fldID, ln=cdslang, callback='yes', content='', confirm=-1):
"""show the sort fields of this collection.."""
output = ''
fld_dict = dict(get_def_name('', "field"))
fld_type = get_fld_nametypes()
fldID = int(fldID)
subtitle = """<a name="4"></a>3. Modify MARC tags for the logical field '%s'&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/bibindex/guide.html">?</a>]</small>""" % (fld_dict[int(fldID)], weburl)
output = """<dl>
<dt>Menu</dt>
<dd><a href="%s/admin/bibindex/bibindexadmin.py/addtag?fldID=%s&amp;ln=%s#4.1">Add MARC tag</a></dd>
<dd><a href="%s/admin/bibindex/bibindexadmin.py/deletetag?fldID=%s&amp;ln=%s#4.1">Delete unused MARC tags</a></dd>
</dl>
""" % (weburl, fldID, ln, weburl, fldID, ln)
header = ['', 'Value', 'Comment', 'Actions']
actions = []
res = get_fld_tags(fldID)
if len(res) > 0:
i = 0
for (fldID, tagID, tname, tvalue, score) in res:
move = ""
if i != 0:
move += """<a href="%s/admin/bibindex/bibindexadmin.py/switchtagscore?fldID=%s&amp;id_1=%s&amp;id_2=%s&amp;ln=%s&amp=rand=%s#4"><img border="0" src="%s/img/smallup.gif" title="Move tag up"></a>""" % (weburl, fldID, tagID, res[i - 1][1], ln, random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;"
i += 1
if i != len(res):
move += '<a href="%s/admin/bibindex/bibindexadmin.py/switchtagscore?fldID=%s&amp;id_1=%s&amp;id_2=%s&amp;ln=%s&amp;rand=%s#4"><img border="0" src="%s/img/smalldown.gif" title="Move tag down"></a>' % (weburl, fldID, tagID, res[i][1], ln, random.randint(0, 1000), weburl)
actions.append([move, tvalue, tname])
for col in [(('Details','showdetailsfieldtag'), ('Modify','modifytag'),('Remove','removefieldtag'),)]:
actions[-1].append('<a href="%s/admin/bibindex/bibindexadmin.py/%s?fldID=%s&amp;tagID=%s&amp;ln=%s#4.1">%s</a>' % (weburl, col[0][1], fldID, tagID, ln, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/bibindex/bibindexadmin.py/%s?fldID=%s&amp;tagID=%s&amp;ln=%s#4.1">%s</a>' % (weburl, function, fldID, tagID, ln, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No fields exists"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editfield(fldID, ln, "perform_modifyfieldtags", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addtag(fldID, ln=cdslang, value=['',-1], name='', callback="yes", confirm=-1):
"""form to add a new field.
fldNAME - the name of the new field
code - the field code"""
output = ""
subtitle = """<a name="4.1"></a>Add MARC tag to logical field"""
text = """
Add new tag:<br>
<span class="adminlabel">Tag value</span>
<input class="admin_w200" maxlength="6" type="text" name="value" value="%s" /><br>
<span class="adminlabel">Tag comment</span>
<input class="admin_w200" type="text" name="name" value="%s" /><br>
""" % ((name=='' and value[0] or name), value[0])
text += """Or existing tag:<br>
<span class="adminlabel">Tag</span>
<select name="value" class="admin_w200">
<option value="-1">- Select a tag -</option>
"""
fld_tags = get_fld_tags(fldID)
tags = get_tags()
fld_tags = dict(map(lambda x: (x[1], x[0]), fld_tags))
for (id_tag, tname, tvalue) in tags:
if not fld_tags.has_key(id_tag):
text += """<option value="%s" %s>%s</option>""" % (tvalue, (tvalue==value[1] and 'selected="selected"' or ''), "%s - %s" % (tvalue, tname))
text += """</select>"""
output = createhiddenform(action="%s/admin/bibindex/bibindexadmin.py/addtag" % weburl,
text=text,
fldID=fldID,
ln=ln,
button="Add tag",
confirm=1)
if (value[0] and value[1] in [-1, "-1"]) or (not value[0] and value[1] not in [-1, "-1"]):
if confirm in ["1", 1]:
res = add_fld_tag(fldID, name, (value[0] !='' and value[0] or value[1]))
output += write_outcome(res)
elif confirm not in ["-1", -1]:
output += """<b><span class="info">Please choose to add either a new or an existing MARC tag, but not both.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyfieldtags(fldID, ln, "perform_addtag", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifytag(fldID, tagID, ln=cdslang, name='', value='', callback='yes', confirm=-1):
"""form to modify a field.
fldID - the field to change."""
subtitle = ""
output = ""
fld_dict = dict(get_def_name('', "field"))
fldID = int(fldID)
tagID = int(tagID)
tag = get_tags(tagID)
if confirm in [-1, "-1"] and not value and not name:
name = tag[0][1]
value = tag[0][2]
subtitle = """<a name="3.1"></a>Modify MARC tag"""
text = """
Any modifications will apply to all logical fields using this tag.<br>
<span class="adminlabel">Tag value</span>
<input class="admin_w200" type="text" name="value" value="%s" /><br>
<span class="adminlabel">Comment</span>
<input class="admin_w200" type="text" name="name" value="%s" /><br>
""" % (value, name)
output += createhiddenform(action="modifytag#4.1",
text=text,
button="Modify",
fldID=fldID,
tagID=tagID,
ln=ln,
confirm=1)
if name and value and confirm in [1, "1"]:
res = modify_tag(tagID, name, value)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyfieldtags(fldID, ln, "perform_modifytag", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_removefieldtag(fldID, tagID, ln=cdslang, callback='yes', confirm=0):
"""form to remove a tag from a field.
fldID - the current field, remove the tag from this field.
tagID - remove the tag with this id"""
subtitle = """<a name="4.1"></a>Remove MARC tag from logical field"""
output = ""
fld_dict = dict(get_def_name('', "field"))
if fldID and tagID:
fldID = int(fldID)
tagID = int(tagID)
tag = get_fld_tags(fldID, tagID)
if confirm not in ["1", 1]:
text = """Do you want to remove the tag '%s - %s ' from the field '%s'.""" % (tag[0][3], tag[0][2], fld_dict[fldID])
output += createhiddenform(action="removefieldtag#4.1",
text=text,
button="Confirm",
fldID=fldID,
tagID=tagID,
confirm=1)
elif confirm in ["1", 1]:
res = remove_fldtag(fldID, tagID)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyfieldtags(fldID, ln, "perform_removefieldtag", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addindexfield(idxID, ln=cdslang, fldID='', callback="yes", confirm=-1):
"""form to add a new field.
fldNAME - the name of the new field
code - the field code"""
output = ""
subtitle = """<a name="4.1"></a>Add logical field to index"""
text = """
<span class="adminlabel">Field name</span>
<select name="fldID" class="admin_w200">
<option value="-1">- Select a field -</option>
"""
fld = get_fld()
for (fldID2, fldNAME, fldCODE) in fld:
text += """<option value="%s" %s>%s</option>""" % (fldID2, (fldID==fldID2 and 'selected="selected"' or ''), fldNAME)
text += """</select>"""
output = createhiddenform(action="%s/admin/bibindex/bibindexadmin.py/addindexfield" % weburl,
text=text,
idxID=idxID,
ln=ln,
button="Add field",
confirm=1)
if fldID and not fldID in [-1, "-1"] and confirm in ["1", 1]:
res = add_idx_fld(idxID, fldID)
output += write_outcome(res)
elif confirm in ["1", 1]:
output += """<b><span class="info">Please select a field to add.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyindexfields(idxID, ln, "perform_addindexfield", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_removeindexfield(idxID, fldID, ln=cdslang, callback='yes', confirm=0):
"""form to remove a field from an index.
idxID - the current index, remove the field from this index.
fldID - remove the field with this id"""
subtitle = """<a name="3.1"></a>Remove field from index"""
output = ""
if fldID and idxID:
fldID = int(fldID)
idxID = int(idxID)
fld = get_fld(fldID)
idx = get_idx(idxID)
if fld and idx and confirm not in ["1", 1]:
text = """Do you want to remove the field '%s' from the index '%s'.""" % (fld[0][1], idx[0][1])
output += createhiddenform(action="removeindexfield#3.1",
text=text,
button="Confirm",
idxID=idxID,
fldID=fldID,
confirm=1)
elif confirm in ["1", 1]:
res = remove_idxfld(idxID, fldID)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyindexfields(idxID, ln, "perform_removeindexfield", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_switchtagscore(fldID, id_1, id_2, ln=cdslang):
"""Switch the score of id_1 and id_2 in the table type.
colID - the current collection
id_1/id_2 - the id's to change the score for.
type - like "format" """
output = ""
name_1 = run_sql("select name from tag where id=%s" % id_1)[0][0]
name_2 = run_sql("select name from tag where id=%s" % id_2)[0][0]
res = switch_score(fldID, id_1, id_2)
output += write_outcome(res)
return perform_modifyfieldtags(fldID, ln, content=output)
def perform_deletetag(fldID, ln=cdslang, tagID=-1, callback='yes', confirm=-1):
"""form to delete an MARC tag not in use.
fldID - the collection id of the current collection.
fmtID - the format id to delete."""
subtitle = """<a name="10.3"></a>Delete an unused MARC tag"""
output = """
<dl>
<dd>Deleting an MARC tag will also delete the translations associated.</dd>
</dl>
"""
fldID = int(fldID)
if tagID not in [-1," -1"] and confirm in [1, "1"]:
ares = delete_tag(tagID)
fld_tag = get_fld_tags()
fld_tag = dict(map(lambda x: (x[1], x[0]), fld_tag))
tags = get_tags()
text = """
<span class="adminlabel">MARC tag</span>
<select name="tagID" class="admin_w200">
"""
text += """<option value="-1">- Select MARC tag -"""
i = 0
for (id, name, value) in tags:
if not fld_tag.has_key(id):
text += """<option value="%s" %s>%s</option>""" % (id, id == int(tagID) and 'selected="selected"' or '', "%s - %s" % (value, name))
i += 1
text += """</select><br>"""
if i == 0:
output += """<b><span class="info">No unused MARC tags</span></b><br>"""
else:
output += createhiddenform(action="deletetag#4.1",
text=text,
button="Delete",
fldID=fldID,
ln=ln,
confirm=0)
if tagID not in [-1,"-1"]:
tagID = int(tagID)
tags = get_tags(tagID)
if confirm in [0, "0"]:
text = """<b>Do you want to delete the MARC tag '%s'.</b>""" % tags[0][2]
output += createhiddenform(action="deletetag#4.1",
text=text,
button="Confirm",
fldID=fldID,
tagID=tagID,
ln=ln,
confirm=1)
elif confirm in [1, "1"]:
output += write_outcome(ares)
elif confirm not in [-1, "-1"]:
output += """<b><span class="info">Choose a MARC tag to delete.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_modifyfieldtags(fldID, ln, content=output)
def compare_on_val(first, second):
"""Compare the two values"""
return cmp(first[1], second[1])
def get_table_status(tblname):
sql = "SHOW TABLE STATUS LIKE '%s'" % tblname
try:
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_col_fld(colID=-1, type = '', id_field=''):
"""Returns either all portalboxes associated with a collection, or based on either colID or language or both.
colID - collection id
ln - language id"""
sql = "SELECT id_collection,id_field,id_fieldvalue,type,score,score_fieldvalue FROM collection_field_fieldvalue, field WHERE id_field=field.id"
try:
if id_field:
sql += " AND id_field=%s" % id_field
sql += " ORDER BY type, score desc, score_fieldvalue desc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_idx(idxID=''):
sql = "SELECT id,name,description,last_updated FROM idxINDEX"
try:
if idxID:
sql += " WHERE id=%s" % idxID
sql += " ORDER BY id asc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_fld_tags(fldID='', tagID=''):
"""Returns tags associated with a field.
fldID - field id
tagID - tag id"""
sql = "SELECT id_field,id_tag, tag.name, tag.value, score FROM field_tag,tag WHERE tag.id=field_tag.id_tag"
try:
if fldID:
sql += " AND id_field=%s" % fldID
if tagID:
sql += " AND id_tag=%s" % tagID
sql += " ORDER BY score desc, tag.value, tag.name"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_tags(tagID=''):
"""Returns all or a given tag.
tagID - tag id
ln - language id"""
sql = "SELECT id, name, value FROM tag"
try:
if tagID:
sql += " WHERE id=%s" % tagID
sql += " ORDER BY name, value"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_fld(fldID=''):
"""Returns all fields or only the given field"""
try:
if not fldID:
res = run_sql("SELECT id, name, code FROM field ORDER by name, code")
else:
res = run_sql("SELECT id, name, code FROM field WHERE id=%s ORDER by name, code" % fldID)
return res
except StandardError, e:
return ""
def get_fld_value(fldvID = ''):
"""Returns fieldvalue"""
try:
sql = "SELECT id, name, value FROM fieldvalue"
if fldvID:
sql += " WHERE id=%s" % fldvID
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_idx_fld(idxID=''):
"""Return a list of fields associated with one or all indexes"""
try:
sql = "SELECT id_idxINDEX, idxINDEX.name, id_field, field.name, regexp_punctuation, regexp_alphanumeric_separators FROM idxINDEX, field, idxINDEX_field WHERE idxINDEX.id = idxINDEX_field.id_idxINDEX AND field.id = idxINDEX_field.id_field"
if idxID:
sql += " AND id_idxINDEX=%s" % idxID
sql += " ORDER BY id_idxINDEX asc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_col_nametypes():
"""Return a list of the various translationnames for the fields"""
type = []
type.append(('ln', 'Long name'))
return type
def get_fld_nametypes():
"""Return a list of the various translationnames for the fields"""
type = []
type.append(('ln', 'Long name'))
return type
def get_idx_nametypes():
"""Return a list of the various translationnames for the index"""
type = []
type.append(('ln', 'Long name'))
return type
def get_sort_nametypes():
"""Return a list of the various translationnames for the fields"""
type = {}
type['soo'] = 'Sort options'
type['seo'] = 'Search options'
type['sew'] = 'Search within'
return type
def remove_fld(colID,fldID, fldvID=''):
"""Removes a field from the collection given.
colID - the collection the format is connected to
fldID - the field which should be removed from the collection."""
try:
sql = "DELETE FROM collection_field_fieldvalue WHERE id_collection=%s AND id_field=%s" % (colID, fldID)
if fldvID:
sql += " AND id_fieldvalue=%s" % fldvID
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def remove_idxfld(idxID, fldID):
"""Remove a field from a index in table idxINDEX_field
idxID - index id from idxINDEX
fldID - field id from field table"""
try:
sql = "DELETE FROM idxINDEX_field WHERE id_field=%s and id_idxINDEX=%s" % (fldID, idxID)
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def remove_fldtag(fldID,tagID):
"""Removes a tag from the field given.
fldID - the field the tag is connected to
tagID - the tag which should be removed from the field."""
try:
sql = "DELETE FROM field_tag WHERE id_field=%s AND id_tag=%s" % (fldID, tagID)
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def delete_tag(tagID):
"""Deletes all data for the given field
fldID - delete all data in the tables associated with field and this id """
try:
res = run_sql("DELETE FROM tag where id=%s" % tagID)
return (1, "")
except StandardError, e:
return (0, e)
def delete_idx(idxID):
"""Deletes all data for the given index together with the idxWORDXXR and idxWORDXXF tables"""
try:
res = run_sql("DELETE FROM idxINDEX WHERE id=%s" % idxID)
res = run_sql("DELETE FROM idxINDEXNAME WHERE id_idxINDEX=%s" % idxID)
res = run_sql("DELETE FROM idxINDEX_field WHERE id_idxINDEX=%s" % idxID)
res = run_sql("DROP TABLE idxWORD%sF" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("DROP TABLE idxWORD%sR" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("DROP TABLE idxPHRASE%sF" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("DROP TABLE idxPHRASE%sR" % (idxID < 10 and "0%s" % idxID or idxID))
return (1, "")
except StandardError, e:
return (0, e)
def delete_fld(fldID):
"""Deletes all data for the given field
fldID - delete all data in the tables associated with field and this id """
try:
res = run_sql("DELETE FROM collection_field_fieldvalue WHERE id_field=%s" % fldID)
res = run_sql("DELETE FROM field_tag WHERE id_field=%s" % fldID)
res = run_sql("DELETE FROM idxINDEX_field WHERE id_field=%s" % fldID)
res = run_sql("DELETE FROM field WHERE id=%s" % fldID)
return (1, "")
except StandardError, e:
return (0, e)
def add_idx(idxNAME):
"""Add a new index. returns the id of the new index.
idxID - the id for the index, number
idxNAME - the default name for the default language of the format."""
try:
idxID = 0
res = run_sql("SELECT id from idxINDEX WHERE name='%s'" % MySQLdb.escape_string(idxNAME))
if res:
return (0, (0, "A index with the given name already exists."))
for i in range(1, 100):
res = run_sql("SELECT id from idxINDEX WHERE id=%s" % i)
res2 = run_sql("SHOW TABLE STATUS LIKE 'idxWORD%s%%'" % (i < 10 and "0%s" % i or i))
if not res and not res2:
idxID = i
break
if idxID == 0:
return (0, (0, "Not possible to create new indexes, delete an index and try again."))
res = run_sql("INSERT INTO idxINDEX(id, name) values('%s','%s')" % (idxID, MySQLdb.escape_string(idxNAME)))
type = get_idx_nametypes()[0][0]
res = run_sql("INSERT INTO idxINDEXNAME(id_idxINDEX, ln, type, value) VALUES(%s,'%s','%s', '%s')" % (idxID, cdslang, type, MySQLdb.escape_string(idxNAME)))
res = run_sql("""CREATE TABLE IF NOT EXISTS idxWORD%sF (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM""" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("""CREATE TABLE IF NOT EXISTS idxWORD%sR (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM""" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("""CREATE TABLE `idxPHRASE%sF` (
`id` mediumint(9) unsigned NOT NULL auto_increment,
`term` varchar(50) default NULL,
`hitlist` longblob,
PRIMARY KEY (`id`),
UNIQUE KEY `term` (`term`)
) TYPE=MyISAM""" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("""CREATE TABLE `idxPHRASE%sR` (
`id_bibrec` mediumint(9) unsigned NOT NULL default '0',
`termlist` longblob,
`type` enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (`id_bibrec`,`type`)
) TYPE=MyISAM""" % (idxID < 10 and "0%s" % idxID or idxID))
res = run_sql("SELECT id from idxINDEX WHERE id=%s" % idxID)
res2 = run_sql("SHOW TABLE STATUS LIKE 'idxWORD%sF'" % (idxID < 10 and "0%s" % idxID or idxID))
res3 = run_sql("SHOW TABLE STATUS LIKE 'idxWORD%sR'" % (idxID < 10 and "0%s" % idxID or idxID))
if res and res2 and res3:
return (1, res[0][0])
elif not res:
return (0, (0, "Could not add the new index to idxINDEX"))
elif not res2:
return (0, (0, "Forward table not created for unknown reason."))
elif not res3:
return (0, (0, "Reverse table not created for unknown reason."))
except StandardError, e:
return (0, e)
def add_fld(name, code):
"""Add a new logical field. Returns the id of the field.
code - the code for the field,
name - the default name for the default language of the field."""
try:
type = get_fld_nametypes()[0][0]
res = run_sql("INSERT INTO field (name, code) values('%s','%s')" % (MySQLdb.escape_string(name), MySQLdb.escape_string(code)))
fldID = run_sql("SELECT id FROM field WHERE code='%s'" % MySQLdb.escape_string(code))
res = run_sql("INSERT INTO fieldname (id_field, type, ln, value) VALUES (%s,'%s','%s','%s')" % (fldID[0][0], type, cdslang, MySQLdb.escape_string(name)))
if fldID:
return (1, fldID[0][0])
else:
raise StandardError
except StandardError, e:
return (0, e)
def add_fld_tag(fldID, name, value):
"""Add a sort/search/field to the collection.
colID - the id of the collection involved
fmtID - the id of the format.
score - the score of the format, decides sorting, if not given, place the format on top"""
try:
res = run_sql("SELECT score FROM field_tag WHERE id_field=%s ORDER BY score desc" % (fldID))
if res:
score = int(res[0][0]) + 1
else:
score = 0
res = run_sql("SELECT id FROM tag WHERE value='%s'" % MySQLdb.escape_string(value))
if not res:
if name == '':
name = value
res = run_sql("INSERT INTO tag(name, value) values('%s','%s')" % (MySQLdb.escape_string(name), MySQLdb.escape_string(value)))
res = run_sql("SELECT id FROM tag WHERE value='%s'" % MySQLdb.escape_string(value))
res = run_sql("INSERT INTO field_tag(id_field, id_tag, score) values(%s, %s, %s)" % (fldID, res[0][0], score))
return (1, "")
except StandardError, e:
return (0, e)
def add_idx_fld(idxID, fldID):
"""Add a field to an index"""
try:
sql = "SELECT * FROM idxINDEX_field WHERE id_idxINDEX=%s and id_field=%s" % (idxID, fldID)
res = run_sql(sql)
if res:
return (0, (0, "The field selected already exists for this index"))
sql = "INSERT INTO idxINDEX_field(id_idxINDEX, id_field) values (%s, %s)" % (idxID, fldID)
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def modify_idx(idxID, idxNAME, idxDESC):
"""Modify index name or index description in idxINDEX table"""
try:
sql = "UPDATE idxINDEX SET name='%s' WHERE id=%s" % (MySQLdb.escape_string(idxNAME), idxID)
res = run_sql(sql)
sql = "UPDATE idxINDEX SET description='%s' WHERE ID=%s" % (MySQLdb.escape_string(idxDESC), idxID)
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def modify_fld(fldID, code):
"""Modify the code of field
fldID - the id of the field to modify
code - the new code"""
try:
sql = "UPDATE field SET code='%s'" % code
sql += " WHERE id=%s" % fldID
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def modify_tag(tagID, name, value):
"""Modify the name and value of a tag.
tagID - the id of the tag to modify
name - the new name of the tag
value - the new value of the tag"""
try:
sql = "UPDATE tag SET name='%s' WHERE id=%s" % (name, tagID)
res = run_sql(sql)
sql = "UPDATE tag SET value='%s' WHERE id=%s" % (value, tagID)
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def switch_score(fldID, id_1, id_2):
"""Switch the scores of id_1 and id_2 in the table given by the argument.
colID - collection the id_1 or id_2 is connected to
id_1/id_2 - id field from tables like format..portalbox...
table - name of the table"""
try:
res1 = run_sql("SELECT score FROM field_tag WHERE id_field=%s and id_tag=%s" % (fldID, id_1))
res2 = run_sql("SELECT score FROM field_tag WHERE id_field=%s and id_tag=%s" % (fldID, id_2))
res = run_sql("UPDATE field_tag SET score=%s WHERE id_field=%s and id_tag=%s" % (res2[0][0], fldID, id_1))
res = run_sql("UPDATE field_tag SET score=%s WHERE id_field=%s and id_tag=%s" % (res1[0][0], fldID, id_2))
return (1, "")
except StandardError, e:
return (0, e)
def get_lang_list(table, field, id):
langs = run_sql("select ln from %s where %s=%s" % (table, field, id))
exists = {}
lang = ''
for lng in langs:
if not exists.has_key(lng[0]):
lang += lng[0] + ", "
exists[lng[0]] = 1
if lang.endswith(", "):
lang = lang [:-2]
if len(exists) == 0:
lang = """<b><span class="info">None</span></b>"""
return lang
diff --git a/modules/bibindex/web/Makefile.am b/modules/bibindex/web/Makefile.am
index 50f0d88b6..54d93e600 100644
--- a/modules/bibindex/web/Makefile.am
+++ b/modules/bibindex/web/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
diff --git a/modules/bibindex/web/admin/Makefile.am b/modules/bibindex/web/admin/Makefile.am
index 642847bc9..eb7ebe4da 100644
--- a/modules/bibindex/web/admin/Makefile.am
+++ b/modules/bibindex/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/bibindex
webapp_DATA = bibindexadmin.py
EXTRA_DIST = bibindexadmin.py
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/bibindex/web/admin/bibindexadmin.py b/modules/bibindex/web/admin/bibindexadmin.py
index 55a86463e..73ca74abb 100644
--- a/modules/bibindex/web/admin/bibindexadmin.py
+++ b/modules/bibindex/web/admin/bibindexadmin.py
@@ -1,643 +1,643 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibIndex Administrator Interface."""
__lastupdated__ = """$Date$"""
import sys
import cdsware.bibindexadminlib as bic
from cdsware.webpage import page, create_error_box
from cdsware.config import weburl,cdslang
from cdsware.webuser import getUid, page_not_authorized
__version__ = "$Id$"
def deletetag(req, fldID, ln=cdslang, tagID=-1, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_deletetag(fldID=fldID,
ln=ln,
tagID=tagID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addtag(req, fldID, ln=cdslang, value=['',-1], name='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_addtag(fldID=fldID,
ln=ln,
value=value,
name=name,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyfieldtags(req, fldID, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_modifyfieldtags(fldID=fldID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addindexfield(req, idxID, ln=cdslang, fldID='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_addindexfield(idxID=idxID,
ln=ln,
fldID=fldID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyindexfields(req, idxID, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_modifyindexfields(idxID=idxID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showdetailsfieldtag(req, fldID, tagID, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_showdetailsfieldtag(fldID=fldID,
tagID=tagID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showdetailsfield(req, fldID, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_showdetailsfield(fldID=fldID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyfield(req, fldID, ln=cdslang, code='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_modifyfield(fldID=fldID,
ln=ln,
code=code,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyindex(req, idxID, ln=cdslang, idxNAME='', idxDESC='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_modifyindex(idxID=idxID,
ln=ln,
idxNAME=idxNAME,
idxDESC=idxDESC,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifytag(req, fldID, tagID, ln=cdslang, name='', value='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_modifytag(fldID=fldID,
tagID=tagID,
ln=ln,
name=name,
value=value,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def deletefield(req, fldID, ln=cdslang, confirm=0):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_deletefield(fldID=fldID,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def deleteindex(req, idxID, ln=cdslang, confirm=0):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_deleteindex(idxID=idxID,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showfieldoverview(req, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Manage logical fields",
body=bic.perform_showfieldoverview(ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def editfields(req, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Manage logical fields",
body=bic.perform_editfields(ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def editfield(req, fldID, ln=cdslang, mtype='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_editfield(fldID=fldID,
ln=ln,
mtype=mtype,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def editindex(req, idxID, ln=cdslang, mtype='', callback='yes', confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_editindex(idxID=idxID,
ln=ln,
mtype=mtype,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyindextranslations(req, idxID, ln=cdslang, sel_type='', trans = [], confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_modifyindextranslations(idxID=idxID,
ln=ln,
sel_type=sel_type,
trans=trans,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyfieldtranslations(req, fldID, ln=cdslang, sel_type='', trans = [], confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_modifyfieldtranslations(fldID=fldID,
ln=ln,
sel_type=sel_type,
trans=trans,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addfield(req, ln=cdslang, fldNAME='', code='', callback="yes", confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Manage logical fields",
body=bic.perform_addfield(ln=cdslang,
fldNAME=fldNAME,
code=code,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addindex(req, ln=cdslang, idxNAME='', callback="yes", confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Manage Indexes",
body=bic.perform_addindex(ln=cdslang,
idxNAME=idxNAME,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def switchtagscore(req, fldID, id_1, id_2, ln=cdslang):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_switchtagscore(fldID=fldID,
id_1=id_1,
id_2=id_2,
ln=ln),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def removeindexfield(req, idxID, fldID, ln=cdslang, callback="yes", confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/index">Manage Indexes</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Index",
body=bic.perform_removeindexfield(idxID=idxID,
fldID=fldID,
ln=cdslang,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def removefieldtag(req, fldID, tagID, ln=cdslang, callback="yes", confirm=-1):
navtrail_previous_links = bic.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibindex/bibindexadmin.py/field">Manage logical fields</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Edit Logical Field",
body=bic.perform_removefieldtag(fldID=fldID,
tagID=tagID,
ln=cdslang,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def index(req, ln=cdslang, mtype='', content=''):
navtrail_previous_links = bic.getnavtrail()
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Manage Indexes",
body=bic.perform_index(ln=ln,
mtype=mtype,
content=content),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def field(req, ln=cdslang, mtype='', content=''):
navtrail_previous_links = bic.getnavtrail()
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = bic.check_user(uid,'cfgbibindex')
if not auth[0]:
return page(title="Manage logical fields",
body=bic.perform_field(ln=ln,
mtype=mtype,
content=content),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def error_page(req):
return page(title="Internal Error",
body = create_error_box(req, verbose=verbose, ln=ln),
description="%s - Internal Error" % cdsname,
keywords="%s, CDSware, Internal Error" % cdsname,
language=ln,
urlargs=req.args)
diff --git a/modules/bibmatch/bin/Makefile.am b/modules/bibmatch/bin/Makefile.am
index 3ba0a2177..6929df378 100644
--- a/modules/bibmatch/bin/Makefile.am
+++ b/modules/bibmatch/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibmatch
EXTRA_DIST = bibmatch.in
CLEANFILES = *~ *.tmp bibmatchc
diff --git a/modules/bibmatch/doc/admin/guide.html.wml b/modules/bibmatch/doc/admin/guide.html.wml
index a396a9135..700055b77 100644
--- a/modules/bibmatch/doc/admin/guide.html.wml
+++ b/modules/bibmatch/doc/admin/guide.html.wml
@@ -1,27 +1,27 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibMatch Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibmatch/>BibMatch Admin</a>" \
navbar_name="admin" \
navbar_select="bibmatch-admin-guide"
FIXME
diff --git a/modules/bibmatch/doc/admin/index.html.wml b/modules/bibmatch/doc/admin/index.html.wml
index 6ba575d19..f79930eb3 100644
--- a/modules/bibmatch/doc/admin/index.html.wml
+++ b/modules/bibmatch/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibMatch Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibmatch"
<dl>
<dt><a href="guide.html">BibMatch Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running BibMatch.</dd>
</dl>
diff --git a/modules/bibmatch/lib/Makefile.am b/modules/bibmatch/lib/Makefile.am
index 7471596ee..2fa01daeb 100644
--- a/modules/bibmatch/lib/Makefile.am
+++ b/modules/bibmatch/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = bibmatch_engine.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibrank/Makefile.am b/modules/bibrank/Makefile.am
index 934d469ac..96b8c20b8 100644
--- a/modules/bibrank/Makefile.am
+++ b/modules/bibrank/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc etc web lib
CLEANFILES = *~
diff --git a/modules/bibrank/bin/Makefile.am b/modules/bibrank/bin/Makefile.am
index 14c182c06..00cfcdb56 100644
--- a/modules/bibrank/bin/Makefile.am
+++ b/modules/bibrank/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibrank bibrankgkb
EXTRA_DIST = bibrank.in bibrankgkb.in
CLEANFILES = *~ *.tmp bibrankc bibrankgkbc
diff --git a/modules/bibrank/bin/bibrank.in b/modules/bibrank/bin/bibrank.in
index bf8ff2f53..7feda56b0 100644
--- a/modules/bibrank/bin/bibrank.in
+++ b/modules/bibrank/bin/bibrank.in
@@ -1,469 +1,469 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
BibRank ranking daemon.
Usage: %s [options]
Ranking examples:
%s -wjif -a --id=0-30000,30001-860000 --verbose=9
%s -wjif -d --modified='2002-10-27 13:57:26'
%s -wwrd --rebalance --collection=Articles
%s -wwrd -a -i 234-250,293,300-500 -u admin@cdsware
Ranking options:
-w, --run=r1[,r2] runs each rank method in the order given
-c, --collection=c1[,c2] select according to collection
-i, --id=low[-high] select according to doc recID
-m, --modified=from[,to] select according to modification date
-l, --lastupdate select according to last update
-a, --add add or update words for selected records
-d, --del delete words for selected records
-S, --stat show statistics for a method
-R, --recalculate recalculate weigth data, used by word frequency method
should be used if ca 1% of the document has been changed
since last time -R was used
Repairing options:
-k, --check check consistency for all records in the table(s)
check if update of ranking data is necessary
-r, --repair try to repair all records in the table(s)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat tasks (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h , 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
"""
__version__ = "$Id$"
try:
from marshal import loads,dumps
from zlib import compress,decompress
from string import split,translate,lower,upper
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import urllib
import signal
import tempfile
import traceback
import cStringIO
import re
import copy
import types
import ConfigParser
except ImportError, e:
import sys
try:
from cdsware.dbquery import run_sql
from cdsware.bibrank_tag_based_indexer import *
from cdsware.bibrank_word_indexer import *
from cdsware.access_control_engine import acc_authorize_action
from cdsware.search_engine import perform_request_search
except ImportError, e:
import sys
task_id = -1 # the task id
nb_char_in_line = 50 # for verbose pretty printing
chunksize = 1000 # default size of chunks that the records will be treated by
base_process_size = 4500 # process base size
bibrank_options = {} # will hold task options
def serialize_via_numeric_array_dumps(arr):
return Numeric.dumps(arr)
def serialize_via_numeric_array_compr(str):
return compress(str)
def serialize_via_numeric_array_escape(str):
return MySQLdb.escape_string(str)
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return serialize_via_numeric_array_escape(serialize_via_numeric_array_compr(serialize_via_numeric_array_dumps(arr)))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(decompress(string))
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(compress(dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return loads(decompress(string))
def authenticate(user, header="BibRank Task Submission", action="runbibrank"):
print header
print "=" * len(header)
if user == "":
print>> sys.stdout, "\rUsername: ",
user = string.strip(string.lower(sys.stdin.readline()))
else:
print>> sys.stdout, "\rUsername: ", user
res = run_sql("select id,password from user where email=%s", (user,), 1)
if not res:
print "Sorry, %s does not exist." % user
sys.exit(1)
else:
(uid_db, password_db) = res[0]
if password_db:
password_entered = getpass.getpass()
if password_db == password_entered:
pass
else:
print "Sorry, wrong credentials for %s." % user
sys.exit(1)
(auth_code, auth_message) = acc_authorize_action(uid_db, action)
if auth_code != 0:
print auth_message
sys.exit(1)
return user
def usage(code, msg=''):
"Prints usage for this module."
if msg:
sys.stderr.write("Error: %s.\n" % msg)
print >> sys.stderr, \
""" Usage: %s [options]
Ranking examples:
%s -wjif -a --id=0-30000,30001-860000 --verbose=9
%s -wjif -d --modified='2002-10-27 13:57:26'
%s -wjif --rebalance --collection=Articles
%s -wsbr -a -i 234-250,293,300-500 -u admin@cdsware
Ranking options:
-w, --run=r1[,r2] runs each rank method in the order given
-c, --collection=c1[,c2] select according to collection
-i, --id=low[-high] select according to doc recID
-m, --modified=from[,to] select according to modification date
-l, --lastupdate select according to last update
-a, --add add or update words for selected records
-d, --del delete words for selected records
-S, --stat show statistics for a method
-R, --recalculate recalculate weigth data, used by word frequency method
should be used if ca 1%% of the document has been changed
since last time -R was used
Repairing options:
-k, --check check consistency for all records in the table(s)
check if update of ranking data is necessary
-r, --repair try to repair all records in the table(s)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat tasks (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h , 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
""" % ((sys.argv[0],) * 5)
sys.exit(code)
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
shift_re = sre.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
if bibrank_options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
if bibrank_options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop_commands():
"""Do all the commands necessary to stop the task before quitting.
Useful for task_sig_stop() handler.
"""
write_message("stopping commands started")
write_message("stopping commands ended")
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
if bibrank_options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
if bibrank_options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
query = "UPDATE schTASK SET progress='%s' where id=%d" % (MySQLdb.escape_string(msg), task_id)
if bibrank_options["verbose"]>= 9:
write_message(query)
run_sql(query)
return
def task_update_status(val):
"""Updates state information in the BibSched task table."""
query = "UPDATE schTASK SET status='%s' where id=%d" % (MySQLdb.escape_string(val), task_id)
if bibrank_options["verbose"]>= 9:
write_message(query)
run_sql(query)
return
def split_ranges(parse_string):
recIDs = []
ranges = string.split(parse_string, ",")
for range in ranges:
tmp_recIDs = string.split(range, "-")
if len(tmp_recIDs)==1:
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[0])])
else:
if int(tmp_recIDs[0]) > int(tmp_recIDs[1]): # sanity check
tmp = tmp_recIDs[0]
tmp_recIDs[0] = tmp_recIDs[1]
tmp_recIDs[1] = tmp
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[1])])
return recIDs
def get_date_range(var):
"Returns the two dates contained as a low,high tuple"
limits = string.split(var, ",")
if len(limits)==1:
low = get_datetime(limits[0])
return low,None
if len(limits)==2:
low = get_datetime(limits[0])
high = get_datetime(limits[1])
return low,high
def command_line():
"""Storing the task together with the parameters given."""
global bibrank_options
long_flags = ["lastupdate","add","del","repair","maxmem", "flush","stat", "rebalance", "id=", "collection=", "check", "modified=", "update", "run=", "user=", "sleeptime=", "time=", "help", "version", "verbose="]
short_flags = "ladSi:m:c:kUrRM:f:w:u:s:t:hVv:"
format_string = "%Y-%m-%d %H:%M:%S"
sleeptime = ""
try:
opts, args = getopt.getopt(sys.argv[1:], short_flags, long_flags)
except getopt.GetoptError, err:
write_message(err, sys.stderr)
usage(1)
if args:
usage(1)
bibrank_options = {"quick":"yes","cmd":"add","flush":100000,"validset":"", "collection":[], "id":[], "check": "", "stat":"", "modified":"", "last_updated":"last_updated","run":"", "verbose":1}
res = run_sql("SELECT name from rnkMETHOD")
bibrank_options["run"] = []
for (name,) in res:
bibrank_options["run"].append(name)
sched_time = time.strftime(format_string)
user = ""
try:
for opt in opts:
if opt == ("-h","") or opt == ("--help",""):
usage(1)
elif opt == ("-V","") or opt == ("--version",""):
print __version__
sys.exit(1)
elif opt[0] in ["--verbose", "-v"]:
bibrank_options["verbose"] = int(opt[1])
elif opt == ("-a","") or opt == ("--add",""):
bibrank_options["cmd"] = "add"
if ("-x","") in opts or ("--del","") in opts:
usage(1)
elif opt[0] in ["--run", "-w"]:
bibrank_options["run"] = []
run = split(opt[1],",")
for key in range(0,len(run)):
bibrank_options["run"].append(run[key])
elif opt == ("-r","") or opt == ("--repair",""):
bibrank_options["cmd"] = "repair"
elif opt == ("-d","") or opt == ("--del",""):
bibrank_options["cmd"]="del"
elif opt[0] in [ "-u", "--user"]:
user = opt[1]
elif opt[0] in [ "-k", "--check"]:
bibrank_options["cmd"]= "check"
elif opt[0] in [ "-S", "--stat"]:
bibrank_options["cmd"] = "stat"
elif opt[0] in [ "-i", "--id" ]:
bibrank_options["id"] = bibrank_options["id"] + split_ranges(opt[1])
bibrank_options["last_updated"] = ""
elif opt[0] in [ "-c", "--collection" ]:
bibrank_options["collection"] = opt[1]
elif opt[0] in [ "-R", "--rebalance"]:
bibrank_options["quick"] = "no"
elif opt[0] in [ "-f", "--flush"]:
bibrank_options["flush"]=int(opt[1])
elif opt[0] in [ "-M", "--maxmem"]:
bibrank_options["maxmem"]=int(opt[1])
if bibrank_options["maxmem"] < base_process_size + 1000:
raise StandardError, "Memory usage should be higher than %d kB" % (base_process_size + 1000)
elif opt[0] in [ "-m", "--modified" ]:
bibrank_options["modified"] = get_date_range(opt[1]) #2002-10-27 13:57:26
bibrank_options["last_updated"] = ""
elif opt[0] in [ "-l", "--lastupdate" ]:
bibrank_options["last_updated"] = "last_updated"
elif opt[0] in [ "-s", "--sleeptime" ]:
get_datetime(opt[1]) # see if it is a valid shift
sleeptime=opt[1]
elif opt[0] in [ "-t", "--time" ]:
sched_time = get_datetime(opt[1])
else:
usage(1)
except StandardError, e:
write_message(e, sys.stderr)
sys.exit(1)
user = authenticate(user)
if bibrank_options["verbose"]>=9:
write_message("Storing task options %s" % bibrank_options)
new_task_id = run_sql("""INSERT INTO schTASK (proc,user,runtime,sleeptime,arguments,status) VALUES ('bibrank',%s,%s,%s,%s,'WAITING')""", (user, sched_time, sleeptime, dumps(bibrank_options)))
print "Task #%d was successfully scheduled for execution." % new_task_id
return
def task_run(row):
"""Run the indexing task. The row argument is the BibSched task
queue row, containing if, arguments, etc.
Return 1 in case of success and 0 in case of failure.
"""
global task_id, bibrank_options
task_id = row[0]
task_proc = row[1]
bibrank_options = loads(row[6])
task_status = row[7]
# install signal handlers
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
if task_proc != "bibrank":
write_message("-The task #%d does not seem to be a BibRank task." % task_id, sys.stderr)
return 0
if task_status != "WAITING":
write_message("The task #%d is %s. I expected WAITING." % (task_id, task_status), sys.stderr)
return 0
if bibrank_options["verbose"]:
write_message("Task #%d started." % task_id)
task_update_status("RUNNING")
try:
bibrank_options = marshal.loads(row[6])
for key in bibrank_options["run"]:
write_message("")
file = etcdir + "/bibrank/" + key + ".cfg"
if bibrank_options["verbose"] >= 9:
write_message("Getting configuration from file: %s" % file)
config = ConfigParser.ConfigParser()
try:
config.readfp(open(file))
except StandardError, e:
write_message("Cannot find configurationfile: %s. The rankmethod may also not be registered using the BibRank Admin Interface." % file, sys.stderr)
raise StandardError
#Using the function variable to call the function related to the rank method
cfg_function = config.get("rank_method", "function")
func_object = globals().get(cfg_function)
if func_object:
func_object(row, key)
else:
write_message("Cannot run method '%s', no function to call" % key)
except StandardError, e:
write_message("\nException caught: %s" % e, sys.stderr)
traceback.print_tb(sys.exc_info()[2])
task_update_status("ERROR")
sys.exit(1)
task_update_status("DONE")
if bibrank_options["verbose"]:
write_message("Task #%d finished." % task_id)
return 1
def main():
if len(sys.argv) == 2:
try:
id = int(sys.argv[1])
except StandardError, err:
command_line()
sys.exit()
res = run_sql("SELECT * FROM schTASK WHERE id='%d'" % (id), None, 1)
if not res:
write_message("Selected task not found.", sys.stderr)
sys.exit(1)
try:
if not task_run(res[0]):
write_message("Error occurred. Exiting.", sys.stderr)
except StandardError, e:
write_message("Unexpected error occurred: %s." % e, sys.stderr)
write_message("Traceback is:")
traceback.print_tb(sys.exc_info()[2])
write_message("Exiting.")
task_update_status("ERROR")
else:
command_line()
if __name__ == "__main__":
main()
diff --git a/modules/bibrank/bin/bibrankgkb.in b/modules/bibrank/bin/bibrankgkb.in
index c9a216f7d..f0f5ceae6 100644
--- a/modules/bibrank/bin/bibrankgkb.in
+++ b/modules/bibrank/bin/bibrankgkb.in
@@ -1,328 +1,328 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Usage: bibrankgkb %s [options]
Examples:
bibrankgkb --input=bibrankgkb.cfg --output=test.kb
bibrankgkb -otest.kb -v9
bibrankgkb -v9
Generate options:
-i, --input=file input file, default from /etc/bibrank/bibrankgkb.cfg
-o, --output=file output file, will be placed in current folder
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
"""
__version__ = "$Id$"
try:
from marshal import loads,dumps
from zlib import compress,decompress
from string import split,translate,lower,upper
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import Numeric
import urllib
import signal
import tempfile
import unicodedata
import traceback
import cStringIO
import re
import copy
import types
import ConfigParser
except ImportError, e:
import sys
try:
from cdsware.config import *
from cdsware.search_engine_config import cfg_max_recID
from cdsware.search_engine import perform_request_search, strip_accents
from cdsware.search_engine import HitSet
from cdsware.dbquery import run_sql
except ImportError, e:
import sys
try:
import psyco
psyco.bind(serialize_via_numeric_array)
except:
pass
opts_dict = {}
task_id = -1
def bibrankgkb(config):
"""Generates a .kb file based on input from the configuration file"""
if opts_dict["verbose"] >= 1:
write_message("Running: Generate Knowledgebase.")
journals = {}
journal_src = {}
i = 0
#Reading the configuration file
while config.has_option("bibrankgkb","create_%s" % i):
cfg = split(config.get("bibrankgkb", "create_%s" % i),",,")
conv = {}
temp = {}
#Input source 1, either file, www or from db
if cfg[0] == "file":
conv = get_from_source(cfg[0], cfg[1])
del cfg[0:2]
elif cfg[0] == "www":
j = 0
urls = {}
while config.has_option("bibrankgkb",cfg[1] % j):
urls[j] = config.get("bibrankgkb",cfg[1] % j)
j = j + 1
conv = get_from_source(cfg[0], (urls, cfg[2]))
del cfg[0:3]
elif cfg[0] == "db":
conv = get_from_source(cfg[0], (cfg[1], cfg[2]))
del cfg[0:3]
if not conv:
del cfg[0:2]
else:
if opts_dict["verbose"] >= 9:
write_message("Using last resource for converting values.")
#Input source 2, either file, www or from db
if cfg[0] == "file":
temp = get_from_source(cfg[0], cfg[1])
elif cfg[0] == "www":
j = 0
urls = {}
while config.has_option("bibrankgkb",cfg[1] % j):
urls[j] = config.get("bibrankgkb",cfg[1] % j)
j = j + 1
temp = get_from_source(cfg[0], (urls, cfg[2]))
elif cfg[0] == "db":
temp = get_from_source(cfg[0], (cfg[1], cfg[2]))
i = i + 1
#If a convertion file is given, the names will be converted to the correct convention
if len(conv) != 0:
if opts_dict["verbose"] >= 9:
write_message("Converting between naming conventions given.")
temp = convert(conv, temp)
if len(journals) != 0:
for element in temp.keys():
if not journals.has_key(element):
journals[element] = temp[element]
else:
journals = temp
#Writing output file
if opts_dict["output"]:
f = open(opts_dict["output"], 'w')
f.write("#Created by %s\n" % __version__)
f.write("#Sources:\n")
for key in journals.keys():
f.write("%s---%s\n" % (key,journals[key]))
f.close()
if opts_dict["verbose"] >= 9:
write_message("Output complete: %s" % opts_dict["output"])
write_message("Number of hits: %s" % len(journals))
if opts_dict["verbose"] >= 9:
write_message("Result:")
for key in journals.keys():
write_message("%s---%s" % (key,journals[key]))
write_message("Total nr of lines: %s" % len(journals))
def showtime(timeused):
if opts_dict["verbose"] >= 9:
write_message("Time used: %d second(s)." % timeused)
def get_from_source(type, data):
"""Read a source based on the input to the function"""
datastruct = {}
if type == "db":
jvalue = run_sql(data[0])
jname = dict(run_sql(data[1]))
if opts_dict["verbose"] >= 9:
write_message("Reading data from database using SQL statements:")
write_message(jvalue)
write_message(jname)
for key, value in jvalue:
if jname.has_key(key):
key2 = string.strip(jname[key])
datastruct[key2] = value
#print "%s---%s" % (key2, value)
elif type == "file":
input = open(data, 'r')
if opts_dict["verbose"] >= 9:
write_message("Reading data from file: %s" % data)
data = input.readlines()
datastruct = {}
for line in data:
#print line
if not line[0:1] == "#":
key = string.strip((string.split(string.strip(line),"---"))[0])
value = (string.split(string.strip(line), "---"))[1]
datastruct[key] = value
#print "%s---%s" % (key,value)
elif type == "www":
if opts_dict["verbose"] >= 9:
write_message("Reading data from www using regexp: %s" % data[1])
write_message("Reading data from url:")
for link in data[0].keys():
if opts_dict["verbose"] >= 9:
write_message(data[0][link])
page = urllib.urlopen(data[0][link])
input = page.read()
#Using the regexp from config file
reg = re.compile(data[1])
iterator = re.finditer(reg, input)
for match in iterator:
if match.group("value"):
key = string.strip(match.group("key"))
value = string.replace(match.group("value"),",",".")
datastruct[key] = value
if opts_dict["verbose"] == 9:
print "%s---%s" % (key,value)
return datastruct
def convert(convstruct, journals):
"""Converting between names"""
if len(convstruct) > 0 and len(journals) > 0:
invconvstruct = dict(map(lambda x: (x[1], x[0]), convstruct.items()))
tempjour = {}
for name in journals.keys():
if convstruct.has_key(name):
tempjour[convstruct[name]] = journals[name]
elif invconvstruct.has_key(name):
tempjour[name] = journals[name]
return tempjour
else:
return journals
def serialize_via_numeric_array_dumps(arr):
return Numeric.dumps(arr)
def serialize_via_numeric_array_compr(str):
return compress(str)
def serialize_via_numeric_array_escape(str):
return MySQLdb.escape_string(str)
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return serialize_via_numeric_array_escape(serialize_via_numeric_array_compr(serialize_via_numeric_array_dumps(arr)))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(decompress(string))
def write_message(msg, stream = sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr). Useful for debugging stuff."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
def usage(code, msg=''):
"Prints usage for this module."
if msg:
sys.stderr.write("Error: %s.\n" % msg)
print >> sys.stderr, \
""" Usage: %s [options]
Examples:
%s --input=bibrankgkb.cfg --output=test.kb
%s -otest.kb -v9
%s -v9
Generate options:
-i, --input=file input file, default from /etc/bibrank/bibrankgkb.cfg
-o, --output=file output file, will be placed in current folder
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
""" % ((sys.argv[0],) * 4)
sys.exit(code)
def command_line():
global opts_dict
long_flags = ["input=", "output=", "help", "version", "verbose="]
short_flags = "i:o:hVv:"
format_string = "%Y-%m-%d %H:%M:%S"
sleeptime = ""
try:
opts, args = getopt.getopt(sys.argv[1:], short_flags, long_flags)
except getopt.GetoptError, err:
write_message(err, sys.stderr)
usage(1)
if args:
usage(1)
opts_dict = {"input": "%s/bibrank/bibrankgkb.cfg" % etcdir, "output":"", "verbose":1}
sched_time = time.strftime(format_string)
user = ""
try:
for opt in opts:
if opt == ("-h","") or opt == ("--help",""):
usage(1)
elif opt == ("-V","") or opt == ("--version",""):
print __version__
sys.exit(1)
elif opt[0] in ["--input", "-i"]:
opts_dict["input"] = opt[1]
elif opt[0] in ["--output", "-o"]:
opts_dict["output"] = opt[1]
elif opt[0] in ["--verbose", "-v"]:
opts_dict["verbose"] = int(opt[1])
else:
usage(1)
startCreate = time.time()
file = opts_dict["input"]
config = ConfigParser.ConfigParser()
config.readfp(open(file))
bibrankgkb(config)
if opts_dict["verbose"] >= 9:
showtime((time.time() - startCreate))
except StandardError, e:
write_message(e, sys.stderr)
sys.exit(1)
return
def main():
command_line()
if __name__ == "__main__":
main()
diff --git a/modules/bibrank/doc/Makefile.am b/modules/bibrank/doc/Makefile.am
index 9ac6a119d..11d00dfa3 100644
--- a/modules/bibrank/doc/Makefile.am
+++ b/modules/bibrank/doc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
\ No newline at end of file
diff --git a/modules/bibrank/doc/admin/Makefile.am b/modules/bibrank/doc/admin/Makefile.am
index e7373b1d9..7550b8dd3 100644
--- a/modules/bibrank/doc/admin/Makefile.am
+++ b/modules/bibrank/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/bibrank
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibrank/doc/admin/guide.html.wml b/modules/bibrank/doc/admin/guide.html.wml
index 525bed88a..240780280 100644
--- a/modules/bibrank/doc/admin/guide.html.wml
+++ b/modules/bibrank/doc/admin/guide.html.wml
@@ -1,566 +1,566 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibRank Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibrank/>BibRank Admin</a>" \
navbar_name="admin" \
navbar_select="bibrank-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1.<a href="#o">Overview</a></strong><br>
<strong>2.<a href="#c">Configuration Conventions</a></strong><br>
<strong>3.<a href="#bai">BibRank Admin Interface</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1.<a href="#mi">Main interface</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2.<a href="#ar">Add rank method</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.3.<a href="#sd">Show details of rank method</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.4.<a href="#mr">Modify rank method</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.5.<a href="#dr">Delete rank method</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6.<a href="#mt">Modify translations</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.7.<a href="#mc">Modify visibility toward collections</a><br>
<strong>4.<a href="#bd">BibRank Daemon</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1.<a href="#cli1">Command Line Interface</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2.<a href="#ubd">Using BibRank</a><br>
<strong>5.<a href="#brm">BibRank Methods</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.1.<a href="#str">Single tag rank method</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.2.<a href="#wrd">Word Similarity/Similar Records</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.3.<a href="#cmb">Combined method</a><br>
<strong>6.<a href="#bt">bibrankgkb Tool</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.1.<a href="#cli2">Command Line Interface</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.2.<a href="#ubt">Using bibrankgkb</a><br>
<strong>7.<a href="#ainf">Additional Information</a></strong><br>
<a name="o"></a><h2>1. Overview</h2>
<p>The bibrank module consist currently of two tools:
<br><br>bibrank - Generates ranking data for ranking search results based on methods like:
<blockquote>
<pre>
Journal Impact Factor
Word Similarity/Similar Records
Combined Method
##Number of downloads
##Author Impact
##Citation Impact
</blockquote>
</pre>
bibrankgkb - For generating knowledge base files for use with bibrank
<br><br>
The bibrankgkb may not be necessary to use, it depends on which ranking methods you are planning
to use, and what data you already got. This guide will take you through the necessary steps in detail in
order to create different kinds of ranking methods for the search engine to use.
<a name="c"></a><h2>2. Configuration Conventions</h2>
<blockquote>
<pre>
- comment line starts with '#' sign in the first column
- each section in a configuration file is declared inside '[' ']' signs
- values in knowledgebasefiles are separated by '---'
</blockquote>
</pre>
<a name="bai"></a><h2>3. BibRank Admin Interface</h2>
The bibrank web interface enables you to modify the configuration of most aspects of BibRank. For full functionality, it is advised to
let the http-daemon have write/read access to your cdsware/etc/bibrank directory. If this is not wanted, you have to edit the configuration files from the console using your favourite text editor.
<a name="mi"></a><h3>3.1 Main interface</h3>
In the main interface screen, you see a list of all rank methods currently added. Each rank method is identified by the rank method code. To find out about the functionality available, check out the topics below.
</br></br><b>Explanation of concepts</b>
<blockquote>
<pre>
Rank method:
A method responsible for creating the necessary data to rank a result.
Translations:
Each rank method may have many names in many languages.
Collections:
Which collections the rank method should be visible in.
</pre>
</blockquote>
<a name="ar"></a><h3>3.2 Add rank method</h3>
When pressing the link in the upper right corner from the main interface, you will see the interface for adding a new rank method. The two available options that needs to be decided upon, are the bibrank code and the template to use, both values can be changed later. The bibrank code is used by the bibrank daemon to run the method, and should be fairly short without spaces. Which template you are using, decides how the ranking will be done, and must before used, be changed to suit your cdsware configuration. When confirming to add a new rank method, it will be added to the list of possible rank methods, and a configuration file will be created if the httpd user has proper rights to the 'cdsware/etc/bibrank' directory. If not, the file has to manually be created with the name 'bibrankcode.cfg' where bibrankcode is the same as given in the interface.
<a name="sd"></a><h3>3.3 Show details of rank method</h3>
This interface gives you an overview of the current status of the rank method, and gives direct access to the various interfaces for changing the configuration.
In the overview section, you see the bibrank code, for use with the bibrank daemon, and the date for the last run of the rank method.
In the statistics section you see how many records have been added to the rank method and other statistic data. In the collection part, the collections which the rank method is visible to is shown. The translations part shows the various translations in the languages available in cdsware. On the bottom the configuration file is shown, if accessible.
<a name="mr"></a><h3>3.4 Modify rank method</h3>
This interface gives access to modify the bibrank code given when creating the rank method and the configuration file of the rank method, if the file can be accessed. If not, it may not exist, or the httpd user doesn't have enough rights to read the file. On the bottom of the interface, it is possible to choose a template, see it, and copy it over the old rank method configuration if wanted. Remember that the values present in the template is an example, and must be changed where necessary. See this documentation for information about this, and the 'BibRank Internals' link below for additional information.
<a name="dr"></a><h3>3.5 Delete rank method</h3>
If it is necessary to delete a rank method, some precautions must be taken since the configuration of the method will be lost. When deleting a rank method, the configuration file will also be deleted ('cdsware/etc/bibrank/bibrankcode.cfg' where bibrankcode is the code of the rank method) if accessible to the httpd user. If not, the file can be deleted manually from console. Any bibrank tasks scheduled to run the deleted rank method must be modified or deleted manually.
<a name="mt"></a><h3>3.6 Modify translations</h3>
If you want to use internalisation of the rank method names, you have to add them using the 'Modify translations' interface. Below a list of all the languages used in the cdsware installation will be shown with the possibility to add the translation for each language.
<a name="mc"></a><h3>3.7 Modify visibility toward collections</h3>
If a rank method should be visible to the users of the cdsware search interface, it must be enabled for one or several collections. A rank method can be visible in the search interface of the whole site, or just one collection. The collections in the upper list box does not show the rank method in the search interface to the user. To change this select the wanted collection and press 'Enable' to enable the rank method for this collection. The collections that the method has been activated for, is shown in the lower list box. To remove a collection, select it and press the 'Disable' button to remove it from the list of collections which the rank method is enabled for.
<a name="bd"></a><h2>4. BibRank Daemon</h2>
The bibrank daemon read the necessary metadata from the cdsware database and combines the read metadata
in different ways to create the ranking data necessary at searchtime to fast be able to rank the results.
<a name="cli1"></a><h3>4.1 Command Line Interface</h3>
<blockquote>
<pre>
Usage bibrank:
bibrank -wjif -a --id=0-30000,30001-860000 --verbose=9
bibrank -wjif -d --modified='2002-10-27 13:57:26'
bibrank -wwrd --recalculate --collection=Articles
bibrank -wwrd -a -i 234-250,293,300-500 -u admin@cdsware
Ranking options:
-w, --run=r1[,r2] runs each rank method in the order given
-c, --collection=c1[,c2] select according to collection
-i, --id=low[-high] select according to doc recID
-m, --modified=from[,to] select according to modification date
-l, --lastupdate select according to last update
-a, --add add or update words for selected records
-d, --del delete words for selected records
-S, --stat show statistics for a method
-R, --recalculate recalculate weigth data, used by word frequency method
should be used if ca 1% of the document has been changed
since last time -R was used
Repairing options:
-k, --check check consistency for all records in the table(s)
check if update of ranking data is necessary
-r, --repair try to repair all records in the table(s)
Scheduling options:
-u, --user=USER user name to store task, password needed
-s, --sleeptime=SLEEP time after which to repeat tasks (no)
e.g.: 1s, 30m, 24h, 7d
-t, --time=TIME moment for the task to be active (now)
e.g.: +15s, 5m, 3h , 2002-10-27 13:57:26
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
</pre>
</blockquote>
<a name="ubd"></a><h3>4.2 Using BibRank</h3>
<h4>Step 1 - Adding the rank option to the search interface</h4>
To be able to add the needed ranking data to the database, you first have to add the rank method to the database, and
add the wished code you want to use together with it. The name of the configuration file in the next section, needs to
have the same name as the code stored in the database.
<h4>Step 2 - Get necessary external data (ex. jif values)</h4>
Find out what is necessary of data for each method. The bibrankgkb documentation below may be of assistance.
<br><br><b>Example of necessary data</b> (<code>jif.kb</code> - journal impact factor knowledge base)
<blockquote>
<pre>
Phys. Rev., D---3.838
Phys. Rev. Lett.---6.462
Phys. Lett., B---4.213
Nucl. Instrum. Methods Phys. Res., A---0.964
J. High Energy Phys.---8.664
</pre>
</blockquote>
<h4>Step 3 - Modify the configuration file</h4>
The configuration files for the different rank methods has different option, so verify that you are using the correct
configuration file and rank method. A template for each rank method exists as examples, but may not work on all configurations of CDSware.
For a description of each rank method and the configuration necessary, check section 6 below.
<h4>Step 4 - Add the ranking method as a scheduled task</h4>
When the configuration is okay, you can add the bibrank daemon to the task scheduler using the scheduling options. The daemon can then do a update of the rank method once each day or similar automatically.
<br><br><b>Example</b>
<blockquote>
<pre>
$ bibrank -wjif -r
Task #53 was successfully scheduled for execution.
</pre>
</blockquote>
It is adviced to run the BibRank daemon using no parameters, since the default settings then will be used.
<br><br><b>Example</b>
<blockquote>
<pre>
$ bibrank
Task #2505 was successfully scheduled for execution.
</pre>
</blockquote>
<h4>Step 5 - Running bibrank manually</h4>
If BibRank is scheduled without any parameters, and no records has been modified, you may get a output like shown below.
<br><br><b>Example</b>
<blockquote>
<pre>
$ bibrank 2505
2004-09-07 17:51:46 --> Task #2505 started.
2004-09-07 17:51:46 -->
2004-09-07 17:51:46 --> Running rank method: Number of downloads.
2004-09-07 17:51:47 --> No new records added since last time method was run
2004-09-07 17:52:10 -->
2004-09-07 17:52:10 --> Running rank method: Journal Impact Factor.
2004-09-07 17:52:10 --> No new records added since last time method was run
2004-09-07 17:52:11 --> Reading knowledgebase file: /soft/cdsware-CDSCERNWIENERDEV/etc/bibrank/cern_jif.kb
2004-09-07 17:52:11 --> Number of lines read from knowledgebase file: 420
2004-09-07 17:52:11 --> Number of records available in rank method: 0
2004-09-07 17:52:12 -->
2004-09-07 17:52:12 --> Running rank method: Word frequency
2004-09-07 17:52:13 --> rnkWORD01F contains 256842 words from 677912 records
2004-09-07 17:52:14 --> rnkWORD01F is in consistent state
2004-09-07 17:52:14 --> Using the last update time for the rank method
2004-09-07 17:52:14 --> No new records added. rnkWORD01F is up to date
2004-09-07 17:52:14 --> rnkWORD01F contains 256842 words from 677912 records
2004-09-07 17:52:14 --> rnkWORD01F is in consistent state
2004-09-07 17:52:14 --> Task #2505 finished.
</pre>
</blockquote>
<h4>Step 6 - Fast update of modified records</h4>
If you just want to update the latest additions or modified records, you may want to do a faster update by running the daemon without the recalculate option. (the recalculate option is off by default). This may cause lower accurancy when ranking.
<a name="brm"></a><h2>5. BibRank Methods</h2>
Each BibRank method has a configuration file which contains different parameters and sections necessary to do the ranking.
<a name="str"></a><h3>5.1 Single tag rank method</h3>
This method uses one MARC tag together with a file containing possible values for this MARC tag together with a ranking value. This data is used to create a structure containing the record id associated with the ranking value based on the content of the tag. The method can be used for various ways of ranking like ranking by Journal Impact Factor, or use it to let certain authors always appear top of a search.
The parameters needed to be configured for this method is the 'tag','kb_src' and 'check_mandatory_tags'.
<br><br><b>Example</b>
<blockquote>
<pre>
<protect>
[rank_method]
function = single_tag_rank_method
[single_tag_rank]
tag = 909C4p
kb_src = /usr/local/cdsware-DEMO/etc/bibrank/jif.kb
check_mandatory_tags = 909C4c,909C4v,909C4y
</protect>
</pre>
</blockquote>
<b>Explanation:</b>
<pre>
<blockquote>
<protect>
[rank_method]
##The function which is responsible for doing the work. Should not be changed
function = single_tag_rank_method
##This section must be available if the single_tag_rank_method is going to be used
[single_tag_kb]
##The tag which got the value to be searched for on the left side in the kb file (like the journal name)
tag = 909C4p
##The path to the kb file which got the content of the tag above on left side, and value on the left side
kb_src = /log/cdsware-DEMODEV/etc/bibrank/jif.kb
##Tags that must be included for a record to be added to the ranking data, to disable remove tags
check_mandatory_tags = 909C4c,909C4v,909C4y
</protect>
</blockquote>
The kb_src file must contain data on the form:
<blockquote>
Phys. Rev., D---3.838
Phys. Rev. Lett.---6.462
Phys. Lett., B---4.213
Nucl. Instrum. Methods Phys. Res., A---0.964
J. High Energy Phys.---8.664
</blockquote>
The left side must match the content of the tag mentioned in the tag variable.
</pre>
<a name="wrd"></a><h3>5.2 Word Similarity/Similar Records</h3>
The Word Similarity/Similar Records method uses the content of the tags selected to determine which records is most relevant to a query, or most similar to a selected record. This method got a lot of parameters to configure, and it may need some tweaking to get the best result. The BibRank code for this method has to be 'wrd' for it to work. For best result, it is adviced to install the stemming module mentioned in INSTALL, and use a stopword list containing stopwords in the languages the records exists in. The stemmer and stopword list is used to get better results and to limit the size of the index, thus making ranking faster and more accurate. For best result with the stemmer, it is important to mark each tag to be used with the most common language the value of the tag may be in. It is adviced to not change the 'function','table' and the parameters under [find_similar]. If the stemmer is not installed, to assure that no problems exists, the 'stem_if_avail' parameter should be set to 'no'. Each tag to be used by the method has to be given a point. The number of points describes how important one word is in this tag.
When running BibRank to update the index for this rank method, it is not necessary to recalculate each time, but when large number of records has been updated/added, it can be wise to recalculate using the recalculate parameter of BibRank.
<br><br><b>Example</b>
<pre>
<blockquote>
<protect>
[rank_method]
function = word_similarity
[word_similarity]
stemming = en
table = rnkWORD01F
stopword = True
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
#relevance_number_output_prologue = <!-
#relevance_number_output_epilogue = -->
#MARC tag,tag points, tag language
tag1 = 6531_a, 2, en
tag2 = 695__a, 1, en
tag3 = 6532_a, 1, en
tag4 = 245__%, 10, en
tag5 = 246_%, 1, fr
tag6 = 250__a, 1, en
tag7 = 711__a, 1, en
tag8 = 210__a, 1, en
tag9 = 222__a, 1, en
tag10 = 520__%, 1, en
tag11 = 590__%, 1, fr
tag12 = 111__a, 1, en
tag13 = 100__%, 2, none
tag14 = 700__%, 1, none
tag15 = 721__a, 1, none
[find_similar]
max_word_occurence = 0.05
min_word_occurence = 0.00
min_word_length = 3
min_nr_words_docs = 3
max_nr_words_upper = 20
max_nr_words_lower = 10
default_min_relevance = 75
</protect>
</blockquote>
</pre>
<b>Explanation:</b>
<pre>
<blockquote>
<protect>
[rank_method]
#internal name for the bibrank program, do not modify
function = word_similarity
[word_similarity]
#if stemmer is available, default stemminglanguage should be given here. Adviced to turn off if not installed
stemming = en
#the internal table to load the index tables from.
table = rnkWORD01F
#remove stopwords?
stopword = True
#text to show before the rank value when the search result is presented. <-- to hide result
relevance_number_output_prologue = (
#text to show after the rank value when the search result is presented. --> to hide result
relevance_number_output_epilogue = )
#MARC tag,tag points, tag language
#a list of the tags to be used, together with a number describing the importance of the tag, and the
#most common language for the content. Not all languages are supported. Among the supported ones are:
#fr/french, en/english, no/norwegian, se/swedish, de/german, it/italian, pt/portugese
#keyword
tag1 = 6531_a, 1, en #keyword
tag2 = 695__a, 1, en #keyword
tag3 = 6532_a, 1, en #keyword
tag4 = 245__%, 10, en #title, the words in the title is usually describing a record very good.
tag5 = 246_% , 1, fr #french title
tag6 = 250__a, 1, en #title
tag7 = 711__a, 1, en #title
tag8 = 210__a, 1, en #abbreviated
tag9 = 222__a, 1, en #key title
[find_similar]
#term should exist in maximum X/100% of documents
max_word_occurence = 0.05
#term should exist in minimum X/100% of documents
min_word_occurence = 0.00
#term should be atleast 3 characters long
min_word_length = 3
#term should be in atleast 3 documents or more
min_nr_words_docs = 3
#do not use more than 20 terms for "find similar"
max_nr_words_upper = 20
#if a document contains less than 10 terms, use much used terms too, if not ignore them
max_nr_words_lower = 10
#default minimum relevance value to use for find similar
default_min_relevance = 75
</protect>
</blockquote>
Tip: When executing a search using a ranking method, you can add "verbose=1" to the list of parameteres
in the URL to see which terms have been used in the ranking.
</pre>
<a name="cmb"></a><h3>5.3 Combine method</h3>
The 'Combine method' is running each method mentioned in the config file and adding the score together
based on the importance of the method given by the percentage.
<br><br><b>Example</b>
<pre>
<blockquote>
<protect>
[rank_method]
function = combine_method
[combine_method]
method1 = cern_jif,33
method2 = cern_acc,33
method3 = wrd,33
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
</protect>
</blockquote>
</pre>
<b>Explanation:</b>
<pre>
<blockquote>
<protect>
[rank_method]
#tells which method to use, do not change
function = combine_method
[combine_method]
#each line tells which method to use, the code is the same as in the BibRank interface, the number describes how
#much of the total score the method should count.
method1 = jif,50
method2 = wrd,50
#text to be shown before the rank value on the search result screen.
relevance_number_output_prologue = (
#text to be shown after the rank value on the search result screen.
relevance_number_output_epilogue = )
</protect>
</blockquote>
</pre>
<a name="bt"></a><h2>6. bibrankgkb Tool</h2>
For some ranking methods, like the single_tag_rank method, a knowledge base file (kb) with the needed data in the correct format is necessary. This file can be created using the bibrankgkb tool which can read the data either from
the cdsware database, from several web pages using regular expressions, or from another file. In case one source
has another naming convention, bibrank can convert between them using a convert file.
<a name="cli2"></a><h3>6.1 Command Line Interface</h3>
<blockquote>
<pre>
Usage: bibrankgkb %s [options]
Examples:
bibrankgkb --input=bibrankgkb.cfg --output=test.kb
bibrankgkb -otest.cfg -v9
bibrankgkb
Generate options:
-i, --input=file input file, default from /etc/bibrank/bibrankgkb.cfg
-o, --output=file output file, will be placed in current folder
General options:
-h, --help print this help and exit
-V, --version print version and exit
-v, --verbose=LEVEL verbose level (from 0 to 9, default 1)
</blockquote>
</pre>
<a name="ubt"></a><h3>6.2 Using bibrankgkb</h3>
<h4>Step 1 - Find sources</h4>
Since some of the data used for ranking purposes is not freely available, it cannot be bundled with CDSware. To get hold of the necessary data,
you may find it useful to ask your library if they have a copy of the data that can be used (like the Journal Impact Factors from the Science Citation Index), or use google to search the web for any public source.
<h4>Step 2 - Create configuration file</h4>
The default configuration file is shown below.
<protect>
<pre>
<blockquote>
##The main section
[bibrankgkb]
##The url to a web page with the data to be read, does not need to have the same name as this one, but if there
are several links, the url parameter should end with _0->
url_0 = http://www.taelinke.land.ru/impact_A.html
url_1 = http://www.taelinke.land.ru/impact_B.html
url_2 = http://www.taelinke.land.ru/impact_C.html
url_3 = http://www.taelinke.land.ru/impact_DE.html
url_4 = http://www.taelinke.land.ru/impact_FH.html
url_5 = http://www.taelinke.land.ru/impact_I.html
url_6 = http://www.taelinke.land.ru/impact_J.html
url_7 = http://www.taelinke.land.ru/impact_KN.html
url_8 = http://www.taelinke.land.ru/impact_QQ.html
url_9 = http://www.taelinke.land.ru/impact_RZ.html
##The regular expression for the url mentioned should be given here
url_regexp =
##The various sources that can be read in, can either be a file, web page or from the database
kb_1 = /home/trondaks/w/cdsware/modules/bibrank/etc/cern_jif.kb
kb_2 = /home/trondaks/w/cdsware/modules/bibrank/etc/cdsware_jif.kb
kb_2_filter = /home/trondaks/w/cdsware/modules/bibrank/etc/convert.kb
kb_3 = SELECT id_bibrec,value FROM bib93x,bibrec_bib93x WHERE tag='938__f' AND id_bibxxx=id
kb_4 = SELECT id_bibrec,value FROM bib21x,bibrec_bib21x WHERE tag='210__a' AND id_bibxxx=id
##This points to the url above (the common part of the url is 'url_' followed by a number
kb_5 = url_%s
##This is the part that will be read by the bibrankgkb tool to determine what to read.
##The first two part (separated by ,,) gives where to look for the conversion file (which convert
##the names between to formats), and the second part is the data source. A conversion file is not
##needed, as shown in create_0. If the source is from a file, url or the database, it must be
##given with file,www or db. If several create lines exists, each will be read in turn, and added
##to a common kb file.
##So this means that:
##create_0: Load from file in variable kb_1 without converting
##create_1: Load from file in variable kb_2 using convertion from file kb_2_filter
##create_3: Load from www using url in variable kb_5 and regular expression in url_regexp
##create_4: Load from database using sql statements in kb_4 and kb_5
create_0 = ,, ,,file,,%(kb_1)s
create_1 = file,,%(kb_2_filter)s,,file,,%(kb_2)s
#create_2 = ,, ,,www,,%(kb_5)s,,%(url_regexp)s
#create_3 = ,, ,,db,,%(kb_4)s,,%(kb_4)s
</pre>
</blockquote>
</protect>
When you have found a source for the data, created the configuration file, it may be necessary to
create an convertion file, but this depends on the conversions used in the available data versus
the convertion used in your cdsware installation.
<br>
The available data may look like this:
<pre>
<blockquote>
COLLOID SURFACE A---1.98
</pre>
</blockquote>
But in cdsware you are using:
<pre>
<blockquote>
Colloids Surf., A---1.98
</pre>
</blockquote>
By using a convertion file like:
<pre>
<blockquote>
COLLOID SURFACE A---Colloids Surf., A
</pre>
</blockquote>
You can convert the source to the correct naming convention.
<pre>
<blockquote>
Colloids Surf., A---1.98
</pre>
</blockquote>
<h4>Step 3 - Run tool</h4>
When ready to run the tool, you may either use the default file (/etc/bibrank/bibrankgkb.cfg), or use another one by giving it using the input variable '--input'.
If you want to test the configuration, you can use '--verbose=9' to output on screen, or if you want to save it to a file, use
'--output=filename', but remember that the file will be saved in the program directory.
The output may look like this:
<pre>
<blockquote>
$ ./bibrankgkb -v9
2004-03-11 17:30:17 --> Running: Generate Knowledge base.
2004-03-11 17:30:17 --> Reading data from file: /log/cdsware-DEMODEV/etc/bibrank/jif.kb
2004-03-11 17:30:17 --> Reading data from file: /log/cdsware-DEMODEV/etc/bibrank/conv.kb
2004-03-11 17:30:17 --> Using last resource for converting values.
2004-03-11 17:30:17 --> Reading data from file: /log/cdsware-DEMODEV/etc/bibrank/jif2.kb
2004-03-11 17:30:17 --> Converting between naming conventions given.
2004-03-11 17:30:17 --> Colloids Surf., A---1.98
2004-03-11 17:30:17 --> Phys. Rev. Lett.---6.462
2004-03-11 17:30:17 --> J. High Energy Phys.---8.664
2004-03-11 17:30:17 --> Nucl. Instrum. Methods Phys. Res., A---0.964
2004-03-11 17:30:17 --> Phys. Lett., B---4.213
2004-03-11 17:30:17 --> Phys. Rev., D---3.838
2004-03-11 17:30:17 --> Total nr of lines: 6
2004-03-11 17:30:17 --> Time used: 0 second(s).
</blockquote>
</pre>
<a name="ainf"></a><h2>7. Additional Information</h2>
<a href="<WEBURL>/hacking/bibrank/">BibRank Internals</a>
diff --git a/modules/bibrank/doc/admin/index.html.wml b/modules/bibrank/doc/admin/index.html.wml
index adc6bcc52..82c0fb47a 100644
--- a/modules/bibrank/doc/admin/index.html.wml
+++ b/modules/bibrank/doc/admin/index.html.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibRank Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibrank"
<p>
This is the gate to the admin area for BibRank. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/bibrank/">login</a> to enter.
</p>
<dl>
<dt><a href="bibrankadmin.py">BibRank Admin Interface</a></dt>
<dd>Start area for BibRank administration.</dd>
</dl>
<dl>
<dt><a href="guide.html">BibRank Admin Guide</a></dt>
<dd>Everything you want to know about BibRank administration</dd>
</dl>
diff --git a/modules/bibrank/doc/hacking/Makefile.am b/modules/bibrank/doc/hacking/Makefile.am
index a7dd1a809..3563bc900 100644
--- a/modules/bibrank/doc/hacking/Makefile.am
+++ b/modules/bibrank/doc/hacking/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/bibrank
doc_DATA= index.html single_tag_rank.html bibrankgkb.html word_similarity.html api.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibrank/doc/hacking/api.html.wml b/modules/bibrank/doc/hacking/api.html.wml
index 59db0e7ad..f3b7911b2 100644
--- a/modules/bibrank/doc/hacking/api.html.wml
+++ b/modules/bibrank/doc/hacking/api.html.wml
@@ -1,141 +1,141 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibRank Record Sorter API" \
navbar_name="hacking-websearch" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=index.html>WebSearch Internals</a> " \
navbar_select="hacking-websearch-api"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<protect>
<pre>
CDSware Bibrank Record Sorter can be called from within your Python
programs via a high-level API and a mid-mid level API.
1. High-level API
Description:
The high-level access to the BibRank Record Sorter is provided
by exactly the same function as called from the web interface
when users submit their queries, if a rank method has been
selected. This should guarantee exactly the same behaviour if
the same parameters are given.
There are three thing to note: (i) When a search is done, the
search engine is sending a HitSet containing all the records that
matches the query. Since only records in the HitSet are ranked, a
HitSet must be created containing wished records to rank and be sent
as a parameter to the function. (ii) Some rank methods may choose to
ignore the HitSet, like the "Similar Records" function. (iii) In case
of an error ranking the records, the returned data is different.
Signature:
def rank_records(rank_method_code, rank_limit_relevance,
hitset_global, pattern, verbose=0):
"""
rank_method_code - 'jif', 'wrd' or other methods
rank_limit_relevance - a number defining the threshold of which
to rank records, may be ignored by rank method.
hitset_global, search engine hits, if all records should be
ranked, fill the HitSet with ones.
pattern, search engine query or record ID, must be a
list. ['CERN', 'fermilab'] or ['recid:12345']
verbose, verbose level - 0-9 defines how much debug information
should be shown
output if successfull:
list of records - [123, 321, 12451, 123, 12, 4]
list of rank values - ascending, same length as the list of
records [0, 10, 20, 30, 40, 100]
prefix - text to show before the rank value, '<--' hides rank
value, defined in config file.
postfix - text to show after the rank value, '-!>' hides rank
value, defined in config file.
verbose_output - the debug text depending on the verbose level.
output if error:
list of records - is None
list of rank values - is None
prefix - Contains headline of error
postfix - Error message or error box if exception.
verbose_output - the debug text depending on the verbose level.
"""
Examples:
>>> # import the function:
>>> from cdsware.bibrank_record_sorter import rank_records
>>> # rank all records with the words 'higgs boson' according to the method "wrd"
>>> rank_records('wrd', 0, a_hitset, ['higgs', 'boson'], 0)
>>> # find similar records to the record 12345, hitset is here ignored because of 'similar records'
>>> rank_records('wrd', 0, a_hitset, ['recid:12345'], 0)
>>> # rank all records based on jif value
>>> rank_records('jif', 0, a_hitset, [], 0)
2. Mid-level API
Description:
Using the mid-level API, you can call directly the various methods
for ranking. The functions will not return data in a way the search
engine understands. They will neither find out if it is the correct
function that is called, but return an error if wrong code/function
is used.
Signatures:
def combine_method(rank_method_code, pattern, hitset, rank_limit_relevance,verbose):
-This method calls each method mentioned in the config file and add the results together
def find_similar(rank_method_code, recID, hitset, rank_limit_relevance,
-This method finds similar records based on the one given in the recID field. The recID field
must be a integer value. hitset is ignored. rank_method_code has to be 'wrd'.
def word_frequency(rank_method_code, lwords, hitset, rank_limit_relevance,verbose):
-This method ranks records based on the list of words in lwords field. rank_method_code has to be
'wrd'. Only records in hitset is ranked.
def rank_by_method(rank_method_code, lwords, hitset, rank_limit_relevance,verbose):
-All other rank methods uses this function together with data from the rnkMETHODDATA table
(a dictionary of {recid: (text, value)} to rank the data. Only records in the hitset is ranked.
These mid-level API functions demands that the function create_rnkmethod_cache() has been called,
since it loads the config options needed.
The rank methods returns all the same data:
([[recid, value],[recid, value]], prefix, postfix, verbose_output)
Examples:
>>> # import the function:
>>> from cdsware.bibrank_record_sorter import find_similar
>>> # find records similar to 12345, hitset must be full
>>> find_similar('wrd', 12345, hitset, 0, 0)
>>> # rank records according to a method called jif, using the single_tag...based method.
>>> # the list of words is here ignored, only the records in the hitset are used.
>>> rank_by_method('jif',['higgs'], hitset, 0, 0)
>>> # rank records containing ['higgs', 'boson'] using word similarity ('wrd')
>>> word_similarity('wrd',['higgs', 'boson'], hitset, 0, 0)
>>> # rank records using various methods, which methods to use is read from the config file.
>>> combine_method('cmb', ['higgs','boson'], hitset, 0, 0)
</pre>
</protect>
diff --git a/modules/bibrank/doc/hacking/bibrankgkb.html.wml b/modules/bibrank/doc/hacking/bibrankgkb.html.wml
index c0e89bc2b..b32ea1553 100644
--- a/modules/bibrank/doc/hacking/bibrankgkb.html.wml
+++ b/modules/bibrank/doc/hacking/bibrankgkb.html.wml
@@ -1,91 +1,91 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Create knowledgebase files (bibrankgkb)" \
navbar_name="hacking-bibrank" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/bibrank/>BibRank Internals</a> " \
navbar_select="hacking-bibrank-index"
<pre>
<blockquotes>
<protect>
1. Read default configuration file or the one specified by the user
2. Read each create_ line from the cfg file, for each line, read the
source(s) from either database, file or www by calling get_from_source().
Convert between naming conventions if source for convertion data is given.
3. Merge into one file, repeat 2. until last source is read.
4. Save file if requested with --output
Configuration:
How to spesify a source:
-create_x = filter, source
Where x is a number from 0 and up. The source and the filter is read,
and each line in the source is checked against the filter to be converted
into the correct naming standard. If no filter is given, the source is
directly translated into a .kb file.
Read filter from:
File:
[bibrankgkb]
#give path to file containing lines like: COLLOID SURFACE A---Colloids Surf., A
kb_1_filter = <ETCDIR>/bibrank/bibrankgkb_jif_conv.kb
#replace filter with the line below (switch kb_1_filter with the variable names you used)
create_0 = file,,%(kb_1_filter)s
Read source from:
Database:
[bibrankgkb]
#Specify sql statements
kb_2 = SELECT id_bibrec,value FROM bib93x,bibrec_bib93x WHERE tag='938__f' AND id_bibxxx=id
kb_3 = SELECT id_bibrec,value FROM bib21x,bibrec_bib21x WHERE tag='210__a' AND id_bibxxx=id
#replace source with the line below (switch kb_2 and kb_3 with the variable names you used)
db,,%(kb_2)s,,%(kb_3)s
File:
[bibrankgkb]
#give path to file containing lines like: COLLOID SURFACE A---1.98
kb_1 = <ETCDIR>/bibrank/bibrankgkb_jif_example.kb
#replace source with the line below (switch kb_1 with the variable names you used)
create_0 = file,,%(kb_1)s
Internet:
[bibrankgkb]
#specify the urls to the file containing JIF data
url_0 = http://www.sciencegateway.org/impact/if03a.htm
url_1 = http://www.sciencegateway.org/impact/if03bc.htm
url_2 = http://www.sciencegateway.org/impact/if03df.htm
url_3 = http://www.sciencegateway.org/impact/if03gi.htm
url_4 = http://www.sciencegateway.org/impact/if03j.htm
url_5 = http://www.sciencegateway.org/impact/if03ko.htm
url_6 = http://www.sciencegateway.org/impact/if03pr.htm
url_7 = http://www.sciencegateway.org/impact/if03sz.htm
#give the regular expression necessary to extract the key and value from the file
<protect>
url_regexp = (TR bgColor=\#ffffff>\s*?\n\s*?<TD>(?P<key>.*?)</TD>\s*?\n\s*?<TD>.*?</TD>\s*?\n\s*?<TD .*?>.*?</TD>\s*?\n\s*?<TD .*?><A.*?\n.*?</TD>\s*?\n\s*?<TD.*?>(?P<value>[\w|,]+)</TD></TR>)
</protect>
#replace source with the line below (switch kb_4 and url_regexp with the variable names you used)
create_0 = www,,%(kb_4)s,,%(url_regexp)s
</protect>
</pre>
</blockquotes>
diff --git a/modules/bibrank/doc/hacking/index.html.wml b/modules/bibrank/doc/hacking/index.html.wml
index 7ab288e8b..b5937458c 100644
--- a/modules/bibrank/doc/hacking/index.html.wml
+++ b/modules/bibrank/doc/hacking/index.html.wml
@@ -1,45 +1,45 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibRank Internals" \
navbar_name="hacking-bibrank" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a>" \
navbar_select="hacking-bibrank-index"
This page summarizes all the information suitable to dig inside
BibRank and it's different ranking methods.
<blockquote>
<dl>
<dt><a href="single_tag_rank.html">Single tag rank method</a>
<dd>Ex. of use: Journal Impact Factor. Explains what this ranking method<br>
does to create the ranking data for use when ranking based on<br>
Journal Impact Factor or similar methods.</dd>
</dt>
<dt><a href="word_similarity.html">Word Similarity/Similar Records methods</a>
<dd>Ex. of use: Ranking based on the importance of words in the whole<br>
collection and in a single record. Explains how the ranking data is calculated.</dd>
</dt>
<dt><a href="api.html">Bibrank Record Sorter API</a>
<dd>How to call the Bibrank Record Sorter library from your python programs if necessary.</dd></dt>
<dt><a href="bibrankgkb.html">Create knowledgebase files (bibrankgkb)</a> <dd>Explains how to create knowledgebase files using the bibrankgkb tool</dd></dt>
</dl>
</blockquote>
diff --git a/modules/bibrank/doc/hacking/single_tag_rank.html.wml b/modules/bibrank/doc/hacking/single_tag_rank.html.wml
index b79224faa..0a6ad3e65 100644
--- a/modules/bibrank/doc/hacking/single_tag_rank.html.wml
+++ b/modules/bibrank/doc/hacking/single_tag_rank.html.wml
@@ -1,43 +1,43 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Single Tag Rank Method" \
navbar_name="hacking-bibrank" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/bibrank/>BibRank Internals</a> " \
navbar_select="hacking-bibrank-index"
<pre>
<blockquotes>
Process:
1. Any records that is going to be added is found.
2. If existing, and if a update is going to be done, existing data is
loaded from database.
3. The configuration file is loaded.
4. Loading knowledgebase file.
5. Getting records from the database containing the MARC21 tag from the
configfile, and which are among the ones to be updated.
6. The function will then go through all records, and if we have the
value for the record as a key in the kb file, the value from the kb
file will be associated to this record id. If the record id already has
a value, this will be replaced if the newest is higher than the old one,
and if there is no match in kb_data it will get the value -1.
7. The database is updated.
</pre>
</blockquotes>
diff --git a/modules/bibrank/doc/hacking/word_similarity.html.wml b/modules/bibrank/doc/hacking/word_similarity.html.wml
index dd86b7d34..d6ab9bd48 100644
--- a/modules/bibrank/doc/hacking/word_similarity.html.wml
+++ b/modules/bibrank/doc/hacking/word_similarity.html.wml
@@ -1,115 +1,115 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Word Similarity/Similar Records Methods" \
navbar_name="hacking-bibrank" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/bibrank/>BibRank Internals</a> " \
navbar_select="hacking-bibrank-index"
<pre>
<blockquote>
<b>Important regarding 'Word Similarity/Similar Records' method:</b>
Because of tight connection with the search_engine and database, there
can only be one method using the "word_similarity" template, and the
code for this method as designated in the BibRank admin interface has
to be 'wrd'.
<b>Preparing word similarity rank indexes:</b>
The 'Word similarity' method works by generating an index over terms in
the tags specified in the configuration file for the given records. The
data is stored in two tables, on forward and one reverse. The forward
index has a list of terms, where each term as a dictionary containing
records using this term. The reverse index contains the opposite, a list
of records, where each record contains a dictionary of the terms it
contains (for the selected tags). This means that the forward/reverse
index is to some degree similar to the tables created by BibIndex.
The main difference is that the rank method stores more information in
the table, based on how important the terms are, based on how many
times they have been used, and how important one term is in one
record. To minimize the number of terms to process, a few techniques
are used. Among these are stemming and stopword removal. Stemming
removes the end of a term, so that only the stem is left, this means
that 'looking' becomes 'look' and minimizes the size of the
database. Stopword removal removes very common words without meaning,
like 'the', 'one', 'me' in english. Terms that consists of numbers or
are below a certain limit is also ignored.
Since automatic language recognisition is not supported, each tag must
therefore be given a language for stemming to work. This means that in
the perfect world one tag should contain text in one language or
mostly in one language. If stemming is not wanted, the module can be
turned off, though lower rank quality may be expected.
Stopword removal works by checking if a term exists in a file, which
can contain any language necessary. Together with the default cdsware
installation, the file contains stopwords in french and english.
For a large CDSware installation (700 000 records), indexing takes
around 2 hours, including calculating the data needed for the
weighting scheme.
How the term importance is computed:
The method used is a variation of the well-known weighting scheme, the
vector model [1], in document retrieval. The method is described in
[2] and called 'Log-entropy' weigthing scheme. For more detailed
explanation of the scheme, the paper should be consulted. Since the
calculations necessary to calculate the number needed by the method is
too demanding, most of the numbers are calculated after the index over
term is created and stored in the database for later use.
<b>Step by step at index time:</b>(Using rebalance)
1. Load configuration for method
2. Begin a loop which loops through all records that should be added
3. Load content of tags in current record range
4. For each tag in all records, check each term if it should be used,
check against stopword list, use stemming, if accepted, add to a structure
the points from configfile for current tag.
5. Add to database the new values
6. Go back to 3 until no more records to be added.
7. Go through list of added terms, get list of all records containing these terms
8. Find all terms in records from last point.
9. For each record, calculate Fi, for each term calculate Gi
10.For each record, calculate normalization value Nj, add Gi value for each
term to the structure in reverse index.
11.Adding the Gi value to each term in forward index, and adding the
normalization value Nj to each term in each document
<b>Word Similarity at search/rank time:</b>
1. For each term, check if it can be used (like check agains stopword list),
use stemming on the term if possible.
2. For each term, get dictionary from forward index, calculate rank values
for each term.
3. Add any records not ranked to end of list.
4. Sort records.
5. Return sorted records
<b>Similar records at search/rank time:</b>
1. Get terms from reverse index which exists in record.
2. Sort terms and use only the most important ones for finding similar records.
3. For selected terms, rank the associated records
4. Sort records
5. Return sorted records
<b>References:</b>
[1] Modern Information Retrieval. Baeza-Yates/Ribeiro-Neto
[2] New term weighting formulas for the vector space method in information retrieval.
ORNL/TM-13756.E.Chisholm/T.G.Kolda
</pre>
\ No newline at end of file
diff --git a/modules/bibrank/etc/Makefile.am b/modules/bibrank/etc/Makefile.am
index 819c70c13..5cede9929 100644
--- a/modules/bibrank/etc/Makefile.am
+++ b/modules/bibrank/etc/Makefile.am
@@ -1,62 +1,62 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir = $(sysconfdir)/bibrank
etc_DATA = bibrankgkb.cfg \
bibrankgkb_jif_conv.kb \
bibrankgkb_jif_example.kb \
demo_jif.cfg \
demo_jif.kb \
stopwords.de.kb \
stopwords.kb \
template_citation.cfg \
template_combine_method.cfg \
template_download_similarity.cfg \
template_download_total.cfg \
template_download_users.cfg \
template_single_tag_rank_method.cfg \
template_word_similarity.cfg \
wrd.cfg
EXTRA_DIST = bibrankgkb.cfg.in \
bibrankgkb_jif_conv.kb \
bibrankgkb_jif_example.kb \
demo_jif.cfg.in \
demo_jif.kb \
stopwords.de.kb \
stopwords.kb \
template_citation.cfg \
template_combine_method.cfg \
template_download_similarity.cfg \
template_download_total.cfg \
template_download_users.cfg \
template_single_tag_rank_method.cfg.in \
template_word_similarity.cfg.wml \
wrd.cfg.wml
CLEANFILES = template_word_similarity.cfg wrd.cfg *.tmp
wrd.cfg: wrd.cfg.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdspage.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
template_word_similarity.cfg: template_word_similarity.cfg.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdspage.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibrank/etc/bibrankgkb.cfg.in b/modules/bibrank/etc/bibrankgkb.cfg.in
index f4868047f..b72c7fad0 100644
--- a/modules/bibrank/etc/bibrankgkb.cfg.in
+++ b/modules/bibrank/etc/bibrankgkb.cfg.in
@@ -1,37 +1,37 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[bibrankgkb]
url_0 = http://www.sciencegateway.org/impact/if03a.htm
url_1 = http://www.sciencegateway.org/impact/if03bc.htm
url_2 = http://www.sciencegateway.org/impact/if03df.htm
url_3 = http://www.sciencegateway.org/impact/if03gi.htm
url_4 = http://www.sciencegateway.org/impact/if03j.htm
url_5 = http://www.sciencegateway.org/impact/if03ko.htm
url_6 = http://www.sciencegateway.org/impact/if03pr.htm
url_7 = http://www.sciencegateway.org/impact/if03sz.htm
url_regexp = (TR bgColor=\#ffffff>\s*?\n\s*?<TD>(?P<key>.*?)</TD>\s*?\n\s*?<TD>.*?</TD>\s*?\n\s*?<TD .*?>.*?</TD>\s*?\n\s*?<TD .*?><A.*?\n.*?</TD>\s*?\n\s*?<TD.*?>(?P<value>[\w|,]+)</TD></TR>)
kb_1 = @prefix@/etc/bibrank/bibrankgkb_jif_example.kb
kb_1_filter = @prefix@/etc/bibrank/bibrankgkb_jif_conv.kb
kb_2 = SELECT id_bibrec,value FROM bib93x,bibrec_bib93x WHERE tag='938__f' AND id_bibxxx=id
kb_3 = SELECT id_bibrec,value FROM bib21x,bibrec_bib21x WHERE tag='210__a' AND id_bibxxx=id
kb_4 = url_%s
#create_0 = file,,%(kb_1_filter)s,,file,,%(kb_1)s
create_0 = ,, ,,www,,%(kb_4)s,,%(url_regexp)s
#create_0 = ,, ,,db,,%(kb_2)s,,%(kb_3)s
diff --git a/modules/bibrank/etc/bibrankgkb_jif_conv.kb b/modules/bibrank/etc/bibrankgkb_jif_conv.kb
index c77ead330..8b0a39f76 100644
--- a/modules/bibrank/etc/bibrankgkb_jif_conv.kb
+++ b/modules/bibrank/etc/bibrankgkb_jif_conv.kb
@@ -1,17 +1,17 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
COLLOID SURFACE A---Colloids Surf., A
diff --git a/modules/bibrank/etc/bibrankgkb_jif_example.kb b/modules/bibrank/etc/bibrankgkb_jif_example.kb
index 8486119f7..685d54d0a 100644
--- a/modules/bibrank/etc/bibrankgkb_jif_example.kb
+++ b/modules/bibrank/etc/bibrankgkb_jif_example.kb
@@ -1,17 +1,17 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
COLLOID SURFACE A---1.98
diff --git a/modules/bibrank/etc/demo_jif.cfg.in b/modules/bibrank/etc/demo_jif.cfg.in
index 6c57cea7f..299a15ae0 100644
--- a/modules/bibrank/etc/demo_jif.cfg.in
+++ b/modules/bibrank/etc/demo_jif.cfg.in
@@ -1,26 +1,26 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = single_tag_rank_method
[single_tag_rank_method]
tag = 909C4p
kb_src = @prefix@/etc/bibrank/demo_jif.kb
check_mandatory_tags =
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/demo_jif.kb b/modules/bibrank/etc/demo_jif.kb
index fa479495e..268826a89 100644
--- a/modules/bibrank/etc/demo_jif.kb
+++ b/modules/bibrank/etc/demo_jif.kb
@@ -1,21 +1,21 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
Phys. Rev., D---3.838
Phys. Rev. Lett.---6.462
Phys. Lett., B---4.213
Nucl. Instrum. Methods Phys. Res., A---0.964
J. High Energy Phys.---8.664
diff --git a/modules/bibrank/etc/stopwords.de.kb b/modules/bibrank/etc/stopwords.de.kb
index 8f29bcdd8..ed65872e7 100644
--- a/modules/bibrank/etc/stopwords.de.kb
+++ b/modules/bibrank/etc/stopwords.de.kb
@@ -1,369 +1,369 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
ab
aber
abgesehen
alle
allein
aller
alles
als
am
an
andere
anderen
anderenfalls
anderer
anderes
anstatt
auch
auf
aus
aussen
außen
ausser
außer
ausserdem
außerdem
außerhalb
ausserhalb
behalten
bei
beide
beiden
beider
beides
beinahe
bevor
bin
bis
bist
bitte
da
daher
danach
dann
darueber
darüber
darueberhinaus
darüberhinaus
darum
das
dass
daß
dem
den
der
des
deshalb
die
diese
diesem
diesen
dieser
dieses
dort
duerfte
duerften
duerftest
duerftet
dürfte
dürften
dürftest
dürftet
durch
durfte
durften
durftest
durftet
ein
eine
einem
einen
einer
eines
einige
einiger
einiges
entgegen
entweder
erscheinen
es
etwas
fast
fertig
fort
fuer
für
gegen
gegenueber
gegenüber
gehalten
geht
gemacht
gemaess
gemäß
genug
getan
getrennt
gewesen
gruendlich
gründlich
habe
haben
habt
haeufig
häufig
hast
hat
hatte
hatten
hattest
hattet
hier
hindurch
hintendran
hinter
hinunter
ich
ihm
ihnen
ihr
ihre
ihrem
ihren
ihrer
ihres
ihrige
ihrigen
ihriges
immer
in
indem
innerhalb
innerlich
irgendetwas
irgendwelche
irgendwenn
irgendwo
irgendwohin
ist
jede
jedem
jeden
jeder
jedes
jedoch
jemals
jemand
jemandem
jemanden
jemandes
jene
jung
junge
jungem
jungen
junger
junges
kann
kannst
kaum
koennen
koennt
koennte
koennten
koenntest
koenntet
können
könnt
könnte
könnten
könntest
könntet
konnte
konnten
konntest
konntet
machen
macht
machte
mehr
mehrere
mein
meine
meinem
meinen
meiner
meines
meistens
mich
mir
mit
muessen
müssen
muesst
müßt
muß
muss
musst
mußt
nach
nachdem
naechste
nächste
nebenan
nein
nichts
niemand
niemandem
niemanden
niemandes
nirgendwo
nur
oben
obwohl
oder
oft
ohne
pro
sagte
sagten
sagtest
sagtet
scheinen
sehr
sei
seid
seien
seiest
seiet
sein
seine
seinem
seinen
seiner
seines
seit
selbst
sich
sie
sind
so
sogar
solche
solchem
solchen
solcher
solches
sollte
sollten
solltest
solltet
sondern
statt
stets
tatsächlich
tatsaechlich
tief
tun
tut
ueber
über
ueberall
überll
um
und
uns
unser
unsere
unserem
unseren
unserer
unseres
unten
unter
unterhalb
usw
viel
viele
vielleicht
von
vor
vorbei
vorher
vorueber
vorüber
waehrend
während
wann
war
waren
warst
wart
was
weder
wegen
weil
weit
weiter
weitere
weiterem
weiteren
weiterer
weiteres
welche
welchem
welchen
welcher
welches
wem
wen
wenige
wenn
wer
werde
werden
werdet
wessen
wie
wieder
wir
wird
wirklich
wirst
wo
wohin
wuerde
wuerden
wuerdest
wuerdet
würde
würden
würdest
würdet
wurde
wurden
wurdest
wurdet
ziemlich
zu
zum
zur
zusammen
zwischen
diff --git a/modules/bibrank/etc/stopwords.kb b/modules/bibrank/etc/stopwords.kb
index 427269f9e..b731892aa 100644
--- a/modules/bibrank/etc/stopwords.kb
+++ b/modules/bibrank/etc/stopwords.kb
@@ -1,1122 +1,1122 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
a
about
above
according
across
actually
adj
after
afterwards
again
against
ago
align
all
almost
alone
along
already
also
although
always
among
amongst
an
and
another
any
anyhow
anyone
anything
anywhere
are
aren't
around
as
at
b
be
became
because
become
becomes
becoming
been
before
beforehand
begin
behind
being
below
beside
besides
between
beyond
both
but
by
c
can
can't
cannot
caption
ch
co
co.
could
couldn't
d
did
didn't
do
does
doesn't
don't
down
during
e
each
eg
eight
eighty
either
else
elsewhere
end
ending
enough
etc
even
ever
every
everyone
everything
everywhere
except
f
few
five
first
for
found
four
from
further
g
h
had
has
hasn't
have
haven't
he
he'd
he'll
he's
hence
her
here
here's
hereafter
hereby
herein
hereupon
hers
herself
him
himself
his
href
how
however
hundred
i
i'd
i'll
i'm
i've
ie
if
img
in
inc.
indeed
instead
into
is
isn't
it
it's
its
itself
j
jpg
k
l
last
later
latter
latterly
least
less
let
let's
like
likely
ltd
m
made
make
makes
many
mar
may
maybe
me
meantime
meanwhile
might
miss
more
moreover
most
mostly
mr
mrs
much
must
my
myself
n
namely
neither
never
nevertheless
next
nine
ninety
no
nobody
none
nonetheless
noone
nor
not
nothing
nowhere
nowrap
o
of
off
often
on
once
one
one's
only
onto
or
org
other
others
otherwise
our
ours
ourselves
out
over
overall
own
p
per
perhaps
q
quot
r
rather
recent
recently
s
same
seem
seemed
seeming
seems
seven
several
src
she
she'd
she'll
she's
should
shouldn't
since
six
so
some
somehow
someone
something
sometime
sometimes
somewhere
still
such
t
taking
ten
than
that
that'll
that's
that've
the
their
them
themselves
then
thence
there
there'd
there'll
there're
there's
there've
thereafter
thereby
therefore
therein
thereupon
these
they
they'd
they'll
they're
they've
thirty
this
those
though
three
through
throughout
thru
thus
to
together
too
top
toward
towards
two
u
under
unless
unlike
unlikely
until
up
upon
us
used
using
v
valign
very
via
w
was
wasn't
we
we'd
we'll
we're
we've
well
were
weren't
what
what'll
what's
what've
whatever
when
whence
whenever
where
where's
whereafter
whereas
whereby
wherein
whereupon
wherever
whether
which
while
whither
who
who'd
who'll
who's
whoever
whole
whom
whomever
whose
why
will
with
within
without
won't
would
wouldn't
x
y
yes
yet
you
you'd
you'll
you're
you've
your
yours
yourself
yourselves
z
$
£
a
A
à
afin
ah
ai
aie
aient
aies
ailleurs
ainsi
ait
alentour
alias
allais
allaient
allait
allons
allez
alors
Ap.
Apr.
apres
apres-demain
arriere
as
assez
attendu
au
aucun
aucune
au-dedans
au-dehors
au-dela
au-dessous
au-dessus
au-devant
audit
aujourd
auparavant
aupres
auquel
aura
aurai
auraient
aurais
aurait
auras
aurez
auriez
aurions
aurons
auront
aussi
aussitot
autant
autour
autre
autrefois
autres
autrui
aux
auxdites
auxdits
auxquelles
auxquels
avaient
avais
avait
avant
avant-hier
avec
avez
aviez
avions
avoir
avons
ayant
ayez
ayons
B
bah
banco
be
beaucoup
ben
bien
bientot
bis
bon
C
c'
c.-a-d.
Ca
ca
cahin-caha
car
ce
-ce
ceans
ceci
cela
celle
celle-ci
celle-la
celles
celles-ci
celles-la
celui
celui-ci
celui-la
cent
cents
cependant
certain
certaine
certaines
certains
certes
ces
c'est-a-dire
cet
cette
ceux
ceux-ci
ceux-la
cf.
cg
cgr
chacun
chacune
chaque
cher
chez
ci
-ci
ci-apres
ci-dessous
ci-dessus
cinq
cinquante
cinquante-cinq
cinquante-deux
cinquante-et-un
cinquante-huit
cinquante-neuf
cinquante-quatre
cinquante-sept
cinquante-six
cinquante-trois
cl
cm
combien
comme
comment
contrario
contre
crescendo
D
d'
d'abord
d'accord
d'affilee
d'ailleurs
dans
d'apres
d'arrache-pied
davantage
de
debout
dedans
dehors
deja
dela
demain
d'emblee
depuis
derechef
derriere
des
des
desdites
desdits
desormais
desquelles
desquels
dessous
dessus
deux
devant
devers
dg
die
differentes
differents
dire
dis
disent
dit
dito
divers
diverses
dix
dix-huit
dix-neuf
dix-sept
dl
dm
donc
dont
dorenavant
douze
du
du
dudit
duquel
durant
E
eh
elle
-elle
elles
-elles
en
'en
-en
encore
enfin
ensemble
ensuite
entre
entre-temps
envers
environ
es
es
est
et
et/ou
etaient
etais
etait
etant
etc
ete
etes
etiez
etions
etre
eu
eue
eues
euh
eumes
eurent
eus
eusse
eussent
eusses
eussiez
eussions
eut
eut
eutes
eux
expres
extenso
extremis
F
facto
fallait
faire
fais
faisais
faisait
faisaient
faisons
fait
faites
faudrait
faut
fi
flac
fors
fort
forte
fortiori
frais
fumes
fur
furent
fus
fusse
fussent
fusses
fussiez
fussions
fut
fut
futes
G
GHz
gr
grosso
guere
H
ha
han
haut
he
hein
hem
heu
hg
hier
hl
hm
hm
hola
hop
hormis
hors
hui
huit
hum
I
ibidem
ici
ici-bas
idem
il
-il
illico
ils
-ils
ipso
item
J
j'
jadis
jamais
je
-je
jusqu'
jusqu'a
jusqu'au
jusqu'aux
jusque
juste
K
kg
km
km²
L
l'
la
-la
la
-la
la-bas
la-dedans
la-dehors
la-derriere
la-dessous
la-dessus
la-devant
la-haut
laquelle
l'autre
le
-le
lequel
les
-les
les
lesquelles
lesquels
leur
-leur
leurs
lez
loin
l'on
longtemps
lors
lorsqu'
lorsque
lui
-lui
l'un
l'une
M
ma
maint
mainte
maintenant
maintes
maints
mais
mal
malgre
me
meme
memes
mes
mg
mgr
MHz
mieux
mil
mille
milliards
millions
minima
ml
mm
modo
moi
-moi
moins
mon
moult
moyennant
mt
N
n'
naguere
ne
neanmoins
neuf
ni
non
nonante
nonobstant
nos
notre
nous
-nous
nul
nulle
O
o
octante
oh
on
-on
ont
onze
or
ou
ou
ouais
oui
outre
P
par
parbleu
parce
par-ci
par-dela
par-derriere
par-dessous
par-dessus
par-devant
parfois
par-la
parmi
partout
pas
passe
passim
pendant
personne
petto
peu
peut
peuvent
peux
peut-etre
pis
plus
plusieurs
plutot
point
posteriori
pour
pourquoi
pourtant
prealable
pres
presqu'
presque
primo
priori
prou
pu
puis
puisqu'
puisque
Q
qu'
qua
quand
quarante
quarante-cinq
quarante-deux
quarante-et-un
quarante-huit
quarante-neuf
quarante-quatre
quarante-sept
quarante-six
quarante-trois
quasi
quatorze
quatre
quatre-vingt
quatre-vingt-cinq
quatre-vingt-deux
quatre-vingt-dix
quatre-vingt-dix-huit
quatre-vingt-dix-neuf
quatre-vingt-dix-sept
quatre-vingt-douze
quatre-vingt-huit
quatre-vingt-neuf
quatre-vingt-onze
quatre-vingt-quatorze
quatre-vingt-quatre
quatre-vingt-quinze
quatre-vingts
quatre-vingt-seize
quatre-vingt-sept
quatre-vingt-six
quatre-vingt-treize
quatre-vingt-trois
quatre-vingt-un
quatre-vingt-une
que
quel
quelle
quelles
quelqu'
quelque
quelquefois
quelques
quelques-unes
quelques-uns
quelqu'un
quelqu'une
quels
qui
quiconque
quinze
quoi
quoiqu'
quoique
R
revoici
revoila
rien
S
s'
sa
sans
sauf
se
secundo
seize
selon
sensu
sept
septante
sera
serai
seraient
serais
serait
seras
serez
seriez
serions
serons
seront
ses
si
sic
sine
sinon
sitot
situ
six
soi
soient
sois
soit
soixante
soixante-cinq
soixante-deux
soixante-dix
soixante-dix-huit
soixante-dix-neuf
soixante-dix-sept
soixante-douze
soixante-et-onze
soixante-et-un
soixante-et-une
soixante-huit
soixante-neuf
soixante-quatorze
soixante-quatre
soixante-quinze
soixante-seize
soixante-sept
soixante-six
soixante-treize
soixante-trois
sommes
son
sont
soudain
sous
souvent
soyez
soyons
stricto
suis
sur
sur-le-champ
surtout
sus
T
-t
t'
ta
tacatac
tant
tantot
tard
te
tel
telle
telles
tels
ter
tes
toi
-toi
ton
tot
toujours
tous
tout
toute
toutefois
toutes
treize
trente
trente-cinq
trente-deux
trente-et-un
trente-huit
trente-neuf
trente-quatre
trente-sept
trente-six
trente-trois
tres
trois
trop
tu
-tu
U
un
une
unes
uns
USD
V
va
vais
vas
vers
veut
veux
via
vice-versa
vingt
vingt-cinq
vingt-deux
vingt-huit
vingt-neuf
vingt-quatre
vingt-sept
vingt-six
vingt-trois
vis-a-vis
vite
vitro
vivo
voici
voila
voire
volontiers
vos
votre
vous
-vous
W
X
y
-y
Z
zero
diff --git a/modules/bibrank/etc/template_citation.cfg b/modules/bibrank/etc/template_citation.cfg
index 975509d99..4c5696016 100644
--- a/modules/bibrank/etc/template_citation.cfg
+++ b/modules/bibrank/etc/template_citation.cfg
@@ -1,29 +1,29 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = citation
[citation]
publication_primary_number_tag = 037a
publication_aditional_number_tag = 088a
publication_reference_number_tag = 999C5r
publication_reference_tag = 999C5s
publication_info_tag = 773s
publication_year_tags = 773y,260c
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/template_combine_method.cfg b/modules/bibrank/etc/template_combine_method.cfg
index cb8345a1a..83c96ad07 100644
--- a/modules/bibrank/etc/template_combine_method.cfg
+++ b/modules/bibrank/etc/template_combine_method.cfg
@@ -1,27 +1,27 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = combine_method
[combine_method]
method1 = cern_jif,50
method2 = wrd,50
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/template_download_similarity.cfg b/modules/bibrank/etc/template_download_similarity.cfg
index 4264de036..d2f4e4710 100644
--- a/modules/bibrank/etc/template_download_similarity.cfg
+++ b/modules/bibrank/etc/template_download_similarity.cfg
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = file_similarity_by_times_downloaded
[file_similarity_by_times_downloaded]
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/template_download_total.cfg b/modules/bibrank/etc/template_download_total.cfg
index 12952319d..db2732472 100644
--- a/modules/bibrank/etc/template_download_total.cfg
+++ b/modules/bibrank/etc/template_download_total.cfg
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = download_weight_total
[download_weight_total]
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/template_download_users.cfg b/modules/bibrank/etc/template_download_users.cfg
index 2932fca29..39ff4ca8c 100644
--- a/modules/bibrank/etc/template_download_users.cfg
+++ b/modules/bibrank/etc/template_download_users.cfg
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = download_weight_filtering_user
[download_weight_filtering_user]
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/template_single_tag_rank_method.cfg.in b/modules/bibrank/etc/template_single_tag_rank_method.cfg.in
index 495aca7ec..a80fd4733 100644
--- a/modules/bibrank/etc/template_single_tag_rank_method.cfg.in
+++ b/modules/bibrank/etc/template_single_tag_rank_method.cfg.in
@@ -1,26 +1,26 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
[rank_method]
function = single_tag_rank_method
[single_tag_rank_method]
tag = 909C4p
kb_src = @prefix@/etc/bibrank/jif.kb
check_mandatory_tags = 909C4c,909C4v,909C4y
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
diff --git a/modules/bibrank/etc/template_word_similarity.cfg.wml b/modules/bibrank/etc/template_word_similarity.cfg.wml
index c95bfe351..81555036f 100644
--- a/modules/bibrank/etc/template_word_similarity.cfg.wml
+++ b/modules/bibrank/etc/template_word_similarity.cfg.wml
@@ -1,79 +1,79 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "config.wml"
[rank_method]
function = word_similarity
[word_similarity]
#None = no stemming
stemming = <CDSLANG>
table = rnkWORD01F
#using stopwordlist from /bibindex/bibindex_engine_config
stopword = True
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
#MARC tag,tag points, tag language
#keyword
tag1 = 6531_a, 1, <cdslang>
#keyword
tag2 = 695__a, 1, <cdslang>
#keyword
tag3 = 6532_a, 1, <cdslang>
#title
tag4 = 245__%, 10, <cdslang>
#title
tag5 = 246_%, 1, fr
#title
tag6 = 250__a, 1, <cdslang>
#title
tag7 = 711__a, 1, <cdslang>
#abbreviated
tag8 = 210__a, 1, <cdslang>
#key title
tag9 = 222__a, 1, <cdslang>
#abstract
tag10 = 520__%, 1, <cdslang>
#abstract
tag11 = 590__%, 1, fr
#conference
tag12 = 111__a, 1, <cdslang>
#author
tag13 = 100__%, 1, none
#author
tag14 = 700__%, 1, none
#author
tag15 = 721__a, 1, none
[find_similar]
#term should exist in maximum X/100% of documents
max_word_occurence = 0.05
#term should exist in minimum X/100% of documents
min_word_occurence = 0.00
#term should be atleast 3 characters long
min_word_length = 3
#term should be in atleast 3 documents or more
min_nr_words_docs = 3
#do not use more than 20 terms for "find similar"
max_nr_words_upper = 20
#if a document contains less than 10 terms, use much used terms too, if not ignore them
max_nr_words_lower = 10
#default minimum relevance value to use for find similar
default_min_relevance = 75
diff --git a/modules/bibrank/etc/wrd.cfg.wml b/modules/bibrank/etc/wrd.cfg.wml
index 96056a6c0..6bbe58410 100644
--- a/modules/bibrank/etc/wrd.cfg.wml
+++ b/modules/bibrank/etc/wrd.cfg.wml
@@ -1,69 +1,69 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "config.wml"
[rank_method]
function = word_similarity
[word_similarity]
#None = no stemming
stemming = <CDSLANG>
table = rnkWORD01F
#using stopword list from /bibindex/bibindex_engine_config
#False = no stopword removal
stopword = True
relevance_number_output_prologue = (
relevance_number_output_epilogue = )
#relevance_number_output_prologue = <!-
#relevance_number_output_epilogue = -->
#MARC tag,tag points, tag language
tag1 = 6531_a, 2, <CDSLANG>
tag2 = 695__a, 1, <CDSLANG>
tag3 = 6532_a, 1, <CDSLANG>
tag4 = 245__%, 10, <CDSLANG>
tag5 = 246_%, 1, fr
tag6 = 250__a, 1, <CDSLANG>
tag7 = 711__a, 1, <CDSLANG>
tag8 = 210__a, 1, <CDSLANG>
tag9 = 222__a, 1, <CDSLANG>
tag10 = 520__%, 1, <CDSLANG>
tag11 = 590__%, 1, fr
tag12 = 111__a, 1, <CDSLANG>
tag13 = 100__%, 2, none
tag14 = 700__%, 1, none
tag15 = 721__a, 1, none
[find_similar]
#term should exist in maximum X/100% of documents
max_word_occurence = 0.05
#term should exist in minimum X/100% of documents
min_word_occurence = 0.00
#term should be atleast 3 characters long
min_word_length = 3
#term should be in atleast 3 documents or more
min_nr_words_docs = 3
#do not use more than 20 terms for "find similar"
max_nr_words_upper = 20
#if a document contains less than 10 terms, use much used terms too, if not ignore them
max_nr_words_lower = 10
#default minimum relevance value to use for find similar
default_min_relevance = 75
diff --git a/modules/bibrank/lib/Makefile.am b/modules/bibrank/lib/Makefile.am
index 067a22772..caf063e35 100644
--- a/modules/bibrank/lib/Makefile.am
+++ b/modules/bibrank/lib/Makefile.am
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = bibrankadminlib.py \
bibrank_tag_based_indexer.py bibrank_tag_based_indexer_tests.py \
bibrank_word_indexer.py \
bibrank_record_sorter.py bibrank_record_sorter_tests.py \
bibrank_downloads_indexer.py bibrank_downloads_indexer_tests.py \
bibrank_downloads_similarity.py \
bibrank_grapher.py bibrank_downloads_grapher.py bibrank_citation_grapher.py \
bibrank_citation_indexer.py bibrank_citation_indexer_tests.py \
bibrank_citation_searcher.py bibrank_citation_searcher_tests.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/bibrank/lib/bibrank_citation_grapher.py b/modules/bibrank/lib/bibrank_citation_grapher.py
index baa147913..781cbcc77 100644
--- a/modules/bibrank/lib/bibrank_citation_grapher.py
+++ b/modules/bibrank/lib/bibrank_citation_grapher.py
@@ -1,133 +1,133 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import os
import time
import tempfile
from marshal import loads
from zlib import decompress
from cdsware.config import weburl, cdslang
from cdsware.dbquery import run_sql
from cdsware.messages import gettext_set_language
from cdsware.bibrank_grapher import create_temporary_image, write_coordinates_in_tmp_file, remove_old_img
from cdsware.bibrank_citation_searcher import calculate_cited_by_list
cfg_bibrank_print_citation_history = 1
color_line_list = ['9', '19', '10', '15', '21', '18']
def get_field_values(recID, tag):
"""Return list of field values for field tag inside record RECID."""
out = []
if tag == "001___":
out.append(str(recID))
else:
digit = tag[0:2]
bx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag LIKE '%s'" "ORDER BY bibx.field_number, bx.tag ASC" % (bx, bibx, recID, tag)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def calculate_citation_history_coordinates(recid):
"""Return a list of citation graph coordinates for RECID, sorted by year."""
result = []
initial_result= get_initial_result(calculate_citation_graphe_x_coordinates(recid))
citlist = calculate_cited_by_list(recid)
for rec_id, cit_weight in citlist:
cit_year = get_field_values(rec_id,'773__y')
if not cit_year: cit_year = get_field_values(rec_id, '260__c')
#print rec_idh,str(cit_year[0])
if initial_result.has_key(int(cit_year[0][0:4])):
initial_result[int(cit_year[0][0:4])] += 1
for key, value in initial_result.items():
result.append((key, value))
result.sort()
return result
def calculate_citation_graphe_x_coordinates(recid):
"""Return a range of year from the publication year of record RECID
until the current year."""
rec_years = []
recordyear = get_field_values(recid, '773__y')
if not recordyear: recordyear = get_field_values(recid, '260__c')
currentyear = time.localtime()[0]
if recordyear == []:
recordyear = currentyear
else:
recordyear = find_year(recordyear[0])
interval = range(int(recordyear), currentyear+1)
return interval
def find_year(recordyear):
"""find the year in the string as a suite of 4 int"""
s = ""
for i in range(len(recordyear)-3):
s = recordyear[i:i+4]
if s.isalnum():
print s
break
return s
def get_initial_result(rec_years):
"""return an initial dictionary with year of record publication as key
and zero as value
"""
result = {}
for year in rec_years :
result[year] = 0
return result
def html_command(file):
t = """<img src='%s/img/%s' align="center" alt="">""" % (weburl, file)
#t += "</table></td></tr></table>"
return t
def create_citation_history_graph_and_box(recid, ln=cdslang):
"""Create graph with citation history for record RECID (into a
temporary file) and return HTML box refering to that image.
Called by Detailed record pages.
"""
_ = gettext_set_language(ln)
html_result = ""
if cfg_bibrank_print_citation_history:
coordinates = calculate_citation_history_coordinates(recid)
if coordinates:
html_head = """</br><table><tr><td class="blocknote">%s</td></tr></table>""" % _("Citation history:")
graphe_file_name = 'citation_%s_stats.png' % str(recid)
remove_old_img(graphe_file_name)
years = calculate_citation_graphe_x_coordinates(recid)
years.sort()
datas_info = write_coordinates_in_tmp_file([coordinates])
graphe = create_temporary_image(recid, 'citation', datas_info[0], 'Year', 'Times Cited', [0,0], datas_info[1], [], ' ', years)
graphe_image = graphe[0]
graphe_source_file = graphe[1]
if graphe_image and graphe_source_file:
if os.path.exists(graphe_source_file):
os.unlink(datas_info[0])
html_graphe_code = """<p>%s"""% html_command(graphe_image)
html_result = html_head + html_graphe_code
return html_result
diff --git a/modules/bibrank/lib/bibrank_citation_indexer.py b/modules/bibrank/lib/bibrank_citation_indexer.py
index 62f46619c..fd46314dd 100644
--- a/modules/bibrank/lib/bibrank_citation_indexer.py
+++ b/modules/bibrank/lib/bibrank_citation_indexer.py
@@ -1,295 +1,295 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import MySQLdb
import time
import os
from marshal import loads, dumps
from zlib import decompress, compress
from cdsware.dbquery import run_sql
from cdsware.search_engine import print_record, search_pattern
from cdsware.bibrecord import create_records, record_get_field_values
class memoise:
def __init__(self, function):
self.memo = {}
self.function = function
def __call__(self, *args):
if self.memo.has_key(args):
return self.memo[args]
else:
object = self.memo[args] = self.function(*args)
return object
def get_recids_matching_query(pvalue, fvalue):
"""Return list of recIDs matching query for PVALUE and FVALUE."""
rec_id = search_pattern(p=pvalue, f=fvalue, m='e').tolist()
return rec_id
get_recids_matching_query = memoise(get_recids_matching_query)
def get_citation_weight(rank_method_code, config):
"""return a dictionary which is used by bibrank daemon for generating
the index of sorted research results by citation inforamtion
"""
begin_time = time.time()
last_update_time = get_bibrankmethod_lastupdate(rank_method_code)
last_modified_records = get_last_modified_rec(last_update_time)
if last_modified_records:
updated_recid_list = create_recordid_list(last_modified_records)
result_intermediate = last_updated_result(rank_method_code, updated_recid_list)
citation_weight_dic_intermediate = result_intermediate[0]
citation_list_intermediate = result_intermediate[1]
reference_list_intermediate = result_intermediate[2]
citation_informations = get_citation_informations(updated_recid_list, config)
dic = ref_analyzer(citation_informations, citation_weight_dic_intermediate, citation_list_intermediate, reference_list_intermediate)
end_time = time.time()
print "Total time of software: ", (end_time - begin_time)
else:
dic = {}
print "No new records added since last time this rank method was executed"
return dic
def get_bibrankmethod_lastupdate(rank_method_code):
"""return the last excution date of bibrank method
"""
query = """select last_updated from rnkMETHOD where name ='%s'""" % rank_method_code
last_update_time = run_sql(query)
return last_update_time[0][0]
def get_last_modified_rec(bibrank_method_lastupdate):
""" return the list of recods which have been modified after the last execution
of bibrank method. The result is expected to have ascending numerical order.
"""
query = """SELECT id FROM bibrec WHERE modification_date>= '%s' """ % bibrank_method_lastupdate
query += "order by id ASC"
list = run_sql(query)
return list
def create_recordid_list(rec_ids):
"""Create a list of record ids out of RECIDS. The result is expected to have ascending numerical order.
"""
rec_list = []
for row in rec_ids:
rec_list.append(row[0])
return rec_list
def create_record_tuple(list):
"""Creates a tuple of record id from a list of id.
The result is expected to have ascending numerical order.
"""
list_length = len(list)
if list_length:
rec_tuple = '('
for row in list[0:list_length-1]:
rec_tuple += str(row)
rec_tuple += ','
rec_tuple += str(list[list_length-1])
rec_tuple += ')'
else: rec_tuple = '()'
return rec_tuple
def last_updated_result(rank_method_code, recid_list):
""" return the last value of dictionary in rnkMETHODDATA table if it exists and
initialize the value of last updated records by zero,otherwise an initial dictionary
with zero as value for all recids
"""
query = """select relevance_data from rnkMETHOD, rnkMETHODDATA where
rnkMETHOD.id = rnkMETHODDATA.id_rnkMETHOD and rnkMETHOD.Name = '%s'"""% rank_method_code
dict = run_sql(query)
if dict:
dic = loads(decompress(dict[0][0]))
query = "select citation_data from rnkCITATIONDATA"
cit_compressed = run_sql(query)
cit = loads(decompress(cit_compressed[0][0]))
query = "select citation_data_reversed from rnkCITATIONDATA"
ref_compressed = run_sql(query)
ref = loads(decompress(ref_compressed[0][0]))
result = get_initial_result(dic, cit, ref, recid_list)
else: result = make_initial_result()
return result
def get_initial_result(dic, cit, ref, recid_list):
"""initialieze the citation weights of the last updated record with zero for
recalculating it later
"""
for recid in recid_list:
dic[recid] = 0
cit[recid] = []
if ref.has_key(recid) and ref[recid]:
for id in ref[recid]:
if cit.has_key(id) and recid in cit[id]:
cit[id].remove(recid)
dic[id] -= 1
if cit.has_key(recid) and cit[recid]:
for id in cit[recid]:
if ref.has_key(id) and recid in ref[id]:
ref[id].remove(recid)
ref[recid] = []
return [dic, cit, ref]
def make_initial_result():
"""return an initial dictinary with recID as key and zero as value
"""
dic = {}
cit = {}
ref = {}
query = "select id from bibrec"
res = run_sql(query)
for key in res:
dic[key[0]] = 0
cit[key[0]] = []
ref[key[0]] = []
return [dic, cit, ref]
def get_citation_informations(recid_list, config):
"""return une dictionary that contains the citation information of cds records
"""
begin_time = os.times()[4]
d_reports_numbers = {}
d_references_report_numbers = {}
d_references_s = {}
d_records_s = {}
citation_informations = []
record_pri_number_tag = config.get(config.get("rank_method", "function"),"publication_primary_number_tag")
record_add_number_tag = config.get(config.get("rank_method", "function"),"publication_aditional_number_tag")
reference_number_tag = config.get(config.get("rank_method", "function"),"publication_reference_number_tag")
reference_tag = config.get(config.get("rank_method", "function"),"publication_reference_tag")
record_publication_info_tag = config.get(config.get("rank_method", "function"),"publication_info_tag")
for recid in recid_list:
xml = print_record(int(recid),'xm')
rs = create_records(xml)
recs = map((lambda x:x[0]), rs)
l_report_numbers = []
for rec in recs:
pri_report_number = record_get_field_values(rec, record_pri_number_tag[0:3], code=record_pri_number_tag[3])
add_report_numbers = record_get_field_values(rec, record_add_number_tag[0:3], code=record_add_number_tag[3])
if pri_report_number:
l_report_numbers.extend(pri_report_number)
if add_report_numbers:
l_report_numbers.extend(add_report_numbers)
d_reports_numbers[recid] = l_report_numbers
reference_report_number = record_get_field_values(rec, reference_number_tag[0:3], ind1=reference_number_tag[3], ind2=reference_number_tag[4], code=reference_number_tag[5])
if reference_report_number:
d_references_report_numbers[recid] = reference_report_number
references_s = record_get_field_values(rec, reference_tag[0:3], ind1=reference_tag[3], ind2=reference_tag[4], code=reference_tag[5])
if references_s:
d_references_s[recid] = references_s
record_s = record_get_field_values(rec, record_publication_info_tag[0:3], ind1='', ind2='', code=record_publication_info_tag[3])
if record_s:
d_records_s[recid] = record_s[0]
citation_informations.append(d_reports_numbers)
citation_informations.append(d_references_report_numbers)
citation_informations.append(d_references_s)
citation_informations.append(d_records_s)
end_time = os.times()[4]
print "Execution time for generating citation inforamtions by parsing xml contents: ", (end_time - begin_time)
return citation_informations
def ref_analyzer(citation_informations, initialresult, initial_citationlist, initial_referencelist):
"""Analyze the citation informations and calculate the citation weight
and cited by list dictionary
"""
citation_list = initial_citationlist
reference_list = initial_referencelist
result = initialresult
d_reports_numbers = citation_informations[0]
d_references_report_numbers = citation_informations[1]
d_references_s = citation_informations[2]
d_records_s = citation_informations[3]
t1 = os.times()[4]
for recid, refnumbers in d_references_report_numbers.iteritems():
for refnumber in refnumbers:
p = refnumber
f = 'reportnumber'
rec_id = get_recids_matching_query(p, f)
if rec_id:
result[rec_id[0]] += 1
citation_list[rec_id[0]].append(recid)
reference_list[recid].append(rec_id[0])
t2 = os.times()[4]
for recid, refss in d_references_s.iteritems():
for refs in refss:
p = refs
f = 'publref'
rec_id = get_recids_matching_query(p, f)
if rec_id and not recid in citation_list[rec_id[0]]:
result[rec_id[0]] += 1
citation_list[rec_id[0]].append(recid)
if rec_id and not rec_id[0] in reference_list[recid]:
reference_list[recid].append(rec_id[0])
t3 = os.times()[4]
for rec_id, recnumbers in d_reports_numbers.iteritems():
for recnumber in recnumbers:
p = recnumber
f = '999C5r'
recid_list = get_recids_matching_query(p, f)
if recid_list:
for recid in recid_list:
if not recid in citation_list[rec_id]:
result[rec_id] += 1
citation_list[rec_id].append(recid)
if not rec_id in reference_list[recid]:
reference_list[recid].append(rec_id)
t4 = os.times()[4]
for recid, recs in d_records_s.iteritems():
tmp = recs.find("-")
if tmp < 0:
recs_modified = recs
else:
recs_modified = recs[:tmp]
p = recs_modified
f = '999C5s'
rec_ids = get_recids_matching_query(p, f)
if rec_ids:
for rec_id in rec_ids:
if not rec_id in citation_list[recid]:
result[recid] += 1
citation_list[recid].append(rec_id)
if not recid in reference_list[rec_id]:
reference_list[rec_id].append(recid)
t5 = os.times()[4]
insert_cit_ref_list_intodb(citation_list, reference_list)
print "\nExecution time for analizing the citation information generating the dictionary: "
print "checking ref number: ", (t2-t1)
print "checking ref ypvt: ", (t3-t2)
print "checking rec number: ", (t4-t3)
print "checking rec ypvt: ", (t5-t4)
print "total time of refAnalize: ", (t5-t1)
return result
def get_decompressed_xml(xml):
"""return a decompressed content of xml into a xml content
"""
decompressed_xml = create_records(decompress(xml))
return decompressed_xml
def insert_cit_ref_list_intodb(citation_dic, reference_dic):
"""Insert the reference and citation list into the database"""
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
id = run_sql("SELECT * from rnkCITATIONDATA ")
if id:
run_sql("update rnkCITATIONDATA set citation_data_reversed = '%s'"%
(get_compressed_dictionary(reference_dic)))
run_sql("update rnkCITATIONDATA set citation_data = '%s'" %
(get_compressed_dictionary(citation_dic)))
else :
run_sql("INSERT INTO rnkCITATIONDATA VALUES ('%s', null)" %
(get_compressed_dictionary(citation_dic)))
run_sql("update rnkCITATIONDATA set citation_data_reversed = '%s'"%
(get_compressed_dictionary(reference_dic)))
def get_compressed_dictionary(dic):
"""Serialize Python object vi a marshal into a compressed string."""
return MySQLdb.escape_string(compress(dumps(dic)))
diff --git a/modules/bibrank/lib/bibrank_citation_indexer_tests.py b/modules/bibrank/lib/bibrank_citation_indexer_tests.py
index 5668ff836..c37ccdd12 100644
--- a/modules/bibrank/lib/bibrank_citation_indexer_tests.py
+++ b/modules/bibrank/lib/bibrank_citation_indexer_tests.py
@@ -1,47 +1,47 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the citation indexer."""
__version__ = "$Id$"
import unittest
from cdsware.bibrank_citation_indexer import last_updated_result
class TestCitationIndexer(unittest.TestCase):
def setUp(self):
self.rank_method_code = 'cit'
self.updated_recid_list = [339705, 339704, 339708]
def test_last_updated_result(self):
"""bibrank citation indexer - last updated result"""
self.assert_(last_updated_result(self.rank_method_code, self.updated_recid_list))
def create_test_suite():
"""Return test suite for the bibrank citation indexer."""
return unittest.TestSuite((unittest.makeSuite(TestCitationIndexer, 'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibrank/lib/bibrank_citation_searcher.py b/modules/bibrank/lib/bibrank_citation_searcher.py
index 7998aee86..c393bae70 100644
--- a/modules/bibrank/lib/bibrank_citation_searcher.py
+++ b/modules/bibrank/lib/bibrank_citation_searcher.py
@@ -1,104 +1,104 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from marshal import loads
from zlib import decompress
from cdsware.dbquery import run_sql
def init_cited_by_dictionary():
"""return citation list dictionary from rnkCITATIONDATA
"""
query = "select citation_data from rnkCITATIONDATA"
compressed_citation_dic = run_sql(query)
citation_dic = None
if compressed_citation_dic and compressed_citation_dic[0]:
citation_dic = loads(decompress(compressed_citation_dic[0][0]))
return citation_dic
def init_reference_list_dictionary():
"""return reference list dictionary from rnkCITATIONDATA
"""
query = "select citation_data_reversed from rnkCITATIONDATA"
compressed_ref_dic = run_sql(query)
ref_dic = None
if compressed_ref_dic and compressed_ref_dic[0]:
ref_dic = loads(decompress(compressed_ref_dic[0][0]))
return ref_dic
cache_cited_by_dictionary = init_cited_by_dictionary()
cache_reference_list_dictionary = init_reference_list_dictionary()
### INTERFACE
def calculate_cited_by_list(record_id, sort_order="d"):
"""Return a tuple of ([recid,citation_weight],...) for all the
record in citing RECORD_ID. The resulting recids is sorted by
ascending/descending citation weights depending or SORT_ORDER.
"""
citation_list = []
result = []
# determine which record cite RECORD_ID:
if cache_cited_by_dictionary:
citation_list = cache_cited_by_dictionary.get(record_id, [])
# get their weights:
query = "select relevance_data from rnkMETHODDATA, rnkMETHOD WHERE rnkMETHOD.id=rnkMETHODDATA.id_rnkMETHOD and rnkMETHOD.name='cit'"
compressed_citation_weight_dic = run_sql(query)
if compressed_citation_weight_dic and compressed_citation_weight_dic[0]:
citation_dic = loads(decompress(compressed_citation_weight_dic[0][0]))
for id in citation_list:
tmp = [id, citation_dic[id]]
result.append(tmp)
# sort them:
if result:
if sort_order == "d":
result.sort(lambda x, y: cmp(y[1], x[1]))
else:
result.sort(lambda x, y: cmp(x[1], y[1]))
return result
def calculate_co_cited_with_list(record_id, sort_order="d"):
"""Return a tuple of ([recid,co-cited weight],...) for records
that are co-cited with RECORD_ID. The resulting recids is sorted by
ascending/descending citation weights depending or SORT_ORDER.
"""
result = []
result_intermediate = {}
citation_list = []
if cache_cited_by_dictionary:
citation_list = cache_cited_by_dictionary.get(record_id, [])
for cit_id in citation_list:
reference_list = []
if cache_reference_list_dictionary:
reference_list = cache_reference_list_dictionary.get(cit_id, [])
for ref_id in reference_list:
if not result_intermediate.has_key(ref_id):
result_intermediate[ref_id] = 1
else: result_intermediate[ref_id] += 1
for key, value in result_intermediate.iteritems():
if not (key==record_id):
result.append([key, value])
if result:
if sort_order == "d":
result.sort(lambda x, y: cmp(y[1], x[1]))
else:
result.sort(lambda x, y: cmp(x[1], y[1]))
return result
diff --git a/modules/bibrank/lib/bibrank_citation_searcher_tests.py b/modules/bibrank/lib/bibrank_citation_searcher_tests.py
index 7c6f1fd6f..488727568 100644
--- a/modules/bibrank/lib/bibrank_citation_searcher_tests.py
+++ b/modules/bibrank/lib/bibrank_citation_searcher_tests.py
@@ -1,60 +1,60 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the citation searcher."""
__version__ = "$Id$"
import unittest
from cdsware import bibrank_citation_searcher
class TestCitationSearcher(unittest.TestCase):
def setUp(self):
self.recid = 339705
self.recids = [339705, 339706]
self.rank_method_code = 'cit'
def test_init_cited_by_dictionary(self):
"""bibrank citation searcher - init cited-by data"""
# FIXME: test postponed
#self.assert_(bibrank_citation_searcher.init_cited_by_dictionary())
def test_init_reference_list_dictionary(self):
"""bibrank citation searcher - init reference data"""
# FIXME: test postponed
#self.assert_(bibrank_citation_searcher.init_reference_list_dictionary())
def test_calculate_cited_by_list(self):
"""bibrank citation searcher - get citing relevance"""
# FIXME: test postponed
def test_calculate_co_cited_with_list(self):
"""bibrank citation searcher - get co-cited-with data"""
# FIXME: test postponed
def create_test_suite():
"""Return test suite for the citation searcher."""
return unittest.TestSuite((unittest.makeSuite(TestCitationSearcher,'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibrank/lib/bibrank_downloads_grapher.py b/modules/bibrank/lib/bibrank_downloads_grapher.py
index 34d0726b8..48445e7ee 100644
--- a/modules/bibrank/lib/bibrank_downloads_grapher.py
+++ b/modules/bibrank/lib/bibrank_downloads_grapher.py
@@ -1,275 +1,275 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import string
import os
import sys
import time
import tempfile
import calendar
from cdsware.config import weburl, cdslang
from cdsware.messages import gettext_set_language
from cdsware.dbquery import run_sql
from cdsware.bibrank_downloads_indexer import database_tuples_to_single_list
from cdsware.bibrank_grapher import *
color_line_list = ['9', '19', '10', '15', '21', '18']
cfg_id_bibdoc_id_bibrec = 5
cfg_bibrank_print_download_history = 1
cfg_bibrank_print_download_split_by_id = 1
def create_download_history_graph_and_box(id_bibrec, ln=cdslang):
"""Create graph with citation history for record ID_BIBREC (into a
temporary file) and return HTML box refering to that image.
Called by Detailed record pages.
Notes:
if id_bibdoc=0 : its an oustide-stored document and it has no id_bibdoc --> only one line
if nb_id_bibdoc <= cfg_id_bibdoc_id_bibrec draw one line per id_bibdoc
if nb_id_bibdoc > cfg_id_bibdoc_id_bibrec draw only one line which hold simultaneously the downloads per id_bibdoc
Each time this function is called, all the images older than 10 minutes are deleted.
"""
_ = gettext_set_language(ln)
html_code = ""
html_content = ""
users_analysis_text = ""
if cfg_bibrank_print_download_split_by_id:
users_analysis_text = "and Users repartition"
#remove images older than 10 minutes
remove_old_img("download")
#Users analysis graph
ips = database_tuples_to_single_list(run_sql("select client_host from rnkDOWNLOADS where id_bibrec=%s;" % id_bibrec))
if ips == []:
pass
else :
users_analysis_results = create_users_analysis_graph(id_bibrec, ips)
graph_file_users = weburl + "/img/" + users_analysis_results[0]
file_to_close_users = users_analysis_results[1]
html_content += """<tr><td valign=center align=center><img src='%s'/></td>""" % graph_file_users
if file_to_close_users:
if os.path.exists(file_to_close_users):
os.unlink(file_to_close_users)
#Downloads history graph and return html code used by get_file or search_engine
if cfg_bibrank_print_download_history:
remove_old_img("download")
nb_id_bibdoc = run_sql("select distinct id_bibdoc from rnkDOWNLOADS where id_bibrec=%s;" % id_bibrec)
history_analysis_results = ()
if nb_id_bibdoc == ():
pass
elif nb_id_bibdoc[0][0] <= cfg_id_bibdoc_id_bibrec and (0, ) not in nb_id_bibdoc:
history_analysis_results = draw_downloads_statistics(id_bibrec, list(nb_id_bibdoc))
else:
history_analysis_results = draw_downloads_statistics(id_bibrec, [])
if history_analysis_results:
graph_file_history = weburl + "/img/" + history_analysis_results[0]
file_to_close_history = history_analysis_results[1]
html_content += """<tr><td valign=center align=center><img src='%s'/></td>""" % graph_file_history
if file_to_close_history :
if os.path.exists(file_to_close_history):
os.unlink(file_to_close_history)
out = ""
if html_content != "":
out += """<br/><br/><table><tr><td class="blocknote">
%s %s</td></tr><tr><td>
<table border="0" cellspacing="1" cellpadding="1">""" % (_("Downloads history:"), users_analysis_text)
out += html_content
out += "</table></td></tr></table>"
return out
def draw_downloads_statistics(id_bibrec, id_bibdoc_list):
"""Create a graph about download history using a temporary file to store datas
and a new png file for each id_bibrec to store the image of the graph which will
be referenced by html code."""
intervals = []
#used to name the different curves when len(id_bibdoc_list)>1
docfile_name_list = []
#used to name the uniquecurve when len(id_bibdoc_list)=0 or > cfg_id_bibdoc_id_bibrec
record_name = run_sql("select value from bibrec_bib24x,bib24x where id_bibrec=%s and id_bibxxx=id;" % id_bibrec)[0][0]
#list of lists of tuples: [[("09/2004",4),..],[(..,..)]..]
#Each list element of the list is represented by a curve
#each elem of each list is a point on the graph
coordinates_list = []
#If the document is not stored in CdsWare it has id_bibrec 0 and no creation date
#In this case the beginning date is the first time the document has been downloaded
creation_date_res = run_sql("""SELECT DATE_FORMAT(creation_date,"%%Y-%%m-%%d-%%H:%%i:%%s") FROM bibrec WHERE id=%s;""" % id_bibrec)
if creation_date_res == ():
creation_date_res = run_sql("""SELECT DATE_FORMAT(MIN(download_time),"%%Y-%%m-%%d-%%H:%%i:%%s") FROM rnkDOWNLOADS where id_bibrec=%s;""" % id_bibrec)
creation_date_year, creation_date_month, creation_date_day, creation_date_time = string.split(creation_date_res[0][0], "-")
creation_date_year = string.atoi(creation_date_year)
creation_date_month = string.atoi(creation_date_month)
creation_date_day = string.atoi(creation_date_day)
creation_date_time = str(creation_date_time)
#create intervals and corresponding values
local_time = time.localtime()
res = create_tic_intervals(local_time, creation_date_year, creation_date_month)
intervals = res[1]
tic_list = res[0]
if id_bibdoc_list == []:
coordinates_list.append(create_list_tuple_data(intervals, id_bibrec))
docfile_name_list = record_name
else :
for i in range(len(id_bibdoc_list)):
datas = create_list_tuple_data(intervals, id_bibrec, id_bibdoc_query_addition="and id_bibdoc=%s" % id_bibdoc_list[i][0])
coordinates_list.append(datas)
docfile_name_list.append(run_sql("select docname from bibdoc where id=%s;" % id_bibdoc_list[i][0])[0][0])
#In case of multiple id_bibdocs datas_max will be used to draw a line which is the total of the others lines
if not (len(intervals)==1 or len(id_bibdoc_list)==1):
datas_max = create_list_tuple_total(intervals, coordinates_list)
coordinates_list.append(datas_max)
#write coordinates_list in a temporary file
result2 = write_coordinates_in_tmp_file(coordinates_list)
fname = result2[0]
y_max = result2[1]
#Use create the graph from the temporary file
return create_temporary_image(id_bibrec, 'download_history', fname, '', 'Downloads/month', (0, 0), y_max, id_bibdoc_list, docfile_name_list, tic_list)
def create_list_tuple_data(intervals, id_bibrec, id_bibdoc_query_addition=""):
"""-Return a list of tuple of the form [('10/2004',3),(..)] used to plot graph
Where 3 is the number of downloads between 01/10/2004 and 31/10/2004"""
list_tuple = []
for elem in intervals:
main_date_end = string.split(elem[1], '/')
end_of_month_end = calendar.monthrange(string.atoi(main_date_end[1]), string.atoi(main_date_end[0]))[1]
s0 = string.split(elem[0], "/")
s1 = string.split(elem[1], "/")
elem0 = s0[1] + "-" + s0[0]
elem1 = s1[1] + "-" + s1[0]
date1 = "%s%s" % (elem0, "-01 00:00:00")
date2 = "%s%s" % (elem1, "-%s 00:00:00" % str(end_of_month_end))
sql_query = "select count(*) from rnkDOWNLOADS where id_bibrec=%s %s and download_time>='%s' and download_time<'%s';" % (id_bibrec, id_bibdoc_query_addition, date1, date2)
res = run_sql(sql_query)[0][0]
list_tuple.append((elem[0], res))
#list_tuple = sort_list_tuple_by_date(list_tuple)
return (list_tuple)
def sort_list_tuple_by_date(list_tuple):
"""Sort a list of tuple of the forme ("09/2004", 3)according to the
year of the first element of the tuple"""
list_tuple.sort(lambda x, y: (cmp(string.split(x[0], '/')[1],
string.split(y[0], '/')[1])))
return list_tuple
def create_list_tuple_total(intervals, list_data):
"""In the case of multiple id_bibdocs, a last paragraph is added
at the end to show the global evolution of the record"""
list_tuple = []
if len(intervals)==1:
res = 0
for j in range(len(list_data)):
res += list_data[j][1]
list_tuple.append((intervals[0][0], res))
else :
for i in range(len(intervals)):
res = 0
for j in range(len(list_data)):
res += list_data[j][i][1]
list_tuple.append((intervals[i][0], res))
#list_tuple = sort_list_tuple_by_date(list_tuple)
return list_tuple
def create_tic_intervals(local_time, creation_date_year, creation_date_month):
"""Create intervals since document creation date until now
Return a list of the tics for the graph of the form ["04/2004","05/2004"), ...]
And a list of tuple(each tuple stands for a period) of the form [("04/2004", "04/2004"),.]
to compute the number of downloads in each period
For the very short periods some tics and tuples are added to make sure that
at least two dates are returned. Useful for drawing graphs.
"""
# okay, off we go
tic_list = []
interval_list = []
local_month = local_time.tm_mon
local_year = local_time.tm_year
original_date = (creation_date_month, creation_date_year)
while (creation_date_year, creation_date_month) <= (local_year, local_month) and creation_date_month <= 12:
date_elem = "%s/%s" % (creation_date_month, creation_date_year)
tic_list.append(date_elem)
interval_list.append((date_elem, date_elem))
if creation_date_month != 12:
creation_date_month = creation_date_month+1
else :
creation_date_year = creation_date_year+1
creation_date_month = 1
next_period = (creation_date_month, creation_date_year)
#additional periods for the short period
if len(interval_list) <= 2:
period_before = "%s/%s" % (sub_month(original_date[0], original_date[1]))
period_after = "%s/%s" % next_period
interval_list.insert(0, (period_before, period_before))
interval_list.append((period_after, period_after))
tic_list.insert(0, period_before)
tic_list.append(period_after)
return (tic_list, interval_list)
def add_month(month, year):
"""Add a month and increment the year if necessary"""
if month == 12:
month = 1
year += 1
else :
month += 1
return (month, year)
def sub_month(month, year):
"""Add a month and decrease the year if necessary"""
if month == 1:
month = 12
year = year -1
else :
month -= 1
return (month, year)
def create_users_analysis_graph(id_bibrec, ips):
"""For a given id_bibrec, classify cern users and other users
Draw a percentage graphic reprentation"""
cern_users = 0
other_users = 0
coordinates_list = []
#compute users repartition
for i in range(len(ips)):
if 2307522817 <= ips[i] <= 2307588095 or 2156724481 <= ips[i] <= 2156789759:
cern_users += 1
else :
other_users += 1
tot = float(cern_users+other_users)
#prepare coordinates list
coordinates_list.append((1, str(float(cern_users)/tot*100)))
coordinates_list.append((3, str(float(other_users)/tot*100)))
#write coordinates in a temporary file
result2 = write_coordinates_in_tmp_file([coordinates_list])
#plot the graph
return create_temporary_image(id_bibrec, 'download_users', result2[0], '', '', (0, 0), result2[1], [], [], [1, 3])
diff --git a/modules/bibrank/lib/bibrank_downloads_indexer.py b/modules/bibrank/lib/bibrank_downloads_indexer.py
index efb4388c7..b117e7fe5 100644
--- a/modules/bibrank/lib/bibrank_downloads_indexer.py
+++ b/modules/bibrank/lib/bibrank_downloads_indexer.py
@@ -1,192 +1,192 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import os
import time
import calendar
import ConfigParser
import string
from cdsware.config import *
from cdsware.dbquery import run_sql
def append_to_file(path, content):
"""print result in a file"""
if os.path.exists(path):
file_dest = open(path,"a")
file_dest.write("Hit on %s reads:" % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
file_dest.write(content)
file_dest.write("\n")
file_dest.close()
return content
def get_download_weight_filtering_user(dic, keys):
""" update the dictionnary.Without duplicates.Count maximum one hit per user per hour"""
for k in keys:
weight = 0
user_ips = run_sql("select count(distinct client_host) from rnkDOWNLOADS where id_bibrec=%s group by id_bibdoc" % k)
for ip in user_ips:
weight = weight + ip[0]
dic[k] = weight
return dic
def get_download_weight_total(dic, keys):
""" update the dictionnary.Count all the hit"""
for k in keys:
values = run_sql("select count(*) from rnkDOWNLOADS where id_bibrec=%s %s" % (k,";"))
dic[k] = values[0][0]
return dic
def uniq(alist):
"""Remove duplicate element in alist
Fastest without order preserving"""
set = {}
map(set.__setitem__, alist, [])
return set.keys()
def database_tuples_to_single_list(tuples):
"""convert a tuple extracted from the database into a list"""
list_result = []
for tup in range(len(tuples)):
list_result.append(tuples[tup][0])
return list_result
def new_downloads_to_index (last_updated):
"""id_bibrec of documents downloaded since the last run of bibrank """
id_bibrec_list = database_tuples_to_single_list(run_sql("select id_bibrec from rnkDOWNLOADS where download_time >=\"%s\"" % last_updated))
res = uniq(id_bibrec_list)
return res
def filter_downloads_per_hour_with_docid (keys, last_updated):
"""filter all the duplicate downloads per user for each hour intervall"""
for k in keys:
id_bibdocs = run_sql("select distinct id_bibdoc from rnkDOWNLOADS where id_bibrec=%s" % k)
for bibdoc in id_bibdocs:
values = run_sql("""select DATE_FORMAT(download_time,"%%Y-%%m-%%d %%H"), client_host from rnkDOWNLOADS where id_bibrec=%s and id_bibdoc=%s and download_time >=\"%s\";""" % (k, bibdoc[0], last_updated))
for val in values:
date_res = val[0]
date1 = "%s:00:00" % (date_res)
date2 = compute_next_hour(date_res)
duplicates = (run_sql("select count(*) from rnkDOWNLOADS where id_bibrec=%s and id_bibdoc=%s and download_time>='%s' and download_time<'%s' and client_host=%s;" % (k, bibdoc[0], date1, date2, val[1]))[0][0])-1
run_sql("delete from rnkDOWNLOADS where id_bibrec=%s and id_bibdoc=%s and download_time>='%s' and download_time<'%s' and client_host=%s limit %s;" % (k, bibdoc[0], date1, date2, val[1], duplicates))
def filter_downloads_per_hour (keys, last_updated):
"""filter all the duplicate downloads per user for each hour intervall"""
for k in keys:
values = run_sql("""select DATE_FORMAT(download_time,"%%Y-%%m-%%d %%H"), client_host from rnkDOWNLOADS where id_bibrec=%s and download_time >=\"%s\";""" % (k, last_updated))
for val in values:
date_res = val[0]
date1 = "%s:00:00" % (date_res)
date2 = compute_next_hour(date_res)
duplicates = (run_sql("select count(*) from rnkDOWNLOADS where id_bibrec=%s and download_time>='%s' and download_time<'%s' and client_host=%s;" % (k, date1, date2, val[1]))[0][0])-1
run_sql("delete from rnkDOWNLOADS where id_bibrec=%s and download_time>='%s' and download_time<'%s' and client_host=%s limit %s;" % (k, date1, date2, val[1], duplicates))
def compute_next_hour(date_res):
"""treat the change of the year, of (special)month etc.. and return the date in database format"""
next_date = ""
date_res, date_hour = string.split(date_res, " ")
date_hour = string.atoi(date_hour)
if date_hour == 23:
date_year, date_month, date_day = string.split(date_res, "-")
date_year = string.atoi(date_year)
date_month = string.atoi(date_month)
date_day = string.atoi(date_day)
if date_month == 12 and date_day == 31:
next_date = "%s-%s-%s 00:00:00" % (date_year + 1, 01, 01)
elif calendar.monthrange(date_year, date_month)[1] == date_day:
next_date = "%s-%s-%s 00:00:00" % (date_year, date_month + 1, 01)
else :
next_date = "%s-%s-%s 00:00:00" % (date_year, date_month, date_day + 1)
else :
next_hour = date_hour + 1
next_date = "%s %s:00:00" % (date_res, next_hour)
return next_date
def get_file_similarity_by_times_downloaded(dic, id_bibrec_list):
"""For each id_bibrec, get the client_host and see which other id_bibrec these users have also downloaded.
Return update dictionnary of this form
{id_bibrec:[(id_bibrec1,score),(id_bibrec2,score)],id_bibrec:[(),()]...}
Take long time so let's see bibrank_downloads_similarity which compute in fly the similarity for
a particular recid."""
dic_result = {}
if id_bibrec_list != []:
tuple_string_id_bibrec_list = str(tuple(id_bibrec_list))
if len(id_bibrec_list) == 1:
tuple_string_id_bibrec_list = tuple_string_id_bibrec_list.replace(',','')
#first compute the download similarity between the new documents
#which have been downloadwd since the last run of bibrank
dic_news = {}
res = run_sql("select id_bibrec,client_host from rnkDOWNLOADS where id_bibrec in %s;" % tuple_string_id_bibrec_list)
for res_elem in res:
id_bibrec_key = res_elem[0]
client_host_value = str(res_elem[1])
if id_bibrec_key in dic_news.keys():
tmp_list = dic_news[id_bibrec_key]
if client_host_value not in dic_news[id_bibrec_key]:
tmp_list.append(client_host_value)
dic_news[id_bibrec_key] = tmp_list
else :
list_client_host_value = []
list_client_host_value.append(client_host_value)
dic_news[id_bibrec_key] = list_client_host_value
#compute occurence of client_host
for j in dic_news.keys():
list_tuple = []
tuple_client_host = str(tuple(dic_news[j]))
if len(tuple(dic_news[j])) == 1:
tuple_client_host = tuple_client_host.replace(',','')
res2 = run_sql("select id_bibrec,count(*) from rnkDOWNLOADS where client_host in %s and id_bibrec in %s and id_bibrec != %s group by id_bibrec;" % (tuple_client_host, tuple_string_id_bibrec_list, j)) #0.0023 par requete
list_tuple.append(list(res2))
dic_result[j] = list_tuple[0]
#merge new values with old dictionnary
return merge_with_old_dictionnary(dic, dic_result)
def merge_with_old_dictionnary(old_dic, new_dic):
"""For each key id_bibrec in new_dic add the old values contained in old_dic
Return not ordered merged dictionnary"""
union_dic = {}
for (key, value) in new_dic.iteritems():
if key in old_dic.keys():
old_dic_value_dic = dict(old_dic[key])
tuple_list = []
old_dic_value_dic_keys = old_dic_value_dic.keys()
for val in value:
if val[0] in old_dic_value_dic_keys:
tuple_list.append((val[0], val[1]+ old_dic_value_dic[val[0]]))
del old_dic_value_dic[val[0]]
else :
tuple_list.append((val[0], val[1]))
old_dic_value_dic_items = old_dic_value_dic.items()
if old_dic_value_dic_items != []:
tuple_list.extend(old_dic_value_dic_items)
union_dic[key] = tuple_list
else :
union_dic[key] = value
for (key, value) in old_dic.iteritems():
if key not in union_dic.keys():
union_dic[key] = value
return union_dic
diff --git a/modules/bibrank/lib/bibrank_downloads_indexer_tests.py b/modules/bibrank/lib/bibrank_downloads_indexer_tests.py
index d29a18d94..eb4faaca6 100644
--- a/modules/bibrank/lib/bibrank_downloads_indexer_tests.py
+++ b/modules/bibrank/lib/bibrank_downloads_indexer_tests.py
@@ -1,54 +1,54 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables
import unittest
from cdsware import bibrank_downloads_indexer
class TestListSetOperations(unittest.TestCase):
"""Test list set operations."""
def test_uniq(self):
"""bibrank downloads indexer - uniq function"""
self.assertEqual([1, 2, 3], bibrank_downloads_indexer.uniq([1, 2, 3, 3, 3, 2]))
def test_database_tuples_to_single_list(self):
"""bibrank downloads indexer - database tuples to list"""
self.assertEqual([1, 2, 3], bibrank_downloads_indexer.database_tuples_to_single_list(((1,), (2,), (3,))))
class TestMergeDictionnaries(unittest.TestCase):
"""Test bibrank_downloads_indexer merge 2 dictionnaries"""
def test_merge_with_old_dictionnary(self):
"""bibrank downloads indexer - merging with old dictionary"""
self.assertEqual({1:[(2, 3)], 2:[(3, 4)], 3:[(4, 5)]}, bibrank_downloads_indexer.merge_with_old_dictionnary(\
{3:[(4, 5)]}, {1:[(2, 3)], 2:[(3, 4)]}))
self.assertEqual({1:[(2, 4)], 2:[(3, 4)]}, bibrank_downloads_indexer.merge_with_old_dictionnary(\
{1:[(2, 1)]}, {1:[(2, 3)], 2:[(3, 4)]}))
self.assertEqual({1:[(3, 3), (2, 3)], 2:[(3, 4)]}, bibrank_downloads_indexer.merge_with_old_dictionnary(\
{1:[(2, 3)]}, {1:[(3, 3)], 2:[(3, 4)]}))
self.assertEqual({}, bibrank_downloads_indexer.merge_with_old_dictionnary({}, {}))
def create_test_suite():
"""Return test suite for the downlaods engine."""
return unittest.TestSuite((unittest.makeSuite(TestListSetOperations, 'test'),
unittest.makeSuite(TestMergeDictionnaries, 'test')))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibrank/lib/bibrank_downloads_similarity.py b/modules/bibrank/lib/bibrank_downloads_similarity.py
index 8a3bcb0ab..2fdae547e 100644
--- a/modules/bibrank/lib/bibrank_downloads_similarity.py
+++ b/modules/bibrank/lib/bibrank_downloads_similarity.py
@@ -1,104 +1,104 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.config import *
from cdsware.dbquery import run_sql
from cdsware.bibrank_downloads_indexer import database_tuples_to_single_list
def get_fieldvalues(recID, tag):
"""Return list of field values for field TAG inside record RECID.
Copy from search_engine"""
out = []
if tag == "001___":
# we have asked for recID that is not stored in bibXXx tables
out.append(str(recID))
else:
# we are going to look inside bibXXx tables
digit = tag[0:2]
bx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag LIKE '%s'" \
"ORDER BY bibx.field_number, bx.tag ASC" % (bx, bibx, recID, tag)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def record_exists(recID):
"""Return 1 if record RECID exists.
Return 0 if it doesn't exist.
Return -1 if it exists but is marked as deleted.
Copy from search_engine"""
out = 0
query = "SELECT id FROM bibrec WHERE id='%s'" % recID
res = run_sql(query, None, 1)
if res:
# record exists; now check whether it isn't marked as deleted:
dbcollids = get_fieldvalues(recID, "980__%")
if ("DELETED" in dbcollids) or (cfg_cern_site and "DUMMY" in dbcollids):
out = -1 # exists, but marked as deleted
else:
out = 1 # exists fine
return out
### INTERFACE
def register_page_view_event(recid, uid, client_ip_address):
"""Register Detailed record page view event for record RECID
consulted by user UID from machine CLIENT_HOST_IP.
To be called by the search engine.
"""
return run_sql("INSERT INTO rnkPAGEVIEWS (id_bibrec,id_user,client_host,view_time) " \
"VALUES (%s,%s,INET_ATON(%s),NOW())", (recid, uid, client_ip_address))
def calculate_reading_similarity_list(recid, type="pageviews"):
"""Calculate reading similarity data to use in reading similarity
boxes (``people who downloaded/viewed this file/page have also
downloaded/viewed''). Return list of (recid1, score1),
(recid2,score2), ... for all recidN that were consulted by the
same people who have also consulted RECID. The reading
similarity TYPE can be either `pageviews' or `downloads',
depending whether we want to obtain page view similarity or
download similarity.
"""
if type == "downloads":
tablename = "rnkDOWNLOADS"
else: # default
tablename = "rnkPAGEVIEWS"
# firstly compute the set of client hosts who consulted recid:
client_host_list = run_sql("SELECT DISTINCT(client_host)" \
" FROM " + tablename + \
" WHERE id_bibrec=%s",
(recid,))
# secondly look up all recids that were consulted by these client hosts,
# and order them by the number of different client hosts reading them:
res = []
if client_host_list != ():
client_host_list = str(database_tuples_to_single_list(client_host_list))
client_host_list = client_host_list.replace("L", "")
client_host_list = client_host_list.replace("[", "")
client_host_list = client_host_list.replace("]", "")
res = run_sql("SELECT id_bibrec,COUNT(DISTINCT(client_host)) AS c" \
" FROM " + tablename + \
" WHERE client_host IN (%s) AND id_bibrec != %s" \
" GROUP BY id_bibrec ORDER BY c DESC LIMIT 10",
(client_host_list, recid))
return res
diff --git a/modules/bibrank/lib/bibrank_grapher.py b/modules/bibrank/lib/bibrank_grapher.py
index 84f4ca3a5..659bf1954 100644
--- a/modules/bibrank/lib/bibrank_grapher.py
+++ b/modules/bibrank/lib/bibrank_grapher.py
@@ -1,204 +1,204 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__version__ = "$Id$"
import os
import sys
import time
import tempfile
from cdsware.config import webdir
from cdsware.websubmit_config import *
## test gnuplot presence:
cfg_gnuplot_available = 1
try:
import Gnuplot
except ImportError, e:
cfg_gnuplot_available = 0
def write_coordinates_in_tmp_file(lists_coordinates):
"""write the graph coordinates in a temporary file for reading it later
by the create_temporary_image method
lists_coordinates is a list of list of this form:
[[(1,3),(2,4),(3,5)],[(1,5),(2,5),(3,6)]
This file is organized into one or more sets of 2 columns.
Each set is separated from the others by two blank lines.
Each intern list represents a set and each tuple a line in the file where fist element
of the tuple is the element of the first column, and second element of the
tuple is the element of the second column.
With gnuplot, first column is used as x coordinates, and second column as y coordinates.
One set represents a curve in the graph.
"""
max_y_datas = 0
tempfile.tempdir = webdir + "img"
fname = tempfile.mktemp()
file_dest = open(fname, 'a')
for list_elem in lists_coordinates:
y_axe = []
#prepare data and store them in a file
for key_value in list_elem:
file_dest.write("%s %s\n"%(key_value[0], key_value[1]))
y_axe.append(key_value[1])
max_tmp = 0
if y_axe:
max_tmp = max(y_axe)
if max_tmp > max_y_datas:
max_y_datas = max_tmp
file_dest.write("\n\n")
file_dest.close()
return [fname, max_y_datas]
def create_temporary_image(recid, kind_of_graphe, data_file, x_label, y_label, origin_tuple, y_max, docid_list, graphe_titles, intervals):
"""From a temporary file, draw a gnuplot graph
The arguments are as follows:
recid - reccord ID
kind_of_graph - takes one of these values : "citation" ,"download_history", "download_users"
All the commons gnuplot commands for these cases, are written at the beginning
After the particular commands dependaing of each case are written.
data_file - Name of the temporary file which contains the gnuplot datas used to plot the graph.
This file is organized into one or more sets of 2 columns.
First column contains x coordinates, and second column contains y coordinates.
Each set is separated from the others by two blank lines.
x_label - Name of the x axe.
y_label - Name of the y axe.
origin_tuple - Reference coordinates for positionning the graph.
y_max - Max value of y. Used to set y range.
docid_list - In download_history case, docid_list is used to plot multiple curves.
graphe_titles - List of graph titles. It's used to name the curve in the legend.
intervals - x tics location and xrange specification"""
if cfg_gnuplot_available == 0:
return (None, None)
#For different curves
color_line_list = ['4', '3', '2', '9', '6']
#Gnuplot graphe object
g = Gnuplot.Gnuplot()
#Graphe name: file to store graph
graphe_name = "tmp_%s_%s_stats.png" % (kind_of_graphe, recid)
g('set terminal png small')
g('set output "%s/img/%s"' % (webdir, graphe_name))
len_intervals = len(intervals)
len_docid_list = len(docid_list)
# Standard options
g('set size 0.5,0.5')
g('set origin %s,%s'% (origin_tuple[0], origin_tuple[1]))
if x_label == '':
g('unset xlabel')
else:
g.xlabel(s = x_label)
if x_label == '':
g('unset ylabel')
else:
g.ylabel(s = y_label)
g('set bmargin 5')
#let a place at the top of the graph
g('set tmargin 1')
#Will be passed to g at the end to plot the graphe
plot_text = ""
if kind_of_graphe == 'download_history':
g('set xdata time') #Set x scale as date
g('set timefmt "%m/%Y"') #Inform about format in file .dat
g('set format x "%b %y"') #Format displaying
if len(intervals) > 1 :
g('set xrange ["%s":"%s"]' % (intervals[0], intervals[len_intervals-1]))
y_offset = max(3, float(y_max)/60)
g('set yrange [0:%s]' %str(y_max + y_offset))
if len_intervals > 1 and len_intervals <= 12:
g('set xtics rotate %s' % str(tuple(intervals)))#to prevent duplicate tics
elif len_intervals > 12 and len_intervals <= 24:
g('set xtics rotate "%s", 7776000, "%s"' % (intervals[0], intervals[len_intervals-1])) #3 months intervalls
else :
g('set xtics rotate "%s",15552000, "%s"' % (intervals[0], intervals[len_intervals-1])) #6 months intervalls
if len_docid_list <= 1: #Only one curve
#g('set style fill solid 0.25')
if len(intervals)<=4:
plot_text = plot_command(1, data_file, (0, 0), "", "imp", color_line_list[0], 20)
else:
plot_text = plot_command(1, data_file, (0, 0), "", "linespoint", color_line_list[0], 1, "pt 26", "ps 0.5")
elif len_docid_list > 1: #Multiple curves
if len(intervals)<=4:
plot_text = plot_command(1, data_file, (0, 0), graphe_titles[0], "imp", color_line_list[0], 20)
else:
plot_text = plot_command(1, data_file, (0, 0), graphe_titles[0], "linespoint", color_line_list[0], 1, "pt 26", "ps 0.5")
for d in range(1, len_docid_list):
if len(intervals)<=4:
plot_text += plot_command(0, data_file, (d, d) , graphe_titles[d], "imp", color_line_list[d], 20)
else :
plot_text += plot_command(0, data_file, (d, d) , graphe_titles[d], "linespoint", color_line_list[d], 1, "pt 26", "ps 0.5")
if len(intervals)>2:
plot_text += plot_command(0, data_file, (len_docid_list, len_docid_list), "", "impulses", 0, 2 )
plot_text += plot_command(0, data_file, (len_docid_list, len_docid_list), "TOTAL", "lines", 0, 5)
elif kind_of_graphe == 'download_users':
g('set size 0.25,0.5')
g('set xrange [0:4]')
g('set yrange [0:100]')
g('set format y "%g %%"')
g("""set xtics ("" 0, "CERN\\n Users" 1, "Other\\n Users" 3, "" 4)""")
g('set ytics 0,10,100')
g('set boxwidth 0.7 relative')
g('set style fill solid 0.25')
plot_text = 'plot "%s" using 1:2 title "" with boxes lt 7 lw 2' % data_file
else: #citation
g('set boxwidth 0.6 relative')
g('set style fill solid 0.250000 border -1')
g('set xtics rotate %s'% str(tuple(intervals)))
g('set xrange [%s:%s]' % (str(intervals[0]), str(intervals[len_intervals-1])))
g('set yrange [0:%s]' %str(y_max+2))
plot_text = """plot "% s" index 0:0 using 1:2 title "" w steps lt %s lw 3""" % (data_file, color_line_list[1])
g('%s' % plot_text)
return (graphe_name, data_file)
def remove_old_img(prefix_file_name):
"""Detele all the images older than 10 minutes to prevent to much storage
Takes 0.0 seconds for 50 files to delete"""
command = "find %s/img/ -name tmp_%s*.png -amin +10 -exec rm -f {} \;" % (webdir, prefix_file_name)
return os.system(command)
def plot_command(first_line, file_source, indexes, title, style, line_type, line_width, point_type="", point_size=""):
"""Return a string of a gnuplot plot command.Particularly useful when multiple curves
From a temporary file, draw a gnuplot graph
Return a plot command string as follows:
plot datafile <first curve parameters>, datafile <second curve parameters>,...
The arguments are as follows:
first_line - only the drawing command of the first curve contains the word plot
file_source - data file source which containes coordinates
indexes - points out set number in data file source
title - title of the curve in the legend box
style - respresentation of the curve ex: linespoints, lines ...
line_type - color of the line
line_width - width of the line
point_type - optionnal parameter: if not mentionned it's a wide string.
Using in the case of style = linespoints to set point style"""
if first_line:
plot_text = """plot "%s" index %s:%s using 1:2 title "%s" with %s lt %s lw %s %s %s""" % (file_source, indexes[0], indexes[1], title, style, line_type, line_width, point_type, point_size)
else:
plot_text = """, "%s" index %s:%s using 1:2 title "%s" with %s lt %s lw %s %s %s""" % (file_source, indexes[0], indexes[1], title, style, line_type, line_width, point_type, point_size)
return plot_text
diff --git a/modules/bibrank/lib/bibrank_record_sorter.py b/modules/bibrank/lib/bibrank_record_sorter.py
index 978d9aed9..9ce766c00 100644
--- a/modules/bibrank/lib/bibrank_record_sorter.py
+++ b/modules/bibrank/lib/bibrank_record_sorter.py
@@ -1,740 +1,740 @@
# -*- coding: utf-8 -*-
##
## $Id$
## Ranking of records using different parameters and methods on the fly.
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import sys
import zlib
import marshal
import string
import time
import math
import MySQLdb
import Numeric
import re
import ConfigParser
import traceback
import copy
from cdsware.config import *
from cdsware.dbquery import run_sql
from cdsware.bibindex_engine_stemmer import stem
from cdsware.bibindex_engine_stopwords import is_stopword
from cdsware.search_engine_config import cfg_max_recID
from cdsware.bibrank_citation_searcher import calculate_cited_by_list
class HitSet:
"""Class describing set of records, implemented as bit vectors of recIDs.
Using Numeric arrays for speed (1 value = 8 bits), can use later "real"
bit vectors to save space."""
def __init__(self, init_set=None):
self._nbhits = -1
if init_set:
self._set = init_set
else:
self._set = Numeric.zeros(cfg_max_recID+1, Numeric.Int0)
def __repr__(self, join=string.join):
return "%s(%s)" % (self.__class__.__name__, join(map(repr, self._set), ', '))
def add(self, recID):
"Adds a record to the set."
self._set[recID] = 1
def addmany(self, recIDs):
"Adds several recIDs to the set."
for recID in recIDs: self._set[recID] = 1
def addlist(self, arr):
"Adds an array of recIDs to the set."
Numeric.put(self._set, arr, 1)
def remove(self, recID):
"Removes a record from the set."
self._set[recID] = 0
def removemany(self, recIDs):
"Removes several records from the set."
for recID in recIDs:
self.remove(recID)
def intersect(self, other):
"Does a set intersection with other. Keep result in self."
self._set = Numeric.bitwise_and(self._set, other._set)
def union(self, other):
"Does a set union with other. Keep result in self."
self._set = Numeric.bitwise_or(self._set, other._set)
def difference(self, other):
"Does a set difference with other. Keep result in self."
#self._set = Numeric.bitwise_not(self._set, other._set)
for recID in Numeric.nonzero(other._set):
self.remove(recID)
def contains(self, recID):
"Checks whether the set contains recID."
return self._set[recID]
__contains__ = contains # Higher performance member-test for python 2.0 and above
def __getitem__(self, index):
"Support for the 'for item in set:' protocol."
return Numeric.nonzero(self._set)[index]
def calculate_nbhits(self):
"Calculates the number of records set in the hitset."
self._nbhits = Numeric.sum(self._set.copy().astype(Numeric.Int))
def items(self):
"Return an array containing all recID."
return Numeric.nonzero(self._set)
def tolist(self):
"Return an array containing all recID."
return Numeric.nonzero(self._set).tolist()
def compare_on_val(first, second):
return cmp(second[1], first[1])
def serialize_via_numeric_array_dumps(arr):
return Numeric.dumps(arr)
def serialize_via_numeric_array_compr(str):
return zlib.compress(str)
def serialize_via_numeric_array_escape(str):
return MySQLdb.escape_string(str)
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return serialize_via_numeric_array_escape(serialize_via_numeric_array_compr(serialize_via_numeric_array_dumps(arr)))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(zlib.decompress(string))
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(zlib.compress(marshal.dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return marshal.loads(zlib.decompress(string))
def adderrorbox(header='', datalist=[]):
"""used to create table around main data on a page, row based"""
try:
perc = str(100 // len(datalist)) + '%'
except ZeroDivisionError:
perc = 1
output = '<table class="errorbox">'
output += '<thead><tr><th class="errorboxheader" colspan="%s">%s</th></tr></thead>' % (len(datalist), header)
output += '<tbody>'
for row in [datalist]:
output += '<tr>'
for data in row:
output += '<td style="vertical-align: top; margin-top: 5px; width: %s;">' % (perc, )
output += data
output += '</td>'
output += '</tr>'
output += '</tbody></table>'
return output
def check_term(term, col_size, term_rec, max_occ, min_occ, termlength):
"""Check if the term is valid for use
term - the term to check
col_size - the number of records in database
term_rec - the number of records which contains this term
max_occ - max frequency of the term allowed
min_occ - min frequence of the term allowed
termlength - the minimum length of the terms allowed"""
try:
if is_stopword(term, 1) or (len(term) <= termlength) or ((float(term_rec) / float(col_size)) >= max_occ) or ((float(term_rec) / float(col_size)) <= min_occ):
return ""
if int(term):
return ""
except StandardError, e:
pass
return "true"
def create_rnkmethod_cache():
"""Create cache with vital information for each rank method."""
global methods
bibrank_meths = run_sql("SELECT name from rnkMETHOD")
methods = {}
global voutput
voutput = ""
for (rank_method_code,) in bibrank_meths:
try:
file = etcdir + "/bibrank/" + rank_method_code + ".cfg"
config = ConfigParser.ConfigParser()
config.readfp(open(file))
except StandardError, e:
pass
cfg_function = config.get("rank_method", "function")
if config.has_section(cfg_function):
methods[rank_method_code] = {}
methods[rank_method_code]["function"] = cfg_function
methods[rank_method_code]["prefix"] = config.get(cfg_function, "relevance_number_output_prologue")
methods[rank_method_code]["postfix"] = config.get(cfg_function, "relevance_number_output_epilogue")
methods[rank_method_code]["chars_alphanumericseparators"] = r"[1234567890\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~]"
else:
raise Exception("Error in configuration file: %s" % (etcdir + "/bibrank/" + rank_method_code + ".cfg"))
i8n_names = run_sql("SELECT ln,value from rnkMETHODNAME,rnkMETHOD where id_rnkMETHOD=rnkMETHOD.id and rnkMETHOD.name='%s'" % (rank_method_code))
for (ln, value) in i8n_names:
methods[rank_method_code][ln] = value
if config.has_option(cfg_function, "table"):
methods[rank_method_code]["rnkWORD_table"] = config.get(cfg_function, "table")
methods[rank_method_code]["col_size"] = run_sql("SELECT count(*) FROM %sR" % methods[rank_method_code]["rnkWORD_table"][:-1])[0][0]
if config.has_option(cfg_function, "stemming") and config.get(cfg_function, "stemming"):
try:
methods[rank_method_code]["stemmer"] = config.get(cfg_function, "stemming")
except Exception,e:
pass
if config.has_option(cfg_function, "stopword"):
methods[rank_method_code]["stopwords"] = config.get(cfg_function, "stopword")
if config.has_section("find_similar"):
methods[rank_method_code]["max_word_occurence"] = float(config.get("find_similar", "max_word_occurence"))
methods[rank_method_code]["min_word_occurence"] = float(config.get("find_similar", "min_word_occurence"))
methods[rank_method_code]["min_word_length"] = int(config.get("find_similar", "min_word_length"))
methods[rank_method_code]["min_nr_words_docs"] = int(config.get("find_similar", "min_nr_words_docs"))
methods[rank_method_code]["max_nr_words_upper"] = int(config.get("find_similar", "max_nr_words_upper"))
methods[rank_method_code]["max_nr_words_lower"] = int(config.get("find_similar", "max_nr_words_lower"))
methods[rank_method_code]["default_min_relevance"] = int(config.get("find_similar", "default_min_relevance"))
if config.has_section("combine_method"):
i = 1
methods[rank_method_code]["combine_method"] = []
while config.has_option("combine_method", "method%s" % i):
methods[rank_method_code]["combine_method"].append(string.split(config.get("combine_method", "method%s" % i), ","))
i += 1
def is_method_valid(colID, rank_method_code):
"""Checks if a method is valid for the collection given"""
enabled_colls = dict(run_sql("SELECT id_collection, score from collection_rnkMETHOD,rnkMETHOD WHERE id_rnkMETHOD=rnkMETHOD.id AND name='%s'" % rank_method_code))
colID = int(colID)
if enabled_colls.has_key(colID):
return 1
else:
while colID:
colID = run_sql("SELECT id_dad FROM collection_collection WHERE id_son=%s" % colID)
if colID and enabled_colls.has_key(colID[0][0]):
return 1
elif colID:
colID = colID[0][0]
return 0
def get_bibrank_methods(collection, ln=cdslang):
"""Returns a list of rank methods and the name om them in the language defined by the ln parameter, if collection is given, only methods enabled for that collection is returned."""
if not globals().has_key('methods'):
create_rnkmethod_cache()
avail_methods = []
for (rank_method_code, options) in methods.iteritems():
if options.has_key("function") and is_method_valid(collection, rank_method_code):
if options.has_key(ln):
avail_methods.append((rank_method_code, options[ln]))
elif options.has_key(cdslang):
avail_methods.append((rank_method_code, options[cdslang]))
else:
avail_methods.append((rank_method_code, rank_method_code))
return avail_methods
def rank_records(rank_method_code, rank_limit_relevance, hitset_global, pattern=[], verbose=0):
"""rank_method_code, e.g. `jif' or `sbr' (word frequency vector model)
rank_limit_relevance, e.g. `23' for `nbc' (number of citations) or `0.10' for `vec'
hitset, search engine hits;
pattern, search engine query or record ID (you check the type)
verbose, verbose level
output:
list of records
list of rank values
prefix
postfix
verbose_output"""
global voutput
voutput = ""
configcreated = ""
try:
hitset = copy.deepcopy(hitset_global) #we are receiving a global hitset
if not globals().has_key('methods'):
create_rnkmethod_cache()
function = methods[rank_method_code]["function"]
func_object = globals().get(function)
if func_object and pattern and pattern[0][0:6] == "recid:" and function == "word_similarity":
result = find_similar(rank_method_code, pattern[0][6:], hitset, rank_limit_relevance, verbose)
elif rank_method_code == "cit" and pattern and pattern[0][0:6] == "recid:":
# FIXME: func_object and pattern and pattern[0][0:6] == "recid:" and function == "citation":
result = find_citations(rank_method_code, pattern[0][6:], hitset, verbose)
elif func_object:
result = func_object(rank_method_code, pattern, hitset, rank_limit_relevance, verbose)
else:
result = rank_by_method(rank_method_code, pattern, hitset, rank_limit_relevance, verbose)
except Exception, e:
result = (None, "", adderrorbox("An error occured when trying to rank the search result", ["Unexpected error: %s<br><b>Traceback:</b>%s" % (e, traceback.format_tb(sys.exc_info()[2]))]), voutput)
if result[0] and result[1]: #split into two lists for search_engine
results_similar_recIDs = map(lambda x: x[0], result[0])
results_similar_relevances = map(lambda x: x[1], result[0])
result = (results_similar_recIDs, results_similar_relevances, result[1], result[2], "%s" % configcreated + result[3])
else:
result = (None, None, result[1], result[2], result[3])
if verbose > 0:
print string.replace(voutput, "<br>", "\n")
return result
def combine_method(rank_method_code, pattern, hitset, rank_limit_relevance,verbose):
"""combining several methods into one based on methods/percentage in config file"""
global voutput
result = {}
try:
for (method, percent) in methods[rank_method_code]["combine_method"]:
function = methods[method]["function"]
func_object = globals().get(function)
percent = int(percent)
if func_object:
this_result = func_object(method, pattern, hitset, rank_limit_relevance, verbose)[0]
else:
this_result = rank_by_method(method, pattern, hitset, rank_limit_relevance, verbose)[0]
for i in range(0, len(this_result)):
(recID, value) = this_result[i]
if value > 0:
result[recID] = result.get(recID, 0) + int((float(i) / len(this_result)) * float(percent))
result = result.items()
result.sort(lambda x, y: cmp(x[1], y[1]))
return (result, "(", ")", voutput)
except Exception, e:
return (None, "Warning: %s method cannot be used for ranking your query." % rank_method_code, "", voutput)
def rank_by_method(rank_method_code, lwords, hitset, rank_limit_relevance,verbose):
"""Ranking of records based on predetermined values.
input:
rank_method_code - the code of the method, from the name field in rnkMETHOD, used to get predetermined values from
rnkMETHODDATA
lwords - a list of words from the query
hitset - a list of hits for the query found by search_engine
rank_limit_relevance - show only records with a rank value above this
verbose - verbose value
output:
reclist - a list of sorted records, with unsorted added to the end: [[23,34], [344,24], [1,01]]
prefix - what to show before the rank value
postfix - what to show after the rank value
voutput - contains extra information, content dependent on verbose value"""
global voutput
rnkdict = run_sql("SELECT relevance_data FROM rnkMETHODDATA,rnkMETHOD where rnkMETHOD.id=id_rnkMETHOD and rnkMETHOD.name='%s'" % rank_method_code)
if not rnkdict:
return (None, "Warning: Could not load ranking data for method %s." % rank_method_code, "", voutput)
lwords_hitset = None
for j in range(0, len(lwords)): #find which docs to search based on ranges..should be done in search_engine...
if lwords[j] and lwords[j][:6] == "recid:":
if not lwords_hitset:
lwords_hitset = HitSet()
lword = lwords[j][6:]
if string.find(lword, "->") > -1:
lword = string.split(lword, "->")
if int(lword[0]) >= cfg_max_recID + 1 or int(lword[1]) >= cfg_max_recID + 1:
return (None, "Warning: Given record IDs are out of range.", "", voutput)
for i in range(int(lword[0]), int(lword[1])):
lwords_hitset.add(int(i))
elif lword < cfg_max_recID + 1:
lwords_hitset.add(int(lword))
else:
return (None, "Warning: Given record IDs are out of range.", "", voutput)
rnkdict = deserialize_via_marshal(rnkdict[0][0])
if verbose > 0:
voutput += "<br>Running rank method: %s, using rank_by_method function in bibrank_record_sorter<br>" % rank_method_code
voutput += "Ranking data loaded, size of structure: %s<br>" % len(rnkdict)
lrecIDs = hitset.items()
if verbose > 0:
voutput += "Number of records to rank: %s<br>" % len(lrecIDs)
reclist = []
reclist_addend = []
if not lwords_hitset: #rank all docs, can this be speed up using something else than for loop?
for recID in lrecIDs:
if rnkdict.has_key(recID):
reclist.append((recID, rnkdict[recID]))
del rnkdict[recID]
else:
reclist_addend.append((recID, 0))
else: #rank docs in hitset, can this be speed up using something else than for loop?
lwords_lrecIDs = lwords_hitset.items()
for recID in lwords_lrecIDs:
if rnkdict.has_key(recID) and hitset.contains(recID):
reclist.append((recID, rnkdict[recID]))
del rnkdict[recID]
elif hitset.contains(recID):
reclist_addend.append((recID, 0))
if verbose > 0:
voutput += "Number of records ranked: %s<br>" % len(reclist)
voutput += "Number of records not ranked: %s<br>" % len(reclist_addend)
reclist.sort(lambda x, y: cmp(x[1], y[1]))
return (reclist_addend + reclist, methods[rank_method_code]["prefix"], methods[rank_method_code]["postfix"], voutput)
def find_citations(rank_method_code, recID, hitset, verbose):
reclist = calculate_cited_by_list(int(recID), "a")
if reclist:
return (reclist,"(", ")", "Warning: citation search functionality is experimental.")
else:
return (reclist,"", "", "Warning: citation search functionality is experimental.")
def find_similar(rank_method_code, recID, hitset, rank_limit_relevance,verbose):
"""Finding terms to use for calculating similarity. Terms are taken from the recid given, returns a list of recids's and relevance,
input:
rank_method_code - the code of the method, from the name field in rnkMETHOD
recID - records to use for find similar
hitset - a list of hits for the query found by search_engine
rank_limit_relevance - show only records with a rank value above this
verbose - verbose value
output:
reclist - a list of sorted records: [[23,34], [344,24], [1,01]]
prefix - what to show before the rank value
postfix - what to show after the rank value
voutput - contains extra information, content dependent on verbose value"""
startCreate = time.time()
global voutput
if verbose > 0:
voutput += "<br>Running rank method: %s, using find_similar/word_frequency in bibrank_record_sorter<br>" % rank_method_code
rank_limit_relevance = methods[rank_method_code]["default_min_relevance"]
try:
recID = int(recID)
except Exception,e :
return (None, "Warning: Error in record ID, please check that a number is given.", "", voutput)
rec_terms = run_sql("SELECT termlist FROM %sR WHERE id_bibrec=%s" % (methods[rank_method_code]["rnkWORD_table"][:-1], recID))
if not rec_terms:
return (None, "Warning: Requested record does not seem to exist.", "", voutput)
rec_terms = deserialize_via_marshal(rec_terms[0][0])
#Get all documents using terms from the selected documents
if len(rec_terms) == 0:
return (None, "Warning: Record specified has no content indexed for use with this method.", "", voutput)
else:
terms = "%s" % rec_terms.keys()
terms_recs = dict(run_sql("SELECT term, hitlist FROM %s WHERE term IN (%s)" % (methods[rank_method_code]["rnkWORD_table"], terms[1:len(terms) - 1])))
tf_values = {}
#Calculate all term frequencies
for (term, tf) in rec_terms.iteritems():
if len(term) >= methods[rank_method_code]["min_word_length"] and terms_recs.has_key(term) and tf[1] != 0:
tf_values[term] = int((1 + math.log(tf[0])) * tf[1]) #calculate term weigth
tf_values = tf_values.items()
tf_values.sort(lambda x, y: cmp(y[1], x[1])) #sort based on weigth
lwords = []
stime = time.time()
(recdict, rec_termcount) = ({}, {})
for (t, tf) in tf_values: #t=term, tf=term frequency
term_recs = deserialize_via_marshal(terms_recs[t])
if len(tf_values) <= methods[rank_method_code]["max_nr_words_lower"] or (len(term_recs) >= methods[rank_method_code]["min_nr_words_docs"] and (((float(len(term_recs)) / float(methods[rank_method_code]["col_size"])) <= methods[rank_method_code]["max_word_occurence"]) and ((float(len(term_recs)) / float(methods[rank_method_code]["col_size"])) >= methods[rank_method_code]["min_word_occurence"]))): #too complicated...something must be done
lwords.append((t, methods[rank_method_code]["rnkWORD_table"])) #list of terms used
(recdict, rec_termcount) = calculate_record_relevance_findsimilar((t, round(tf, 4)) , term_recs, hitset, recdict, rec_termcount, verbose, "true") #true tells the function to not calculate all unimportant terms
if len(tf_values) > methods[rank_method_code]["max_nr_words_lower"] and (len(lwords) == methods[rank_method_code]["max_nr_words_upper"] or tf < 0):
break
if len(recdict) == 0 or len(lwords) == 0:
return (None, "Could not find any similar documents, possibly because of error in ranking data.", "", voutput)
else: #sort if we got something to sort
(reclist, hitset) = sort_record_relevance_findsimilar(recdict, rec_termcount, hitset, rank_limit_relevance, verbose)
if verbose > 0:
voutput += "<br>Number of terms: %s<br>" % run_sql("SELECT count(id) FROM %s" % methods[rank_method_code]["rnkWORD_table"])[0][0]
voutput += "Number of terms to use for query: %s<br>" % len(lwords)
voutput += "Terms: %s<br>" % lwords
voutput += "Current number of recIDs: %s<br>" % (methods[rank_method_code]["col_size"])
voutput += "Prepare time: %s<br>" % (str(time.time() - startCreate))
voutput += "Total time used: %s<br>" % (str(time.time() - startCreate))
rank_method_stat(rank_method_code, reclist, lwords)
return (reclist[:len(reclist)], methods[rank_method_code]["prefix"], methods[rank_method_code]["postfix"], voutput)
def word_similarity(rank_method_code, lwords, hitset, rank_limit_relevance,verbose):
"""Ranking a records containing specified words and returns a sorted list.
input:
rank_method_code - the code of the method, from the name field in rnkMETHOD
lwords - a list of words from the query
hitset - a list of hits for the query found by search_engine
rank_limit_relevance - show only records with a rank value above this
verbose - verbose value
output:
reclist - a list of sorted records: [[23,34], [344,24], [1,01]]
prefix - what to show before the rank value
postfix - what to show after the rank value
voutput - contains extra information, content dependent on verbose value"""
global voutput
startCreate = time.time()
if verbose > 0:
voutput += "<br>Running rank method: %s, using word_frequency function in bibrank_record_sorter<br>" % rank_method_code
lwords_old = lwords
lwords = []
#Check terms, remove non alphanumeric characters. Use both unstemmed and stemmed version of all terms.
for i in range(0, len(lwords_old)):
term = string.lower(lwords_old[i])
if not methods[rank_method_code]["stopwords"] == "True" or methods[rank_method_code]["stopwords"] and not is_stopword(term, 1):
lwords.append((term, methods[rank_method_code]["rnkWORD_table"]))
terms = string.split(string.lower(re.sub(methods[rank_method_code]["chars_alphanumericseparators"], ' ', term)))
for term in terms:
if methods[rank_method_code].has_key("stemmer"): # stem word
term = stem(string.replace(term, ' ', ''), methods[rank_method_code]["stemmer"])
if lwords_old[i] != term: #add if stemmed word is different than original word
lwords.append((term, methods[rank_method_code]["rnkWORD_table"]))
(recdict, rec_termcount, lrecIDs_remove) = ({}, {}, {})
#For each term, if accepted, get a list of the records using the term
#calculate then relevance for each term before sorting the list of records
for (term, table) in lwords:
term_recs = run_sql("SELECT term, hitlist FROM %s WHERE term='%s'" % (methods[rank_method_code]["rnkWORD_table"], MySQLdb.escape_string(term)))
if term_recs: #if term exists in database, use for ranking
term_recs = deserialize_via_marshal(term_recs[0][1])
(recdict, rec_termcount) = calculate_record_relevance((term, int(term_recs["Gi"][1])) , term_recs, hitset, recdict, rec_termcount, verbose, quick=None)
del term_recs
if len(recdict) == 0 or (len(lwords) == 1 and lwords[0] == ""):
return (None, "Records not ranked. The query is not detailed enough, or not enough records found, for ranking to be possible.", "", voutput)
else: #sort if we got something to sort
(reclist, hitset) = sort_record_relevance(recdict, rec_termcount, hitset, rank_limit_relevance, verbose)
#Add any documents not ranked to the end of the list
if hitset:
hitset.calculate_nbhits()
lrecIDs = hitset.tolist() #using 2-3mb
reclist = zip(lrecIDs, [0] * len(lrecIDs)) + reclist #using 6mb
if verbose > 0:
voutput += "<br>Current number of recIDs: %s<br>" % (methods[rank_method_code]["col_size"])
voutput += "Number of terms: %s<br>" % run_sql("SELECT count(id) FROM %s" % methods[rank_method_code]["rnkWORD_table"])[0][0]
voutput += "Terms: %s<br>" % lwords
voutput += "Prepare and pre calculate time: %s<br>" % (str(time.time() - startCreate))
voutput += "Total time used: %s<br>" % (str(time.time() - startCreate))
rank_method_stat(rank_method_code, reclist, lwords)
return (reclist, methods[rank_method_code]["prefix"], methods[rank_method_code]["postfix"], voutput)
def calculate_record_relevance(term, invidx, hitset, recdict, rec_termcount, verbose, quick=None):
"""Calculating the relevance of the documents based on the input, calculates only one word
term - (term, query term factor) the term and its importance in the overall search
invidx - {recid: tf, Gi: norm value} The Gi value is used as a idf value
hitset - a hitset with records that are allowed to be ranked
recdict - contains currently ranked records, is returned with new values
rec_termcount - {recid: count} the number of terms in this record that matches the query
verbose - verbose value
quick - if quick=yes only terms with a positive qtf is used, to limit the number of records to sort"""
(t, qtf) = term
if invidx.has_key("Gi"):#Gi = weigth for this term, created by bibrank_word_indexer
Gi = invidx["Gi"][1]
del invidx["Gi"]
else: #if not existing, bibrank should be run with -R
return (recdict, rec_termcount)
if not quick or (qtf >= 0 or (qtf < 0 and len(recdict) == 0)):
#Only accept records existing in the hitset received from the search engine
for (j, tf) in invidx.iteritems():
if hitset.contains(j):#only include docs found by search_engine based on query
try: #calculates rank value
recdict[j] = recdict.get(j, 0) + int(math.log(tf[0] * Gi * tf[1] * qtf))
except:
return (recdict, rec_termcount)
rec_termcount[j] = rec_termcount.get(j, 0) + 1 #number of terms from query in document
elif quick: #much used term, do not include all records, only use already existing ones
for (j, tf) in recdict.iteritems(): #i.e: if doc contains important term, also count unimportant
if invidx.has_key(j):
tf = invidx[j]
recdict[j] = recdict.get(j, 0) + int(math.log(tf[0] * Gi * tf[1] * qtf))
rec_termcount[j] = rec_termcount.get(j, 0) + 1 #number of terms from query in document
return (recdict, rec_termcount)
def calculate_record_relevance_findsimilar(term, invidx, hitset, recdict, rec_termcount, verbose, quick=None):
"""Calculating the relevance of the documents based on the input, calculates only one word
term - (term, query term factor) the term and its importance in the overall search
invidx - {recid: tf, Gi: norm value} The Gi value is used as a idf value
hitset - a hitset with records that are allowed to be ranked
recdict - contains currently ranked records, is returned with new values
rec_termcount - {recid: count} the number of terms in this record that matches the query
verbose - verbose value
quick - if quick=yes only terms with a positive qtf is used, to limit the number of records to sort"""
(t, qtf) = term
if invidx.has_key("Gi"): #Gi = weigth for this term, created by bibrank_word_indexer
Gi = invidx["Gi"][1]
del invidx["Gi"]
else: #if not existing, bibrank should be run with -R
return (recdict, rec_termcount)
if not quick or (qtf >= 0 or (qtf < 0 and len(recdict) == 0)):
#Only accept records existing in the hitset received from the search engine
for (j, tf) in invidx.iteritems():
if hitset.contains(j): #only include docs found by search_engine based on query
#calculate rank value
recdict[j] = recdict.get(j, 0) + int((1 + math.log(tf[0])) * Gi * tf[1] * qtf)
rec_termcount[j] = rec_termcount.get(j, 0) + 1 #number of terms from query in document
elif quick: #much used term, do not include all records, only use already existing ones
for (j, tf) in recdict.iteritems(): #i.e: if doc contains important term, also count unimportant
if invidx.has_key(j):
tf = invidx[j]
recdict[j] = recdict[j] + int((1 + math.log(tf[0])) * Gi * tf[1] * qtf)
rec_termcount[j] = rec_termcount.get(j, 0) + 1 #number of terms from query in document
return (recdict, rec_termcount)
def sort_record_relevance(recdict, rec_termcount, hitset, rank_limit_relevance, verbose):
"""Sorts the dictionary and returns records with a relevance higher than the given value.
recdict - {recid: value} unsorted
rank_limit_relevance - a value > 0 usually
verbose - verbose value"""
startCreate = time.time()
global voutput
reclist = []
#remove all ranked documents so that unranked can be added to the end
hitset.removemany(recdict.keys())
#gives each record a score between 0-100
divideby = max(recdict.values())
for (j, w) in recdict.iteritems():
w = int(w * 100 / divideby)
if w >= rank_limit_relevance:
reclist.append((j, w))
#sort scores
reclist.sort(lambda x, y: cmp(x[1], y[1]))
if verbose > 0:
voutput += "Number of records sorted: %s<br>" % len(reclist)
voutput += "Sort time: %s<br>" % (str(time.time() - startCreate))
return (reclist, hitset)
def sort_record_relevance_findsimilar(recdict, rec_termcount, hitset, rank_limit_relevance, verbose):
"""Sorts the dictionary and returns records with a relevance higher than the given value.
recdict - {recid: value} unsorted
rank_limit_relevance - a value > 0 usually
verbose - verbose value"""
startCreate = time.time()
global voutput
reclist = []
#Multiply with the number of terms of the total number of terms in the query existing in the records
for j in recdict.keys():
if recdict[j] > 0 and rec_termcount[j] > 1:
recdict[j] = math.log((recdict[j] * rec_termcount[j]))
else:
recdict[j] = 0
hitset.removemany(recdict.keys())
#gives each record a score between 0-100
divideby = max(recdict.values())
for (j, w) in recdict.iteritems():
w = int(w * 100 / divideby)
if w >= rank_limit_relevance:
reclist.append((j, w))
#sort scores
reclist.sort(lambda x, y: cmp(x[1], y[1]))
if verbose > 0:
voutput += "Number of records sorted: %s<br>" % len(reclist)
voutput += "Sort time: %s<br>" % (str(time.time() - startCreate))
return (reclist, hitset)
def rank_method_stat(rank_method_code, reclist, lwords):
"""Shows some statistics about the searchresult.
rank_method_code - name field from rnkMETHOD
reclist - a list of sorted and ranked records
lwords - the words in the query"""
global voutput
if len(reclist) > 20:
j = 20
else:
j = len(reclist)
voutput += "<br>Rank statistics:<br>"
for i in range(1, j + 1):
voutput += "%s,Recid:%s,Score:%s<br>" % (i,reclist[len(reclist) - i][0],reclist[len(reclist) - i][1])
for (term, table) in lwords:
term_recs = run_sql("SELECT hitlist FROM %s WHERE term='%s'" % (table, term))
if term_recs:
term_recs = deserialize_via_marshal(term_recs[0][0])
if term_recs.has_key(reclist[len(reclist) - i][0]):
voutput += "%s-%s / " % (term, term_recs[reclist[len(reclist) - i][0]])
voutput += "<br>"
voutput += "<br>Score variation:<br>"
count = {}
for i in range(0, len(reclist)):
count[reclist[i][1]] = count.get(reclist[i][1], 0) + 1
i = 100
while i >= 0:
if count.has_key(i):
voutput += "%s-%s<br>" % (i, count[i])
i -= 1
try:
import psyco
psyco.bind(find_similar)
psyco.bind(rank_by_method)
psyco.bind(calculate_record_relevance)
psyco.bind(post_calculate_record_relevance)
psyco.bind(word_similarity)
psyco.bind(sort_record_relevance)
psyco.bind(serialize_via_numeric_array)
psyco.bind(serialize_via_marshal)
psyco.bind(deserialize_via_numeric_array)
psyco.bind(deserialize_via_marshal)
except StandardError, e:
pass
diff --git a/modules/bibrank/lib/bibrank_record_sorter_tests.py b/modules/bibrank/lib/bibrank_record_sorter_tests.py
index 62e684460..780313201 100644
--- a/modules/bibrank/lib/bibrank_record_sorter_tests.py
+++ b/modules/bibrank/lib/bibrank_record_sorter_tests.py
@@ -1,56 +1,56 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the ranking engine."""
__version__ = "$Id$"
import unittest
from cdsware import bibrank_record_sorter
from cdsware.search_engine import HitSet
class TestListSetOperations(unittest.TestCase):
"""Test list set operations."""
def test_record_sorter(self):
"""bibrank record sorter - sorting records"""
hitset = HitSet()
hitset.addlist((1,2,5))
hitset2 = HitSet()
hitset2.add(5)
rec_termcount = {1: 1, 2: 1, 5: 1}
(res1, res2) = bibrank_record_sorter.sort_record_relevance({1: 50, 2:30, 3:70,4:10},rec_termcount,hitset, 50,0)
self.assertEqual(([(1, 71), (3, 100)], hitset2.tolist()), (res1, res2.tolist()))
def test_calculate_record_relevance(self):
"""bibrank record sorter - calculating relevances"""
hitset = HitSet()
hitset.addlist((1,2,5))
self.assertEqual(({1: 7, 2: 7, 5: 5}, {1: 1, 2: 1, 5: 1}), bibrank_record_sorter.calculate_record_relevance(("testterm", 2.0),
{"Gi":(0, 50.0), 1: (3, 4.0), 2: (4, 5.0), 5: (1, 3.5)}, hitset, {}, {}, 0, None))
def create_test_suite():
"""Return test suite for the indexing engine."""
return unittest.TestSuite((unittest.makeSuite(TestListSetOperations,'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibrank/lib/bibrank_tag_based_indexer.py b/modules/bibrank/lib/bibrank_tag_based_indexer.py
index 32c05aa95..173a9e750 100644
--- a/modules/bibrank/lib/bibrank_tag_based_indexer.py
+++ b/modules/bibrank/lib/bibrank_tag_based_indexer.py
@@ -1,595 +1,595 @@
# -*- coding: utf-8 -*-
## $Id$
## Ranking of records using different parameters and methods.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__version__ = "$Id$"
from marshal import loads,dumps
from zlib import compress,decompress
from string import split,translate,lower,upper
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import Numeric
import urllib
import signal
import tempfile
import unicodedata
import traceback
import cStringIO
import re
import copy
import types
import ConfigParser
from cdsware.config import *
from cdsware.search_engine_config import cfg_max_recID
from cdsware.search_engine import perform_request_search, strip_accents
from cdsware.search_engine import HitSet, get_index_id, create_basic_search_units
from cdsware.bibrank_citation_indexer import get_citation_weight
from cdsware.bibrank_downloads_indexer import *
from cdsware.dbquery import run_sql
options = {}
def citation_exec(rank_method_code, name, config):
"""Creating the rank method data for citation"""
dict = get_citation_weight(rank_method_code, config)
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if dict: intoDB(dict, date, rank_method_code)
else: print "no need to update the indexes for citations"
def single_tag_rank_method_exec(rank_method_code, name, config):
"""Creating the rank method data"""
startCreate = time.time()
rnkset = {}
rnkset_old = fromDB(rank_method_code)
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
rnkset_new = single_tag_rank(config)
rnkset = union_dicts(rnkset_old, rnkset_new)
intoDB(rnkset, date, rank_method_code)
def download_weight_filtering_user(row,run):
return bibrank_engine(row,run)
def download_weight_total(row,run):
return bibrank_engine(row,run)
def file_similarity_by_times_downloaded(row,run):
return bibrank_engine(row,run)
def download_weight_filtering_user_exec (rank_method_code, name, config):
"""Ranking by number of downloads per User.
Only one full Text Download is taken in account for one specific userIP address"""
time1 = time.time()
dic = fromDB(rank_method_code)
last_updated = get_lastupdated(rank_method_code)
keys = new_downloads_to_index(last_updated)
filter_downloads_per_hour(keys,last_updated)
dic = get_download_weight_filtering_user(dic, keys)
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
intoDB(dic, date, rank_method_code)
time2 = time.time()
return {"time":time2-time1}
def download_weight_total_exec(rank_method_code, name, config):
"""rankink by total number of downloads without check the user ip
if users downloads 3 time the same full text document it has to be count as 3 downloads"""
time1 = time.time()
dic = fromDB(rank_method_code)
last_updated = get_lastupdated(rank_method_code)
keys = new_downloads_to_index(last_updated)
filter_downloads_per_hour(keys,last_updated)
dic = get_download_weight_total(dic, keys)
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
intoDB(dic, date, rank_method_code)
time2 = time.time()
return {"time":time2-time1}
def file_similarity_by_times_downloaded_exec(rank_method_code, name, config):
"""update dictionnary {recid:[(recid,nb page similarity),()..]}"""
time1 = time.time()
dic = fromDB(rank_method_code)
last_updated = get_lastupdated(rank_method_code)
keys = new_downloads_to_index(last_updated)
filter_downloads_per_hour(keys,last_updated)
dic = get_file_similarity_by_times_downloaded(dic, keys)
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
intoDB(dic, date, rank_method_code)
time2 = time.time()
return {"time":time2-time1}
def single_tag_rank_method_exec(rank_method_code, name, config):
"""Creating the rank method data"""
startCreate = time.time()
rnkset = {}
rnkset_old = fromDB(rank_method_code)
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
rnkset_new = single_tag_rank(config)
rnkset = union_dicts(rnkset_old, rnkset_new)
intoDB(rnkset, date, rank_method_code)
def single_tag_rank(config):
"""Connect the given tag with the data from the kb file given"""
if options["verbose"] >= 9:
write_message("Loading knowledgebase file")
kb_data = {}
records = []
write_message("Reading knowledgebase file: %s" % config.get(config.get("rank_method", "function"), "kb_src"))
input = open(config.get(config.get("rank_method", "function"), "kb_src"), 'r')
data = input.readlines()
for line in data:
if not line[0:1] == "#":
kb_data[string.strip((string.split(string.strip(line),"---"))[0])] = (string.split(string.strip(line), "---"))[1]
write_message("Number of lines read from knowledgebase file: %s" % len(kb_data))
tag = config.get(config.get("rank_method", "function"),"tag")
tags = split(config.get(config.get("rank_method", "function"), "check_mandatory_tags"),",")
if tags == ['']:
tags = ""
records = []
for (recids,recide) in options["recid_range"]:
write_message("......Processing records #%s-%s" % (recids, recide))
recs = run_sql("SELECT id_bibrec,value FROM bib%sx,bibrec_bib%sx WHERE tag='%s' AND id_bibxxx=id and id_bibrec >=%s and id_bibrec<=%s" % (tag[0:2], tag[0:2], tag, recids, recide))
valid = HitSet(Numeric.ones(cfg_max_recID + 1))
for key in tags:
newset = HitSet()
newset.addlist(run_sql("SELECT id_bibrec FROM bib%sx,bibrec_bib%sx WHERE id_bibxxx=id AND tag='%s' AND id_bibxxx=id and id_bibrec >=%s and id_bibrec<=%s" % (tag[0:2], tag[0:2], key, recids, recide)))
valid.intersect(newset)
if tags:
recs = filter(lambda x: valid.contains(x[0]), recs)
records = records + list(recs)
write_message("Number of records found with the necessary tags: %s" % len(records))
records = filter(lambda x: options["validset"].contains(x[0]), records)
rnkset = {}
for key,value in records:
if kb_data.has_key(value):
if not rnkset.has_key(key):
rnkset[key] = float(kb_data[value])
else:
if kb_data.has_key(rnkset[key]) and float(kb_data[value]) > float((rnkset[key])[1]):
rnkset[key] = float(kb_data[value])
else:
rnkset[key] = 0
write_message("Number of records available in rank method: %s" % len(rnkset))
return rnkset
def get_lastupdated(rank_method_code):
"""Get the last time the rank method was updated"""
res = run_sql("SELECT rnkMETHOD.last_updated FROM rnkMETHOD WHERE name='%s'" % rank_method_code)
if res:
return res[0][0]
else:
raise Exception("Is this the first run? Please do a complete update.")
def intoDB(dict, date, rank_method_code):
"""Insert the rank method data into the database"""
id = run_sql("SELECT id from rnkMETHOD where name='%s'" % rank_method_code)
del_rank_method_codeDATA(rank_method_code)
run_sql("INSERT INTO rnkMETHODDATA(id_rnkMETHOD, relevance_data) VALUES ('%s','%s')" % (id[0][0], serialize_via_marshal(dict)))
run_sql("UPDATE rnkMETHOD SET last_updated='%s' WHERE name='%s'" % (date, rank_method_code))
def fromDB(rank_method_code):
"""Get the data for a rank method"""
id = run_sql("SELECT id from rnkMETHOD where name='%s'" % rank_method_code)
res = run_sql("SELECT relevance_data FROM rnkMETHODDATA WHERE id_rnkMETHOD=%s" % id[0][0])
if res:
return deserialize_via_marshal(res[0][0])
else:
return {}
def del_rank_method_codeDATA(rank_method_code):
"""Delete the data for a rank method"""
id = run_sql("SELECT id from rnkMETHOD where name='%s'" % rank_method_code)
res = run_sql("DELETE FROM rnkMETHODDATA WHERE id_rnkMETHOD=%s" % id[0][0])
def del_recids(rank_method_code, range):
"""Delete some records from the rank method"""
id = run_sql("SELECT id from rnkMETHOD where name='%s'" % rank_method_code)
res = run_sql("SELECT relevance_data FROM rnkMETHODDATA WHERE id_rnkMETHOD=%s" % id[0][0])
if res:
rec_dict = deserialize_via_marshal(res[0][0])
write_message("Old size: %s" % len(rec_dict))
for (recids,recide) in range:
for i in range(int(recids), int(recide)):
if rec_dict.has_key(i):
del rec_dict[i]
write_messag("New size: %s" % len(rec_dict))
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
intoDB(rec_dict, date, rank_method_code)
else:
print "Create before deleting!"
def union_dicts(dict1, dict2):
"Returns union of the two dicts."
union_dict = {}
for (key, value) in dict1.iteritems():
union_dict[key] = value
for (key, value) in dict2.iteritems():
union_dict[key] = value
return union_dict
def rank_method_code_statistics(rank_method_code):
"""Print statistics"""
method = fromDB(rank_method_code)
max = ('',-999999)
maxcount = 0
min = ('',999999)
mincount = 0
for (recID, value) in method.iteritems():
if value < min and value > 0:
min = value
if value > max:
max = value
for (recID, value) in method.iteritems():
if value == min:
mincount += 1
if value == max:
maxcount += 1
write_message("Showing statistic for selected method")
write_message("Method name: %s" % getName(rank_method_code))
write_message("Short name: %s" % rank_method_code)
write_message("Last run: %s" % get_lastupdated(rank_method_code))
write_message("Number of records: %s" % len(method))
write_message("Lowest value: %s - Number of records: %s" % (min, mincount))
write_message("Highest value: %s - Number of records: %s" % (max, maxcount))
write_message("Divided into 10 sets:")
for i in range(1,11):
setcount = 0
distinct_values = {}
lower = -1.0 + ((float(max + 1) / 10)) * (i - 1)
upper = -1.0 + ((float(max + 1) / 10)) * i
for (recID, value) in method.iteritems():
if value >= lower and value <= upper:
setcount += 1
distinct_values[value] = 1
write_message("Set %s (%s-%s) %s Distinct values: %s" % (i, lower, upper, len(distinct_values), setcount))
def check_method(rank_method_code):
write_message("Checking rank method...")
if len(fromDB(rank_method_code)) == 0:
write_message("Rank method not yet executed, please run it to create the necessary data.")
else:
if len(add_recIDs_by_date(rank_method_code)) > 0:
write_message("Records modified, update recommended")
else:
write_message("No records modified, update not necessary")
def write_message(msg, stream = sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr). Useful for debugging stuff."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
shift_re = sre.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
if options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
if options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
if options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("stopping...")
task_update_status("STOPPING")
errcode = 0
try:
task_sig_stop_commands()
write_message("stopped")
task_update_status("STOPPED")
except StandardError, err:
write_message("Error during stopping! %e" % err)
task_update_status("STOPPINGFAILED")
errcode = 1
sys.exit(errcode)
def task_sig_stop_commands():
"""Do all the commands necessary to stop the task before quitting.
Useful for task_sig_stop() handler.
"""
write_message("stopping commands started")
write_message("stopping commands ended")
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
if options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
if options["verbose"]>= 9:
write_message("got signal %d" % sig)
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
query = "UPDATE schTASK SET progress='%s' where id=%d" % (MySQLdb.escape_string(msg), task_id)
if options["verbose"]>= 9:
write_message(query)
run_sql(query)
return
def task_update_status(val):
"""Updates state information in the BibSched task table."""
query = "UPDATE schTASK SET status='%s' where id=%d" % (MySQLdb.escape_string(val), task_id)
if options["verbose"]>= 9:
write_message(query)
run_sql(query)
return
def split_ranges(parse_string):
recIDs = []
ranges = string.split(parse_string, ",")
for range in ranges:
tmp_recIDs = string.split(range, "-")
if len(tmp_recIDs)==1:
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[0])])
else:
if int(tmp_recIDs[0]) > int(tmp_recIDs[1]): # sanity check
tmp = tmp_recIDs[0]
tmp_recIDs[0] = tmp_recIDs[1]
tmp_recIDs[1] = tmp
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[1])])
return recIDs
def bibrank_engine(row, run):
"""Run the indexing task. The row argument is the BibSched task
queue row, containing if, arguments, etc.
Return 1 in case of success and 0 in case of failure.
"""
try:
import psyco
psyco.bind(single_tag_rank)
psyco.bind(single_tag_rank_method_exec)
psyco.bind(serialize_via_numeric_array)
psyco.bind(deserialize_via_numeric_array)
except StandardError, e:
print "Psyco ERROR",e
startCreate = time.time()
global options, task_id
task_id = row[0]
task_proc = row[1]
options = loads(row[6])
task_starting_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
sets = {}
try:
options["run"] = []
options["run"].append(run)
for rank_method_code in options["run"]:
cfg_name = getName(rank_method_code)
if options["verbose"] >= 0:
write_message("Running rank method: %s." % cfg_name)
file = etcdir + "/bibrank/" + rank_method_code + ".cfg"
config = ConfigParser.ConfigParser()
try:
config.readfp(open(file))
except StandardError, e:
write_message("Cannot find configurationfile: %s" % file, sys.stderr)
raise StandardError
cfg_short = rank_method_code
cfg_function = config.get("rank_method", "function") + "_exec"
cfg_name = getName(cfg_short)
options["validset"] = get_valid_range(rank_method_code)
if options["collection"]:
l_of_colls = string.split(options["collection"], ",")
recIDs = perform_request_search(c=l_of_colls)
recIDs_range = []
for recID in recIDs:
recIDs_range.append([recID,recID])
options["recid_range"] = recIDs_range
elif options["id"]:
options["recid_range"] = options["id"]
elif options["modified"]:
options["recid_range"] = add_recIDs_by_date(rank_method_code, options["modified"])
elif options["last_updated"]:
options["recid_range"] = add_recIDs_by_date(rank_method_code)
else:
if options["verbose"] > 1:
write_message("No records specified, updating all")
min_id = run_sql("SELECT min(id) from bibrec")[0][0]
max_id = run_sql("SELECT max(id) from bibrec")[0][0]
options["recid_range"] = [[min_id, max_id]]
if options["quick"] == "no" and options["verbose"] >= 9:
write_message("Recalculate parameter not used, parameter ignored.")
if options["cmd"] == "del":
del_recids(cfg_short, options["recid_range"])
elif options["cmd"] == "add":
func_object = globals().get(cfg_function)
func_object(rank_method_code, cfg_name, config)
elif options["cmd"] == "stat":
rank_method_code_statistics(rank_method_code)
elif options["cmd"] == "check":
check_method(rank_method_code)
elif options["cmd"] == "repair":
pass
else:
write_message("Invalid command found processing %s" % rank_method_code, sys.stderr)
raise StandardError
except StandardError, e:
write_message("\nException caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
raise StandardError
if options["verbose"]:
showtime((time.time() - startCreate))
return 1
def get_valid_range(rank_method_code):
"""Return a range of records"""
if options["verbose"] >=9:
write_message("Getting records from collections enabled for rank method.")
res = run_sql("SELECT collection.name FROM collection,collection_rnkMETHOD,rnkMETHOD WHERE collection.id=id_collection and id_rnkMETHOD=rnkMETHOD.id and rnkMETHOD.name='%s'" % rank_method_code)
l_of_colls = []
for coll in res:
l_of_colls.append(coll[0])
if len(l_of_colls) > 0:
recIDs = perform_request_search(c=l_of_colls)
else:
recIDs = []
valid = HitSet()
valid.addlist(recIDs)
return valid
def add_recIDs_by_date(rank_method_code, dates=""):
"""Return recID range from records modified between DATES[0] and DATES[1].
If DATES is not set, then add records modified since the last run of
the ranking method RANK_METHOD_CODE.
"""
if not dates:
try:
dates = (get_lastupdated(rank_method_code),'')
except Exception, e:
dates = ("0000-00-00 00:00:00", '')
query = """SELECT b.id FROM bibrec AS b WHERE b.modification_date >= '%s'""" % dates[0]
if dates[1]:
query += "and b.modification_date <= '%s'" % dates[1]
query += "ORDER BY b.id ASC"""
res = run_sql(query)
list = create_range_list(res)
if not list:
if options["verbose"]:
write_message("No new records added since last time method was run")
return list
def getName(rank_method_code, ln=cdslang, type='ln'):
"""Returns the name of the method if it exists"""
try:
rnkid = run_sql("SELECT id FROM rnkMETHOD where name='%s'" % rank_method_code)
if rnkid:
rnkid = str(rnkid[0][0])
res = run_sql("SELECT value FROM rnkMETHODNAME where type='%s' and ln='%s' and id_rnkMETHOD=%s" % (type, ln, rnkid))
if not res:
res = run_sql("SELECT value FROM rnkMETHODNAME WHERE ln='%s' and id_rnkMETHOD=%s and type='%s'" % (cdslang, rnkid, type))
if not res:
return rank_method_code
return res[0][0]
else:
raise Exception
except Exception, e:
write_message("Cannot run rank method, either given code for method is wrong, or it has not been added using the webinterface.")
raise Exception
def create_range_list(res):
"""Creates a range list from a recID select query result contained
in res. The result is expected to have ascending numerical order."""
if not res:
return []
row = res[0]
if not row:
return []
else:
range_list = [[row[0],row[0]]]
for row in res[1:]:
id = row[0]
if id == range_list[-1][1] + 1:
range_list[-1][1] = id
else:
range_list.append([id,id])
return range_list
def single_tag_rank_method(row, run):
return bibrank_engine(row, run)
def serialize_via_numeric_array_dumps(arr):
return Numeric.dumps(arr)
def serialize_via_numeric_array_compr(str):
return compress(str)
def serialize_via_numeric_array_escape(str):
return MySQLdb.escape_string(str)
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return serialize_via_numeric_array_escape(serialize_via_numeric_array_compr(serialize_via_numeric_array_dumps(arr)))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(decompress(string))
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(compress(dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return loads(decompress(string))
def showtime(timeused):
"""Show time used for method"""
if options["verbose"] >= 9:
write_message("Time used: %d second(s)." % timeused)
def citation(row,run):
return bibrank_engine(row, run)
diff --git a/modules/bibrank/lib/bibrank_tag_based_indexer_tests.py b/modules/bibrank/lib/bibrank_tag_based_indexer_tests.py
index fae8fe2ee..a3c9d13f8 100644
--- a/modules/bibrank/lib/bibrank_tag_based_indexer_tests.py
+++ b/modules/bibrank/lib/bibrank_tag_based_indexer_tests.py
@@ -1,48 +1,48 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the ranking engine."""
__lastupdated__ = """$Date$"""
__version__ = "$Id$"
import unittest
from cdsware import bibrank_tag_based_indexer
class TestListSetOperations(unittest.TestCase):
"""Test list set operations."""
def test_union_dicts(self):
"""bibrank tag based indexer - union dicts"""
self.assertEqual({1: 5, 2: 6, 3: 9, 4: 10, 10: 1}, bibrank_tag_based_indexer.union_dicts({1: 5, 2: 6, 3: 9}, {3:9, 4:10, 10: 1}))
def test_split_ranges(self):
"""bibrank tag based indexer - split ranges"""
self.assertEqual([[0, 500], [600, 1000]], bibrank_tag_based_indexer.split_ranges("0-500,600-1000"))
def create_test_suite():
"""Return test suite for the indexing engine."""
return unittest.TestSuite((unittest.makeSuite(TestListSetOperations,'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/bibrank/lib/bibrank_word_indexer.py b/modules/bibrank/lib/bibrank_word_indexer.py
index fd359375b..325641c01 100644
--- a/modules/bibrank/lib/bibrank_word_indexer.py
+++ b/modules/bibrank/lib/bibrank_word_indexer.py
@@ -1,1465 +1,1465 @@
## $Id$
## BibRank word frequency indexer utility.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__version__ = "$Id$"
from zlib import compress,decompress
from string import split,translate,lower,upper
import marshal
import getopt
import getpass
import string
import os
import sre
import sys
import time
import MySQLdb
import Numeric
import urllib
import signal
import tempfile
import unicodedata
import traceback
import cStringIO
import math
import re
import ConfigParser
from cdsware.config import *
from cdsware.search_engine_config import cfg_max_recID
from cdsware.search_engine import perform_request_search, strip_accents, HitSet
from cdsware.dbquery import run_sql
from cdsware.bibindex_engine_stemmer import is_stemmer_available_for_language, stem
from cdsware.bibindex_engine_stopwords import is_stopword
from cdsware.bibindex_engine_config import conv_programs, conv_programs_helpers
## safety parameters concerning MySQL thread-multiplication problem:
cfg_check_mysql_threads = 0 # to check or not to check the problem?
cfg_max_mysql_threads = 50 # how many threads (connections) we consider as still safe
cfg_mysql_thread_timeout = 20 # we'll kill threads that were sleeping for more than X seconds
## override urllib's default password-asking behaviour:
class MyFancyURLopener(urllib.FancyURLopener):
def prompt_user_passwd(self, host, realm):
# supply some dummy credentials by default
return ("mysuperuser", "mysuperpass")
def http_error_401(self, url, fp, errcode, errmsg, headers):
# do not bother with protected pages
raise IOError, (999, 'unauthorized access')
return None
#urllib._urlopener = MyFancyURLopener()
## precompile some often-used regexp for speed reasons:
re_subfields = sre.compile('\$\$\w');
nb_char_in_line = 50 # for verbose pretty printing
chunksize = 1000 # default size of chunks that the records will be treated by
wordTables = []
base_process_size = 4500 # process base size
## Dictionary merging functions
def dict_union(list1, list2):
"Returns union of the two dictionaries."
union_dict = {}
for (e, count) in list1.iteritems():
union_dict[e] = count
for (e, count) in list2.iteritems():
if not union_dict.has_key(e):
union_dict[e] = count
else:
union_dict[e] = (union_dict[e][0] + count[0], count[1])
#for (e, count) in list2.iteritems():
# list1[e] = (list1.get(e, (0, 0))[0] + count[0], count[1])
#return list1
return union_dict
## safety function for killing slow MySQL threads:
def kill_sleepy_mysql_threads(max_threads=cfg_max_mysql_threads, thread_timeout=cfg_mysql_thread_timeout):
"""Check the number of MySQL threads and if there are more than
MAX_THREADS of them, lill all threads that are in a sleeping
state for more than THREAD_TIMEOUT seconds. (This is useful
for working around the the max_connection problem that appears
during indexation in some not-yet-understood cases.) If some
threads are to be killed, write info into the log file.
"""
res = run_sql("SHOW FULL PROCESSLIST")
if len(res) > max_threads:
for row in res:
r_id,r_user,r_host,r_db,r_command,r_time,r_state,r_info = row
if r_command == "Sleep" and int(r_time) > thread_timeout:
run_sql("KILL %s", (r_id,))
if options["verbose"] >= 1:
write_message("WARNING: too many MySQL threads, killing thread %s" % r_id)
return
# tagToFunctions mapping. It offers an indirection level necesary for
# indexing fulltext. The default is get_words_from_phrase
tagToWordsFunctions = {}
def get_words_from_phrase(phrase, weight, lang="",
chars_punctuation=r"[\.\,\:\;\?\!\"]",
chars_alphanumericseparators=r"[1234567890\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~]",
split=string.split):
"Returns list of words from phrase 'phrase'."
words = {}
phrase = strip_accents(phrase)
phrase = lower(phrase)
#Getting rid of strange characters
phrase = re.sub("&eacute;", 'e', phrase)
phrase = re.sub("&egrave;", 'e', phrase)
phrase = re.sub("&agrave;", 'a', phrase)
phrase = re.sub("&nbsp;", ' ', phrase)
phrase = re.sub("&laquo;", ' ', phrase)
phrase = re.sub("&raquo;", ' ', phrase)
phrase = re.sub("&ecirc;", ' ', phrase)
phrase = re.sub("&amp;", ' ', phrase)
if string.find(phrase, "</") > -1:
#Most likely html, remove html code
phrase = re.sub("(?s)<[^>]*>|&#?\w+;", ' ', phrase)
#removes http links
phrase = re.sub("(?s)http://[^( )]*", '', phrase)
phrase = re.sub(chars_punctuation, ' ', phrase)
#By doing this like below, characters standing alone, like c a b is not added to the inedx, but when they are together with characters like c++ or c$ they are added.
for word in split(phrase):
if options["remove_stopword"] == "True" and not is_stopword(word, 1) and check_term(word, 0):
if lang and lang !="none" and options["use_stemming"]:
word = stem(word, lang)
if not words.has_key(word):
words[word] = (0,0)
words[word] = (words[word][0] + weight, 0)
elif options["remove_stopword"] == "True" and not is_stopword(word, 1):
phrase = re.sub(chars_alphanumericseparators, ' ', word)
for word_ in split(phrase):
if lang and lang !="none" and options["use_stemming"]:
word_ = stem(word_, lang)
if word_:
if not words.has_key(word_):
words[word_] = (0,0)
words[word_] = (words[word_][0] + weight, 0)
return words
def split_ranges(parse_string):
recIDs = []
ranges = string.split(parse_string, ",")
for range in ranges:
tmp_recIDs = string.split(range, "-")
if len(tmp_recIDs)==1:
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[0])])
else:
if int(tmp_recIDs[0]) > int(tmp_recIDs[1]): # sanity check
tmp = tmp_recIDs[0]
tmp_recIDs[0] = tmp_recIDs[1]
tmp_recIDs[1] = tmp
recIDs.append([int(tmp_recIDs[0]), int(tmp_recIDs[1])])
return recIDs
def get_date_range(var):
"Returns the two dates contained as a low,high tuple"
limits = string.split(var, ",")
if len(limits)==1:
low = get_date(limits[0])
return low,None
if len(limits)==2:
low = get_date(limits[0])
high = get_date(limits[1])
return low,high
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
shift_re=sre.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def create_range_list(res):
"""Creates a range list from a recID select query result contained
in res. The result is expected to have ascending numerical order."""
if not res:
return []
row = res[0]
if not row:
return []
else:
range_list = [[row[0],row[0]]]
for row in res[1:]:
id = row[0]
if id == range_list[-1][1] + 1:
range_list[-1][1] = id
else:
range_list.append([id,id])
return range_list
def beautify_range_list(range_list):
"""Returns a non overlapping, maximal range list"""
ret_list = []
for new in range_list:
found = 0
for old in ret_list:
if new[0] <= old[0] <= new[1] + 1 or new[0] - 1 <= old[1] <= new[1]:
old[0] = min(old[0], new[0])
old[1] = max(old[1], new[1])
found = 1
break
if not found:
ret_list.append(new)
return ret_list
def serialize_via_numeric_array_dumps(arr):
return Numeric.dumps(arr)
def serialize_via_numeric_array_compr(str):
return compress(str)
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return serialize_via_numeric_array_compr(serialize_via_numeric_array_dumps(arr))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(decompress(string))
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(compress(marshal.dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return marshal.loads(decompress(string))
class WordTable:
"A class to hold the words table."
def __init__(self, tablename, fields_to_index, separators="[^\s]"):
"Creates words table instance."
self.tablename = tablename
self.recIDs_in_mem = []
self.fields_to_index = fields_to_index
self.separators = separators
self.value = {}
def get_field(self, recID, tag):
"""Returns list of values of the MARC-21 'tag' fields for the
record 'recID'."""
out = []
bibXXx = "bib" + tag[0] + tag[1] + "x"
bibrec_bibXXx = "bibrec_" + bibXXx
query = """SELECT value FROM %s AS b, %s AS bb
WHERE bb.id_bibrec=%s AND bb.id_bibxxx=b.id
AND tag LIKE '%s'""" % (bibXXx, bibrec_bibXXx, recID, tag);
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def clean(self):
"Cleans the words table."
self.value={}
def put_into_db(self, mode="normal", split=string.split):
"""Updates the current words table in the corresponding MySQL's
rnkWORD table. Mode 'normal' means normal execution,
mode 'emergency' means words index reverting to old state.
"""
if options["verbose"]:
write_message("%s %s wordtable flush started" % (self.tablename,mode))
write_message('...updating %d words into %sR started' % \
(len(self.value), self.tablename[:-1]))
task_update_progress("%s flushed %d/%d words" % (self.tablename, 0, len(self.value)))
self.recIDs_in_mem = beautify_range_list(self.recIDs_in_mem)
if mode == "normal":
for group in self.recIDs_in_mem:
query = """UPDATE %sR SET type='TEMPORARY' WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='CURRENT'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
nb_words_total = len(self.value)
nb_words_report = int(nb_words_total/10)
nb_words_done = 0
for word in self.value.keys():
self.put_word_into_db(word, self.value[word])
nb_words_done += 1
if nb_words_report!=0 and ((nb_words_done % nb_words_report) == 0):
if options["verbose"]:
write_message('......processed %d/%d words' % (nb_words_done, nb_words_total))
task_update_progress("%s flushed %d/%d words" % (self.tablename, nb_words_done, nb_words_total))
if options["verbose"] >= 9:
write_message('...updating %d words into %s ended' % \
(nb_words_total, self.tablename))
#if options["verbose"]:
# write_message('...updating reverse table %sR started' % self.tablename[:-1])
if mode == "normal":
for group in self.recIDs_in_mem:
query = """UPDATE %sR SET type='CURRENT' WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='FUTURE'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
query = """DELETE FROM %sR WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='TEMPORARY'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
if options["verbose"] >= 9:
write_message('End of updating wordTable into %s' % self.tablename)
elif mode == "emergency":
write_message("emergency")
for group in self.recIDs_in_mem:
query = """UPDATE %sR SET type='CURRENT' WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='TEMPORARY'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
query = """DELETE FROM %sR WHERE id_bibrec
BETWEEN '%d' AND '%d' AND type='FUTURE'""" % \
(self.tablename[:-1], group[0], group[1])
if options["verbose"] >= 9:
write_message(query)
run_sql(query)
if options["verbose"] >= 9:
write_message('End of emergency flushing wordTable into %s' % self.tablename)
#if options["verbose"]:
# write_message('...updating reverse table %sR ended' % self.tablename[:-1])
self.clean()
self.recIDs_in_mem = []
if options["verbose"]:
write_message("%s %s wordtable flush ended" % (self.tablename, mode))
task_update_progress("%s flush ended" % (self.tablename))
def load_old_recIDs(self,word):
"""Load existing hitlist for the word from the database index files."""
query = "SELECT hitlist FROM %s WHERE term=%%s" % self.tablename
res = run_sql(query, (word,))
if res:
return deserialize_via_marshal(res[0][0])
else:
return None
def merge_with_old_recIDs(self,word,recIDs, set):
"""Merge the system numbers stored in memory (hash of recIDs with value[0] > 0 or -1
according to whether to add/delete them) with those stored in the database index
and received in set universe of recIDs for the given word.
Return 0 in case no change was done to SET, return 1 in case SET was changed.
"""
set_changed_p = 0
for recID,sign in recIDs.iteritems():
if sign[0] == -1 and set.has_key(recID):
# delete recID if existent in set and if marked as to be deleted
del set[recID]
set_changed_p = 1
elif sign[0] > -1 and not set.has_key(recID):
# add recID if not existent in set and if marked as to be added
set[recID] = sign
set_changed_p = 1
elif sign[0] > -1 and sign[0] != set[recID][0]:
set[recID] = sign
set_changed_p = 1
return set_changed_p
def put_word_into_db(self, word, recIDs, split=string.split):
"""Flush a single word to the database and delete it from memory"""
set = self.load_old_recIDs(word)
#write_message("%s %s" % (word, self.value[word]))
if set: # merge the word recIDs found in memory:
options["modified_words"][word] = 1
if self.merge_with_old_recIDs(word, recIDs, set) == 0:
# nothing to update:
if options["verbose"] >= 9:
write_message("......... unchanged hitlist for ``%s''" % word)
pass
else:
# yes there were some new words:
if options["verbose"] >= 9:
write_message("......... updating hitlist for ``%s''" % word)
run_sql("UPDATE %s SET hitlist='%s' WHERE term='%s'" % (self.tablename, serialize_via_marshal(set), MySQLdb.escape_string(word)))
else: # the word is new, will create new set:
if options["verbose"] >= 9:
write_message("......... inserting hitlist for ``%s''" % word)
set = self.value[word]
if len(set) > 0:
#new word, add to list
options["modified_words"][word] = 1
run_sql("INSERT INTO %s (term, hitlist) VALUES ('%s', '%s')" % (self.tablename, MySQLdb.escape_string(word), serialize_via_marshal(set)))
if not set: # never store empty words
run_sql("DELETE from %s WHERE term=%%s" % self.tablename,
(word,))
del self.value[word]
def display(self):
"Displays the word table."
keys = self.value.keys()
keys.sort()
for k in keys:
if options["verbose"]:
write_message("%s: %s" % (k, self.value[k]))
def count(self):
"Returns the number of words in the table."
return len(self.value)
def info(self):
"Prints some information on the words table."
if options["verbose"]:
write_message("The words table contains %d words." % self.count())
def lookup_words(self, word=""):
"Lookup word from the words table."
if not word:
done = 0
while not done:
try:
word = raw_input("Enter word: ")
done = 1
except (EOFError, KeyboardInterrupt):
return
if self.value.has_key(word):
if options["verbose"]:
write_message("The word '%s' is found %d times." \
% (word, len(self.value[word])))
else:
if options["verbose"]:
write_message("The word '%s' does not exist in the word file."\
% word)
def update_last_updated(self, rank_method_code, starting_time=None):
"""Update last_updated column of the index table in the database.
Puts starting time there so that if the task was interrupted for record download,
the records will be reindexed next time."""
if starting_time is None:
return None
if options["verbose"] >= 9:
write_message("updating last_updated to %s...", starting_time)
return run_sql("UPDATE rnkMETHOD SET last_updated=%s WHERE name=%s",
(starting_time, rank_method_code,))
def add_recIDs(self, recIDs):
"""Fetches records which id in the recIDs range list and adds
them to the wordTable. The recIDs range list is of the form:
[[i1_low,i1_high],[i2_low,i2_high], ..., [iN_low,iN_high]].
"""
global chunksize
flush_count = 0
records_done = 0
records_to_go = 0
for range in recIDs:
records_to_go = records_to_go + range[1] - range[0] + 1
time_started = time.time() # will measure profile time
for range in recIDs:
i_low = range[0]
chunksize_count = 0
while i_low <= range[1]:
# calculate chunk group of recIDs and treat it:
i_high = min(i_low+options["flush"]-flush_count-1,range[1])
i_high = min(i_low+chunksize-chunksize_count-1, i_high)
try:
self.chk_recID_range(i_low, i_high)
except StandardError, e:
write_message("Exception caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
task_update_status("ERROR")
task_sig_stop_commands()
sys.exit(1)
if options["verbose"]:
write_message("%s adding records #%d-#%d started" % \
(self.tablename, i_low, i_high))
if cfg_check_mysql_threads:
kill_sleepy_mysql_threads()
task_update_progress("%s adding recs %d-%d" % (self.tablename, i_low, i_high))
self.del_recID_range(i_low, i_high)
just_processed = self.add_recID_range(i_low, i_high)
flush_count = flush_count + i_high - i_low + 1
chunksize_count = chunksize_count + i_high - i_low + 1
records_done = records_done + just_processed
if options["verbose"]:
write_message("%s adding records #%d-#%d ended " % \
(self.tablename, i_low, i_high))
if chunksize_count >= chunksize:
chunksize_count = 0
# flush if necessary:
if flush_count >= options["flush"]:
self.put_into_db()
self.clean()
if options["verbose"]:
write_message("%s backing up" % (self.tablename))
flush_count = 0
self.log_progress(time_started,records_done,records_to_go)
# iterate:
i_low = i_high + 1
if flush_count > 0:
self.put_into_db()
self.log_progress(time_started,records_done,records_to_go)
def add_recIDs_by_date(self, dates=""):
"""Add recIDs modified between DATES[0] and DATES[1].
If DATES is not set, then add records modified since the last run of
the ranking method.
"""
if not dates:
write_message("Using the last update time for the rank method")
query = """SELECT last_updated FROM rnkMETHOD WHERE name='%s'
""" % options["current_run"]
res = run_sql(query)
if not res:
return
if not res[0][0]:
dates = ("0000-00-00",'')
else:
dates = (res[0][0],'')
query = """SELECT b.id FROM bibrec AS b WHERE b.modification_date >=
'%s'""" % dates[0]
if dates[1]:
query += "and b.modification_date <= '%s'" % dates[1]
query += "ORDER BY b.id ASC"""
res = run_sql(query)
list = create_range_list(res)
if not list:
if options["verbose"]:
write_message( "No new records added. %s is up to date" % self.tablename)
else:
self.add_recIDs(list)
return list
def add_recID_range(self, recID1, recID2):
empty_list_string = serialize_via_marshal([])
wlist = {}
normalize = {}
self.recIDs_in_mem.append([recID1,recID2])
# secondly fetch all needed tags:
for (tag, weight, lang) in self.fields_to_index:
if tag in tagToWordsFunctions.keys():
get_words_function = tagToWordsFunctions[ tag ]
else: get_words_function = get_words_from_phrase
bibXXx = "bib" + tag[0] + tag[1] + "x"
bibrec_bibXXx = "bibrec_" + bibXXx
query = """SELECT bb.id_bibrec,b.value FROM %s AS b, %s AS bb
WHERE bb.id_bibrec BETWEEN %d AND %d
AND bb.id_bibxxx=b.id AND tag LIKE '%s'""" % (bibXXx, bibrec_bibXXx, recID1, recID2, tag)
res = run_sql(query)
nb_total_to_read = len(res)
verbose_idx = 0 # for verbose pretty printing
for row in res:
recID, phrase = row
if options["validset"].contains(recID):
if not wlist.has_key(recID): wlist[recID] = {}
new_words = get_words_function(phrase, weight, lang) # ,self.separators
wlist[recID] = dict_union(new_words,wlist[recID])
# were there some words for these recIDs found?
if len(wlist) == 0: return 0
recIDs = wlist.keys()
for recID in recIDs:
# was this record marked as deleted?
if "DELETED" in self.get_field(recID, "980__c"):
wlist[recID] = {}
if options["verbose"] >= 9:
write_message("... record %d was declared deleted, removing its word list" % recID)
if options["verbose"] >= 9:
write_message("... record %d, termlist: %s" % (recID, wlist[recID]))
query_factory = cStringIO.StringIO()
qwrite = query_factory.write
qwrite( "INSERT INTO %sR (id_bibrec,termlist,type) VALUES" % self.tablename[:-1])
qwrite( "('" )
qwrite( str(recIDs[0]) )
qwrite( "','" )
qwrite( serialize_via_marshal(wlist[recIDs[0]]) )
qwrite( "','FUTURE')" )
for recID in recIDs[1:]:
qwrite(",('")
qwrite(str(recID))
qwrite("','")
qwrite(serialize_via_marshal(wlist[recID]))
qwrite("','FUTURE')")
query = query_factory.getvalue()
query_factory.close()
run_sql(query)
query_factory = cStringIO.StringIO()
qwrite = query_factory.write
qwrite("INSERT INTO %sR (id_bibrec,termlist,type) VALUES" % self.tablename[:-1])
qwrite("('")
qwrite(str(recIDs[0]))
qwrite("','")
qwrite(serialize_via_marshal(wlist[recIDs[0]]))
qwrite("','CURRENT')")
for recID in recIDs[1:]:
qwrite( ",('" )
qwrite( str(recID) )
qwrite( "','" )
qwrite( empty_list_string )
qwrite( "','CURRENT')" )
query = query_factory.getvalue()
query_factory.close()
try:
run_sql(query)
except MySQLdb.DatabaseError:
pass
put = self.put
for recID in recIDs:
for (w, count) in wlist[recID].iteritems():
put(recID, w, count)
return len(recIDs)
def log_progress(self, start, done, todo):
"""Calculate progress and store it.
start: start time,
done: records processed,
todo: total number of records"""
time_elapsed = time.time() - start
# consistency check
if time_elapsed == 0 or done > todo:
return
time_recs_per_min = done/(time_elapsed/60.0)
if options["verbose"]:
write_message("%d records took %.1f seconds to complete.(%1.f recs/min)"\
% (done, time_elapsed, time_recs_per_min))
if time_recs_per_min:
if options["verbose"]:
write_message("Estimated runtime: %.1f minutes" % \
((todo-done)/time_recs_per_min))
def put(self, recID, word, sign):
"Adds/deletes a word to the word list."
try:
word = lower(word[:50])
if self.value.has_key(word):
# the word 'word' exist already: update sign
self.value[word][recID] = sign
# PROBLEM ?
else:
self.value[word] = {recID: sign}
except:
write_message("Error: Cannot put word %s with sign %d for recID %s." % (word, sign, recID))
def del_recIDs(self, recIDs):
"""Fetches records which id in the recIDs range list and adds
them to the wordTable. The recIDs range list is of the form:
[[i1_low,i1_high],[i2_low,i2_high], ..., [iN_low,iN_high]].
"""
count = 0
for range in recIDs:
self.del_recID_range(range[0],range[1])
count = count + range[1] - range[0]
self.put_into_db()
def del_recID_range(self, low, high):
"""Deletes records with 'recID' system number between low
and high from memory words index table."""
if options["verbose"] > 2:
write_message("%s fetching existing words for records #%d-#%d started" % \
(self.tablename, low, high))
self.recIDs_in_mem.append([low,high])
query = """SELECT id_bibrec,termlist FROM %sR as bb WHERE bb.id_bibrec
BETWEEN '%d' AND '%d'""" % (self.tablename[:-1], low, high)
recID_rows = run_sql(query)
for recID_row in recID_rows:
recID = recID_row[0]
wlist = deserialize_via_marshal(recID_row[1])
for word in wlist:
self.put(recID, word, (-1, 0))
if options["verbose"] > 2:
write_message("%s fetching existing words for records #%d-#%d ended" % \
(self.tablename, low, high))
def report_on_table_consistency(self):
"""Check reverse words index tables (e.g. rnkWORD01R) for
interesting states such as 'TEMPORARY' state.
Prints small report (no of words, no of bad words).
"""
# find number of words:
query = """SELECT COUNT(*) FROM %s""" % (self.tablename)
res = run_sql(query, None, 1)
if res:
nb_words = res[0][0]
else:
nb_words = 0
# find number of records:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR""" % (self.tablename[:-1])
res = run_sql(query, None, 1)
if res:
nb_records = res[0][0]
else:
nb_records = 0
# report stats:
if options["verbose"]:
write_message("%s contains %d words from %d records" % (self.tablename, nb_words, nb_records))
# find possible bad states in reverse tables:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR WHERE type <> 'CURRENT'""" % (self.tablename[:-1])
res = run_sql(query)
if res:
nb_bad_records = res[0][0]
else:
nb_bad_records = 999999999
if nb_bad_records:
write_message("EMERGENCY: %s needs to repair %d of %d records" % \
(self.tablename, nb_bad_records, nb_records))
else:
if options["verbose"]:
write_message("%s is in consistent state" % (self.tablename))
return nb_bad_records
def repair(self):
"""Repair the whole table"""
# find possible bad states in reverse tables:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR WHERE type <> 'CURRENT'""" % (self.tablename[:-1])
res = run_sql(query, None, 1)
if res:
nb_bad_records = res[0][0]
else:
nb_bad_records = 0
# find number of records:
query = """SELECT COUNT(DISTINCT(id_bibrec)) FROM %sR""" % (self.tablename[:-1])
res = run_sql(query)
if res:
nb_records = res[0][0]
else:
nb_records = 0
if nb_bad_records == 0:
return
query = """SELECT id_bibrec FROM %sR WHERE type <> 'CURRENT' ORDER BY id_bibrec""" \
% (self.tablename[:-1])
res = run_sql(query)
recIDs = create_range_list(res)
flush_count = 0
records_done = 0
records_to_go = 0
for range in recIDs:
records_to_go = records_to_go + range[1] - range[0] + 1
time_started = time.time() # will measure profile time
for range in recIDs:
i_low = range[0]
chunksize_count = 0
while i_low <= range[1]:
# calculate chunk group of recIDs and treat it:
i_high = min(i_low+options["flush"]-flush_count-1,range[1])
i_high = min(i_low+chunksize-chunksize_count-1, i_high)
try:
self.fix_recID_range(i_low, i_high)
except StandardError, e:
write_message("Exception caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
task_update_status("ERROR")
task_sig_stop_commands()
sys.exit(1)
flush_count = flush_count + i_high - i_low + 1
chunksize_count = chunksize_count + i_high - i_low + 1
records_done = records_done + i_high - i_low + 1
if chunksize_count >= chunksize:
chunksize_count = 0
# flush if necessary:
if flush_count >= options["flush"]:
self.put_into_db("emergency")
self.clean()
flush_count = 0
self.log_progress(time_started,records_done,records_to_go)
# iterate:
i_low = i_high + 1
if flush_count > 0:
self.put_into_db("emergency")
self.log_progress(time_started,records_done,records_to_go)
write_message("%s inconsistencies repaired." % self.tablename)
def chk_recID_range(self, low, high):
"""Check if the reverse index table is in proper state"""
## check db
query = """SELECT COUNT(*) FROM %sR WHERE type <> 'CURRENT'
AND id_bibrec BETWEEN '%d' AND '%d'""" % (self.tablename[:-1], low, high)
res = run_sql(query, None, 1)
if res[0][0]==0:
if options["verbose"]:
write_message("%s for %d-%d is in consistent state"%(self.tablename,low,high))
return # okay, words table is consistent
## inconsistency detected!
write_message("EMERGENCY: %s inconsistencies detected..." % self.tablename)
write_message("""EMERGENCY: Errors found. You should check consistency of the %s - %sR tables.\nRunning 'bibindex --repair' is recommended.""" \
% (self.tablename, self.tablename[:-1]))
raise StandardError
def fix_recID_range(self, low, high):
"""Try to fix reverse index database consistency (e.g. table rnkWORD01R) in the low,high doc-id range.
Possible states for a recID follow:
CUR TMP FUT: very bad things have happened: warn!
CUR TMP : very bad things have happened: warn!
CUR FUT: delete FUT (crash before flushing)
CUR : database is ok
TMP FUT: add TMP to memory and del FUT from memory
flush (revert to old state)
TMP : very bad things have happened: warn!
FUT: very bad things have happended: warn!
"""
state = {}
query = "SELECT id_bibrec,type FROM %sR WHERE id_bibrec BETWEEN '%d' AND '%d'"\
% (self.tablename[:-1], low, high)
res = run_sql(query)
for row in res:
if not state.has_key(row[0]):
state[row[0]]=[]
state[row[0]].append(row[1])
ok = 1 # will hold info on whether we will be able to repair
for recID in state.keys():
if not 'TEMPORARY' in state[recID]:
if 'FUTURE' in state[recID]:
if 'CURRENT' not in state[recID]:
write_message("EMERGENCY: Record %d is in inconsistent state. Can't repair it" % recID)
ok = 0
else:
write_message("EMERGENCY: Inconsistency in record %d detected" % recID)
query = """DELETE FROM %sR
WHERE id_bibrec='%d'""" % (self.tablename[:-1], recID)
run_sql(query)
write_message("EMERGENCY: Inconsistency in record %d repaired." % recID)
else:
if 'FUTURE' in state[recID] and not 'CURRENT' in state[recID]:
self.recIDs_in_mem.append([recID,recID])
# Get the words file
query = """SELECT type,termlist FROM %sR
WHERE id_bibrec='%d'""" % (self.tablename[:-1], recID)
if options["verbose"] >= 9:
write_message(query)
res = run_sql(query)
for row in res:
wlist = deserialize_via_marshal(row[1])
if options["verbose"] >= 9:
write_message("Words are %s " % wlist)
if row[0] == 'TEMPORARY':
sign = 1
else:
sign = -1
for word in wlist:
self.put(recID, word, wlist[word])
else:
write_message("EMERGENCY: %s for %d is in inconsistent state. Couldn't repair it." % (self.tablename, recID))
ok = 0
if not ok:
write_message("""EMERGENCY: Unrepairable errors found. You should check consistency
of the %s - %sR tables. Deleting affected records is
recommended.""" % (self.tablename, self.tablename[:-1]))
raise StandardError
def word_index(row, run):
"""Run the indexing task. The row argument is the BibSched task
queue row, containing if, arguments, etc.
Return 1 in case of success and 0 in case of failure.
"""
## import optional modules:
try:
import psyco
psyco.bind(get_words_from_phrase)
psyco.bind(WordTable.merge_with_old_recIDs)
psyco.bind(serialize_via_numeric_array)
psyco.bind(serialize_via_marshal)
psyco.bind(deserialize_via_numeric_array)
psyco.bind(deserialize_via_marshal)
psyco.bind(update_rnkWORD)
psyco.bind(check_rnkWORD)
except StandardError,e:
print "Warning: Psyco", e
pass
global options, task_id, wordTables, languages
# read from SQL row:
task_id = row[0]
task_proc = row[1]
options = marshal.loads(row[6])
# install signal handlers
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
## go ahead and treat each table:
options["run"] = []
options["run"].append(run)
for rank_method_code in options["run"]:
method_starting_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
write_message("Running rank method: %s" % getName(rank_method_code))
try:
file = etcdir + "/bibrank/" + rank_method_code + ".cfg"
config = ConfigParser.ConfigParser()
config.readfp(open(file))
except StandardError, e:
write_message("Cannot find configurationfile: %s" % file, sys.stderr)
raise StandardError
options["current_run"] = rank_method_code
options["modified_words"] = {}
options["table"] = config.get(config.get("rank_method", "function"), "table")
options["use_stemming"] = config.get(config.get("rank_method","function"),"stemming")
options["remove_stopword"] = config.get(config.get("rank_method","function"),"stopword")
tags = get_tags(config) #get the tags to include
options["validset"] = get_valid_range(rank_method_code) #get the records from the collections the method is enabled for
function = config.get("rank_method","function")
wordTable = WordTable(options["table"], tags)
wordTable.report_on_table_consistency()
try:
if options["cmd"] == "del":
if options["id"]:
wordTable.del_recIDs(options["id"])
elif options["collection"]:
l_of_colls = string.split(options["collection"], ",")
recIDs = perform_request_search(c=l_of_colls)
recIDs_range = []
for recID in recIDs:
recIDs_range.append([recID,recID])
wordTable.del_recIDs(recIDs_range)
else:
write_message("Missing IDs of records to delete from index %s.", wordTable.tablename,
sys.stderr)
raise StandardError
elif options["cmd"] == "add":
if options["id"]:
wordTable.add_recIDs(options["id"])
elif options["collection"]:
l_of_colls = string.split(options["collection"], ",")
recIDs = perform_request_search(c=l_of_colls)
recIDs_range = []
for recID in recIDs:
recIDs_range.append([recID,recID])
wordTable.add_recIDs(recIDs_range)
elif options["last_updated"]:
wordTable.add_recIDs_by_date("")
# only update last_updated if run via automatic mode:
wordTable.update_last_updated(rank_method_code, method_starting_time)
elif options["modified"]:
wordTable.add_recIDs_by_date(options["modified"])
else:
wordTable.add_recIDs([[0,cfg_max_recID]])
elif options["cmd"] == "repair":
wordTable.repair()
check_rnkWORD(options["table"])
elif options["cmd"] == "check":
check_rnkWORD(options["table"])
options["modified_words"] = {}
elif options["cmd"] == "stat":
rank_method_code_statistics(options["table"])
else:
write_message("Invalid command found processing %s" % \
wordTable.tablename, sys.stderr)
raise StandardError
update_rnkWORD(options["table"], options["modified_words"])
except StandardError, e:
write_message("Exception caught: %s" % e, sys.stderr)
if options["verbose"] >= 9:
traceback.print_tb(sys.exc_info()[2])
sys.exit(1)
wordTable.report_on_table_consistency()
# We are done. State it in the database, close and quit
return 1
def get_tags(config):
"""Get the tags that should be used creating the index and each tag's parameter"""
tags = []
function = config.get("rank_method","function")
i = 1
shown_error = 0
#try:
if 1:
while config.has_option(function,"tag%s"% i):
tag = config.get(function, "tag%s" % i)
tag = string.split(tag, ",")
tag[1] = int(string.strip(tag[1]))
tag[2] = string.strip(tag[2])
#check if stemmer for language is available
if config.get(function,"stemming") and stem("information", "en") != "inform":
if shown_error == 0:
write_message("Warning: PyStemmer not found. Please read INSTALL.")
shown_error = 1
elif tag[2] and tag[2] != "none" and config.get(function,"stemming") and not is_stemmer_available_for_language(tag[2]):
write_message("Warning: Language '%s' not available in PyStemmer." % tag[2])
tags.append(tag)
i += 1
#except Exception:
# write_message("Could not read data from configuration file, please check for errors")
# raise StandardError
return tags
def get_valid_range(rank_method_code):
"""Returns which records are valid for this rank method, according to which collections it is enabled for."""
#if options["verbose"] >=9:
# write_message("Getting records from collections enabled for rank method.")
#res = run_sql("SELECT collection.name FROM collection,collection_rnkMETHOD,rnkMETHOD WHERE collection.id=id_collection and id_rnkMETHOD=rnkMETHOD.id and rnkMETHOD.name='%s'" % rank_method_code)
#l_of_colls = []
#for coll in res:
# l_of_colls.append(coll[0])
#if len(l_of_colls) > 0:
# recIDs = perform_request_search(c=l_of_colls)
#else:
# recIDs = []
valid = HitSet(Numeric.ones(cfg_max_recID+1, Numeric.Int0))
#valid.addlist(recIDs)
return valid
def write_message(msg, stream=sys.stdout):
"""Prints message and flush output stream (may be sys.stdout or sys.stderr)."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
def check_term(term, termlength):
"""Check if term contains not allowed characters, or for any other reasons for not using this term."""
try:
if len(term) <= termlength:
return False
reg = re.compile(r"[1234567890\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~]")
if re.search(reg, term):
return False
term = str.replace(term, "-", "")
term = str.replace(term, ".", "")
term = str.replace(term, ",", "")
if int(term):
return False
except StandardError, e:
pass
return True
def check_rnkWORD(table):
"""Checks for any problems in rnkWORD tables."""
i = 0
errors = {}
termslist = run_sql("SELECT term FROM %s" % table)
N = run_sql("select max(id_bibrec) from %sR" % table[:-1])[0][0]
write_message("Checking integrity of rank values in %s" % table)
terms = map(lambda x: x[0], termslist)
while i < len(terms):
current_terms = ""
for j in range(i, ((i+5000)< len(terms) and (i+5000) or len(terms))):
current_terms += "'%s'," % terms[j]
terms_docs = run_sql("SELECT term, hitlist FROM %s WHERE term in (%s)" % (table, current_terms[:-1]))
for (t, hitlist) in terms_docs:
term_docs = deserialize_via_marshal(hitlist)
if (term_docs.has_key("Gi") and term_docs["Gi"][1] == 0) or not term_docs.has_key("Gi"):
write_message("ERROR: Missing value for term: %s (%s) in %s: %s" % (t, repr(t), table, len(term_docs)))
errors[t] = 1
i += 5000
write_message("Checking integrity of rank values in %sR" % table[:-1])
i = 0
while i < N:
docs_terms = run_sql("SELECT id_bibrec, termlist FROM %sR WHERE id_bibrec>=%s and id_bibrec<=%s" % (table[:-1], i, i+5000))
for (j, termlist) in docs_terms:
termlist = deserialize_via_marshal(termlist)
for (t, tf) in termlist.iteritems():
if tf[1] == 0 and not errors.has_key(t):
errors[t] = 1
write_message("ERROR: Gi missing for record %s and term: %s (%s) in %s" % (j,t,repr(t), table))
terms_docs = run_sql("SELECT term, hitlist FROM %s WHERE term='%s'" % (table, t))
termlist = deserialize_via_marshal(terms_docs[0][1])
i += 5000
if len(errors) == 0:
write_message("No direct errors found, but nonconsistent data may exist.")
else:
write_message("%s errors found during integrity check, repair and rebalancing recommended." % len(errors))
options["modified_words"] = errors
def rank_method_code_statistics(table):
"""Shows some statistics about this rank method."""
maxID = run_sql("select max(id) from %s" % table)
maxID = maxID[0][0]
terms = {}
Gi = {}
write_message("Showing statistics of terms in index:")
write_message("Important: For the 'Least used terms', the number of terms is shown first, and the number of occurences second.")
write_message("Least used terms---Most important terms---Least important terms")
i = 0
while i < maxID:
terms_docs=run_sql("SELECT term, hitlist FROM %s WHERE id>= %s and id < %s" % (table, i, i + 10000))
for (t, hitlist) in terms_docs:
term_docs=deserialize_via_marshal(hitlist)
terms[len(term_docs)] = terms.get(len(term_docs), 0) + 1
if term_docs.has_key("Gi"):
Gi[t] = term_docs["Gi"]
i=i + 10000
terms=terms.items()
terms.sort(lambda x, y: cmp(y[1], x[1]))
Gi=Gi.items()
Gi.sort(lambda x, y: cmp(y[1], x[1]))
for i in range(0, 20):
write_message("%s/%s---%s---%s" % (terms[i][0],terms[i][1], Gi[i][0],Gi[len(Gi) - i - 1][0]))
def update_rnkWORD(table, terms):
"""Updates rnkWORDF and rnkWORDR with Gi and Nj values. For each term in rnkWORDF, a Gi value for the term is added. And for each term in each document, the Nj value for that document is added. In rnkWORDR, the Gi value for each term in each document is added. For description on how things are computed, look in the hacking docs.
table - name of forward index to update
terms - modified terms"""
stime = time.time()
Gi = {}
Nj = {}
N = run_sql("select count(id_bibrec) from %sR" % table[:-1])[0][0]
if len(terms) == 0 and options["quick"] == "yes":
write_message("No terms to process, ending...")
return ""
elif options["quick"] == "yes": #not used -R option, fast calculation (not accurate)
write_message("Beginning post-processing of %s terms" % len(terms))
#Locating all documents related to the modified/new/deleted terms, if fast update,
#only take into account new/modified occurences
write_message("Phase 1: Finding records containing modified terms")
terms = terms.keys()
i = 0
while i < len(terms):
terms_docs = get_from_forward_index(terms, i, (i+5000), table)
for (t, hitlist) in terms_docs:
term_docs = deserialize_via_marshal(hitlist)
if term_docs.has_key("Gi"):
del term_docs["Gi"]
for (j, tf) in term_docs.iteritems():
if (options["quick"] == "yes" and tf[1] == 0) or options["quick"] == "no":
Nj[j] = 0
write_message("Phase 1: ......processed %s/%s terms" % ((i+5000>len(terms) and len(terms) or (i+5000)), len(terms)))
i += 5000
write_message("Phase 1: Finished finding records containing modified terms")
#Find all terms in the records found in last phase
write_message("Phase 2: Finding all terms in affected records")
records = Nj.keys()
i = 0
while i < len(records):
docs_terms = get_from_reverse_index(records, i, (i + 5000), table)
for (j, termlist) in docs_terms:
doc_terms = deserialize_via_marshal(termlist)
for (t, tf) in doc_terms.iteritems():
Gi[t] = 0
write_message("Phase 2: ......processed %s/%s records " % ((i+5000>len(records) and len(records) or (i+5000)), len(records)))
i += 5000
write_message("Phase 2: Finished finding all terms in affected records")
else: #recalculate
max_id = run_sql("SELECT MAX(id) FROM %s" % table)
max_id = max_id[0][0]
write_message("Beginning recalculation of %s terms" % max_id)
terms = []
i = 0
while i < max_id:
terms_docs = get_from_forward_index_with_id(i, (i+5000), table)
for (t, hitlist) in terms_docs:
Gi[t] = 0
term_docs = deserialize_via_marshal(hitlist)
if term_docs.has_key("Gi"):
del term_docs["Gi"]
for (j, tf) in term_docs.iteritems():
Nj[j] = 0
write_message("Phase 1: ......processed %s/%s terms" % ((i+5000)>max_id and max_id or (i+5000), max_id))
i += 5000
write_message("Phase 1: Finished finding which records contains which terms")
write_message("Phase 2: Jumping over..already done in phase 1 because of -R option")
terms = Gi.keys()
Gi = {}
i = 0
if options["quick"] == "no":
#Calculating Fi and Gi value for each term
write_message("Phase 3: Calculating importance of all affected terms")
while i < len(terms):
terms_docs = get_from_forward_index(terms, i, (i+5000), table)
for (t, hitlist) in terms_docs:
term_docs = deserialize_via_marshal(hitlist)
if term_docs.has_key("Gi"):
del term_docs["Gi"]
Fi = 0
Gi[t] = 1
for (j, tf) in term_docs.iteritems():
Fi += tf[0]
for (j, tf) in term_docs.iteritems():
if tf[0] != Fi:
Gi[t] = Gi[t] + ((float(tf[0]) / Fi) * math.log(float(tf[0]) / Fi) / math.log(2)) / math.log(N)
write_message("Phase 3: ......processed %s/%s terms" % ((i+5000>len(terms) and len(terms) or (i+5000)), len(terms)))
i += 5000
write_message("Phase 3: Finished calculating importance of all affected terms")
else:
#Using existing Gi value instead of calculating a new one. Missing some accurancy.
write_message("Phase 3: Getting approximate importance of all affected terms")
while i < len(terms):
terms_docs = get_from_forward_index(terms, i, (i+5000), table)
for (t, hitlist) in terms_docs:
term_docs = deserialize_via_marshal(hitlist)
if term_docs.has_key("Gi"):
Gi[t] = term_docs["Gi"][1]
elif len(term_docs) == 1:
Gi[t] = 1
else:
Fi = 0
Gi[t] = 1
for (j, tf) in term_docs.iteritems():
Fi += tf[0]
for (j, tf) in term_docs.iteritems():
if tf[0] != Fi:
Gi[t] = Gi[t] + ((float(tf[0]) / Fi) * math.log(float(tf[0]) / Fi) / math.log(2)) / math.log(N)
write_message("Phase 3: ......processed %s/%s terms" % ((i+5000>len(terms) and len(terms) or (i+5000)), len(terms)))
i += 5000
write_message("Phase 3: Finished getting approximate importance of all affected terms")
write_message("Phase 4: Calculating normalization value for all affected records and updating %sR" % table[:-1])
records = Nj.keys()
i = 0
while i < len(records):
#Calculating the normalization value for each document, and adding the Gi value to each term in each document.
docs_terms = get_from_reverse_index(records, i, (i + 5000), table)
for (j, termlist) in docs_terms:
doc_terms = deserialize_via_marshal(termlist)
for (t, tf) in doc_terms.iteritems():
if Gi.has_key(t):
Nj[j] = Nj.get(j, 0) + math.pow(Gi[t] * (1 + math.log(tf[0])), 2)
Git = int(math.floor(Gi[t]*100))
if Git >= 0:
Git += 1
doc_terms[t] = (tf[0], Git)
else:
Nj[j] = Nj.get(j, 0) + math.pow(tf[1] * (1 + math.log(tf[0])), 2)
Nj[j] = 1.0 / math.sqrt(Nj[j])
Nj[j] = int(Nj[j] * 100)
if Nj[j] >= 0:
Nj[j] += 1
run_sql("UPDATE %sR SET termlist='%s' WHERE id_bibrec=%s" % (table[:-1], serialize_via_marshal(doc_terms), j))
write_message("Phase 4: ......processed %s/%s records" % ((i+5000>len(records) and len(records) or (i+5000)), len(records)))
i += 5000
write_message("Phase 4: Finished calculating normalization value for all affected records and updating %sR" % table[:-1])
write_message("Phase 5: Updating %s with new normalization values" % table)
i = 0
terms = Gi.keys()
while i < len(terms):
#Adding the Gi value to each term, and adding the normalization value to each term in each document.
terms_docs = get_from_forward_index(terms, i, (i+5000), table)
for (t, hitlist) in terms_docs:
term_docs = deserialize_via_marshal(hitlist)
if term_docs.has_key("Gi"):
del term_docs["Gi"]
for (j, tf) in term_docs.iteritems():
if Nj.has_key(j):
term_docs[j] = (tf[0], Nj[j])
Git = int(math.floor(Gi[t]*100))
if Git >= 0:
Git += 1
term_docs["Gi"] = (0, Git)
run_sql("UPDATE %s SET hitlist='%s' WHERE term='%s'" % (table, serialize_via_marshal(term_docs), MySQLdb.escape_string(t)))
write_message("Phase 5: ......processed %s/%s terms" % ((i+5000>len(terms) and len(terms) or (i+5000)), len(terms)))
i += 5000
write_message("Phase 5: Finished updating %s with new normalization values" % table)
write_message("Time used for post-processing: %.1fmin" % ((time.time() - stime) / 60))
write_message("Finished post-processing")
def get_from_forward_index(terms, start, stop, table):
current_terms = ""
for j in range(start, (stop < len(terms) and stop or len(terms))):
current_terms += "'%s'," % terms[j]
terms_docs = run_sql("SELECT term, hitlist FROM %s WHERE term IN (%s)" % (table,current_terms[:-1]))
return terms_docs
def get_from_forward_index_with_id(start, stop, table):
terms_docs = run_sql("SELECT term, hitlist FROM %s WHERE id between %s and %s" % (table, start, stop))
return terms_docs
def get_from_reverse_index(records, start, stop, table):
current_recs = "%s" % records[start:stop]
current_recs = current_recs[1:-1]
docs_terms = run_sql("SELECT id_bibrec, termlist FROM %sR WHERE id_bibrec IN (%s)" % (table[:-1],current_recs))
return docs_terms
def test_word_separators(phrase="hep-th/0101001"):
"""Tests word separating policy on various input."""
print "%s:" % phrase
gwfp = get_words_from_phrase(phrase)
for (word, count) in gwfp.iteritems():
print "\t-> %s - %s" % (word, count)
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("stopping...")
task_update_status("STOPPING")
errcode = 0
try:
task_sig_stop_commands()
write_message("stopped")
task_update_status("STOPPED")
except StandardError, err:
write_message("Error during stopping! %e" % err)
task_update_status("STOPPINGFAILED")
errcode = 1
sys.exit(errcode)
def task_sig_stop_commands():
"""Do all the commands necessary to stop the task before quitting.
Useful for task_sig_stop() handler.
"""
write_message("stopping commands started")
for table in wordTables:
table.put_into_db()
write_message("stopping commands ended")
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task progress to %s." % msg)
return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, task_id))
def task_update_status(val):
"""Updates state information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task status to %s." % val)
return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, task_id))
def getName(methname, ln=cdslang, type='ln'):
"""Returns the name of the rank method, either in default language or given language.
methname = short name of the method
ln - the language to get the name in
type - which name "type" to get."""
try:
rnkid = run_sql("SELECT id FROM rnkMETHOD where name='%s'" % methname)
if rnkid:
rnkid = str(rnkid[0][0])
res = run_sql("SELECT value FROM rnkMETHODNAME where type='%s' and ln='%s' and id_rnkMETHOD=%s" % (type, ln, rnkid))
if not res:
res = run_sql("SELECT value FROM rnkMETHODNAME WHERE ln='%s' and id_rnkMETHOD=%s and type='%s'" % (cdslang, rnkid, type))
if not res:
return methname
return res[0][0]
else:
raise Exception
except Exception, e:
write_message("Cannot run rank method, either given code for method is wrong, or it has not been added using the webinterface.")
raise Exception
def word_similarity(row, run):
"""Call correct method"""
return word_index(row, run)
diff --git a/modules/bibrank/lib/bibrankadminlib.py b/modules/bibrank/lib/bibrankadminlib.py
index 39006367d..b2369ab56 100644
--- a/modules/bibrank/lib/bibrankadminlib.py
+++ b/modules/bibrank/lib/bibrankadminlib.py
@@ -1,1071 +1,1071 @@
## $Id$
## Administrator interface for BibRank
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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.
##
## Youshould have received a copy of the GNU General Public License
## along with CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibRank Administrator Interface."""
__lastupdated__ = """$Date$"""
## fill config variables:
import cgi
import re
import MySQLdb
import Numeric
import os
import ConfigParser
from zlib import compress,decompress
from mod_python import apache
import cdsware.access_control_engine as acce
from cdsware.messages import language_list_long
from cdsware.config import *
from cdsware.webpage import page, pageheaderonly, pagefooteronly
from cdsware.webuser import getUid, get_email
__version__ = "$Id$"
def getnavtrail(previous = ''):
navtrail = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/bibrank/">BibRank Admin</a> """ % (weburl, weburl)
navtrail = navtrail + previous
return navtrail
def check_user(uid, role, adminarea=2, authorized=0):
(auth_code, auth_message) = is_adminuser(uid, role)
if not authorized and auth_code != 0:
return ("false", auth_message)
return ("", auth_message)
def is_adminuser(uid, role):
"""check if user is a registered administrator. """
return acce.acc_authorize_action(uid, role)
def perform_index(ln=cdslang):
"""create the bibrank main area menu page."""
header = ['Code', 'Translations', 'Collections', 'Rank method']
rnk_list = get_def_name('', "rnkMETHOD")
actions = []
for (rnkID, name) in rnk_list:
actions.append([name])
for col in [(('Modify', 'modifytranslations'),),
(('Modify', 'modifycollection'),),
(('Show Details', 'showrankdetails'),
('Modify', 'modifyrank'),
('Delete', 'deleterank'))]:
actions[-1].append('<a href="%s/admin/bibrank/bibrankadmin.py/%s?rnkID=%s&ln=%s">%s</a>' % (weburl, col[0][1], rnkID, ln, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/bibrank/bibrankadmin.py/%s?rnkID=%s&ln=%s">%s</a>' % (weburl, function, rnkID, ln, str)
output = """
<a href="%s/admin/bibrank/bibrankadmin.py/addrankarea?ln=%s">Add new rank method</a><br><br>
""" % (weburl, ln)
output += tupletotable(header=header, tuple=actions)
return addadminbox("""Overview of rank methods&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/bibrank/guide.html#mi">?</a>]</small>""" % weburl, datalist=[output, ''])
def perform_modifycollection(rnkID='', ln=cdslang, func='', colID='', confirm=0):
"""Modify which collections the rank method is visible to"""
output = ""
subtitle = ""
if rnkID:
rnkNAME = get_def_name(rnkID, "rnkMETHOD")[0][1]
if func in ["0", 0] and confirm in ["1", 1]:
finresult = attach_col_rnk(rnkID, colID)
elif func in ["1", 1] and confirm in ["1", 1]:
finresult = detach_col_rnk(rnkID, colID)
if colID:
colNAME = get_def_name(colID, "collection")[0][1]
subtitle = """Step 1 - Select collection to enable/disable rank method '%s' for""" % rnkNAME
output = """
<dl>
<dt>The rank method is currently enabled for these collections:</dt>
<dd>
"""
col_list = get_rnk_col(rnkID, ln)
if not col_list:
output += """No collections"""
else:
for (id, name) in col_list:
output += """%s, """ % name
output += """</dd>
</dl>
"""
col_list = get_def_name('', "collection")
col_rnk = dict(get_rnk_col(rnkID))
col_list = filter(lambda x: not col_rnk.has_key(x[0]), col_list)
if col_list:
text = """
<span class="adminlabel">Enable for:</span>
<select name="colID" class="admin_w200">
<option value="">- select collection -</option>
"""
for (id, name) in col_list:
text += """<option value="%s" %s>%s</option>""" % (id, (func in ["0", 0] and confirm in ["0", 0] and colID and int(colID) == int(id)) and 'selected="selected"' or '' , name)
text += """</select>"""
output += createhiddenform(action="modifycollection",
text=text,
button="Enable",
rnkID=rnkID,
ln=ln,
func=0,
confirm=1)
if confirm in ["0", 0] and func in ["0", 0] and colID:
subtitle = "Step 2 - Confirm to enable rank method for the chosen collection"
text = "<b><p>Please confirm to enable rank method '%s' for the collection '%s'</p></b>" % (rnkNAME, colNAME)
output += createhiddenform(action="modifycollection",
text=text,
button="Confirm",
rnkID=rnkID,
ln=ln,
colID=colID,
func=0,
confirm=1)
elif confirm in ["1", 1] and func in ["0", 0] and colID:
subtitle = "Step 3 - Result"
output += write_outcome(finresult)
elif confirm not in ["0", 0] and func in ["0", 0]:
output += """<b><span class="info">Please select a collection.</span></b>"""
col_list = get_rnk_col(rnkID, ln)
if col_list:
text = """
<span class="adminlabel">Disable for:</span>
<select name="colID" class="admin_w200">
<option value="">- select collection -</option>
"""
for (id, name) in col_list:
text += """<option value="%s" %s>%s</option>""" % (id, (func in ["1", 1] and confirm in ["0", 0] and colID and int(colID) == int(id)) and 'selected="selected"' or '' , name)
text += """</select>"""
output += createhiddenform(action="modifycollection",
text=text,
button="Disable",
rnkID=rnkID,
ln=ln,
func=1,
confirm=1)
if confirm in ["1", 1] and func in ["1", 1] and colID:
subtitle = "Step 3 - Result"
output += write_outcome(finresult)
elif confirm not in ["0", 0] and func in ["1", 1]:
output += """<b><span class="info">Please select a collection.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle + """&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/bibrank/guide.html#mc">?</a>]</small>""" % weburl, body)
def perform_modifytranslations(rnkID, ln, sel_type, trans, confirm, callback='yes'):
"""Modify the translations of a rank method"""
output = ''
subtitle = ''
cdslangs = get_languages()
cdslangs.sort()
if confirm in ["2", 2] and rnkID:
finresult = modify_translations(rnkID, cdslangs, sel_type, trans, "rnkMETHOD")
rnk_name = get_def_name(rnkID, "rnkMETHOD")[0][1]
rnk_dict = dict(get_i8n_name('', ln, get_rnk_nametypes()[0][0], "rnkMETHOD"))
if rnkID and rnk_dict.has_key(int(rnkID)):
rnkID = int(rnkID)
subtitle = """<a name="3">3. Modify translations for rank method '%s'</a>""" % rnk_name
if type(trans) is str:
trans = [trans]
if sel_type == '':
sel_type = get_rnk_nametypes()[0][0]
header = ['Language', 'Translation']
actions = []
text = """
<span class="adminlabel">Name type</span>
<select name="sel_type" class="admin_w200">
"""
types = get_rnk_nametypes()
if len(types) > 1:
for (key, value) in types:
text += """<option value="%s" %s>%s""" % (key, key == sel_type and 'selected="selected"' or '', value)
trans_names = get_name(rnkID, ln, key, "rnkMETHOD")
if trans_names and trans_names[0][0]:
text += ": %s" % trans_names[0][0]
text += "</option>"
text += """</select>"""
output += createhiddenform(action="modifytranslations",
text=text,
button="Select",
rnkID=rnkID,
ln=ln,
confirm=0)
if confirm in [-1, "-1", 0, "0"]:
trans = []
for key, value in cdslangs:
try:
trans_names = get_name(rnkID, key, sel_type, "rnkMETHOD")
trans.append(trans_names[0][0])
except StandardError, e:
trans.append('')
for nr in range(0,len(cdslangs)):
actions.append(["%s %s" % (cdslangs[nr][1], (cdslangs[nr][0]==cdslang and '<small>(def)</small>' or ''))])
actions[-1].append('<input type="text" name="trans" size="30" value="%s"/>' % trans[nr])
text = tupletotable(header=header, tuple=actions)
output += createhiddenform(action="modifytranslations",
text=text,
button="Modify",
rnkID=rnkID,
sel_type=sel_type,
ln=ln,
confirm=2)
if sel_type and len(trans) and confirm in ["2", 2]:
output += write_outcome(finresult)
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle + """&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/bibrank/guide.html#mt">?</a>]</small>""" % weburl, body)
def perform_addrankarea(rnkcode='', ln=cdslang, template='', confirm=-1):
"""form to add a new rank method with these values:"""
subtitle = 'Step 1 - Create new rank method'
output = """
<dl>
<dt>BibRank code:</dt>
<dd>A unique code that identifies a rank method, is used when running the bibrank daemon and used to name the configuration file for the method.
<br>The template files includes the necessary parameters for the chosen rank method, and only needs to be edited with the correct tags and paths.
<br>For more information, please go to the <a title="See guide" href="%s/admin/bibrank/guide.html">BibRank guide</a> and read the section about adding a rank method</dd>
</dl>
""" % weburl
text = """
<span class="adminlabel">BibRank code</span>
<input class="admin_wvar" type="text" name="rnkcode" value="%s" />
""" % (rnkcode)
text += """<br>
<span class="adminlabel">Cfg template</span>
<select name="template" class="admin_w200">
<option value="">No template</option>
"""
templates = get_templates()
for templ in templates:
text += """<option value="%s" %s>%s</option>""" % (templ, template == templ and 'selected="selected"' or '', templ[9:len(templ)-4])
text += """</select>"""
output += createhiddenform(action="addrankarea",
text=text,
button="Add rank method",
ln=ln,
confirm=1)
if rnkcode:
if confirm in ["0", 0]:
subtitle = 'Step 2 - Confirm addition of rank method'
text = """<b>Add rank method with BibRank code: '%s'.</b>""" % (rnkcode)
if template:
text += """<br><b>Using configuration template: '%s'.</b>""" % (template)
else:
text += """<br><b>Create empty configuration file.</b>"""
output += createhiddenform(action="addrankarea",
text=text,
rnkcode=rnkcode,
button="Confirm",
template=template,
confirm=1)
elif confirm in ["1", 1]:
rnkID = add_rnk(rnkcode)
subtitle = "Step 3 - Result"
if rnkID[0] == 1:
rnkID = rnkID[1]
text = """<b><span class="info">Added new rank method with BibRank code '%s'</span></b>""" % rnkcode
try:
if template:
infile = open("%s/bibrank/%s" % (etcdir, template), 'r')
indata = infile.readlines()
infile.close()
else:
indata = ()
file = open("%s/bibrank/%s.cfg" % (etcdir, get_rnk_code(rnkID)[0][0]), 'w')
for line in indata:
file.write(line)
file.close()
if template:
text += """<b><span class="info"><br>Configuration file created using '%s' as template.</span></b>""" % template
else:
text += """<b><span class="info"><br>Empty configuration file created.</span></b>"""
except StandardError, e:
text += """<b><span class="info"><br>Sorry, could not create configuration file: '%s/bibrank/%s.cfg', either because it already exists, or not enough rights to create file. <br>Please create the file in the path given.</span></b>""" % (etcdir, get_rnk_code(rnkID)[0][0])
else:
text = """<b><span class="info">Sorry, could not add rank method, rank method with the same BibRank code probably exists.</span></b>"""
output += text
elif not rnkcode and confirm not in [-1, "-1"]:
output += """<b><span class="info">Sorry, could not add rank method, not enough data submitted.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle + """&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/bibrank/guide.html#ar">?</a>]</small>""" % weburl, body)
def perform_modifyrank(rnkID, rnkcode='', ln=cdslang, template='', cfgfile='', confirm=0):
"""form to modify a rank method
rnkID - id of the rank method
"""
subtitle = 'Step 1 - Please modify the wanted values below'
if not rnkcode:
oldcode = get_rnk_code(rnkID)[0]
else:
oldcode = rnkcode
output = """
<dl>
<dd>When changing the BibRank code of a rank method, you must also change any scheduled tasks using the old value.
<br>For more information, please go to the <a title="See guide" href="%s/admin/bibrank/guide.html">BibRank guide</a> and read the section about modifying a rank method's BibRank code.</dd>
</dl>
""" % weburl
text = """
<span class="adminlabel">BibRank code</span>
<input class="admin_wvar" type="text" name="rnkcode" value="%s" />
<br>
""" % (oldcode)
try:
text += """<span class="adminlabel">Cfg file</span>"""
textarea = ""
if cfgfile:
textarea +=cfgfile
else:
file = open("%s/bibrank/%s.cfg" % (etcdir, get_rnk_code(rnkID)[0][0]))
for line in file.readlines():
textarea += line
text += """<textarea class="admin_wvar" name="cfgfile" rows="15" cols="70">""" + textarea + """</textarea>"""
except StandardError, e:
text += """<b><span class="info">Cannot load file, either it does not exist, or not enough rights to read it: '%s/bibrank/%s.cfg'<br>Please create the file in the path given.</span></b>""" % (etcdir, get_rnk_code(rnkID)[0][0])
output += createhiddenform(action="modifyrank",
text=text,
rnkID=rnkID,
button="Modify",
confirm=1)
if rnkcode and confirm in ["1", 1] and get_rnk_code(rnkID)[0][0] != rnkcode:
oldcode = get_rnk_code(rnkID)[0][0]
result = modify_rnk(rnkID, rnkcode)
subtitle = "Step 3 - Result"
if result:
text = """<b><span class="info">Rank method modified.</span></b>"""
try:
file = open("%s/bibrank/%s.cfg" % (etcdir, oldcode), 'r')
file2 = open("%s/bibrank/%s.cfg" % (etcdir, rnkcode), 'w')
lines = file.readlines()
for line in lines:
file2.write(line)
file.close()
file2.close()
os.remove("%s/bibrank/%s.cfg" % (etcdir, oldcode))
except StandardError, e:
text = """<b><span class="info">Sorry, could not change name of cfg file, must be done manually: '%s/bibrank/%s.cfg'</span></b>""" % (etcdir, oldcode)
else:
text = """<b><span class="info">Sorry, could not modify rank method.</span></b>"""
output += text
if cfgfile and confirm in ["1", 1]:
try:
file = open("%s/bibrank/%s.cfg" % (etcdir, get_rnk_code(rnkID)[0][0]), 'w')
file.write(cfgfile)
file.close()
text = """<b><span class="info"><br>Configuration file modified: '%s/bibrank/%s.cfg'</span></b>""" % (etcdir, get_rnk_code(rnkID)[0][0])
except StandardError, e:
text = """<b><span class="info"><br>Sorry, could not modify configuration file, please check for rights to do so: '%s/bibrank/%s.cfg'<br>Please modify the file manually.</span></b>""" % (etcdir, get_rnk_code(rnkID)[0][0])
output += text
finoutput = addadminbox(subtitle + """&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/bibrank/guide.html#mr">?</a>]</small>""" % weburl, [output])
output = ""
text = """
<span class="adminlabel">Select</span>
<select name="template" class="admin_w200">
<option value="">- select template -</option>
"""
templates = get_templates()
for templ in templates:
text += """<option value="%s" %s>%s</option>""" % (templ, template == templ and 'selected="selected"' or '', templ[9:len(templ)-4])
text += """</select><br>"""
output += createhiddenform(action="modifyrank",
text=text,
rnkID=rnkID,
button="Show template",
confirm=0)
try:
if template:
textarea = ""
text = """<span class="adminlabel">Content:</span>"""
file = open("%s/bibrank/%s" % (etcdir, template), 'r')
lines = file.readlines()
for line in lines:
textarea += line
file.close()
text += """<textarea class="admin_wvar" readonly="true" rows="15" cols="70">""" + textarea + """</textarea>"""
output += text
except StandardError, e:
output += """Cannot load file, either it does not exist, or not enough rights to read it: '%s/bibrank/%s'""" % (etcdir, template)
finoutput += addadminbox("View templates", [output])
return finoutput
def perform_deleterank(rnkID, ln=cdslang, confirm=0):
"""form to delete a rank method
"""
subtitle =''
output = """
<span class="warning">
<strong>
<dl>
<dt>WARNING:</dt>
<dd>When deleting a rank method, you also deletes all data related to the rank method, like translations, which collections
it was attached to and the data necessary to rank the searchresults. Any scheduled tasks using the deleted rank method will also stop working.
<br><br>For more information, please go to the <a title="See guide" href="%s/admin/bibrank/guide.html">BibRank guide</a> and read the section regarding deleting a rank method.</dd>
</dl>
</strong>
</span>
""" % weburl
if rnkID:
if confirm in ["0", 0]:
rnkNAME = get_def_name(rnkID, "rnkMETHOD")[0][1]
subtitle = 'Step 1 - Confirm deletion'
text = """Delete rank method '%s'.""" % (rnkNAME)
output += createhiddenform(action="deleterank",
text=text,
button="Confirm",
rnkID=rnkID,
confirm=1)
elif confirm in ["1", 1]:
try:
rnkNAME = get_def_name(rnkID, "rnkMETHOD")[0][1]
rnkcode = get_rnk_code(rnkID)[0][0]
table = ""
try:
config = ConfigParser.ConfigParser()
config.readfp(open("%s/bibrank/%s.cfg" % (etcdir, rnkcode), 'r'))
table = config.get(config.get('rank_method', "function"), "table")
except Exception:
pass
result = delete_rnk(rnkID, table)
subtitle = "Step 2 - Result"
if result:
text = """<b><span class="info">Rank method deleted</span></b>"""
try:
os.remove("%s/bibrank/%s.cfg" % (etcdir, rnkcode))
text += """<br><b><span class="info">Configuration file deleted: '%s/bibrank/%s.cfg'.</span></b>""" % (etcdir, rnkcode)
except StandardError, e:
text += """<br><b><span class="info">Sorry, could not delete configuration file: '%s/bibrank/%s.cfg'.</span><br>Please delete the file manually.</span></b>""" % (etcdir, rnkcode)
else:
text = """<b><span class="info">Sorry, could not delete rank method</span></b>"""
except StandardError, e:
text = """<b><span class="info">Sorry, could not delete rank method, most likely already deleted</span></b>"""
output = text
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle + """&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/bibrank/guide.html#dr">?</a>]</small>""" % weburl, body)
def perform_showrankdetails(rnkID, ln=cdslang):
"""Returns details about the rank method given by rnkID"""
subtitle = """Overview <a href="%s/admin/bibrank/bibrankadmin.py/modifyrank?rnkID=%s&ln=%s">[Modify]</a>""" % (weburl, rnkID, ln)
text = """
BibRank code: %s<br>
Last updated by BibRank:
""" % (get_rnk_code(rnkID)[0][0])
if get_rnk(rnkID)[0][2]:
text += "%s<br>" % get_rnk(rnkID)[0][2]
else:
text += "Not yet run.<br>"
output = addadminbox(subtitle, [text])
subtitle = """Rank method statistics"""
text = ""
try:
text = "Not yet implemented"
except StandardError, e:
text = "BibRank not yet run, cannot show statistics for method"
output += addadminbox(subtitle, [text])
subtitle = """Attached to collections <a href="%s/admin/bibrank/bibrankadmin.py/modifycollection?rnkID=%s&ln=%s">[Modify]</a>""" % (weburl, rnkID, ln)
text = ""
col = get_rnk_col(rnkID, ln)
for key, value in col:
text+= "%s<br>" % value
if not col:
text +="No collections"
output += addadminbox(subtitle, [text])
subtitle = """Translations <a href="%s/admin/bibrank/bibrankadmin.py/modifytranslations?rnkID=%s&ln=%s">[Modify]</a>""" % (weburl, rnkID, ln)
prev_lang = ''
trans = get_translations(rnkID)
types = get_rnk_nametypes()
types = dict(map(lambda x: (x[0], x[1]), types))
text = ""
languages = dict(get_languages())
if trans:
for lang, type, name in trans:
if lang and languages.has_key(lang) and type and name:
if prev_lang != lang:
prev_lang = lang
text += """%s: <br>""" % (languages[lang])
if types.has_key(type):
text+= """<span style="margin-left: 10px">'%s'</span><span class="note">(%s)</span><br>""" % (name, types[type])
else:
text = """No translations exists"""
output += addadminbox(subtitle, [text])
subtitle = """Configuration file: '%s/bibrank/%s.cfg' <a href="%s/admin/bibrank/bibrankadmin.py/modifyrank?rnkID=%s&ln=%s">[Modify]</a>""" % (etcdir, get_rnk_code(rnkID)[0][0], weburl, rnkID, ln)
text = ""
try:
file = open("%s/bibrank/%s.cfg" % (etcdir, get_rnk_code(rnkID)[0][0]))
text += """<pre>"""
for line in file.readlines():
text += line
text += """</pre>"""
except StandardError, e:
text = """Cannot load file, either it does not exist, or not enough rights to read it."""
output += addadminbox(subtitle, [text])
return output
def compare_on_val(second, first):
return cmp(second[1], first[1])
def get_rnk_code(rnkID):
"""Returns the name from rnkMETHOD based on argument
rnkID - id from rnkMETHOD"""
try:
res = run_sql("SELECT name FROM rnkMETHOD where id=%s" % (rnkID))
return res
except StandardError, e:
return ()
def get_rnk(rnkID=''):
"""Return one or all rank methods
rnkID - return the rank method given, or all if not given"""
try:
if rnkID:
res = run_sql("SELECT id,name,DATE_FORMAT(last_updated, '%%Y-%%m-%%d %%H:%%i:%%s') from rnkMETHOD WHERE id=%s" % rnkID)
else:
res = run_sql("SELECT id,name,DATE_FORMAT(last_updated, '%%Y-%%m-%%d %%H:%%i:%%s') from rnkMETHOD")
return res
except StandardError, e:
return ()
def get_translations(rnkID):
"""Returns the translations in rnkMETHODNAME for a rankmethod
rnkID - the id of the rankmethod from rnkMETHOD """
try:
res = run_sql("SELECT ln, type, value FROM rnkMETHODNAME where id_rnkMETHOD=%s ORDER BY ln,type" % (rnkID))
return res
except StandardError, e:
return ()
def get_rnk_nametypes():
"""Return a list of the various translationnames for the rank methods"""
type = []
type.append(('ln', 'Long name'))
#type.append(('sn', 'Short name'))
return type
def get_col_nametypes():
"""Return a list of the various translationnames for the rank methods"""
type = []
type.append(('ln', 'Long name'))
return type
def get_rnk_col(rnkID, ln=cdslang):
""" Returns a list of the collections the given rank method is attached to
rnkID - id from rnkMETHOD"""
try:
res1 = dict(run_sql("SELECT id_collection, '' FROM collection_rnkMETHOD WHERE id_rnkMETHOD=%s" % rnkID))
res2 = get_def_name('', "collection")
result = filter(lambda x: res1.has_key(x[0]), res2)
return result
except StandardError, e:
return ()
def get_templates():
"""Read etcdir/bibrank and returns a list of all files with 'template' """
templates = []
files = os.listdir(etcdir + "/bibrank/")
for file in files:
if str.find(file,"template_") != -1:
templates.append(file)
return templates
def attach_col_rnk(rnkID, colID):
"""attach rank method to collection
rnkID - id from rnkMETHOD table
colID - id of collection, as in collection table """
try:
res = run_sql("INSERT INTO collection_rnkMETHOD(id_collection, id_rnkMETHOD) values (%s,%s)" % (colID, rnkID))
return (1, "")
except StandardError, e:
return (0, e)
def detach_col_rnk(rnkID, colID):
"""detach rank method from collection
rnkID - id from rnkMETHOD table
colID - id of collection, as in collection table """
try:
res = run_sql("DELETE FROM collection_rnkMETHOD WHERE id_collection=%s AND id_rnkMETHOD=%s" % (colID, rnkID))
return (1, "")
except StandardError, e:
return (0, e)
def delete_rnk(rnkID, table=""):
"""Deletes all data for the given rank method
rnkID - delete all data in the tables associated with ranking and this id """
try:
res = run_sql("DELETE FROM rnkMETHOD WHERE id=%s" % rnkID)
res = run_sql("DELETE FROM rnkMETHODNAME WHERE id_rnkMETHOD=%s" % rnkID)
res = run_sql("DELETE FROM collection_rnkMETHOD WHERE id_rnkMETHOD=%s" % rnkID)
res = run_sql("DELETE FROM rnkMETHODDATA WHERE id_rnkMETHOD=%s" % rnkID)
if table:
res = run_sql("truncate %s" % table)
res = run_sql("truncate %sR" % table[:-1])
return (1, "")
except StandardError, e:
return (0, e)
def modify_rnk(rnkID, rnkcode):
"""change the code for the rank method given
rnkID - change in rnkMETHOD where id is like this
rnkcode - new value for field 'name' in rnkMETHOD """
try:
res = run_sql("UPDATE rnkMETHOD set name='%s' WHERE id=%s" % (MySQLdb.escape_string(rnkcode), rnkID))
return (1, "")
except StandardError, e:
return (0, e)
def add_rnk(rnkcode):
"""Adds a new rank method to rnkMETHOD
rnkcode - the "code" for the rank method, to be used by bibrank daemon """
try:
res = run_sql("INSERT INTO rnkMETHOD(name) VALUES('%s')" % MySQLdb.escape_string(rnkcode))
res = run_sql("SELECT id FROM rnkMETHOD WHERE name='%s'" % MySQLdb.escape_string(rnkcode))
if res:
return (1, res[0][0])
else:
raise StandardError
except StandardError, e:
return (0, e)
def addadminbox(header='', datalist=[], cls="admin_wvar"):
"""used to create table around main data on a page, row based.
header - header on top of the table
datalist - list of the data to be added row by row
cls - possible to select wich css-class to format the look of the table."""
if len(datalist) == 1: per = '100'
else: per = '75'
output = '<table class="%s" ' % (cls, ) + 'width="95%">\n'
output += """
<thead>
<tr>
<th class="adminheaderleft" colspan="%s">%s</th>
</tr>
</thead>
<tbody>
""" % (len(datalist), header)
output += ' <tr>\n'
output += """
<td style="vertical-align: top; margin-top: 5px; width: %s;">
%s
</td>
""" % (per+'%', datalist[0])
if len(datalist) > 1:
output += """
<td style="vertical-align: top; margin-top: 5px; width: %s;">
%s
</td>
""" % ('25%', datalist[1])
output += ' </tr>\n'
output += """
</tbody>
</table>
"""
return output
def tupletotable(header=[], tuple=[], start='', end='', extracolumn=''):
"""create html table for a tuple.
header - optional header for the columns
tuple - create table of this
start - text to be added in the beginning, most likely beginning of a form
end - text to be added in the end, mot likely end of a form.
extracolumn - mainly used to put in a button. """
# study first row in tuple for alignment
align = []
try:
firstrow = tuple[0]
if type(firstrow) in [int, long]:
align = ['admintdright']
elif type(firstrow) in [str, dict]:
align = ['admintdleft']
else:
for item in firstrow:
if type(item) is int:
align.append('admintdright')
else:
align.append('admintdleft')
except IndexError:
firstrow = []
tblstr = ''
for h in header + ['']:
tblstr += ' <th class="adminheader">%s</th>\n' % (h, )
if tblstr: tblstr = ' <tr>\n%s\n </tr>\n' % (tblstr, )
tblstr = start + '<table class="admin_wvar_nomargin">\n' + tblstr
# extra column
try:
extra = '<tr>'
if type(firstrow) not in [int, long, str, dict]:
# for data in firstrow: extra += '<td class="%s">%s</td>\n' % ('admintd', data)
for i in range(len(firstrow)): extra += '<td class="%s">%s</td>\n' % (align[i], firstrow[i])
else:
extra += ' <td class="%s">%s</td>\n' % (align[0], firstrow)
extra += '<td rowspan="%s" style="vertical-align: top">\n%s\n</td>\n</tr>\n' % (len(tuple), extracolumn)
except IndexError:
extra = ''
tblstr += extra
# for i in range(1, len(tuple)):
for row in tuple[1:]:
tblstr += ' <tr>\n'
# row = tuple[i]
if type(row) not in [int, long, str, dict]:
# for data in row: tblstr += '<td class="admintd">%s</td>\n' % (data,)
for i in range(len(row)): tblstr += '<td class="%s">%s</td>\n' % (align[i], row[i])
else:
tblstr += ' <td class="%s">%s</td>\n' % (align[0], row)
tblstr += ' </tr> \n'
tblstr += '</table> \n '
tblstr += end
return tblstr
def tupletotable_onlyselected(header=[], tuple=[], selected=[], start='', end='', extracolumn=''):
"""create html table for a tuple.
header - optional header for the columns
tuple - create table of this
selected - indexes of selected rows in the tuple
start - put this in the beginning
end - put this in the beginning
extracolumn - mainly used to put in a button"""
tuple2 = []
for index in selected:
tuple2.append(tuple[int(index)-1])
return tupletotable(header=header,
tuple=tuple2,
start=start,
end=end,
extracolumn=extracolumn)
def addcheckboxes(datalist=[], name='authids', startindex=1, checked=[]):
"""adds checkboxes in front of the listdata.
datalist - add checkboxes in front of this list
name - name of all the checkboxes, values will be associated with this name
startindex - usually 1 because of the header
checked - values of checkboxes to be pre-checked """
if not type(checked) is list: checked = [checked]
for row in datalist:
if 1 or row[0] not in [-1, "-1", 0, "0"]: # always box, check another place
chkstr = str(startindex) in checked and 'checked="checked"' or ''
row.insert(0, '<input type="checkbox" name="%s" value="%s" %s />' % (name, startindex, chkstr))
else:
row.insert(0, '')
startindex += 1
return datalist
def createhiddenform(action="", text="", button="confirm", cnfrm='', **hidden):
"""create select with hidden values and submit button
action - name of the action to perform on submit
text - additional text, can also be used to add non hidden input
button - value/caption on the submit button
cnfrm - if given, must check checkbox to confirm
**hidden - dictionary with name=value pairs for hidden input """
output = '<form action="%s" method="POST">\n' % (action, )
output += '<table>\n<tr><td style="vertical-align: top">'
output += text
if cnfrm:
output += ' <input type="checkbox" name="confirm" value="1"/>'
for key in hidden.keys():
if type(hidden[key]) is list:
for value in hidden[key]:
output += ' <input type="hidden" name="%s" value="%s"/>\n' % (key, value)
else:
output += ' <input type="hidden" name="%s" value="%s"/>\n' % (key, hidden[key])
output += '</td><td style="vertical-align: bottom">'
output += ' <input class="adminbutton" type="submit" value="%s"/>\n' % (button, )
output += '</td></tr></table>'
output += '</form>\n'
return output
def adderrorbox(header='', datalist=[]):
"""used to create table around main data on a page, row based"""
try: perc= str(100 // len(datalist)) + '%'
except ZeroDivisionError: perc= 1
output = '<table class="errorbox">'
output += '<thead><tr><th class="errorboxheader" colspan="%s">%s</th></tr></thead>' % (len(datalist), header)
output += '<tbody>'
for row in [datalist]:
output += '<tr>'
for data in row:
output += '<td style="vertical-align: top; margin-top: 5px; width: %s;">' % (perc, )
output += data
output += '</td>'
output += '</tr>'
output += '</tbody></table>'
return output
def serialize_via_numeric_array_dumps(arr):
return Numeric.dumps(arr)
def serialize_via_numeric_array_compr(str):
return compress(str)
def serialize_via_numeric_array_escape(str):
return MySQLdb.escape_string(str)
def serialize_via_numeric_array(arr):
"""Serialize Numeric array into a compressed string."""
return serialize_via_numeric_array_escape(serialize_via_numeric_array_compr(serialize_via_numeric_array_dumps(arr)))
def deserialize_via_numeric_array(string):
"""Decompress and deserialize string into a Numeric array."""
return Numeric.loads(decompress(string))
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(compress(dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return loads(decompress(string))
def get_languages():
languages = []
for (lang, lang_namelong) in language_list_long():
languages.append((lang, lang_namelong))
languages.sort()
return languages
def get_def_name(ID, table):
"""Returns a list of the names, either with the name in the current language, the default language, or just the name from the given table
ln - a language supported by cdsware
type - the type of value wanted, like 'ln', 'sn'"""
name = "name"
if table[-1:].isupper():
name = "NAME"
try:
if ID:
res = run_sql("SELECT id,name FROM %s where id=%s" % (table, ID))
else:
res = run_sql("SELECT id,name FROM %s" % table)
res = list(res)
res.sort(compare_on_val)
return res
except StandardError, e:
return []
def get_i8n_name(ID, ln, rtype, table):
"""Returns a list of the names, either with the name in the current language, the default language, or just the name from the given table
ln - a language supported by cdsware
type - the type of value wanted, like 'ln', 'sn'"""
name = "name"
if table[-1:].isupper():
name = "NAME"
try:
res = ""
if ID:
res = run_sql("SELECT id_%s,value FROM %s%s where type='%s' and ln='%s' and id_%s=%s" % (table, table, name, rtype,ln, table, ID))
else:
res = run_sql("SELECT id_%s,value FROM %s%s where type='%s' and ln='%s'" % (table, table, name, rtype,ln))
if ln != cdslang:
if ID:
res1 = run_sql("SELECT id_%s,value FROM %s%s WHERE ln='%s' and type='%s' and id_%s=%s" % (table, table, name, cdslang, rtype, table, ID))
else:
res1 = run_sql("SELECT id_%s,value FROM %s%s WHERE ln='%s' and type='%s'" % (table, table, name, cdslang, rtype))
res2 = dict(res)
result = filter(lambda x: not res2.has_key(x[0]), res1)
res = res + result
if ID:
res1 = run_sql("SELECT id,name FROM %s where id=%s" % (table, ID))
else:
res1 = run_sql("SELECT id,name FROM %s" % table)
res2 = dict(res)
result = filter(lambda x: not res2.has_key(x[0]), res1)
res = res + result
res = list(res)
res.sort(compare_on_val)
return res
except StandardError, e:
raise StandardError
def get_name(ID, ln, rtype, table):
"""Returns the value from the table name based on arguments
ID - id
ln - a language supported by cdsware
type - the type of value wanted, like 'ln', 'sn'
table - tablename"""
name = "name"
if table[-1:].isupper():
name = "NAME"
try:
res = run_sql("SELECT value FROM %s%s WHERE type='%s' and ln='%s' and id_%s=%s" % (table, name, rtype, ln, table, ID))
return res
except StandardError, e:
return ()
def modify_translations(ID, langs, sel_type, trans, table):
"""add or modify translations in tables given by table
frmID - the id of the format from the format table
sel_type - the name type
langs - the languages
trans - the translations, in same order as in langs
table - the table"""
name = "name"
if table[-1:].isupper():
name = "NAME"
try:
for nr in range(0,len(langs)):
res = run_sql("SELECT value FROM %s%s WHERE id_%s=%s AND type='%s' AND ln='%s'" % (table, name, table, ID, sel_type, langs[nr][0]))
if res:
if trans[nr]:
res = run_sql("UPDATE %s%s SET value='%s' WHERE id_%s=%s AND type='%s' AND ln='%s'" % (table, name, MySQLdb.escape_string(trans[nr]), table, ID, sel_type, langs[nr][0]))
else:
res = run_sql("DELETE FROM %s%s WHERE id_%s=%s AND type='%s' AND ln='%s'" % (table, name, table, ID, sel_type, langs[nr][0]))
else:
if trans[nr]:
res = run_sql("INSERT INTO %s%s(id_%s, type, ln, value) VALUES (%s,'%s','%s','%s')" % (table, name, table, ID, sel_type, langs[nr][0], MySQLdb.escape_string(trans[nr])))
return (1, "")
except StandardError, e:
return (0, e)
def write_outcome(res):
try:
if res and res[0] == 1:
return """<b><span class="info">Operation successfully completed.</span></b>"""
elif res:
return """<b><span class="info">Operation failed. Reason:</span></b><br>%s""" % res[1][1]
except Exception, e:
return """<b><span class="info">Operation failed. Reason unknown</span></b><br>"""
diff --git a/modules/bibrank/web/Makefile.am b/modules/bibrank/web/Makefile.am
index b1171321a..52c701cf6 100644
--- a/modules/bibrank/web/Makefile.am
+++ b/modules/bibrank/web/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
\ No newline at end of file
diff --git a/modules/bibrank/web/admin/Makefile.am b/modules/bibrank/web/admin/Makefile.am
index 30787bdc6..7052c2913 100644
--- a/modules/bibrank/web/admin/Makefile.am
+++ b/modules/bibrank/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/bibrank
webapp_DATA = bibrankadmin.py
EXTRA_DIST = bibrankadmin.py
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/bibrank/web/admin/bibrankadmin.py b/modules/bibrank/web/admin/bibrankadmin.py
index 05fb2ab34..62d393d73 100644
--- a/modules/bibrank/web/admin/bibrankadmin.py
+++ b/modules/bibrank/web/admin/bibrankadmin.py
@@ -1,198 +1,198 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware BibRank Administrator Interface."""
__lastupdated__ = """$Date$"""
import sys
import cdsware.bibrankadminlib as brc
#reload(brc)
from cdsware.webpage import page, create_error_box
from cdsware.config import weburl,cdslang
from cdsware.webuser import getUid, page_not_authorized
__version__ = "$Id$"
def index(req, ln=cdslang):
navtrail_previous_links = brc.getnavtrail() # + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="BibRank Admin Interface",
body=brc.perform_index(ln),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__,
urlargs=req.args)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addrankarea(req, ln=cdslang, rnkcode='', template='', confirm=-1):
navtrail_previous_links = brc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py/">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="Add new rank method",
body=brc.perform_addrankarea(rnkcode=rnkcode,
ln=cdslang,
template=template,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifytranslations(req, rnkID='', ln=cdslang, sel_type='', trans = [], confirm=0):
navtrail_previous_links = brc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py/">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="Modify translations",
body=brc.perform_modifytranslations(rnkID=rnkID,
ln=ln,
sel_type=sel_type,
trans=trans,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifycollection(req, ln=cdslang, rnkID='', func='', colID='', confirm=0):
navtrail_previous_links = brc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py/">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="Modify visibility toward collections",
body=brc.perform_modifycollection(rnkID=rnkID,
ln=ln,
func=func,
colID=colID,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def deleterank(req, ln=cdslang, rnkID='', confirm=0):
navtrail_previous_links = brc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py/">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="Delete rank method",
body=brc.perform_deleterank(rnkID=rnkID,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyrank(req, ln=cdslang, rnkID='', rnkcode='', template='', cfgfile='', confirm=0):
navtrail_previous_links = brc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py/">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="Modify rank method",
body=brc.perform_modifyrank(rnkID=rnkID,
ln=ln,
rnkcode=rnkcode,
cfgfile=cfgfile,
template=template,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showrankdetails(req, ln=cdslang, rnkID=''):
navtrail_previous_links = brc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/bibrank/bibrankadmin.py/">BibRank Admin Interface</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = brc.check_user(uid,'cfgbibrank')
if not auth[0]:
return page(title="Rank method details",
body=brc.perform_showrankdetails(rnkID=rnkID,
ln=ln),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def error_page(req):
return page(title="Internal Error",
body = create_error_box(req, verbose=verbose, ln=ln),
description="%s - Internal Error" % cdsname,
keywords="%s, CDSware, Internal Error" % cdsname,
language=ln,
urlargs=req.args)
diff --git a/modules/bibsched/Makefile.am b/modules/bibsched/Makefile.am
index a49e81bbe..e6a00688e 100644
--- a/modules/bibsched/Makefile.am
+++ b/modules/bibsched/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/bibsched/bin/Makefile.am b/modules/bibsched/bin/Makefile.am
index a6ee12e86..98e4700f5 100644
--- a/modules/bibsched/bin/Makefile.am
+++ b/modules/bibsched/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibsched bibtaskex
EXTRA_DIST = bibsched.in bibtaskex.in
CLEANFILES = *~ *.tmp bibtaskexc
diff --git a/modules/bibsched/bin/bibsched.in b/modules/bibsched/bin/bibsched.in
index 783d81ca3..1757e0518 100644
--- a/modules/bibsched/bin/bibsched.in
+++ b/modules/bibsched/bin/bibsched.in
@@ -1,796 +1,796 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""BibSched - task management, scheduling and executing system for CDSware
"""
__version__ = "$Id$"
### -- local configuration section starts here ---
cfg_valid_processes = ["bibindex","bibupload","bibreformat","webcoll","bibtaskex","bibrank","oaiharvest","oaiarchive"] # which tasks are reconized as valid?
### -- local configuration section ends here ---
## import interesting modules:
try:
import os
import imp
import string
import sys
import MySQLdb
import time
import sre
import getopt
import curses
import curses.panel
from curses.wrapper import wrapper
import signal
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
try:
from cdsware.config import *
from cdsware.dbquery import run_sql
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
try:
date = time.time()
shift_re=sre.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
except:
return None
def get_my_pid(process,args=''):
COMMAND = "ps -C %s o '%%p%%a' | grep '%s %s' | grep -v 'grep' | sed -n 1p" % (process,process,args)
answer = string.strip(os.popen(COMMAND).read())
if answer=='':
answer = 0
else:
answer = answer[:string.find(answer,' ')]
return int(answer)
def get_output_channelnames(task_id):
"Construct and return filename for stdout and stderr for the task 'task_id'."
filenamebase = "%s/bibsched_task_%d" % (logdir, task_id)
return [filenamebase + ".log", filenamebase + ".err"]
class Manager:
def __init__(self):
self.helper_modules = cfg_valid_processes
self.running = 1
self.footer_move_mode = "[KeyUp/KeyDown Move] [M Select mode] [Q Quit]"
self.footer_auto_mode = "[A Manual mode] [1/2 Display Type] [Q Quit]"
self.footer_select_mode = "[KeyUp/KeyDown/PgUp/PgDown Select] [L View Log] [1/2 Display Type] [M Move mode] [A Auto mode] [Q Quit]"
self.footer_waiting_item = "[R Run] [D Delete]"
self.footer_running_item = "[S Sleep] [T Stop] [K Kill]"
self.footer_stopped_item = "[I Initialise] [D Delete]"
self.footer_sleeping_item = "[W Wake Up]"
self.item_status = ""
self.selected_line = 2
self.rows = []
self.panel = None
self.display = 2
self.first_visible_line = 0
self.move_mode = 0
self.auto_mode = 0
self.currentrow = ["","","","","","",""]
wrapper( self.start )
def handle_keys(self, chr):
if chr == -1:
return
if self.auto_mode and (chr not in (curses.KEY_UP,curses.KEY_DOWN,curses.KEY_PPAGE,curses.KEY_NPAGE,ord("q"),ord("Q"),ord("a"),ord("A"),ord("1"),ord("2"))):
self.display_in_footer("in automatic mode")
self.stdscr.refresh()
elif self.move_mode and (chr not in (curses.KEY_UP,curses.KEY_DOWN,ord("m"),ord("M"),ord("q"),ord("Q"))):
self.display_in_footer("in move mode")
self.stdscr.refresh()
else:
if chr == curses.KEY_UP:
if self.move_mode:
self.move_up()
else:
self.selected_line = max( self.selected_line - 1 , 2 )
self.repaint()
if chr == curses.KEY_PPAGE:
self.selected_line = max( self.selected_line - 10 , 2 )
self.repaint()
elif chr == curses.KEY_DOWN:
if self.move_mode:
self.move_down()
else:
self.selected_line = min(self.selected_line + 1, len(self.rows) + 1 )
self.repaint()
elif chr == curses.KEY_NPAGE:
self.selected_line = min(self.selected_line + 10, len(self.rows) + 1 )
self.repaint()
elif chr == curses.KEY_HOME:
self.first_visible_line = 0
self.selected_line = 2
elif chr in (ord("a"), ord("A")):
self.change_auto_mode()
elif chr in (ord("l"), ord("L")):
self.openlog()
elif chr in (ord("w"), ord("W")):
self.wakeup()
elif chr in (ord("r"), ord("R")):
self.run()
elif chr in (ord("s"), ord("S")):
self.sleep()
elif chr in (ord("k"), ord("K")):
self.kill()
elif chr in (ord("t"), ord("T")):
self.stop()
elif chr in (ord("d"), ord("D")):
self.delete()
elif chr in (ord("i"), ord("I")):
self.init()
elif chr in (ord("m"), ord("M")):
self.change_select_mode()
elif chr == ord("1"):
self.display = 1
self.first_visible_line = 0
self.selected_line = 2
self.display_in_footer("only done processes are displayed")
elif chr == ord("2"):
self.display = 2
self.first_visible_line = 0
self.selected_line = 2
self.display_in_footer("only not done processes are displayed")
elif chr in (ord("q"), ord("Q")):
if curses.panel.top_panel() == self.panel:
self.panel.bottom()
curses.panel.update_panels()
else:
self.running = 0
return
def set_status(self, id, status):
return run_sql("UPDATE schTASK set status=%s WHERE id=%s", (status, id))
def set_progress(self, id, progress):
return run_sql("UPDATE schTASK set progress=%s WHERE id=%s", (progress, id))
def openlog(self):
self.win = curses.newwin( self.height-2, self.width-2, 1, 1 )
self.panel = curses.panel.new_panel( self.win )
self.panel.top()
self.win.border()
self.win.addstr(1, 1, "Not implemented yet...")
self.win.refresh()
curses.panel.update_panels()
def count_processes(self,status):
out = 0
res = run_sql("SELECT COUNT(id) FROM schTASK WHERE status=%s GROUP BY status", (status,))
try:
out = res[0][0]
except:
pass
return out
def wakeup(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
if self.count_processes('RUNNING') + self.count_processes('CONTINUING') >= 1:
self.display_in_footer("a process is already running!")
elif status == "SLEEPING":
mypid = get_my_pid(process,str(id))
if mypid!=0:
os.kill(mypid, signal.SIGCONT)
self.display_in_footer("process woken up")
else:
self.display_in_footer("process is not sleeping")
self.stdscr.refresh()
def run(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
sleeptime = self.currentrow[4]
if self.count_processes('RUNNING') + self.count_processes('CONTINUING') >= 1:
self.display_in_footer("a process is already running!")
elif status == "STOPPED" or status == "WAITING":
if process in self.helper_modules:
program=os.path.join( bindir, process )
fdout, fderr = get_output_channelnames(id)
COMMAND = "%s %s >> %s 2>> %s &" % (program, str(id), fdout, fderr)
os.system(COMMAND)
Log("manually running task #%d (%s)" % (id, process))
if sleeptime:
next_runtime=get_datetime(sleeptime)
run_sql("INSERT INTO schTASK (proc, user, runtime, sleeptime, arguments, status) "\
" VALUES (%s,%s,%s,%s,%s,'WAITING')",
(process,self.currentrow[2], next_runtime,sleeptime,self.currentrow[7]))
else:
self.display_in_footer("process status should be STOPPED or WAITING!")
self.stdscr.refresh()
def sleep(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
if status!='RUNNING' and status!='CONTINUING':
self.display_in_footer("this process is not running!")
else:
mypid = get_my_pid(process,str(id))
if mypid!=0:
os.kill(mypid, signal.SIGUSR1)
self.display_in_footer("SLEEP signal sent to process #%s" % mypid)
else:
self.set_status(id,'STOPPED')
self.display_in_footer("cannot find process...")
self.stdscr.refresh()
def kill(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
mypid = get_my_pid(process,str(id))
if mypid!=0:
os.kill(mypid, signal.SIGKILL)
self.set_status(id,'STOPPED')
self.display_in_footer("KILL signal sent to process #%s" % mypid)
else:
self.set_status(id,'STOPPED')
self.display_in_footer("cannot find process...")
self.stdscr.refresh()
def stop(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
mypid = get_my_pid(process, str(id))
if mypid!=0:
os.kill(mypid, signal.SIGINT)
self.display_in_footer("INT signal sent to process #%s" % mypid)
else:
self.set_status(id,'STOPPED')
self.display_in_footer("cannot find process...")
self.stdscr.refresh()
def delete(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
if status!='RUNNING' and status!='CONTINUING' and status!='SLEEPING':
self.set_status(id,"%s_DELETED" % status)
self.display_in_footer("process deleted")
self.selected_line = max(self.selected_line, 2)
else:
self.display_in_footer("cannot delete running processes")
self.stdscr.refresh()
def init(self):
id = self.currentrow[0]
process = self.currentrow[1]
status = self.currentrow[5]
if status!='RUNNING' and status!='CONTINUING' and status!='SLEEPING':
self.set_status(id,"WAITING")
self.set_progress(id,"None")
self.display_in_footer("process initialised")
else:
self.display_in_footer("cannot initialise running processes")
self.stdscr.refresh()
def change_select_mode(self):
if self.move_mode:
self.move_mode = 0
else:
status = self.currentrow[5]
if status in ( "RUNNING" , "CONTINUING" , "SLEEPING" ):
self.display_in_footer("cannot move running processes!")
else:
self.move_mode = 1
self.stdscr.refresh()
def change_auto_mode(self):
if self.auto_mode:
program = os.path.join( bindir, "bibsched")
COMMAND = "%s -q stop" % program
os.system(COMMAND)
self.auto_mode = 0
else:
program = os.path.join( bindir, "bibsched")
COMMAND = "%s -q start" % program
os.system(COMMAND)
self.auto_mode = 1
self.move_mode = 0
self.stdscr.refresh()
def move_up(self):
self.display_in_footer("not implemented yet")
self.stdscr.refresh()
def move_down(self):
self.display_in_footer("not implemented yet")
self.stdscr.refresh()
def put_line(self, row):
col_w = [ 5 , 11 , 21 , 21 , 7 , 11 , 25 ]
maxx = self.width
if self.y == self.selected_line - self.first_visible_line and self.y > 1:
if self.auto_mode:
attr = curses.color_pair(2) + curses.A_STANDOUT + curses.A_BOLD
elif self.move_mode:
attr = curses.color_pair(7) + curses.A_STANDOUT + curses.A_BOLD
else:
attr = curses.color_pair(8) + curses.A_STANDOUT + curses.A_BOLD
self.item_status = row[5]
self.currentrow = row
elif self.y == 0:
if self.auto_mode:
attr = curses.color_pair(2) + curses.A_STANDOUT + curses.A_BOLD
elif self.move_mode:
attr = curses.color_pair(7) + curses.A_STANDOUT + curses.A_BOLD
else:
attr = curses.color_pair(8) + curses.A_STANDOUT + curses.A_BOLD
elif row[5] == "DONE":
attr = curses.color_pair(5) + curses.A_BOLD
elif row[5] == "STOPPED":
attr = curses.color_pair(6) + curses.A_BOLD
elif sre.search("ERROR",row[5]):
attr = curses.color_pair(4) + curses.A_BOLD
elif row[5] == "WAITING":
attr = curses.color_pair(3) + curses.A_BOLD
elif row[5] in ("RUNNING","CONTINUING") :
attr = curses.color_pair(2) + curses.A_BOLD
else:
attr = curses.A_BOLD
myline = str(row[0]).ljust(col_w[0])
myline += str(row[1]).ljust(col_w[1])
myline += str(row[2]).ljust(col_w[2])
myline += str(row[3])[:19].ljust(col_w[3])
myline += str(row[4]).ljust(col_w[4])
myline += str(row[5]).ljust(col_w[5])
myline += str(row[6]).ljust(col_w[6])
myline = myline.ljust(maxx)
self.stdscr.addnstr(self.y, 0, myline, maxx, attr)
self.y = self.y+1
def display_in_footer(self, footer, i = 0, print_time_p=0):
if print_time_p:
footer = "%s %s" % (footer, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
maxx = self.stdscr.getmaxyx()[1]
footer = footer.ljust(maxx)
if self.auto_mode:
colorpair = 2
elif self.move_mode:
colorpair = 7
else:
colorpair = 1
self.stdscr.addnstr(self.y - i, 0, footer, maxx - 1, curses.A_STANDOUT + curses.color_pair(colorpair) + curses.A_BOLD )
def repaint(self):
self.y = 0
self.stdscr.clear()
self.height,self.width = self.stdscr.getmaxyx()
maxy = self.height - 2
maxx = self.width
self.put_line( ("ID","PROC","USER","RUNTIME","SLEEP","STATUS","PROGRESS") )
self.put_line( ("---","----","----","-------------------","-----","-----","--------") )
if self.selected_line > maxy + self.first_visible_line - 1:
self.first_visible_line = self.selected_line - maxy + 1
if self.selected_line < self.first_visible_line + 2:
self.first_visible_line = self.selected_line - 2
for row in self.rows[self.first_visible_line:self.first_visible_line+maxy-2]:
id,proc,user,runtime,sleeptime,status,progress,arguments = row
self.put_line( row )
self.y = self.stdscr.getmaxyx()[0] - 1
if self.auto_mode:
self.display_in_footer(self.footer_auto_mode, print_time_p=1)
elif self.move_mode:
self.display_in_footer(self.footer_move_mode, print_time_p=1)
else:
self.display_in_footer(self.footer_select_mode, print_time_p=1)
footer2 = ""
if sre.search("DONE",self.item_status) or self.item_status == "ERROR" or self.item_status == "STOPPED":
footer2 += self.footer_stopped_item
elif self.item_status == "RUNNING" or self.item_status == "CONTINUING":
footer2 += self.footer_running_item
elif self.item_status == "SLEEPING":
footer2 += self.footer_sleeping_item
elif self.item_status == "WAITING":
footer2 += self.footer_waiting_item
self.display_in_footer(footer2,1)
self.stdscr.refresh()
def start(self, stdscr):
ring = 0
if curses.has_colors():
curses.start_color()
curses.init_pair(8, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_RED)
curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_MAGENTA, curses.COLOR_BLACK)
curses.init_pair(4, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(5, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(6, curses.COLOR_CYAN, curses.COLOR_BLACK)
curses.init_pair(7, curses.COLOR_YELLOW, curses.COLOR_BLACK)
self.stdscr = stdscr
self.base_panel = curses.panel.new_panel( self.stdscr )
self.base_panel.bottom()
curses.panel.update_panels()
self.height,self.width = stdscr.getmaxyx()
self.stdscr.clear()
if server_pid (): self.auto_mode = 1
if self.display == 1:
where = "and status='DONE'"
order = "DESC"
else:
where = "and status!='DONE'"
order = "ASC"
self.rows = run_sql("SELECT id,proc,user,runtime,sleeptime,status,progress,arguments FROM schTASK WHERE status NOT LIKE '%%DELETED%%' %s ORDER BY runtime %s" % (where,order))
self.repaint()
ring=0
while self.running:
ring += 1
chr = -1
try:
chr = timed_out(self.stdscr.getch, 1)
if chr == 27: # escaping sequence
chr = self.stdscr.getch()
if chr == 79: # arrow
chr = self.stdscr.getch()
if chr == 65: #arrow up
chr = curses.KEY_UP
elif chr == 66: #arrow down
chr = curses.KEY_DOWN
elif chr == 72:
chr = curses.KEY_PPAGE
elif chr == 70:
chr = curses.KEY_NPAGE
elif chr == 91:
chr = self.stdscr.getch()
if chr == 53:
chr = self.stdscr.getch()
if chr == 126:
chr = curses.KEY_HOME
except TimedOutExc:
chr = -1
self.handle_keys(chr)
if ring == 4:
if self.display == 1:
where = "and status='DONE'"
order = "DESC"
else:
where = "and status!='DONE'"
order = "ASC"
self.rows = run_sql("SELECT id,proc,user,runtime,sleeptime,status,progress,arguments FROM schTASK WHERE status NOT LIKE '%%DELETED%%' %s ORDER BY runtime %s" % (where,order))
ring = 0
self.repaint()
class BibSched:
def __init__(self):
self.helper_modules = cfg_valid_processes
self.running = {}
self.sleep_done = {}
self.sleep_sent ={}
self.stop_sent = {}
self.suicide_sent = {}
def set_status(self, id, status):
return run_sql("UPDATE schTASK set status=%s WHERE id=%s", (status, id))
def can_run( self, proc ):
return len( self.running.keys() ) == 0
def get_running_processes(self):
row = None
res = run_sql("SELECT id,proc,user,UNIX_TIMESTAMP(runtime),sleeptime,arguments,status FROM schTASK "\
" WHERE status='RUNNING' or status='CONTINUING' LIMIT 1")
try:
row = res[0]
except:
pass
return row
def handle_row( self, row ):
id,proc,user,runtime,sleeptime,arguments,status = row
if status == "SLEEP":
if id in self.running.keys():
self.set_status( id, "SLEEP SENT" )
os.kill( self.running[id], signal.SIGUSR1 )
self.sleep_sent[id] = self.running[id]
elif status == "SLEEPING":
if id in self.sleep_sent.keys():
self.sleep_done[id] = self.sleep_sent[id]
del self.sleep_sent[id]
if status == "WAKEUP":
if id in self.sleep_done.keys():
self.running[id] = self.sleep_done[id]
del self.sleep_done[id]
os.kill( self.running[id], signal.SIGCONT )
self.set_status( id, "RUNNING" )
elif status == "STOP":
if id in self.running.keys():
self.set_status( id, "STOP SENT" )
os.kill( self.running[id], signal.SIGUSR2 )
self.stop_sent[id] = self.running[id]
del self.running[id]
elif status == "STOPPED" and id in self.stop_sent.keys():
del self.stop_sent[id]
elif status == "SUICIDE":
if id in self.running.keys():
self.set_status( id, "SUICIDE SENT" )
os.kill( self.running[id], signal.SIGABRT )
self.suicide_sent[id] = self.running[id]
del self.running[id]
elif status == "SUICIDED" and id in self.suicide_sent.keys():
del self.suicide_sent[ id ]
elif sre.search("DONE",status) and id in self.running.keys():
del self.running[id]
elif self.can_run(proc) and status == "WAITING" and runtime <= time.time():
if proc in self.helper_modules:
program=os.path.join( bindir, proc )
fdout, fderr = get_output_channelnames(id)
COMMAND = "%s %s >> %s 2>> %s" % (program, str(id), fdout, fderr)
Log("task #%d (%s) started" % (id, proc))
os.system(COMMAND)
Log("task #%d (%s) ended" % (id, proc))
self.running[id] = get_my_pid(proc,str(id))
if sleeptime:
next_runtime=get_datetime(sleeptime)
run_sql("INSERT INTO schTASK (proc, user, runtime, sleeptime, arguments, status) "\
" VALUES (%s,%s,%s,%s,%s,'WAITING')",
(proc, user, next_runtime, sleeptime, arguments))
def watch_loop(self):
running_process = self.get_running_processes()
if running_process:
proc = running_process[ 1 ]
id = running_process[ 0 ]
if get_my_pid(proc,str(id)):
self.running[id] = get_my_pid(proc,str(id))
else:
self.set_status(id,"ERROR")
rows = []
while 1:
for row in rows:
self.handle_row( row )
time.sleep(1)
rows = run_sql("SELECT id,proc,user,UNIX_TIMESTAMP(runtime),sleeptime,arguments,status FROM schTASK ORDER BY runtime ASC")
class TimedOutExc(Exception):
def __init__(self, value = "Timed Out"):
self.value = value
def __str__(self):
return repr(self.value)
def timed_out(f, timeout, *args, **kwargs):
def handler(signum, frame):
raise TimedOutExc()
old = signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout)
try:
result = f(*args, **kwargs)
finally:
signal.signal(signal.SIGALRM, old)
signal.alarm(0)
return result
def Log(message):
log=open(logdir + "/bibsched.log","a")
log.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
log.write(message)
log.write("\n")
log.close()
def redirect_stdout_and_stderr():
"This function redirects stdout and stderr to bibsched.log and bibsched.err file."
sys.stdout = open(logdir + "/bibsched.log", "a")
sys.stderr = open(logdir + "/bibsched.err", "a")
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write ("""\
Usage: %s [options] [start|stop|restart|monitor]
The following commands are available for bibsched:
- start: start bibsched in background
- stop: stop a running bibsched
- restart: restart a running bibsched
- monitor: enter the interactive monitor
Command options:
-d, --daemon\t Launch BibSched in the daemon mode (deprecated, use 'start')
General options:
-h, --help \t\t Print this help.
-V, --version \t\t Print version information.
""" % sys.argv [0])
#sys.stderr.write(" -v, --verbose=LEVEL \t Verbose level (0=min, 1=default, 9=max).\n")
sys.exit(exitcode)
import pwd, grp
prefix = '@prefix@'
pidfile = os.path.join (prefix, 'var', 'run', 'bibsched.pid')
def error (msg):
print >> sys.stderr, "error: " + msg
sys.exit (1)
def server_pid ():
# The pid must be stored on the filesystem
try:
pid = int (open (pidfile).read ())
except IOError:
return None
# Even if the pid is available, we check if it corresponds to an
# actual process, as it might have been killed externally
try:
os.kill (pid, signal.SIGCONT)
except OSError:
return None
return pid
def start (verbose = True):
""" Fork this process in the background and start processing
requests. The process PID is stored in a pid file, so that it can
be stopped later on."""
if verbose:
sys.stdout.write ("starting bibsched: ")
sys.stdout.flush ()
pid = server_pid ()
if pid:
error ("another instance of bibsched (pid %d) is running" % pid)
# start the child process using the "double fork" technique
pid = os.fork ()
if pid > 0: sys.exit (0)
os.setsid ()
os.chdir ('/')
pid = os.fork ()
if pid > 0:
if verbose:
sys.stdout.write ('pid %d\n' % pid)
Log ("daemon started (pid %d)" % pid)
open (pidfile, 'w').write ('%d' % pid)
return
sys.stdin.close ()
redirect_stdout_and_stderr ()
sched = BibSched()
sched.watch_loop ()
return
def stop (verbose = True):
pid = server_pid ()
if not pid:
error ('bibsched seems not to be running.')
try: os.kill (pid, signal.SIGKILL)
except OSError:
print >> sys.stderr, 'no bibsched process found'
Log ("daemon stopped (pid %d)" % pid)
if verbose: print "stopping bibsched: pid %d" % pid
os.unlink (pidfile)
return
def monitor (verbose = True):
redirect_stdout_and_stderr()
manager = Manager ()
return
def restart (verbose = True):
stop (verbose)
start (verbose)
return
def main():
verbose = True
try:
opts, args = getopt.getopt(sys.argv[1:], "hVdq", [
"help","version","daemon", "quiet"])
except getopt.GetoptError, err:
Log ("Error: %s" % err)
usage(1, err)
for opt, arg in opts:
if opt in ["-h", "--help"]:
usage (0)
elif opt in ["-V", "--version"]:
print __version__
sys.exit(0)
elif opt in ["-d", "--daemon"]:
redirect_stdout_and_stderr ()
sched = BibSched()
Log("daemon started")
sched.watch_loop()
elif opt in ['-q', '--quiet']:
verbose = False
else:
usage(1)
try: cmd = args [0]
except IndexError: cmd = 'monitor'
try:
{ 'start': start,
'stop': stop,
'restart': restart,
'monitor': monitor } [cmd] (verbose)
except KeyError:
usage (1, 'unkown command: %s' % `cmd`)
return
if __name__ == '__main__':
main()
diff --git a/modules/bibsched/bin/bibtaskex.in b/modules/bibsched/bin/bibtaskex.in
index 81a43786d..7ba751b41 100644
--- a/modules/bibsched/bin/bibtaskex.in
+++ b/modules/bibsched/bin/bibtaskex.in
@@ -1,333 +1,333 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Bibliographic Task Example. Demonstrates BibTask <-> BibSched connectivity,
signal handling, error handling, etc.
"""
__version__ = "$Id$"
## import interesting modules:
try:
import sys
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
import getopt
import getpass
import marshal
import signal
import sre
import string
import sys
import time
import traceback
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
cfg_n_default = 30 # how many Fibonacci numbers to calculate if none submitted?
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
shift_re=sre.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def write_message(msg, stream=sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr). Useful for debugging stuff."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
write_message("stopping...")
task_update_status("STOPPING")
write_message("flushing cache or whatever...")
time.sleep(3)
write_message("closing tables or whatever...")
time.sleep(1)
write_message("stopped")
task_update_status("STOPPED")
sys.exit(0)
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def fib(n):
"""Returns Fibonacci number for 'n'."""
out = 1
if n >= 2:
out = fib(n-2) + fib(n-1)
return out
def authenticate(user, header="BibTaskEx Task Submission", action="runbibtaskex"):
"""Authenticate the user against the user database.
Check for its password, if it exists.
Check for action access rights.
Return user name upon authorization success,
do system exit upon authorization failure.
"""
print header
print "=" * len(header)
if user == "":
print >> sys.stdout, "\rUsername: ",
user = string.strip(string.lower(sys.stdin.readline()))
else:
print >> sys.stdout, "\rUsername: ", user
## first check user pw:
res = run_sql("select id,password from user where email=%s", (user,), 1)
if not res:
print "Sorry, %s does not exist." % user
sys.exit(1)
else:
(uid_db, password_db) = res[0]
if password_db:
password_entered = getpass.getpass()
if password_db == password_entered:
pass
else:
print "Sorry, wrong credentials for %s." % user
sys.exit(1)
## secondly check authorization for the action:
(auth_code, auth_message) = acc_authorize_action(uid_db, action)
if auth_code != 0:
print auth_message
sys.exit(1)
return user
def task_submit(options):
"""Submits task to the BibSched task queue. This is what people will be invoking via command line."""
## sanity check: remove eventual "task" option:
if options.has_key("task"):
del options["task"]
## authenticate user:
user = authenticate(options.get("user", ""))
## submit task:
if options["verbose"] >= 9:
print ""
write_message("storing task options %s\n" % options)
task_id = run_sql("""INSERT INTO schTASK (id,proc,user,runtime,sleeptime,status,arguments)
VALUES (NULL,'bibtaskex',%s,%s,%s,'WAITING',%s)""",
(user, options["runtime"], options["sleeptime"], marshal.dumps(options)))
## update task number:
options["task"] = task_id
run_sql("""UPDATE schTASK SET arguments=%s WHERE id=%s""", (marshal.dumps(options),task_id))
write_message("Task #%d submitted." % task_id)
return task_id
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task progress to %s." % msg)
return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, task_id))
def task_update_status(val):
"""Updates status information in the BibSched task table."""
global task_id, options
if options["verbose"] >= 9:
write_message("Updating task status to %s." % val)
return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, task_id))
def task_read_status(task_id):
"""Read status information in the BibSched task table."""
res = run_sql("SELECT status FROM schTASK where id=%s", (task_id,), 1)
try:
out = res[0][0]
except:
out = 'UNKNOWN'
return out
def task_get_options(id):
"""Returns options for the task 'id' read from the BibSched task queue table."""
out = {}
res = run_sql("SELECT arguments FROM schTASK WHERE id=%s AND proc='bibtaskex'", (id,))
try:
out = marshal.loads(res[0][0])
except:
write_message("Error: BibTaskEx task %d does not seem to exist." % id, sys.stderr)
sys.exit(1)
return out
def task_run():
"""Runs the task by fetching arguments from the BibSched task queue. This is what BibSched will be invoking via daemon call.
The task prints Fibinacci numbers for up to NUM on the stdout, and some messages on stderr.
Return 1 in case of success and 0 in case of failure."""
global task_id, options
options = task_get_options(task_id) # get options from BibSched task table
## check task id:
if not options.has_key("task"):
write_message("Error: The task #%d does not seem to be a BibTaskEx task." % task_id, sys.stderr)
return 0
## check task status:
task_status = task_read_status(task_id)
if task_status != "WAITING":
write_message("Error: The task #%d is %s. I expected WAITING." % (task_id, task_status), sys.stderr)
return 0
## we can run the task now:
if options["verbose"]:
write_message("Task #%d started." % task_id)
task_update_status("RUNNING")
## initialize signal handler:
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
## run the task:
if options.has_key("number"):
n = options["number"]
else:
n = cfg_n_default
if options["verbose"] >= 9:
write_message("Printing %d Fibonacci numbers." % n)
for i in range(0,n):
if i > 0 and i % 4 == 0:
if options["verbose"] >= 3:
write_message("Error: water in the CPU. Ignoring and continuing.", sys.stderr)
elif i > 0 and i % 5 == 0:
if options["verbose"]:
write_message("Error: floppy drive dropped on the floor. Ignoring and continuing.", sys.stderr)
if options["verbose"]:
write_message("fib(%d)=%d" % (i, fib(i)))
task_update_progress("Done %d out of %d." % (i,n))
time.sleep(1)
## we are done:
task_update_progress("Done %d out of %d." % (n,n))
task_update_status("DONE")
if options["verbose"]:
write_message("Task #%d finished." % task_id)
return 1
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write("Command options:\n")
sys.stderr.write(" -n, --number=NUM\t Print Fibonacci numbers for up to NUM. [default=%d]\n" % cfg_n_default)
sys.stderr.write("Scheduling options:\n")
sys.stderr.write(" -u, --user=USER \t User name to submit the task as, password needed.\n")
sys.stderr.write(" -t, --runtime=TIME \t Time to execute the task (now), e.g.: +15s, 5m, 3h, 2002-10-27 13:57:26\n")
sys.stderr.write(" -s, --sleeptime=SLEEP \t Sleeping frequency after which to repeat task (no), e.g.: 30m, 2h, 1d\n")
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.stderr.write(" -v, --verbose=LEVEL \t Verbose level (0=min, 1=default, 9=max).\n")
sys.exit(exitcode)
def main():
"""Main function that analyzes command line input and calls whatever is appropriate.
Useful for learning on how to write BibSched tasks."""
global task_id, options
## parse command line:
if len(sys.argv) == 2 and sys.argv[1].isdigit():
## A - run the task
task_id = int(sys.argv[1])
try:
if not task_run():
write_message("Error occurred. Exiting.", sys.stderr)
except StandardError, e:
write_message("Unexpected error occurred: %s." % e, sys.stderr)
write_message("Traceback is:", sys.stderr)
traceback.print_tb(sys.exc_info()[2])
write_message("Exiting.", sys.stderr)
task_update_status("ERROR")
else:
## B - submit the task
# set default values:
options = {}
options["runtime"] = time.strftime("%Y-%m-%d %H:%M:%S")
options["sleeptime"] = ""
options["verbose"] = 1
# set user-defined options:
try:
opts, args = getopt.getopt(sys.argv[1:], "hVv:n:u:s:t:", ["help", "version", "verbose=","number=","user=","sleep=","time="])
except getopt.GetoptError, err:
usage(1, err)
try:
for opt in opts:
if opt[0] in ["-h", "--help"]:
usage(0)
elif opt[0] in ["-V", "--version"]:
print __version__
sys.exit(0)
elif opt[0] in [ "-u", "--user"]:
options["user"] = opt[1]
elif opt[0] in ["-v", "--verbose"]:
options["verbose"] = int(opt[1])
elif opt[0] in ["-n", "--number"]:
options["number"]=int(opt[1])
elif opt[0] in [ "-s", "--sleeptime" ]:
get_datetime(opt[1]) # see if it is a valid shift
options["sleeptime"] = opt[1]
elif opt[0] in [ "-t", "--runtime" ]:
options["runtime"] = get_datetime(opt[1])
else:
usage(1)
except StandardError, e:
usage(e)
task_submit(options)
return
### okay, here we go:
if __name__ == '__main__':
main()
diff --git a/modules/bibsched/doc/Makefile.am b/modules/bibsched/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibsched/doc/Makefile.am
+++ b/modules/bibsched/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibsched/doc/admin/Makefile.am b/modules/bibsched/doc/admin/Makefile.am
index 137c6fe9b..738cfb415 100644
--- a/modules/bibsched/doc/admin/Makefile.am
+++ b/modules/bibsched/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/bibsched
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibsched/doc/admin/guide.html.wml b/modules/bibsched/doc/admin/guide.html.wml
index cf6d22e4b..0bf9d5ccd 100644
--- a/modules/bibsched/doc/admin/guide.html.wml
+++ b/modules/bibsched/doc/admin/guide.html.wml
@@ -1,69 +1,69 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibSched Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibsched/>BibSched Admin</a>" \
navbar_name="admin" \
navbar_select="bibsched-admin-guide"
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
WARNING: THIS ADMIN GUIDE IS NOT FULLY COMPLETED
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
This Admin Guide is not yet completed. If you are interested
in seeing some specific things implemented with high priority,
please contact us at <SUPPORTEMAIL>. Thanks for your interest!
</td>
</tr>
</tbody>
</table>
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Overview</h2>
<p>BibSched -- the bibliographic task scheduler -- is central unit of the
system that allows all other modules to access the bibliographic
database in a controlled manner, preventing sharing violation threats
and assuring the coherent execution of the database update tasks. The
module comes with an administrative interface that allows to monitor
the task queue including various possibilities of a manual
intervention, for example to re-schedule queued tasks, change the task
order, etc.
You can run the administrative interface by doing:
<blockquote>
<pre>
$ bibsched
</pre>
</blockquote>
The <code>bibsched</code> can run in two modes: auto and manual. In
the auto mode, it will execute tasks automatically as they arrive in
the waiting queue. In the manual mode, the administrator has to
launch the tasks manually.
diff --git a/modules/bibsched/doc/admin/index.html.wml b/modules/bibsched/doc/admin/index.html.wml
index 4988242cc..c43dcb72a 100644
--- a/modules/bibsched/doc/admin/index.html.wml
+++ b/modules/bibsched/doc/admin/index.html.wml
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibSched Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibsched"
<p>
This is the gate to the admin area for BibSched. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/bibsched/">login</a> to enter.
</p>
<dl>
<dt><a href="guide.html">BibSched Admin Guide</a></dt>
<dd>Everything you want to know about BibSched administration</dd>
</dl>
diff --git a/modules/bibupload/Makefile.am b/modules/bibupload/Makefile.am
index 9d87b6024..8e90d98da 100644
--- a/modules/bibupload/Makefile.am
+++ b/modules/bibupload/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc
CLEANFILES = *~
diff --git a/modules/bibupload/bin/Makefile.am b/modules/bibupload/bin/Makefile.am
index 1fedd63be..ab86da094 100644
--- a/modules/bibupload/bin/Makefile.am
+++ b/modules/bibupload/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = bibupload
EXTRA_DIST = bibupload.in
CLEANFILES = *~ *.tmp
diff --git a/modules/bibupload/bin/bibupload.in b/modules/bibupload/bin/bibupload.in
index ad081b83a..3fe43f02f 100644
--- a/modules/bibupload/bin/bibupload.in
+++ b/modules/bibupload/bin/bibupload.in
@@ -1,1694 +1,1694 @@
#!@PHP@ -q
<?
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
$mysql_dbname = "@DBNAME@";
$mysql_machine = "@DBHOST@";
$mysql_docid = "@DBUSER@";
$mysql_docpw = "@DBPASS@";
$__version__ = '$Id$';
##########################################################################
# file: bibupload
# created by: T. Baron
# revision: $Id$
# parameters: Usage: bibupload [options] file1.xml [file2.xml ...]
# Options:
# -h, --help print this help
# -d, --display display records analysis - no integration
# -b, --database display integration requests - integration
# -m, --mute Silent mode.
# description: this program takes file(s) written in XML following
# the DTD used in the LoC MARC XML. For each record found,
# the program decides whether it is an upload or a
# correction (sysno existence, report number existence).
# Then each field is created or corrected.
# The process is based on three classes: record, field and
# subfield.
#
##########################################################################
// first test if pcntl is loaded
if (!extension_loaded('pcntl')) {
print "error... pcntl php module needed for running bibupload. Check your php installation";
exit();
}
// then test if mysql is loaded
if (!extension_loaded('mysql')) {
print "error... mysql php module needed for running bibupload. Check your php installation";
exit();
}
// time limit for script execution
set_time_limit(86340);
$prefix = "@prefix@";
$exec_prefix="@exec_prefix@";
$libdir = "@libdir@";
include("${libdir}/php/cdsware/errors/errorHandling.php");
// array of all the "untouchable" field tags
$strongtags = array("");
//////////////////////////////////////////////////////////////////////
// BIBSCHED FUNCTIONS
// These functions allow bibupload to run in the framework of
// the CDS scheduler
//////////////////////////////////////////////////////////////////////
function task_submit()
{
// This function submits the task to bibsched task queue
// This is what users will be invoking via command line.
global $options,$errorfp;
// To be sure no task is set
if ($options['TASKRUN']) {
$options['TASKRUN'] = FALSE;
}
if ($options['DATE'] == "")
$date = "NOW()";
else
$date = "'".$options['DATE']."'";
$cwd = getcwd();
$totalrecs = 0;
$fullrecordfiles = array();
chdir("/");
foreach ($options['recordfiles'] as $originalrecordfile) {
$recordfile = $originalrecordfile;
if (!file_exists("$recordfile"))
$recordfile = $cwd."/$recordfile";
if (!file_exists("$recordfile")) {
fwrite($errorfp,"Error: Cannot find file $recordfile.\n");
exit(1);
}
array_push($fullrecordfiles,$recordfile);
$totalrecs += trim(`grep -a "<record" $recordfile | wc -l`);
}
$options['recordfiles'] = $fullrecordfiles;
// submit task
$query = "INSERT INTO schTASK (id,proc,user,runtime,arguments,status,progress)
VALUES (NULL,'bibupload','".$options['USER']."',$date,'".mysql_escape_string(serialize($options))."','WAITING','Done 0 out of $totalrecs')";
$res = mysql_perform_query($query);
$taskid = mysql_insert_id();
print "Task #$taskid submitted.";
}
function task_sig_sleep($signo)
{
// Signal handler for the 'sleep' signal sent by BibSched.
global $sleepstate;
if ($sleepstate == "") {
// we leave the current integration finish
print " [going to sleep...] ";
task_update_state("GOING TO SLEEP");
$sleepstate = $signo;
}
else {
print " [sleeping...] ";
task_update_state("SLEEPING");
while ($sleepstate) {
usleep(10);
}
}
}
function task_sig_wakeup($signo)
{
//Signal handler for the 'wakeup' signal sent by BibSched.
global $sleepstate;
$sleepstate = 0;
print " [continuing...] ";
task_update_state("CONTINUING");
}
function task_sig_stop($signo)
{
global $stopstate;
//Signal handler for the 'stop' signal sent by BibSched.
if ($stopstate == "") {
// we leave the current integration finish
print " [stopping...] ";
task_update_state("STOPPING");
$stopstate = $signo;
}
else {
// then really quit
print " [stopped...] ";
task_update_state("STOPPED");
mysql_close();
exit(0);
}
}
function task_sig_suicide($signo)
{
//Signal handler for the 'suicide' signal sent by BibSched.
print " [suiciding myself now...] ";
task_update_state("SUICIDING");
print " [suicided] ";
task_update_state("SUICIDED");
exit(0);
}
function task_sig_unknown($signo)
{
//Signal handler for the other unknown signals sent by shell or user.
print " [unknown signal $signo ignored] "; // do nothing
}
function task_update_progress($msg)
{
//Updates progress information in the BibSched task table.
global $options;
$query = "UPDATE schTASK SET progress='".mysql_escape_string($msg)."' where id=".$options['TASKRUN'];
mysql_perform_query($query);
}
function task_update_state($val)
{
//Updates state information in the BibSched task table.
global $options;
$query = "UPDATE schTASK SET status='".mysql_escape_string($val)."' where id=".$options['TASKRUN'];
mysql_perform_query($query);
}
function task_get_state()
{
//Retrieve state information in the BibSched task table.
global $options;
$query = "SELECT status from schTASK WHERE id=".$options['TASKRUN'];
$res = mysql_perform_query($query);
$row = mysql_fetch_row($res);
return $row[0];
}
function task_get_progress()
{
//Retrieve state information in the BibSched task table.
global $options;
$query = "SELECT progress from schTASK WHERE id=".$options['TASKRUN'];
$res = mysql_perform_query($query);
$row = mysql_fetch_row($res);
$progress = ereg_replace("Done (.*) out of .*","\\1",$row[0]);
return $progress;
}
function task_get_options($id)
{
//Returns options for the task 'id' read from the BibSched task
//queue table.
global $errorfp;
$out = array();
$query = "SELECT arguments FROM schTASK WHERE id=$id AND proc='bibupload'";
$res = mysql_perform_query($query);
$row = mysql_fetch_row($res);
if ($row) {
$out = unserialize($row[0]);
}
else{
fwrite($errorfp,"Error: BibUpload task #$id does not seem to exist.\n");
exit(1);
}
return $out;
}
//////////////////////////////////////////////////////////////////////
// STRUCTURE CLASSES
// A MARC XML record is composed of some data fields elements which
// may in turn contain subfields.
// A record starts with "<record>" and ends with "</record>
//////////////////////////////////////////////////////////////////////
class subfield {
// this class stores the subfield items
var $subfieldcode; // type
var $value; // value
var $position; // position
// constructor
function subfield($param1=null, $param2=null, $param3=null) {
global $currentfield;
global $errorfp;
$numargs = func_num_args();
$arg_list = func_get_args();
$args = "";
for ($i=0; $i<$numargs; $i++) {
if ($i != 0) {
$args .= ", ";
}
$args .= "\$param" . ($i + 1);
}
// Call constructor function
eval("\$this->constructor" . $i . "(" . $args . ");");
}
function constructor1($number)
{
global $currentfield;
global $errorfp;
global $validrec;
$this->position = $number;
$this->subfieldcode = $currentfield[attributes][CODE];
if ($this->subfieldcode == "")
$this->subfieldcode == "_";
if ($currentfield[type] == "complete")
$this->value = $currentfield[value];
else
{
// get cdata
getnexttag();
if ($currentfield[tag]=="SUBFIELD" && $currentfield[type] == "cdata")
{
$this->value = $currentfield[value];
getnexttag();
}
//close tag
if ($currentfield[tag]!="SUBFIELD" || $currentfield[type] != "close")
{
fwrite($errorfp,"subfield: ERROR! Bad XML file!\n");
$validrec = false;
}
getnexttag();
}
}
function constructor3($subfieldcode,$value,$position) {
$this->position = $position;
$this->subfieldcode = $subfieldcode;
$this->value = $value;
}
}
class field {
// this class stores the field items
var $type; // type (tag)
var $i1; // indicator 1
var $i2; // indicator 2
var $value;
var $subfields;
var $nbsubfields;
var $position;
// constructor
function field($param1=null, $param2=null, $param3=null, $param4=null, $param5=null, $param6=null) {
global $currentfield;
$numargs = func_num_args();
$arg_list = func_get_args();
$args = "";
for ($i=0; $i<$numargs; $i++) {
if ($i != 0) {
$args .= ", ";
}
$args .= "\$param" . ($i + 1);
}
// Call constructor function
eval("\$this->constructor" . $i . "(" . $args . ");");
}
function constructor1($nbfield)
{
global $currentfield;
$this->position = $nbfield;
$this->type = $currentfield[attributes][TAG];
$this->i1 = strtoupper($currentfield[attributes][IND1]);
$this->i2 = strtoupper($currentfield[attributes][IND2]);
if (ereg_replace("[ \n\r\t]+","",$this->i1) == "") { $this->i1 = "_"; }
if (ereg_replace("[ \n\r\t]+","",$this->i2) == "") { $this->i2 = "_"; }
$this->nbsubfields = 0;
if ($currentfield[type] == "complete")
{
$this->value = $currentfield[value];
getnexttag();
}
else
{
getnexttag();
while (($currentfield[tag] == "SUBFIELD" ||
($currentfield[tag] == "CONTROLFIELD" &&
$currentfield[type] == "cdata") ||
($currentfield[tag] == "DATAFIELD" &&
$currentfield[type] == "cdata")))
{
if (($currentfield[tag] == "CONTROLFIELD" &&
$currentfield[type] == "cdata") ||
($currentfield[tag] == "DATAFIELD" &&
$currentfield[type] == "cdata"))
$this->value = $currentfield[value];
else
{
$this->subfields[$this->nbsubfields] = new subfield(
$this->nbsubfields);
$this->nbsubfields ++;
}
getnexttag();
}
}
}
function constructor6($position,$type,$i1,$i2,$subfieldcode,$value) {
$this->position = $position;
$this->type = $type;
$this->i1 = $i1;
$this->i2 = $i2;
$this->nbsubfields = 1;
$this->subfields[0] = new subfield($subfieldcode,$value,0);
}
function get_subfield($subfieldcode)
{
$subfieldcode = strtolower($subfieldcode);
$j=0;
while (strtolower($this->subfields[$j]->subfieldcode) != "$subfieldcode"
&& $j <= $this->nbsubfields)
$j++;
if ($j == $this->nbsubfields)
return 0;
else
return $this->subfields[$j]->value;
}
}
class record {
// this class stores the record items
var $fields; // contains all fields
var $recid; // system number: 000 if new
var $nbfields; // number of fields
// Constructor
function record()
{
global $currentfield;
global $errorfp;
global $validrec;
$this->nbfields = 0;
getnexttag();
while ( $currentfield[tag] != "CONTROLFIELD"
&& $currentfield[tag] != "DATAFIELD"
&& $currentfield != NULL) {
getnexttag();
}
while ($currentfield[tag] == "CONTROLFIELD" || $currentfield[tag] == "DATAFIELD")
{
// If system number
if ($currentfield[attributes][TAG] == "001")
{
$this->recid = $currentfield[value];
getnexttag();
if ($this->recid == "")
$this->recid = "000";
}
else if ($currentfield[type] != "close")
{
$this->fields[$this->nbfields] = new field($this->nbfields);
$this->nbfields ++;
}
else if ($currentfield[type] == "close")
getnexttag();
else
{
fwrite($errorfp,"field: ERROR! Bad XML file!\n");
$validrec = false;
}
}
if ($this->recid == "")
$this->recid = "000";
}
function get_field($tag,$i1,$i2)
{
$j=0;
while ((($this->fields[$j]->type != "$tag") ||
($this->fields[$j]->i1 != "$i1") ||
($this->fields[$j]->i2 != "$i2")) && ($j <= ($this->nbfields)))
$j++;
if ($j == $this->nbfields)
return 0;
else
return $this->fields[$j];
}
function get_subfield($tag,$i1,$i2,$subfieldcode)
{
global $errorfp;
$i1 = strtolower($i1);
$i2 = strtolower($i2);
$subfieldcode = strtolower($subfieldcode);
$tag = strtolower($tag);
$j=0;
$found = 0;
while (!$found && ($j <= $this->nbfields))
{
if ($this->fields[$j] &&
strtolower($this->fields[$j]->type) == "$tag" &&
strtolower($this->fields[$j]->i1) == "$i1" &&
strtolower($this->fields[$j]->i2) == "$i2")
{
if ($this->fields[$j]->get_subfield($subfieldcode)) {
$found = $this->fields[$j]->get_subfield($subfieldcode);
}
}
$j++;
}
return $found;
}
}
//////////////////////////////////////////////////////////////////////
// TREATMENT FUNCTIONS
//////////////////////////////////////////////////////////////////////
// from an array passed as parameter, this function returns a
// comma-separated list of all elements in the array
function createTextFromArray($array)
{
reset($array);
$text = "(''";
while (list($key,$value) = each($array)) {
$text .= ",'".$value."'";
}
$text .= ")";
return $text;
}
// This function gets the next available field number for
// a given table name, and a given record id
function getNextFieldNumber($tablename,$recid)
{
global $maxfieldno,$options;
if ($maxfieldno[$tablename] != "") {
$maxfieldno[$tablename] = $maxfieldno[$tablename] + 1;
$field_number = $maxfieldno[$tablename];
}
else {
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT MAX(field_number)
FROM bibrec_$tablename
WHERE id_bibrec=$recid");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select MAX(field_number) from ".
"bibrec_$tablename where id_bibrec=$recid\n";
$row = mysql_fetch_row($res);
$maxfieldno[$tablename] = $row[0]+1;
$field_number = $maxfieldno[$tablename];
}
return $field_number;
}
function mysql_perform_query($query, $behaviour="continue") {
global $errorfp, $sock, $mysql_machine, $mysql_docid, $mysql_docpw, $mysql_dbname;
// connect to mysql
$sock = @mysql_connect("${mysql_machine}","${mysql_docid}","${mysql_docpw}");
while (!$sock) {
sleep(1);
$sock = @mysql_connect("${mysql_machine}","${mysql_docid}","${mysql_docpw}");
mysql_select_db("${mysql_dbname}") or die("Sorry, cannot choose ".${mysql_dbname}." database. Please try later.\n");
}
$result = mysql_query($query);
if (!$result) {
fwrite($errorfp, "\nMySQL: could not execute your query:\n $query" .
"\nError " . mysql_errno() . ": " . mysql_error() . ".\n");
if ($behaviour == "die"){
exit(0);
}
}
return $result;
}
function getnexttag()
{
global $i; // current position in the structure
global $index; // structure containing the XML
global $currentfield;
global $nbTags;
// this function retrieves the next valuable field (one of "record"
// "controlfield", "datafield" or "subfield")
//get next tag
$i++;
while ($index[$i][tag] != "RECORD" &&
$index[$i][tag] != "CONTROLFIELD" &&
$index[$i][tag] != "DATAFIELD" &&
$index[$i][tag] != "SUBFIELD" && $i <= $nbTags)
$i++;
if ($i <= $nbTags)
$currentfield = $index[$i];
else
$currentfield = NULL;
}
function Test_In_DB($value,$tag,$table)
{
global $options, $mysql_dbname;
$value = ereg_replace("^[\n\r\t ]*","",$value);
$value = ereg_replace("[\r\n\t ]* $","",$value);
$value = mysql_escape_string($value);
mysql_select_db($mysql_dbname);
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT id,value
FROM $table
WHERE value='$value' and
tag='$tag'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select id from $table where value='$value' and".
" tag='$tag'\n";
while ($arr = mysql_fetch_row($res))
{
if ($arr[1] == "$value") {
$t1 = getmicrotime();
$res2 = mysql_perform_query("
SELECT id_bibrec
FROM bibrec_".$table."
WHERE id_bibxxx=".$arr[0]);
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select id_bibrec from bibrec_".$table.
" where id_bibxxx=".$arr[0]."\n";
$result = mysql_fetch_row($res2);
return $result[0];
}
}
return 0;
}
function insert($rec,$logfp)
{
global $WORDFILEJOB,$options;
//create the bibrec
$now = strftime("%Y-%m-%d %H:%M:%S");
$cd = $now;
$md = $now;
$t1 = getmicrotime();
mysql_perform_query("
INSERT
INTO bibrec (creation_date,modification_date)
values('$cd','$md')");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." insert into bibrec (creation_date,modification_date)".
" values('$cd','$md')\n";
#get the created item id
$recid = mysql_insert_id();
#for each field
$nbfields = $rec->nbfields;
for ($j=0;$j<$nbfields;$j++)
{
if ($rec->fields[$j])
{
$position = $j + 1;
$field = $rec->fields[$j];
$tag = $field->type;
$i1 = $field->i1;
$i2 = $field->i2;
$tablenumber = substr($tag,0,2);
$tablename = "bib" . $tablenumber . "x";
// special treatment for the format field
if ($tag == "FMT")
{
if ($field->subfields[1]->value != "")
{
$format = $field->subfields[0]->value;
$value = mysql_escape_string(gzcompress($field->subfields[1]->value));
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT id
FROM bibfmt
WHERE id_bibrec=$recid and
format='$format'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select id from bibfmt where".
" id_bibrec=$recid and format='$format'\n";
if (mysql_num_rows($res) != 0)
{
$t1 = getmicrotime();
mysql_perform_query("
UPDATE bibfmt
SET format='$format',
value='$value',
last_updated=NOW()
WHERE id_bibrec=$recid and
format='$format'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." update bibfmt set format='$format',".
"value='$value', last_updated=NOW()".
" where id_bibrec=$recid and format='$format'\n";
}
else
{
$t1 = getmicrotime();
mysql_perform_query("
INSERT
INTO bibfmt(id_bibrec,format,value,last_updated)
values ($recid,'$format','$value',NOW())");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." insert into bibfmt(id_bibrec,format,".
"value, last_updated)values($recid,'$format','$value'," .
"NOW())\n";
}
}
else
{
$format = $field->subfields[0]->value;
$t1 = getmicrotime();
mysql_perform_query("
DELETE
FROM bibfmt
WHERE id_bibrec=$recid and
format='$format'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." delete from bibfmt where id_bibrec=$recid".
" and format='$format'\n";
}
}
// we do not want field 001 to be integrated
elseif ($tag != "001")
{
#main value
if ($field->value != "")
{
$fulltag = "$tag${i1}${i2}_";
$value = mysql_escape_string($field->value);
insertfield($fulltag,$value,$tablename,$recid,$position,$logfp);
}
#sub fields
$nbsubfields = $field->nbsubfields;
for ($k=0;$k<$nbsubfields;$k++)
{
$subfield = $field->subfields[$k];
$subfieldcode = $subfield->subfieldcode;
if ($subfield->value != "")
{
$fulltag = "$tag$i1$i2$subfieldcode";
$value = mysql_escape_string($subfield->value);
insertfield($fulltag,$value,$tablename,$recid,$position,$logfp);
}
}
}
}
}
// insert xml full format
insertFMTfield($recid,$rec);
if (!$options['MUTE']) {
print "inserted. [$recid]\n";
}
}
function deletefield($recid,$fulltag,$tablename,$logfp)
{
global $strongtags,$options,$mysql_server_version;
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT DISTINCT field_number
FROM bibrec_$tablename,
$tablename
WHERE id_bibxxx = id and
id_bibrec=$recid and
tag LIKE '$fulltag'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select DISTINCT field_number from bibrec_$tablename,$tablename".
" where id_bibxxx = id and id_bibrec=$recid and tag LIKE '$fulltag'\n";
while ($row = mysql_fetch_row($res)) {
// delete main value + subfields
$t1 = getmicrotime();
if (strcmp($mysql_server_version, "4.0") < 0) {
$res2 = mysql_perform_query("
SELECT id_bibxxx
FROM bibrec_$tablename,
$tablename
WHERE id_bibrec=$recid and
field_number=$row[0] and
id_bibxxx=id and
tag NOT IN ".createTextFromArray($strongtags));
while ($row2 = mysql_fetch_row($res2)) {
mysql_perform_query("
DELETE
FROM bibrec_$tablename
WHERE id_bibrec=$recid and
id_bibxxx=$row2[0] and
field_number = $row[0]");
}
} else {
mysql_perform_query("
DELETE
FROM bibrec_$tablename
USING bibrec_$tablename,
$tablename
WHERE id_bibrec=$recid and
field_number=$row[0] and
id_bibxxx=id and
tag NOT IN ".createTextFromArray($strongtags));
}
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." delete from bibrec_$tablename using bibrec_$tablename, ".
" $tablename where id_bibrec=$recid and field_number=$row[0] and ".
"id_bibxxx=id and tag NOT IN ".createTextFromArray($strongtags)."\n";
}
}
function update($rec,$recid,$logfp)
{
global $WORDFILEJOB,$strongtags,$options,$maxfieldno;
global $errorfp;
$now = strftime("%Y-%m-%d %H:%M:%S");
$md = $now;
// firstly check whether this 'id' exists in the bibrec table:
$res = mysql_perform_query("SELECT COUNT(*) FROM bibrec WHERE id=$recid\n");
$row = mysql_fetch_row($res);
if ($row[0] == 0) {
if (!$options['MUTE']) {
fwrite($errorfp,"update error. [record $recid does not exist]\n");
}
return;
}
mysql_free_result($res);
// update the modification datetime field
// if we don't have only FMT fields inside the record
$onlyFMT = true;
for ($j=0;$j<$rec->nbfields;$j++) {
if ($rec->fields[$j] && $rec->fields[$j]->type != "FMT") {
$onlyFMT = false;
}
}
if (!$onlyFMT && !$options['FORMAT'] && !$options['NOTIMECHANGE']) {
$t1 = getmicrotime();
mysql_perform_query("
UPDATE bibrec
SET modification_date='$md'
WHERE id=$recid\n");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." update bibrec set modification_date='$md',".
" where id=$recid\n";
}
if ($options['HBFMTUPDATE']) {
mysql_perform_query("
UPDATE bibfmt
SET last_updated='1970-01-01 00:00:00'
WHERE id_bibrec=$recid and
format='hb'\n");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." update bibfmt set last_updated='1970-01-01 00:00:00',".
" where id_bibrec=$recid and format='hb'\n";
}
// then if this is a replace, we retrieve the existing 964__a field (holdings) and adds it to the record
if($options['REPLACE'] && !$onlyFMT) {
$sql = "
SELECT id,value
FROM bib96x,
bibrec_bib96x
WHERE id=id_bibxxx and
id_bibrec=$recid and
tag='964__a'
LIMIT 1";
$res = mysql_perform_query($sql);
if ($row = mysql_fetch_row($res)) {
$value = $row[1];
$rec->fields[$rec->nbfields] = new field($rec->nbfields,"964","_","_","a",$value);
$rec->nbfields ++;
}
}
$nbfields = $rec->nbfields;
if ($options['CORRECT']) {
// delete each found field
for ($j=0;$j<$nbfields;$j++) {
$field = $rec->fields[$j];
$tag = $field->type;
$i1 = $field->i1;
$i2 = $field->i2;
$tablenumber = substr($tag,0,2);
$tablename = "bib" . $tablenumber . "x";
$nbsubfields = $field->nbsubfields;
for ($k=0;$k<$nbsubfields;$k++) {
$subfield = $field->subfields[$k];
$subfieldcode = $subfield->subfieldcode;
$fulltag = "$tag$i1$i2$subfieldcode";
if ($tag != "FMT") {
if (!$options['REF'] || $tag == "999")
deletefield($recid,$fulltag,$tablename,$logfp);
}
}
}
// delete the xml format
deletexmformat($recid);
}
if ($options['APPEND']) {
// delete the xml format
deletexmformat($recid);
}
if($options['REPLACE'] && !$onlyFMT) {
for ($i=0;$i<100;$i++) {
deletefield($recid,"%","bib".($i<10 ? "0$i" : "$i")."x",$logfp);
}
}
// insert each found field
for ($j=0;$j<$nbfields;$j++) {
if ($rec->fields[$j]) {
$fieldnumber = -1;
$field = $rec->fields[$j];
$tag = $field->type;
$i1 = $field->i1;
$i2 = $field->i2;
$tablenumber = substr($tag,0,2);
$tablename = "bib" . $tablenumber . "x";
$fulltag = "$tag$i1${i2}_";
if ($tag == "FMT") {
if ($field->subfields[1]->value != "") {
$format = $field->subfields[0]->value;
$value = mysql_escape_string(gzcompress($field->subfields[1]->value));
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT id
FROM bibfmt
WHERE id_bibrec=$recid and
format='$format'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select id from bibfmt where ".
"id_bibrec=$recid and format='$format'\n";
if (mysql_num_rows($res) != 0) {
$t1 = getmicrotime();
mysql_perform_query("
UPDATE bibfmt
SET format='$format',
value='$value',
last_updated=NOW()
WHERE id_bibrec=$recid and
format='$format'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." update bibfmt set format='$format',".
"value='$value', last_updated=NOW()".
" where id_bibrec=$recid and format='$format'\n";
}
else {
$t1 = getmicrotime();
mysql_perform_query("
INSERT
INTO bibfmt(id_bibrec,format,value,last_updated)
values($recid,'$format','$value',NOW())");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." insert into bibfmt(id_bibrec,format,".
"value, last_updated)values($recid,'$format','$value', NOW())\n";
}
}
else {
$format = $field->subfields[0]->value;
$t1 = getmicrotime();
$res = mysql_perform_query("
DELETE
FROM bibfmt
WHERE id_bibrec=$recid and
format='$format'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." delete from bibfmt where id_bibrec=$recid".
" and format='$format'\n";
}
}
else if (!$options['FORMAT']) {
if (!$options['REF'] || $tag=="999") {
// main value
if ($field->value != "") {
$fieldnumber = getNextFieldNumber($tablename,$recid);
$value = mysql_escape_string($field->value);
insertfield($fulltag,$value,$tablename,$recid,
$fieldnumber,$logfp);
}
// sub fields
$nbsubfields = $field->nbsubfields;
for ($k=0;$k<$nbsubfields;$k++) {
$subfield = $field->subfields[$k];
$subfieldcode = $subfield->subfieldcode;
$fulltag = "$tag$i1$i2$subfieldcode";
if ($subfield->value != "") { // got rid of and !in_array($fulltag,$strongtags)
if ($fieldnumber == "-1")
$fieldnumber = getNextFieldNumber($tablename,$recid);
$value = mysql_escape_string($subfield->value);
insertfield($fulltag,$value,$tablename,$recid,
$fieldnumber,$logfp);
}
}
}
}
}
}
if($options['REPLACE'] && !$onlyFMT) {
// insert xml full format
insertFMTfield($recid,$rec);
}
if (!$options['MUTE']) {
print "updated. [$recid]\n";
}
}
function deletexmformat($recid)
{
$res = mysql_perform_query("delete from bibfmt where id_bibrec=$recid and format='xm'");
}
function insertFMTfield($recid,$rec)
{
global $xml,$options;
$field964 = $rec->get_field("964","_","_");
if ($field964 != 0) {
$value964 = $field964->get_subfield("a");
$xml = ereg_replace("<record([^>]*)>","<record\\1>
<datafield tag=\"964\" ind1=\"\" ind2=\"\">
<subfield code=\"a\">$value964</subfield>
</datafield>",$xml);
}
if ($recid != "000" && $recid != "") {
// get rid of existing 001
$xml = ereg_replace("<controlfield tag=\"001\">[^<]*</controlfield>\n","",$xml);
// add sysno to xml record
$xml = ereg_replace("<record([^>]*)>","<record\\1>
<controlfield tag=\"001\">$recid</controlfield>",$xml);
}
$format = "xm";
$value = mysql_escape_string(gzcompress($xml));
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT id
FROM bibfmt
WHERE id_bibrec=$recid and
format='xm'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select id from bibfmt where ".
"id_bibrec=$recid and format='xm'\n";
if (mysql_num_rows($res) != 0) {
$t1 = getmicrotime();
mysql_perform_query("
UPDATE bibfmt
SET format='xm',
value='$value',
last_updated=NOW()
WHERE id_bibrec=$recid and
format='xm'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." update bibfmt set format='xm',".
"value='$value', last_updated=NOW() where id_bibrec=$recid and ".
"format='xm'\n";
}
else {
$t1 = getmicrotime();
mysql_perform_query("
INSERT
INTO bibfmt(id_bibrec,format,value,last_updated)
values($recid,'xm','$value',NOW())");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." insert into bibfmt(id_bibrec,format,".
"value,last_updated)values($recid,'xm','$value',NOW())\n";
}
}
function insertfield($fulltag,$value,$tablename,$recid,$position,$logfp)
{
global $options,$errorfp;
$t1 = getmicrotime();
$res = mysql_perform_query("
SELECT id,value
FROM $tablename
WHERE tag='$fulltag' and
value='$value'");
$t2 = getmicrotime();
if ($options['PRINTDB'])
print ($t2-$t1)." select id from $tablename where tag='$fulltag' and".
" value='$value'\n";
if (!$res)
fwrite($errorfp, "failed query: select id from $tablename where tag='$fulltag' ".
"and value='$value'\n");
# if an entry already exists with this couple tag/value
$found = false;
while (!$found && $row = mysql_fetch_row($res)) {
if ($row[1] == "$value") {
$found = true;
$idbibxxx = $row[0];
}
}
if (!$found)
{
#create
$t1 = getmicrotime();
$query = "INSERT INTO $tablename (tag,value) VALUES ('$fulltag','$value')";
if ($options['PRINTDB'])
print "Query: $query ... \n";
mysql_perform_query($query);
$t2 = getmicrotime();
if ($options['PRINTDB'])
print " Query took: ".($t2-$t1)." seconds.\n";
#get the id back
$idbibxxx = mysql_insert_id();
}
#then create the bibrec_bibxxx entry with position number
$t1 = getmicrotime();
$query = "INSERT INTO bibrec_$tablename VALUES ($recid,$idbibxxx,$position)";
if ($options['PRINTDB'])
print "Query: $query ...\n";
mysql_perform_query($query);
$t2 = getmicrotime();
if ($options['PRINTDB'])
print " Query took: ".($t2-$t1)." seconds.\n";
}
function display($rec)
{
global $nbRecords,$options;
#for each field
$nbfields = $rec->nbfields;
print "\n\nRecord $nbRecords: $nbfields fields\n";
for ($j=0;$j<=$nbfields;$j++)
{
if ($rec->fields[$j])
{
$field = $rec->fields[$j];
$tag = $field->type;
$i1 = $field->i1;
$i2 = $field->i2;
$tablenumber = substr($tag,0,2);
$tablename = "bib" . $tablenumber . "x";
print "field $j: $tag$i1$i2\n";
#main value
if ($field->value != "")
{
$fulltag = "$tag${i1}${i2}_";
$value = $field->value;
print " main value: $value\n";
}
#sub fields
$nbsubfields = $field->nbsubfields;
if ($nbsubfields != 0)
{
for ($k=0;$k<$nbsubfields;$k++)
{
$subfield = $field->subfields[$k];
$subfieldcode = $subfield->subfieldcode;
print " subfield $k: ($subfieldcode) " .
$subfield->value . "\n";
}
}
}
}
}
function integrate ($rec)
{
global $nbRecords, $nbUpdatedRecords, $nbInsertedRecords, $nbErrorRecords, $xml, $options;
global $errorfp;
// get sysno
$recid = $rec->recid;
// display record name
if (!$options['MUTE']) {
print ("Record #".($nbRecords+1)." ");
}
// no record matching the main criteria was found
if ($recid == "000") {
// test on A500 system number
$oldsysno = $rec->get_subfield("970","_","_","a");
// Aleph500 imports for CERN must be done on uppercase keys
if ($CFG_CERN_SITE) {
$oldsysno = strtoupper($oldsysno);
}
$oldsysnoExists = Test_In_DB($oldsysno,"970__a","bib97x");
if ($oldsysnoExists)
$recid = $oldsysnoExists;
// if still not found and options['REF'] is found, we check against
// the 037 tag
if ($recid == "000" && $options['REF']) {
$myfield = $rec->get_subfield("037","_","_","a");
$myfieldExists = Test_In_DB($myfield,"037__a","bib03x");
if (!$myfieldExists)
$myfieldExists = Test_In_DB($myfield,"088__a","bib08x");
if (!$myfieldExists)
$myfieldExists = Test_In_DB($myfield,"088__9","bib08x");
if ($myfieldExists)
$recid = $myfieldExists;
}
if ($recid != "000") {
// a record matching the additional criteria was found
if ($options['DISPLAY'])
display($rec);
if ($options['REPLACE'] || $options['CORRECT'] || $options['APPEND']) {
update($rec,$recid,$logfp);
$nbUpdatedRecords++;
}
}
else {
// no matching record was found
if ($options['DISPLAY'])
display($rec);
if (!$options['FORMAT']) {
if (!$options['INSERT']) {
fwrite($errorfp,"Error: Cannot update record. Record not found\n");
fwrite($errorfp,$xml."\n");
$nbErrorRecords++;
print (" [Error]\n");
}
else {
insert($rec,$logfp);
$nbInsertedRecords++;
}
}
}
}
else {
// this is an update
if ($options['DISPLAY'])
display($rec);
if ($options['REPLACE'] || $options['CORRECT'] || $options['APPEND'] || $options['FORMAT']) {
update($rec,$recid,$logfp);
$nbUpdatedRecords++;
}
}
}
function get_next_record($fp)
{
global $options;
static $line = ""; // needed static so as to preserve line between successive calls to get_next_record()
$xmlrecord = "";
// get begining of next record
$line = stristr($line,"</record"); // useful if there were more records in the same line
while (!stristr($line,"<record") && !feof($fp))
$line = fgets($fp, 4096);
// if the end of the file is reached without finding any record
if (feof($fp))
return "";
// get full record
$line = stristr($line,"<record"); // continue after the above "<record" match only
$xmlrecord = $line;
while (!stristr($line,"</record>") && !feof($fp))
{
$line = fgets($fp, 4096);
$xmlrecord .= ereg_replace("<record.*","",$line); // get rid of the beginning of the next record, if any
}
return $xmlrecord;
}
function getmicrotime()
{
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
function formatfield($field)
{
return $field; # FIXME: the real body function below switched off since it apparently breaks UTF-8
// whatever character encoding in input, we want UTF8 in output
// to check if the file is Latin-1, we use the fact that there
// is a loss when you utf8_decode a latin-1 string
if ($field != utf8_encode(utf8_decode($field))) {
$field = utf8_encode($field);
}
return $field;
}
function parse_command($argv)
{
global $options,$errorfp;
$options['TASKRUN'] = FALSE;
$options['DISPLAY'] = FALSE;
$options['PRINTDB'] = FALSE;
$options['MUTE'] = FALSE;
$options['INSERT'] = FALSE;
$options['REPLACE'] = FALSE;
$options['APPEND'] = FALSE;
$options['CORRECT'] = FALSE;
$options['FORMAT'] = FALSE;
$options['REF'] = FALSE;
$options['NOTIMECHANGE'] = FALSE;
$options['HBFMTUPDATE'] = FALSE;
$options['USER'] = "";
$options['DATE'] = "";
$verbosity = 1;
$i = 1;
if (count($argv) < 2)
{
fwrite($errorfp, "Bad parameter count!\n");
displayhelp();
exit;
}
elseif (count($argv) == 2 && $argv[1] == strval(intval($argv[1])))
{
$options['TASKRUN'] = $argv[1];
return;
}
else
{
while (substr($argv[$i],0,1) == "-")
{
if ($argv[$i] == "-h" || $argv[$i] == "--help")
{
displayhelp();
exit;
}
if ($argv[$i] == "-V" || $argv[$i] == "--version")
{
displayversion();
exit;
}
else if ($argv[$i] == "-u" || $argv[$i] == "--user") {
$i++;
$options['USER'] = $argv[$i];
}
else if ($argv[$i] == "-t" || $argv[$i] == "--time") {
$i++;
$options['DATE'] = $argv[$i];
}
else if ($argv[$i] == "-v" || $argv[$i] == "--verbose") {
$i++;
$verbosity = $argv[$i];
}
else if ($argv[$i] == "-r" || $argv[$i] == "--replacerecord" )
$options['REPLACE'] = TRUE;
else if ($argv[$i] == "-a" || $argv[$i] == "--appendfield")
$options['APPEND'] = TRUE;
else if ($argv[$i] == "-c" || $argv[$i] == "--correctfield")
$options['CORRECT'] = TRUE;
else if ($argv[$i] == "-f" || $argv[$i] == "--format")
$options['FORMAT'] = TRUE;
else if ($argv[$i] == "-n" || $argv[$i] == "--notimechange")
$options['NOTIMECHANGE'] = TRUE;
else if ($argv[$i] == "-b" || $argv[$i] == "--brieffmtupdate")
$options['HBFMTUPDATE'] = TRUE;
else if ($argv[$i] == "-i" || $argv[$i] == "--insertrecord")
$options['INSERT'] = TRUE;
else if ($argv[$i] == "-z" || $argv[$i] == "--ref") {
$options['CORRECT'] = TRUE;
$options['REF'] = TRUE;
}
else
{
fwrite($errorfp, "Unrecognized option " . $argv[$i] . "!\n");
displayhelp();
exit;
}
$i++;
}
}
if ($verbosity == 0)
$options['MUTE'] = TRUE;
if ($verbosity > 1)
$options['DISPLAY'] = TRUE;
if ($verbosity > 2)
$options['PRINTDB'] = TRUE;
if ($options['USER'] == "")
$options['USER'] = "nobody";
if (!$options['APPEND'] && !$options['REPLACE'] && !$options['FORMAT'] && !$options['CORRECT'] && !$options['INSERT']) {
fwrite($errorfp, "\nPlease specify at least one update/insert mode!\n\n");
exit;
}
if ( $options['REPLACE'] + $options['APPEND'] + $options['CORRECT'] + $options['FORMAT'] > 1 ) {
fwrite($errorfp, "\nYou can only specify ONE update mode!\n\n");
exit;
}
if ( $options['APPEND'] + $options['CORRECT'] + $options['FORMAT'] + $options['INSERT'] > 1 ) {
fwrite($errorfp, "\nINSERT mode can only be mixed with REPLACE update mode!\n\n");
exit;
}
$options['recordfiles'] = array_slice($argv, $i);
if (!count($options['recordfiles']))
{
fwrite($errorfp, "\nMissing filename!\n\n");
displayhelp();
exit;
}
}
function displayversion()
{
global $__version__;
print $__version__."\n";
}
function displayhelp()
{
global $errorfp;
fwrite($errorfp, "Usage: bibupload [options] file1.xml [file2.xml ...]
Uploads xml records in the bibliographical database.
Bibupload first tries to match the xml record with an existing one.
o If the match succeeds and an update mode is selected, the matched record
is updated
o If the match succeeds and no update mode is selected, an error occurs
o If the match fails and an insert mode is selected, the record is added as new
o If the match fails and no insert mode is selected, an error occurs
Options:
-h, --help print this help
-V, --version print version information
-u, --user choose user
-v, --verbose verbosity level (0=mute, 1=default info msg,
2=display record analysis, 3=display integration requests,
9=max information)
-n, --notimechange
do not change record last modification date when updating
-b, --brieffmtupdate
force brief format recreation at next reformatting
(sets bibfmt hb last_update to 1970)
-t, --time sets date/time of execution (format 'yyyy-mm-dd hh:mm:ss')
INSERT Mode
-i, --insertrecord unmatched records are added as new.
this can be mixed with -r.
UPDATE Modes:
-r, --replacerecord the existing record is entirely replaced by the new one
-a, --appendfield new fields are appended to the existing record
-c, --correctfield fields are replaced by the new ones in the existing
record
-f, --format takes only the FMT fields into account. Does not update
the modification stamp either.
-z, --ref update references (update only 999 fields and check 037 field
against both 037 and 088.)
Example:
./bibupload -t '2004-10-24 05:00' -i toto.xml\n");
}
function task_run()
{
global $maxfieldno,$index,$options,$xml,$nbTags,$nbUpdatedRecords,$nbInsertedRecords,$nbErrorRecords, $nbRecords,$currentfield,$i,$stopstate,$sleepstate,$errorfp,$validrec;
// read task options:
$task_id = $options["TASKRUN"]; // remember task id
$options = array();
$options = task_get_options($task_id); // get options from BibSched task table
$options["TASKRUN"] = $task_id;
if (task_get_state() != "WAITING") {
$progress = task_get_progress();
}
else {
$progress = 0;
}
task_update_state("RUNNING");
$starttime = getmicrotime();
$vals = array();
$nbRecords = 0;
$totalrecs = 0;
foreach ($options['recordfiles'] as $recordfile) {
//open xml file
$fp = @fopen("$recordfile","r");
if (!$fp) {
fwrite($errorfp, "Error: cannot localize and/or open file $recordfile for reading.\n");
task_update_state("ERROR");
exit(1);
}
else {
$totalrecs += `grep "<record" $recordfile | wc -l`;
if (!$options['MUTE'])
print "\nInput file: $recordfile\n";
$xml = "";
$xml = get_next_record($fp);
while ($xml != "") {
$i = 0;
$validrec = true;
$xml = formatfield($xml);
// create XML structure
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($p,$xml,$index,$vals);
xml_parser_free($p);
$nbTags = count($index);
// record creation
$rec = new record();
// start insertion where the program last stopped
if ($nbRecords >= $progress) {
if ($validrec) {
integrate($rec);
}
else {
$nbErrorRecords++;
fwrite($errorfp,$xml."\n");
}
}
unset($rec);
unset($GLOBALS['maxfieldno']);
$nbRecords++;
$totalrecs = ereg_replace("[\t\n\r ]+","",$totalrecs);
if ($nbRecords > $progress) {
task_update_progress("Done ".$nbRecords." out of ".$totalrecs.".");
}
if ($stopstate) {
task_sig_stop($stopstate);
}
if ($sleepstate) {
task_sig_sleep($sleepstate);
}
$xml = get_next_record($fp);
}
fclose($fp);
}
}
if(!$options['MUTE']) {
print "\nIdentified: $nbRecords records\n";
print "Updated: $nbUpdatedRecords records\n";
print "Inserted: ".$nbInsertedRecords." records\n";
print "Errors: ".$nbErrorRecords." records\n";
$endtime = getmicrotime();
$time = $endtime - $starttime;
$meantreatment = ($nbRecords != 0 ? ($time/$nbRecords) : "-");
print "in $time seconds\n";
printf("Average record treatment time: %.2f seconds", $meantreatment);
}
if ($nbErrorRecords==0)
task_update_state("DONE");
else
task_update_state("DONE WITH ERRORS");
}
///////////////////////////////////////////////////////////////////////
// MAIN SCRIPT //
///////////////////////////////////////////////////////////////////////
$errorfp = fopen("php://stderr","w");
pcntl_signal(SIGUSR1, "task_sig_sleep");
pcntl_signal(SIGTSTP, "task_sig_sleep");
pcntl_signal(SIGTERM, "task_sig_stop");
pcntl_signal(SIGINT, "task_sig_stop");
pcntl_signal(SIGABRT, "task_sig_suicide");
pcntl_signal(SIGCONT, "task_sig_wakeup");
$maxfieldno = array();
$index = array();
$options = array();
$nbUpdatedRecords = 0;
$nbInsertedRecords = 0;
$nbErrorRecords = 0;
$stopstate = 0;
$sleepstate = 0;
// Analyse of the command-line arguments
// This program should take the path to the record file as parameter
parse_command($argv);
// connect to mysql
$sock = @mysql_connect("${mysql_machine}","${mysql_docid}","${mysql_docpw}")
or die("Sorry, cannot connect to SQL server.\nPlease try later.\n");
mysql_select_db("${mysql_dbname}")
or die("Sorry, cannot choose ".${mysql_dbname}." database. Please try later.\n");
// detect MySQL server version
$mysql_server_version = mysql_get_server_info();
// do what is required:
if ($options['TASKRUN']) {
task_run();
}
else {
task_submit();
}
?>
diff --git a/modules/bibupload/doc/Makefile.am b/modules/bibupload/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/bibupload/doc/Makefile.am
+++ b/modules/bibupload/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/bibupload/doc/admin/Makefile.am b/modules/bibupload/doc/admin/Makefile.am
index 9e4cf888c..c5b408e0c 100644
--- a/modules/bibupload/doc/admin/Makefile.am
+++ b/modules/bibupload/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/bibupload
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/bibupload/doc/admin/guide.html.wml b/modules/bibupload/doc/admin/guide.html.wml
index a40c3b835..a8dd1dcf1 100644
--- a/modules/bibupload/doc/admin/guide.html.wml
+++ b/modules/bibupload/doc/admin/guide.html.wml
@@ -1,120 +1,120 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibUpload Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/bibupload/>BibUpload Admin</a>" \
navbar_name="admin" \
navbar_select="bibupload-admin-guide"
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
WARNING: THIS ADMIN GUIDE IS NOT FULLY COMPLETED
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
This Admin Guide is not yet completed. Moreover, some
admin-level functionality for this module exists only in the form of
manual recipes. We are in the process of developing both the
guide as well as the web admin interface. If you are interested
in seeing some specific things implemented with high priority,
please contact us at <SUPPORTEMAIL>. Thanks for your interest!
</td>
</tr>
</tbody>
</table>
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Overview</h2>
<p>BibUpload enables you to upload bibliographic data in XML MARC
format into CDSware bibliographic database.
<h2>Configuring BibUpload</h2>
<p>There is nothing to be configured at the moment. All the data
upload configuration is usually done when transforming the data via <a
href="../bibconvert/">BibConvert</a>.
<p><strong>NOTE</strong>: Please note that BibUpload currently assumes
<code>037 $a</code> tag to be a "primary report number" that is unique
throughout the system. Therefore, if you upload two records with the
same <code>037 $a</code> tag value, it will override the exising
record with the new one. See the beginning of the BibUpload file to
know more.
<p>More advanced BibUpload configuration functionality will be
included later.
<h2>Running BibUpload</h2>
<p>Consider that you have an XML MARC file that is to be uploaded into
the CDSware. (For example, it might have been produced by <a
href="../bibconvert/">BibConvert</a>.) To finish the upload, you
would call the BibUpload script as follows:
<blockquote>
<pre>
$ bibupload -i file.xml
<pre>
</blockquote>
<p>For available command-line options, see <code>bibupload
--help</code>.
<h2>BibUpload Modes</h2>
FIXME
<pre>
-i, --insertrecord Insert records from XML MARC file as new into the system.
Signals error if record already exists (see the -m matching
option below on how this is decided).
-r, --replacerecord Replace existing records by those from the XML MARC file.
The original content is wiped out and fully replaced.
Signals error if record is not found via -m matching criteria.
Note also that `-r' can be combined with `-i' into an `-ir' option
that would automatically either insert records as new if they are
not found in the system, or correct existing records if they
are found to exist.
-a, --appendfield Append fields from XML MARC file at the end of existing records.
The original content is enriched only.
Signals error if record is not found via -m matching criteria.
-c, --correctfield Correct fields of existing records by those from XML MARC file.
The original record content is modified only in the fields
from the XML MARC file: the original fields are removed and replaced
by those from the XML MARC file. Fields not present in XML MARC file
are not changed (unlike the -r option).
Signals error if record is not found via -m matching criteria.
-f, --format Upload only the format (FMT) fields.
The original content is not changed, and neither its modification date.
</pre>
diff --git a/modules/bibupload/doc/admin/index.html.wml b/modules/bibupload/doc/admin/index.html.wml
index 52e771507..abad0edd6 100644
--- a/modules/bibupload/doc/admin/index.html.wml
+++ b/modules/bibupload/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="BibUpload Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="bibupload"
<dl>
<dt><a href="guide.html">BibUpload Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running BibUpload.</dd>
</dl>
diff --git a/modules/elmsubmit/Makefile.am b/modules/elmsubmit/Makefile.am
index 4793034e7..10035be87 100644
--- a/modules/elmsubmit/Makefile.am
+++ b/modules/elmsubmit/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin etc doc lib
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/elmsubmit/bin/Makefile.am b/modules/elmsubmit/bin/Makefile.am
index 657a6c77d..73c2fd2bf 100644
--- a/modules/elmsubmit/bin/Makefile.am
+++ b/modules/elmsubmit/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = elmsubmit
EXTRA_DIST = elmsubmit.in
CLEANFILES = *~ *.tmp index.wml
diff --git a/modules/elmsubmit/bin/elmsubmit.in b/modules/elmsubmit/bin/elmsubmit.in
index 6f7c16ba9..fced00d19 100644
--- a/modules/elmsubmit/bin/elmsubmit.in
+++ b/modules/elmsubmit/bin/elmsubmit.in
@@ -1,55 +1,55 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import sys
import getopt
import cdsware.elmsubmit as elmsubmit
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.stderr.write("""Description: read specially-formatted email message from stdin
and upload the records it contains to the system.\n""")
sys.exit(exitcode)
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], "hV", ["help", "version"])
except getopt.GetoptError, err:
usage(1, err)
try:
for opt in opts:
if opt[0] in ["-h", "--help"]:
usage(0)
elif opt[0] in ["-V", "--version"]:
print elmsubmit.__version__
sys.exit(0)
except StandardError, e:
usage(e)
elmsubmit.process_email(sys.stdin.read())
diff --git a/modules/elmsubmit/doc/Makefile.am b/modules/elmsubmit/doc/Makefile.am
index 9ac6a119d..11d00dfa3 100644
--- a/modules/elmsubmit/doc/Makefile.am
+++ b/modules/elmsubmit/doc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
\ No newline at end of file
diff --git a/modules/elmsubmit/doc/admin/Makefile.am b/modules/elmsubmit/doc/admin/Makefile.am
index b8e9f02f2..9f61a93e6 100644
--- a/modules/elmsubmit/doc/admin/Makefile.am
+++ b/modules/elmsubmit/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/elmsubmit
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/elmsubmit/doc/admin/guide.html.wml b/modules/elmsubmit/doc/admin/guide.html.wml
index 3a1850c52..6ba0476f4 100644
--- a/modules/elmsubmit/doc/admin/guide.html.wml
+++ b/modules/elmsubmit/doc/admin/guide.html.wml
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="ElmSubmit Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/elmsubmit/>ElmSubmit Admin</a>" \
navbar_name="admin" \
navbar_select="elsubmit-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
FIXME.
diff --git a/modules/elmsubmit/doc/admin/index.html.wml b/modules/elmsubmit/doc/admin/index.html.wml
index e4c0ba1cf..ef25bab3a 100644
--- a/modules/elmsubmit/doc/admin/index.html.wml
+++ b/modules/elmsubmit/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="ElmSubmit Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="elmsubmit"
<dl>
<dt><a href="guide.html">ElmSubmit Admin Guide</a></dt>
<dd>Everything you want to know about ElmSubmit administration</dd>
</dl>
diff --git a/modules/elmsubmit/doc/hacking/Makefile.am b/modules/elmsubmit/doc/hacking/Makefile.am
index e61c77492..853f35fba 100644
--- a/modules/elmsubmit/doc/hacking/Makefile.am
+++ b/modules/elmsubmit/doc/hacking/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/elmsubmit
doc_DATA=
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/elmsubmit/etc/Makefile.am b/modules/elmsubmit/etc/Makefile.am
index 292ea4c16..f10a05ec1 100644
--- a/modules/elmsubmit/etc/Makefile.am
+++ b/modules/elmsubmit/etc/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir = $(sysconfdir)/elmsubmit
etc_DATA = elmsubmit.cfg
EXTRA_DIST = elmsubmit.cfg.in
CLEANFILES = *~ *.tmp
diff --git a/modules/elmsubmit/etc/elmsubmit.cfg.in b/modules/elmsubmit/etc/elmsubmit.cfg.in
index a2c66e23b..d0135fe5c 100644
--- a/modules/elmsubmit/etc/elmsubmit.cfg.in
+++ b/modules/elmsubmit/etc/elmsubmit.cfg.in
@@ -1,91 +1,91 @@
## $Id$</protect>
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
# elmsubmit configuration file:
[files]
prefix: @prefix@
localstatedir: @prefix@/var
storagedir: @prefix@/var/data/submit/storage
maildir: @prefix@/var/data/submit/storage/mail
[sub_handlers]
test: elmsubmit_doctype_test
[nolangmsgs]
# Messages we need to send to the user, before we've identified the
# correct language to talk to them in (so we assume English!):
bad_email:
Your email could not be parsed correctly to discover a
submission. Please check your email client is functioning correctly.
bad_submission:
The submission data that you have provided could not be parsed
correctly. Please visit <@WEBURL@> for a
description of the correct format.
missing_type:
The submission data that you have provided does not contain a TYPE
field. This is mandatory for all submissions.
unsupported_type:
The TYPE field of your submission does not contain a recognized
value.
missing_fields_1: Your submission of type
missing_fields_2: does not contain all the required fields:
bad_field: This field does not validate correctly:
correct_format: It must be formatted as follows:
missing_attachment:
We could not find the following file attached to your submission
email:
temp_problem:
There is a temporary problem with CDSware's email submission
interface. Please retry your submission again shortly.
[servers]
smtp = localhost
[people]
admin = cds.support@cern.ch
[field_mappings]
title: TI
author: AU
affiliation: AF
language: LANG
num: Num
date: Date
keywords: KW
abstract: AB
note: NO
refnums: REP
files: files
diff --git a/modules/elmsubmit/lib/Makefile.am b/modules/elmsubmit/lib/Makefile.am
index cf5b31ec9..6ea6b3732 100644
--- a/modules/elmsubmit/lib/Makefile.am
+++ b/modules/elmsubmit/lib/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = magic
pylibdir = $(libdir)/python/cdsware
pylib_DATA = elmsubmit.py elmsubmit_misc.py elmsubmit_config.py elmsubmit_enriched2txt.py elmsubmit_EZArchive.py elmsubmit_EZEmail.py elmsubmit_field_validation.py elmsubmit_filename_generator.py elmsubmit_html2txt.py elmsubmit_misc.py elmsubmit_richtext2txt.py elmsubmit_generate_marc.py elmsubmit_submission_parser.py myhtmlentitydefs.py mime.types.edited elmsubmit_tests.py
EXTRA_DIST = $(pylib_DATA) mime.types.edited
CLEANFILES = *~ *.tmp *.pyc
\ No newline at end of file
diff --git a/modules/elmsubmit/lib/elmsubmit.py b/modules/elmsubmit/lib/elmsubmit.py
index 47696daa0..4e84bd05b 100644
--- a/modules/elmsubmit/lib/elmsubmit.py
+++ b/modules/elmsubmit/lib/elmsubmit.py
@@ -1,262 +1,262 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__version__ = "$Id$"
# import sys
import os
import os.path
import smtplib
import cdsware.elmsubmit_EZEmail as elmsubmit_EZEmail
import cdsware.elmsubmit_submission_parser as elmsubmit_submission_parser
# import the config file
import cdsware.elmsubmit_config as elmsubmit_config
import cdsware.elmsubmit_field_validation as elmsubmit_field_validation
from cdsware.elmsubmit_misc import random_alphanum_string as _random_alphanum_string
import cdsware.elmsubmit_generate_marc as elmsubmit_generate_marc
def process_email(email_string):
""" main entry point of the module, handles whole processing of the email
"""
# See if we can parse the email:
try:
e = elmsubmit_EZEmail.ParseMessage(email_string)
except elmsubmit_EZEmail.EZEmailParseError, err:
try:
if err.basic_email_info['from'] is None:
raise ValueError
response = elmsubmit_EZEmail.CreateMessage(to=err.basic_email_info['from'],
_from=elmsubmit_config.people['admin'],
message=elmsubmit_config.nolangmsgs['bad_email'],
subject="Re: " + (err.basic_email_info.get('Subject', '') or ''),
references=[err.basic_email_info.get('message-id', '') or ''],
wrap_message=False)
_send_smtp(_from=elmsubmit_config.people['admin'], to=err.basic_email_info['from'], msg=response)
raise elmsubmitError("Email could not be parsed. Reported to sender.")
except ValueError:
raise elmsubmitError("From: field of submission email could not be parsed. Could not report to sender.")
# See if we can parse the submission fields in the email:
try:
# Note that this returns a dictionary loaded with utf8 byte strings:
submission_dict = elmsubmit_submission_parser.parse_submission(e.primary_message.encode('utf8'))
# Add the submitter's email:
submission_dict['SuE'] = e.from_email.encode('utf8')
except elmsubmit_submission_parser.SubmissionParserError:
_notify(msg=e, response=elmsubmit_config.nolangmsgs.bad_submission)
raise elmsubmitSubmissionError("Could not parse submission.")
# Check we have been given the required fields:
available_fields = submission_dict.keys()
if not len(filter(lambda x: x in available_fields, elmsubmit_config.required_fields)) == len(elmsubmit_config.required_fields):
response = elmsubmit_config.nolangmsgs['missing_fields_1'] + elmsubmit_config.nolangmsgs['missing_fields_2'] + "\n\n" + repr(elmsubmit_config.required_fields)
_notify(msg=e, response=response)
raise elmsubmitSubmissionError("Submission does not contain the required fields for document type %s. Required fields: %s" % (doctype, elmsubmit_config.required_fields))
# Check that the fields we have been given validate OK:
map(lambda field: validate_submission_field(e, submission_dict, field, submission_dict[field]), elmsubmit_config.required_fields)
# Get a submission directory:
storage_dir = get_storage_dir(e)
# Process the files list:
process_files(e, submission_dict, storage_dir)
#generate the appropriate Marc_XML for the submission
marc_xml = elmsubmit_generate_marc.generate_marc(submission_dict)
print marc_xml
return marc_xml
def validate_submission_field(msg, submission_dict, field, value):
try:
(field_documentation, fixed_value, validation_success) = getattr(elmsubmit_field_validation, field)(value.decode('utf8'))
submission_dict[field] = fixed_value.encode('utf8')
if not validation_success:
_notify(msg=msg, response=elmsubmit_config.nolangmsgs['bad_field'] + ' ' + field.upper() + '\n\n'
+ elmsubmit_config.nolangmsgs['correct_format'] + '\n\n' + field_documentation)
raise elmsubmitSubmissionError("Submission contains field %s which does not validate." % (field))
except AttributeError:
# No validation defined for this field:
pass
def get_storage_dir(msg):
path = os.path.join(elmsubmit_config.files['maildir'], _random_alphanum_string(15))
while os.path.exists(path):
path = os.path.join(elmsubmit_config.files['maildir'], _random_alphanum_string(15))
try:
os.makedirs(path)
except EnvironmentError:
_notify(msg=msg, response=elmsubmit_config.nolangmsgs['temp_problem'])
_notify_admin(response="Could not create directory: %s" % (path))
raise elmsubmitError("Could not create directory: %s" % (path))
return path
def process_files(msg, submission_dict, storage_dir):
""" extract the files out of the email and include them in the submission dict
"""
files = map(lambda filename: filename.decode('utf8'), submission_dict['files'])
# Check for the special filename 'all': if we find it, add all of
# the files attached to the email to the list of files to submit:
if 'all' in files:
f = lambda attachment: attachment['filename'] is not None
g = lambda attachment: attachment['filename'].lower()
attached_filenames = map(g, filter(f, msg.attachments))
files.extend(attached_filenames)
files = filter(lambda name: name != 'all', files)
# Filter out duplicate filenames:
_temp = {}
map(lambda filename: _temp.update({ filename : 1}), files)
files = _temp.keys()
# Get the files out of the mail message:
# file dictionary with file content needed for saving the file to proper directory
file_dict = {}
# file list needed to be included in submission_dict
file_list = []
for filename in files:
# See if we have special keyword self (which uses the mail message itself as the file):
if filename == 'self':
file_attachment = msg.original_message
filename = _random_alphanum_string(8) + '_' + msg.date_sent_utc.replace(' ', '_').replace(':', '-') + '.msg'
else:
nominal_attachments = filter(lambda attachment: attachment['filename'].lower() == filename, msg.attachments)
try:
file_attachment = nominal_attachments[0]['file']
except IndexError:
_notify(msg=msg, response=elmsubmit_config.nolangmsgs['missing_attachment'] + ' ' + filename)
raise elmsubmitSubmissionError("Submission is missing attached file: %s" % (filename))
file_dict[filename.encode('utf8')] = file_attachment
#merge the file name and the storage dir in the submission_dict
full_file_name = os.path.join(storage_dir, filename.encode('utf8'))
file_list.append(full_file_name)
submission_dict['files'] = file_list
def create_files((path, dictionary_or_data)):
"""
Take any dictionary, eg.:
{ 'title' : 'The loveliest title.',
'name' : 'Pete the dog.',
'info' : 'pdf file content'
}
and create a set of files in the given directory:
directory/title
directory/name
directory/info
so that each filename is a dictionary key, and the contents of
each file is the value that the key pointed to.
"""
fullpath = os.path.join(storage_dir, path)
try:
dictionary_or_data.has_key
except AttributeError:
open(fullpath, 'wb').write(dictionary_or_data)
try:
map(create_files, file_dict.items())
except EnvironmentError:
response_email = elmsubmit_config.nolangmsgs['temp_problem']
admin_response_email = "There was a problem writing data to directory %s." % (storage_dir)
error = elmsubmitError("There was a problem writing data to directory %s." % (storage_dir))
return (response_email, admin_response_email, error)
return None
def _send_smtp(_from, to, msg):
s = smtplib.SMTP()
s.connect(host=elmsubmit_config.servers['smtp'])
s.sendmail(_from, to, msg)
s.close()
def _notify(msg, response):
response = elmsubmit_EZEmail.CreateMessage(to=[(msg.from_name, msg.from_email)],
_from=elmsubmit_config.people['admin'],
message=response,
subject="Re: " + msg.subject,
references=[msg.message_id],
wrap_message=False)
_send_smtp(_from=elmsubmit_config.people['admin'], to=msg.from_email, msg=response)
def _notify_admin(response):
response = elmsubmit_EZEmail.CreateMessage(to=elmsubmit_config.people['admin'],
_from=elmsubmit_config.people['admin'],
message=response,
subject="CDSWare / elmsubmit problem.",
wrap_message=False)
_send_smtp(_from=elmsubmit_config.people['admin'], to=elmsubmit_config.people['admin'], msg=response)
class elmsubmitError(Exception):
pass
class elmsubmitSubmissionError(elmsubmitError):
pass
class _elmsubmitPrivateError(Exception):
"""
An emtpy parent class for all the private errors in this module.
"""
pass
diff --git a/modules/elmsubmit/lib/elmsubmit_EZArchive.py b/modules/elmsubmit/lib/elmsubmit_EZArchive.py
index 5789c8b29..58c69dc08 100644
--- a/modules/elmsubmit/lib/elmsubmit_EZArchive.py
+++ b/modules/elmsubmit/lib/elmsubmit_EZArchive.py
@@ -1,1034 +1,1034 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import gzip
import bz2
import zipfile
import tarfile
import shutil
import os
import copy
import re
import tempfile
import glob
import sys
WARN_SKIP = True
from cdsware.elmsubmit_filename_generator import calculate_filename_extension as _calculate_filename_extension
# from cdsware.elmsubmit_filename_generator import generate_filename as _generate_filename
from cdsware.elmsubmit_misc import write_to_and_return_tempfile_name as _write_to_and_return_tempfile_name
from cdsware.elmsubmit_misc import provide_dir_with_perms_then_exec as _provide_dir_with_perms_then_exec
from cdsware.elmsubmit_misc import dirtree as _dirtree
from cdsware.elmsubmit_misc import count_dotdot as _count_dotdot
from cdsware.elmsubmit_misc import get_perms as _get_perms
from cdsware.elmsubmit_misc import random_alphanum_string as _random_alphanum_string
from cdsware.elmsubmit_misc import backup_directory as _backup_directory
from cdsware.elmsubmit_misc import open_tempfile as _open_tempfile
from cdsware.elmsubmit_misc import split_common_path as _split_common_path
from cdsware.elmsubmit_misc import recursive_dir_contents as _recursive_dir_contents
from cdsware.elmsubmit_misc import concat as _concat
from cdsware.elmsubmit_misc import mkdir_parents as _mkdir_parents
# Store all files written out in two lists:
# 1. remove_always is for temporary files, which we try to remove regardless.
# 2. remove_on_error is for files the user wants, but need removing if we
# encounter an error.
def _validate_args(arg, received, allowed):
if received not in allowed:
raise ValueError('argument %s must be a value from set %s: got %s' % (arg, allowed, received))
_remove_on_error = []
_remove_always = []
def _remember_write(file_loc, error_only=False):
if error_only:
_remove_on_error.append(file_loc)
else:
_remove_always.append(file_loc)
def _delete_files(list):
for item in list:
if os.path.isdir(item):
shutil.rmtree(item)
else:
os.unlink(item)
def _calc_perms(permissions, umask):
return permissions & (~umask)
## os.chmod('/tmp/thisthis', stat.S_IMODE(os.stat('/tmp')[stat.ST_MODE]))
def _check_mode(current_mode, allowed_mode):
if current_mode != allowed_mode: raise _ModeError
_valid_file_types = ['regular', 'dir', 'symlink', 'hardlink', 'char_dev', 'block_dev', 'fifo']
def _file_type(tarinfo_obj):
if tarinfo_obj.isfile():
return 'regular'
elif tarinfo_obj.isdir():
return 'dir'
elif tarinfo_obj.issym():
return 'symlink'
elif tarinfo_obj.islnk():
return 'hardlink'
elif tarinfo_obj.ischr():
return 'char_dev'
elif tarinfo_obj.isblk():
return 'block_dev'
elif tarinfo_obj.isfifo():
return 'fifo'
def _pick_compression_type(ext):
# Fix the extension; for example if its a gzipped pdf,
# calculate_filname_extension will return pdf.gz. To combat
# this, we find the longest extension from: tar.gz, tar.bz2,
# tar, gz, bz2.
return re.sub(r'^.*?(tar\.gz|tar\.bz2|tar|gz|bz2)$', r'\1', string=ext, count=1)
def _verify_filename(name, seen_filenames, filename_collision, num_random_bits, rename_from_set):
# name could be a filename or directory.
if seen_filenames.has_key(name):
seen_filenames[name] += 1
times = seen_filenames[name]
(dirname, basename) = os.path.split(name)
if filename_collision == 'throw_error':
raise EZArchiveError('filename collision: %s' % (name))
elif filename_collision == 'rename_similar':
# Just in case archive contains a list of
# filenames that follow the same pattern as this
# incrementing, we need to check the increment
# doesn't collide as well:
incremented_basename = str(times) + '.' + basename
while seen_filenames.has_key(os.path.join(dirname, incremented_basename)):
times += 1
incremented_basename = str(times) + '.' + basename
# Make a note of how many increments we've had to
# do:
seen_filenames[name] = times
name = os.path.join(dirname, incremented_basename)
elif filename_collision == 'rename_random':
# Just in case of random collision, we introduce the while loop.
randbasename = _random_alphanum_string(num_random_bits, chars=rename_from_set)
tries = 1
while seen_filenames.has_key(os.path.join(dirname, randbasename)):
randbasename = _random_alphanum_string(num_random_bits, chars=rename_from_set)
# If user gives small set rename_from_set and low number of bits,
# then it is possible we will exhaust all posibile combinations:
tries += 1
if tries > 20:
raise EZArchiveError('20 random filename selections collided: perhaps you need to increase num_rand_bits?')
seen_filenames[os.path.join(dirname, randbasename)] = 0
name = os.path.join(dirname, randbasename)
elif filename_collision == 'overwrite':
pass
elif filename_collision == 'skip':
return ['skip']
else:
seen_filenames[name] = 0
return name
def extract(input, # byte string of file location
input_disposition='byte_string', # ['byte_string', 'file_location']
compression_hint=None, # [None, 'gz', 'bz2', 'tar', 'tar.gz', 'tar.bz2', 'zip']
extract_to='byte_strings', # ['byte_strings', 'my_directory', 'temp_directory']
my_directory=None, # directory path
backup_extension=None, # extension including dot, for backup of my_directory
directory_structure='retain', # ['retain', 'flatten']
file_handle = None, # [None, 'py', 'os']
file_handle_mode = 'rb',
force_file_permissions=None, # file permission bits. eg 0777.
force_dir_permissions=None, # file permission bits. eg 0777.
umask=None, # file permission bits. eg. 0777 (assuming standard umask interpretation).
allow_file_types=_valid_file_types, # list containing any of ['regular, dir, symlink, hardlink, char_dev, block_dev, fifo']
on_find_invalid_file_type='throw_error', # ['throw_error', 'skip']
filename_collision='rename_similar', # ['throw_error', 'rename_similar', 'rename_random', 'overwrite', 'skip']
rename_from_set='abcdefghijklmnopqrstuvwxyz', # characters to use if filename_collision='rename_random'
num_random_bits=8, # number of random bits to use in the random filename.
allow_clobber=False, # [True, False]
on_find_dotdot_path='throw_error', # ['throw_error', 'skip', 'allow']
on_find_absolute_path='throw_error' # ['throw_error', 'skip', 'allow']
# Shelved options:
# file_name_regexp, non_matches='rename_safely', etc.
# Hopefully to be implemented in the future.
):
# Clean out the written files list:
global _remove_on_error
global _remove_always
_remove_on_error = []
_remove_always = []
# Validate arguments.
_validate_args('input_disposition', input_disposition, ['byte_string', 'file_location'])
_validate_args('compression_hint', compression_hint, [None] + available_tools.keys())
_validate_args('extract_to', extract_to, ['byte_strings', 'my_directory', 'temp_directory'])
# _validate_args('extract_to', return_objects, [None, 'file_location', 'open_c_filehandles', 'open_py_file_handles'])
f = lambda type: _validate_args('allow_file_types', type, _valid_file_types)
map(f, allow_file_types)
if not input: raise ValueError('argument input must specify a filename or a byte string')
# From here on, we start writing things out to disk, so we wrap it
# in a try loop and catch all exceptions. This allows us to clean
# up the disk if we didn't succeed with the whole of the
# extraction.
try:
# try/except/finally cannot be combined, so we have to nest:
try:
# Write input to a temp file if we are given a byte string.
if input_disposition == 'byte_string':
input_file_loc = _write_to_and_return_tempfile_name(input)
_remember_write(input_file_loc)
else:
# input_disposition == 'file_location'
# Check that the input file location we've been given exists;
# stat will throw the right error for us:
os.stat(input)
# Check it is a file:
if not os.path.isfile(input):
raise ValueError("argument input must be a path to an archive file if input_disposition='file_location': %s"
% (input))
input_file_loc = input
# Make sure we know what type of file we're dealing with:
if compression_hint is None:
compression_ext = _calculate_filename_extension(filename=input_file_loc)
compression_ext = _pick_compression_type(compression_ext)
else:
compression_ext = compression_hint
# Select approriate archive/compression tool:
try:
tool_class = available_tools[compression_ext]
except KeyError:
raise EZArchiveError('Unrecognized archive type: %s' % (compression_ext))
# Instantiate the tool:
archive = tool_class(input_file_loc, mode='r', allow_clobber=allow_clobber)
if extract_to == 'byte_strings':
# If extract_to == byte_strings, permissions mean nothing.
# However, because we use a temp directory to load the files
# into byte strings, we force the permissions to be nice and
# liberal inside the temp dir:
force_file_permissions = 0700
force_dir_permissions = 0700
# Get extraction_root:
if extract_to == 'byte_strings' or extract_to == 'temp_directory':
# Need a temp directory to work in.
extraction_root = tempfile.mkdtemp()
if extract_to == 'byte_strings':
_remember_write(extraction_root, error_only=False)
else:
# extract_to == 'temp_directory':
_remember_write(extraction_root, error_only=True)
else:
# extract_to == 'my_directory':
if my_directory is None:
raise ValueError("my_directory must be specified if extract_to='my_directory'")
# Make given directory into a nice sane one.
my_directory = os.path.abspath(os.path.expanduser(os.path.normpath(my_directory)))
# Check it exists, and we can stat it:
# stat will throw the right error for us:
os.stat(my_directory)
# Check it is a dir.
if not os.path.isdir(my_directory):
raise ValueError("argument my_directory must be a directory: %s" % (my_directory))
# If we've been asked to back it up, do so:
if backup_extension is not None:
backup_dir = my_directory + backup_extension
if _backup_directory(my_directory, backup_dir) is not None:
raise EZArchiveError('creation of backup directory using GNU mirrordir failed: %s' % (backup_dir))
# Finally set the extraction root:
extraction_root = my_directory
# Logically we would also check we have write permissions
# here. But this is acutally better served by letting
# builtin/other functions raise EnvironmentErrors when we fail
# to write: Checking for write permissions is actually quite
# complex: e.g. you'd have to check group membership to see if
# the group bits allow write.
# If we haven't been given a umask, use take the system umask as a
# default. If we have been given a umask, set the system umask to
# it, so all calls to builtin open/file apply the given umask:
if umask is None:
# It doesn't seem possible to read the umask without also
# setting it. Hence this fudge:
umask = os.umask(0777)
os.umask(umask)
# Used in the extraction for loop to check for filename collisions
# when flattening directory structure:
seen_filenames = {}
# Collect the returned file information here:
return_data = []
for mem in archive.list_all_members():
name = mem['name']
dir = mem['dir']
file_type = mem['file_type']
identity_object = mem['identity_object']
# Check it is an allowed file type:
if file_type not in allow_file_types:
if on_find_invalid_file_type=='skip':
continue
else:
# on_find_invalid_file_type='throw_error':
raise EZArchiveError("found disallowed file type '%s': %s" % (file_type, os.path.join(dir, name)))
# Deal with dotdot paths:
if on_find_dotdot_path == 'allow':
pass
else:
# check if path contains '..'
dir_parts = dir.split(os.sep)
if '..' in dir_parts or name == '..':
if on_find_dotdot_path == 'throw_error':
raise EZArchiveError("tar entry's path contains '..' (*cautiously* consider on_find_dotdot_path='allow'): "
+ os.path.join(dir, name))
else:
# on_find_dotdot_path == 'skip'
# next file please:
continue
# Deal with absolute paths in a similar way:
if on_find_absolute_path == 'allow':
pass
else:
# check if path begins with '/'
if dir != '' and dir[0] == '/':
if on_find_absolute_path == 'throw_error':
raise EZArchiveError("tar entry's path is absolute (*cautiously* consider on_find_absolute_path='allow'): "
+ os.path.join(dir, name))
else:
# on_find_absolute_path == 'skip'
# next file please:
continue
# Deal with flattening of directories:
if directory_structure == 'flatten':
dir = ''
if file_type == 'dir':
continue
# tars allow multiple entries for same path/file:
# extracting such tarballs with GNU/tar will just
# cause the second entry to overwrite the first. We
# try to be more graceful:
verified_fullname = _verify_filename(name=os.path.join(dir, name), seen_filenames=seen_filenames,
filename_collision=filename_collision, num_random_bits=num_random_bits,
rename_from_set=rename_from_set)
if verified_fullname == ['skip']: continue
name = os.path.basename(verified_fullname)
archive.extract_member(identity_object=identity_object, root_dir=extraction_root, dir=dir, new_filename=name,
umask=umask, force_file_permissions=force_file_permissions, force_dir_permissions=force_dir_permissions,
allow_clobber=allow_clobber)
fullname = os.path.join(extraction_root, dir, name)
file_info = {}
file_info['basename'] = name
file_info['tar_dir'] = dir
file_info['file_type'] = file_type
if extract_to == 'byte_strings':
if file_type == 'regular':
file_info['file'] = open(fullname, 'rb').read()
else:
# extract_to in ['my_directory', 'temp_directory']
file_info['fullname'] = fullname
file_info['dirname'] = os.path.join(extraction_root, dir)
if file_type == 'regular':
if file_handle == 'py':
file_info['fh'] = open(fullname, file_handle_mode)
elif file_handle == 'os':
file_info['fh'] = os.open(fullname, file_handle_mode)
return_data.append(file_info)
if extract_to == 'temp_directory':
return (extraction_root, return_data)
else:
return return_data
except:
# Clean up non-temporary file if we get an error:
_delete_files(_remove_on_error)
raise
finally:
# Always clean up temporary files, error or not:
_delete_files(_remove_always)
def create(input, # list of files or named ([['name', 'data...'], ...]) or anonymous ([[data...], ...]) byte strings.
input_disposition='named_byte_strings', # ['file_locations', 'anonymous_byte_strings', 'named_byte_strings']
compression='tar.gz', # ['gz', 'bz2', 'tar', 'tar.gz', 'tar.bz2', 'zip']
compress_to = 'byte_string', # ['byte_string', 'my_file', 'temp_file']
my_file=None, # name of output archive, if compress_to='my_file'
recurse_dirs=True, # [True, False]
directory_structure='retain', # ['retain', 'flatten']
use_compression_root='calculate_minimum', # ['calculate_minimum', 'this_root']
this_root=None, # root path for compression of files.
filename_collision='rename_similar', # ['throw_error', 'rename_similar', 'rename_random', 'overwrite', 'skip']
rename_from_set='abcdefghijklmnopqrstuvwxyz', # characters to use if filename_collision='rename_random'
num_random_bits=8, # number of random bits to use in the random filename.
force_file_permissions=None, # file permission bits. eg 0777.
force_dir_permissions=None, # file permission bits. eg 0777.
file_handle = None, # [None, 'py', 'os']
file_handle_mode = 'rb',
allow_clobber=False, # [True, False]
):
# Basic idea: If we are told to output an archive (tar or zip)
# then all files given in input are put into a single archive. If
# we are told to output compressed files (gz, bz2) then we must be
# given a maximum of one archive file.
# If we are given anonymous byte strings with no filename, we use
# filename_generator.generate_filename() to provide a random
# filename with hopefully a correct file extension.
# Clean out written files list:
global _remove_on_error
global _remove_always
_remove_on_error = []
_remove_always = []
# Validate arguments.
# ??????????????????
# From here on, we start writing things out to disk, so we wrap it
# in a try loop and catch all exceptions. This allows us to clean
# up the disk if we didn't succeed with the whole of the
# extraction.
try:
# try/except/finally cannot be combined, so we have to nest:
try:
# Write input to a temp file if we are given a byte string.
# Work out where the output archive file is going to go:
if compress_to == 'my_file':
if my_file is None:
raise ValueError("if compress_to == 'my_file' then argument my_file must be specified. got None.")
# Make given file into a nice sane one:
archive_fullname = os.path.abspath(os.path.expanduser(os.path.normpath(my_file)))
# Should we remember this file or not? If we get an error in
# the middle of processing, should we delete a user specified
# archive file? The decision is not so clear cut as with
# temporary files (see next). My choice is not to remember
# (and so not to delete on error)
else:
# compress_to in ['temp_file', 'byte_string']
(tf, tf_name) = _open_tempfile(mode='wb')
# close filehandle because we don't need it:
tf.close()
# delete the empty tempfile that open_tempfile
# created, so we don't get ClobberError
os.unlink(tf_name)
del tf
if compress_to == 'temp_file':
_remember_write(tf_name, error_only=True)
else:
# compress_to == 'byte_string'
_remember_write(tf_name, error_only=False)
archive_fullname = tf_name
# Get an archive/compress tool:
tool_class = available_tools[compression]
archive = tool_class(file_loc=archive_fullname, mode='w', allow_clobber=allow_clobber)
# Deal with the input:
# We do this as follows:
# 1. Take anonymous byte strings and turn them into byte strings
# by generating a filename for each string, then set
# input=[new list of named byte strings]
# input_disposition='named_byte_strings'
# 2. Take named byte strings and write them to a temporary
# directory, chdir to this directory and set:
# input = [glob of temp dir]
# input_diposition = 'file_locations'
if input_disposition == 'anonymous_byte_strings':
# If input is anonymous byte strings, we need generate a filename
# for each of the strings:
seen_rand_names = []
def f(bytstr):
rand_name = _random_alphanum_string(num_random_bits, chars=rename_from_set)
tries = 1
while rand_name in seen_rand_names:
rand_name = _random_alphanum_string(num_random_bits, chars=rename_from_set)
tries += 1
if tries > 20:
raise EZArchiveError('20 random filename selections collided: perhaps you need to increase num_rand_bits?')
seen_rand_names.append(rand_name)
return [rand_name, bytstr]
input = map(f, input)
input_disposition = 'named_byte_strings'
if input_disposition == 'named_byte_strings':
# Write the byte strings out to the temporary directory.
temp_dir = tempfile.mkdtemp()
_remember_write(temp_dir, error_only=False)
if this_root is not None:
# santize:
this_root = os.path.abspath(os.path.expanduser(os.path.normpath(this_root)))
# chop off the root slashes:
this_root = re.sub(r'^/+', '', string=this_root, count=1)
# rejig the root dir to reflect the fact we've shoved
# everything under a psuedo-root temp directory:
this_root = os.path.join(temp_dir, this_root)
new_input = []
seen_filenames = {}
for filename, bytestr in input:
# Sanitize the filename we've been given:
filename = os.path.abspath(os.path.expanduser(os.path.normpath(filename)))
# chop off the root slashes:
filename = re.sub(r'^/+', '', string=filename, count=1)
dirname = os.path.dirname(filename)
# Use temp_dir as a 'fake_root': (There is some possible
# dodginess here if the user names one of the files as if
# it were inside the not yet existant temp directory:
# unlikely scenario; should we work around it? I haven't.
_mkdir_parents(os.path.join(temp_dir, dirname))
filename = _verify_filename(name=filename, seen_filenames=seen_filenames,
filename_collision=filename_collision, num_random_bits=num_random_bits,
rename_from_set=rename_from_set)
if filename == ['skip']: continue
tempfile_fullname = os.path.join(temp_dir, filename)
open(tempfile_fullname, 'wb').write(bytestr)
new_input.append(tempfile_fullname)
input = new_input
input_disposition='file_locations'
# At this point, input_disposition='file_locations' and input contains a list of filenames.
# sanitize the list of filenames
f = lambda x: os.path.abspath(os.path.expanduser(os.path.normpath(x)))
input = map(f, input)
# Expand any directories into filenames (excluding symlinks):
new_input = []
for item in input:
if os.path.isdir(item):
new_input.append(item)
if recurse_dirs:
new_input.extend(_recursive_dir_contents(item))
else:
new_input.append(item)
input = new_input
# calculate the compression root:
if use_compression_root == 'calculate_minimum':
first_input = input[0]
if input == filter(lambda x: x == first_input, input):
# all of the filenames we've been given are the same:
compression_root = os.path.dirname(first_input)
files_to_compress = [os.path.basename(first_input)] * len(input)
else:
# find out the common root of the filenames:
(compression_root, files_to_compress) = _split_common_path(input)
# if compression_root was also specified in input, it will
# have become a blank entry '' in files_to_compress:
files_to_compress = filter(lambda x: (x != '' and True) or False, files_to_compress)
else:
# use_compression_root == 'this_root':
if this_root is None:
raise EZArchiveError("if compression_root=='this_root' then argument this_root must be specified")
this_root = os.path.abspath(os.path.expanduser(os.path.normpath(this_root)))
# check that this_root is indeed a prefix of all of the input
# files we've been given:
if input != filter(lambda file: this_root in _dirtree(file), input):
raise EZArchiveError('not all files specified in argument input are children of argument this_root')
# get rid of the entries that are exactly this_root:
input = filter(lambda file: file != this_root, input)
compression_root = this_root
# Chop off this_root from input:
if this_root == '/' or this_root == '//':
this_root_len = len(this_root)
else:
this_root_len = len(this_root + '/')
files_to_compress = map(lambda file: file[this_root_len:], input)
old_cwd = os.getcwd()
os.chdir(compression_root)
seen_filenames = {}
for file_to_compress in files_to_compress:
if directory_structure == 'flatten':
if os.path.isdir(file_to_compress):
continue
archive_name = os.path.basename(file_to_compress)
archive_name = _verify_filename(name=archive_name, seen_filenames=seen_filenames,
filename_collision=filename_collision,
num_random_bits=num_random_bits,
rename_from_set=rename_from_set)
if archive_name == ['skip']: continue
archive.add_member(file_loc=file_to_compress, archive_name=archive_name,
force_file_permissions=force_file_permissions,
force_dir_permissions=force_dir_permissions)
else:
# directory_structure == 'retain':
archive.add_member(file_loc=file_to_compress, archive_name=None,
force_file_permissions=force_file_permissions,
force_dir_permissions=force_dir_permissions)
# get rid of the archive object, which has an open
# filehandle, mode 'wb' on the archive file:
# not closing this would prevent us from seeing what
# has been written to the files.
del archive
# now see if we need to return anything:
if compress_to == 'my_file':
return None
elif compress_to == 'temp_file':
return tf_name
else:
# compress_to == 'byte_string':
return open(archive_fullname, 'rb').read()
except:
# Clean up non-temporary file if we get an error:
_delete_files(_remove_on_error)
raise
finally:
# Always clean up temporary files, error or not:
_delete_files(_remove_always)
try:
os.chdir(old_cwd)
except:
pass
class ArchiveTool:
def __init__(self, file_loc, mode, allow_clobber=False):
raise Exception("method must be overided in child class")
def list_all_members(self):
raise Exception("method must be overided in child class")
# Should return dictionary:
# { filename =
# tar_location =
# new_location =
# file_type =
# }
def extract_member(self, identity_object, root_dir, dir, new_filename, umask, force_file_permissions=None,
force_dir_permissions=None, allow_clobber=False):
raise Exception("method must be overided in child class")
def add_member(self, file_loc, archive_name=None, force_file_permissions=None, force_dir_permissions=None):
raise Exception("method must be overided in child class")
class tarArchiveTool(ArchiveTool):
# Overide this in child classes tarbz2ArchiveTool and
# targzArchiveTool to make the mode string reflect the required
# compression.
def _mode_string(string):
return string + ':'
_mode_string = staticmethod(_mode_string)
def __init__(self, file_loc, mode, allow_clobber=False):
if mode not in ('r', 'w'): raise ValueError('mode argument must equal "r" or "w"')
if mode == 'w':
if os.path.exists(file_loc) and not allow_clobber:
raise ClobberError(file_loc)
# Set adjusted mode to reflect whether we are dealing with a
# tar.gz tar.bz2 or just a tar.
adjusted_mode = self._mode_string(mode)
self._tarfile_obj = tarfile.open(name=file_loc, mode=adjusted_mode)
self._tarfile_obj.errorlevel=2
self._mode = mode
self._filename = os.path.basename(file_loc)
self._file_loc = file_loc
def list_all_members(self):
_check_mode(self._mode, 'r')
f = lambda tarinfo_obj: { 'name' : os.path.basename(os.path.normpath(tarinfo_obj.name)),
'dir' : os.path.dirname(os.path.normpath(tarinfo_obj.name)),
'file_type' : _file_type(tarinfo_obj),
'identity_object' : tarinfo_obj }
return map(f, self._tarfile_obj.getmembers())
def extract_member(self, identity_object, root_dir, dir, new_filename, umask, force_file_permissions=None,
force_dir_permissions=None, allow_clobber=False):
_check_mode(self._mode, 'r')
tarinfo_obj = identity_object
output_location = os.path.join(root_dir, dir, new_filename)
if os.path.exists(output_location) and not allow_clobber:
raise ClobberError(output_location)
# Extract the file to the given location.
saved_name = tarinfo_obj.name
tarinfo_obj.name = os.path.join(dir, new_filename)
saved_mode = tarinfo_obj.mode
tarinfo_obj.mode = _calc_perms(tarinfo_obj.mode, umask) # Apply umask to permissions.
try:
self._tarfile_obj.extract(tarinfo_obj, root_dir)
except EnvironmentError, e:
if e.errno == 13:
def f():
# Have already done this, but permissions might
# have caused a fallacious answer previously:
if os.path.exists(output_location) and not allow_clobber:
raise ClobberError(output_location)
elif os.path.exists(output_location) and allow_clobber:
if os.path.isdir(output_location):
# can ignore dirs; we can overwrite them
# whatever their current perms
pass
else:
# non-write permissions will prevent
# .extract method from overwriting, so
# unlink first:
os.unlink(output_location)
return self._tarfile_obj.extract(tarinfo_obj, root_dir)
number_dotdot = _count_dotdot(dir)
if number_dotdot != 0:
# This is the reason why allow_dotdot_paths = True is v. dangerous:
barrier_dir = None
# shunted_root_dir = os.path.join(root_dir, '../' * number_dotdot)
# normed_shunted_root_dir = os.path.normpath(shunted_root_dir)
# barrier_dir = normed_shunted_root_dir
else:
barrier_dir=root_dir
_provide_dir_with_perms_then_exec(dir=os.path.join(root_dir, dir), function=f, perms=0700, barrier_dir=barrier_dir)
else:
raise
tarinfo_obj.name = saved_name
tarinfo_obj.mode = saved_mode
# If we've been asked to force permissions, do so:
type = _file_type(tarinfo_obj)
if type == 'regular':
if force_file_permissions is not None:
try:
os.chmod(output_location, force_file_permissions)
except EnvironmentError, e:
if e.errno == 13:
f = lambda: os.chmod(output_location, force_file_permissions)
_provide_dir_with_perms_then_exec(dir=os.path.join(root_dir, dir), function=f, perms=0700, barrier_dir=root_dir)
else:
raise
elif type == 'dir':
if force_dir_permissions is not None:
try:
os.chmod(output_location, force_dir_permissions)
except EnvironmentError, e:
if e.errno == 13:
f = lambda: os.chmod(output_location, force_dir_permissions)
_provide_dir_with_perms_then_exec(dir=os.path.join(root_dir, dir), function=f, perms=0700, barrier_dir=root_dir)
else:
raise
else:
# We don't attempt to play with permissions of special
# file types.
pass
def add_member(self, file_loc, archive_name=None, force_file_permissions=None, force_dir_permissions=None):
_check_mode(self._mode, 'w')
if archive_name is None:
archive_name = file_loc
tarinfo_obj = self._tarfile_obj.gettarinfo(name=file_loc, arcname=archive_name)
if tarinfo_obj is None:
if WARN_SKIP:
sys.stderr.write("Skipping unsupported file type (eg. socket): %s\n" % (file_loc))
return None
if os.path.isdir(file_loc) and force_dir_permissions is not None:
tarinfo_obj.mode = force_dir_permissions
if os.path.isfile(file_loc) and force_file_permissions is not None:
tarinfo_obj.mode = force_file_permissions
if tarinfo_obj.isfile():
self._tarfile_obj.addfile(tarinfo_obj, open(file_loc, 'rb'))
else:
self._tarfile_obj.addfile(tarinfo_obj)
class targzArchiveTool(tarArchiveTool):
def _mode_string(string):
return string + ':gz'
_mode_string = staticmethod(_mode_string)
class tarbz2ArchiveTool(tarArchiveTool):
def _mode_string(string):
return string + ':bz2'
_mode_string = staticmethod(_mode_string)
class zipArchiveTool(ArchiveTool):
pass
class CompressTool:
# Use to prevent trying to compress multiple files into the
# unstructured gz file (if you want to do this, use a tar.gz,
# tar.bz2, zip instead!):
_write_protected = False
def __init__(self, file_loc, mode, allow_clobber=False):
"""
Overided child methods must set class properties:
self._fh
self._filename
self._file_loc
self._mode
"""
raise Exception("method must be overided in child class")
def list_all_members(self):
_check_mode(self._mode, 'r')
uncompressed_filename = re.sub(r'\.' + self._ext + r'$', '', string=self._filename, count=1)
return [{ 'name' : uncompressed_filename,
'dir' : '',
'file_type' : 'regular',
'identity_object' : None } ]
def extract_member(self, identity_object, root_dir, dir, new_filename, umask, force_file_permissions=None,
force_dir_permissions=None, allow_clobber=False):
_check_mode(self._mode, 'r')
output_location = os.path.join(root_dir, dir, new_filename)
if os.path.exists(output_location) and not allow_clobber:
raise ClobberError(output_location)
elif os.path.exists(output_location) and allow_clobber:
# unlink instead of just overwriting: this makes sure the
# file permissions take the umask into account:
os.unlink(output_location)
output_fh = open(output_location, 'wb')
output_fh.write(self._fh.read())
output_fh.close()
# See if we need to force the file permissions. Otherwise, we
# do nothing, since open call above will have obeyed the
# system umask.
if force_file_permissions is not None:
os.chmod(output_location, force_file_permissions)
def add_member(self, file_loc, archive_name=None, force_file_permissions=None, force_dir_permissions=None):
if not os.path.isfile(file_loc):
raise EZArchiveError("%s file format only supports compression of regular files: %s" % (self._ext, file_loc))
if not self._write_protected:
input_fh = open(file_loc, 'rb')
self._fh.write(input_fh.read())
input_fh.close()
self._fh.close()
self._write_protected = True
else:
raise EZArchiveError('tried to compress more than one file into a single %s file' % (self._ext))
class gzCompressTool(CompressTool):
def __init__(self, file_loc, mode, allow_clobber=False):
if mode not in ('r', 'w'): raise ValueError('mode argument must equal "r" or "w"')
if mode == 'w':
if os.path.exists(file_loc) and not allow_clobber:
raise ClobberError(file_loc)
self._fh = gzip.GzipFile(file_loc, mode=mode+'b')
self._filename = os.path.basename(file_loc)
self._file_loc = file_loc
self._mode = mode
self._ext = 'gz'
class bz2CompressTool(CompressTool):
def __init__(self, file_loc, mode, allow_clobber=False):
if mode not in ('r', 'w'): raise ValueError('mode argument must equal "r" or "w"')
if mode == 'w':
if os.path.exists(file_loc) and not allow_clobber:
raise ClobberError(file_loc)
self._fh = bz2.BZ2File(file_loc, mode=mode+'b')
self._filename = os.path.basename(file_loc)
self._file_loc = file_loc
self._mode = mode
self._ext = 'bz2'
available_tools = { 'tar' : tarArchiveTool,
'tar.gz' : targzArchiveTool,
'tar.bz2' : tarbz2ArchiveTool,
'zip' : zipArchiveTool,
'gz' : gzCompressTool,
'bz2' : bz2CompressTool }
# Errors:
class _ModeError(Exception):
"""
This is a private error raised iff there is an attempt to use a
class method that is not allowed by the 'mode' in which the class
instance has been instantiated. Eg. If we have created a
CompressTool in write mode, and we try to use a method intended
only for use in read mode.
This should only occur in the case of a programming error in the
module.
"""
pass
class _NotInArchive(Exception):
"""
A private error raised iff there is an attempt to extract a file
from a given archive that does not exist inside the archive.
This should only occur in the case of a programming error in the
module.
"""
pass
class EZArchiveError(Exception):
pass
class ClobberError(EZArchiveError):
pass
def tester(tar):
t = targzArchiveTool(tar, mode='r', allow_clobber=False)
for mem in t.list_all_members():
name = mem['name']
dir = mem['dir']
identity_object = mem['identity_object']
t.extract_member(identity_object=identity_object, root_dir='/tmp', dir=dir, new_filename=name,
umask=0002, force_file_permissions=None, force_dir_permissions=None, allow_clobber=False)
def tester2(file):
tar = tarfile.open(file, mode="r:gz")
for tarinfo in tar:
tar.extract(tarinfo, '/tmp/')
tar.close()
diff --git a/modules/elmsubmit/lib/elmsubmit_EZEmail.py b/modules/elmsubmit/lib/elmsubmit_EZEmail.py
index 17dea037d..d0d8c76e2 100644
--- a/modules/elmsubmit/lib/elmsubmit_EZEmail.py
+++ b/modules/elmsubmit/lib/elmsubmit_EZEmail.py
@@ -1,1994 +1,1994 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
# Side note: CJK codecs at http://cjkpython.i18n.org/.
Exports blah blah blah.
Speed:
Testing it on a random sample of 1500 messages culled from my INBOX,
it took an average of 5/100ths seconds to process each
message. (Running on a Linux P4 2Ghz machine).
Shortcomings:
- Does not support message/partial mime type.
The message/partial mime type is designed to allow mailers to split
up the body of large messages into several 'message/partial' parts,
which can then be sent inside seperate email messages to the
intended receipient (see RFC2046 for the precise semantics). Upon
receipt the MUA is supposed to recombine the parts into the orignal
message. Supporting this fairly rare MIME type would add a lot of
complexity to the module; there would have to be a mechanism for
passing several email messages to the Message class constructor; further,
- Simply deletes RFC2231 language specification extensions from
RFC2047 encoded header text. The rest of RFC2231 relating to header
parameter values is observed. Note that a language specfication is
different from a charset. This is an issue in very few
circumstances. Hopefully it won't be an issue at all eventually,
because soon charsets should allow language specifications to be
built into them, and whatever happens in the future to unicode (and
accordingly python's unicode object and function) will adapt to
this. Quoting from RFC2231:
> 8. Character sets which allow specification of language
>
> In the future it is likely that some character sets will provide
> facilities for inline language labeling. Such facilities are
> inherently more flexible than those defined here as they allow for
> language switching in the middle of a string.
>
> If and when such facilities are developed they SHOULD be used in
> preference to the language labeling facilities specified here. Note
> that all the mechanisms defined here allow for the omission of
> language labels so as to be able to accommodate this possible future
> usage.
"""
# Quicker to do "from email import *" but this gives us a reminder of
# what's available:
import email
import email.Message
import email.Parser
import email.Generator
import email.Header
import email.Charset
import email.Encoders
import email.MIMENonMultipart
import email.MIMEMultipart
import email.MIMEMessage
import email.MIMEText
import email.Utils
import email.Errors
import mimetypes
# Non email imports:
import time
import datetime
import os
import StringIO
import quopri
import uu
import base64
import re
cfg_elmsubmit_have_rtflib = 0
try:
import rtf.Rtf2Txt
from rtf.RtfParser import RtfException as _RtfException
cfg_elmsubmit_have_rtflib = 1
except ImportError:
pass
import cdsware.elmsubmit_richtext2txt as _richtext2txt
import cdsware.elmsubmit_enriched2txt as _enriched2txt
import cdsware.elmsubmit_html2txt as _html2txt
from cdsware.elmsubmit_misc import concat as _concat
from cdsware.elmsubmit_misc import cr2lf as _cr2lf
from cdsware.elmsubmit_misc import random_alphanum_string as _random_alphanum_string
from cdsware.elmsubmit_misc import wrap_text as _wrap_text
from cdsware.elmsubmit_filename_generator import generate_filename as _generate_filename
import cdsware.elmsubmit_EZArchive as elmsubmit_EZArchive
# Message Parsing:
# (Search down to "# Message Creation:" also.)
_default_handling_hints = { 'generate_filename' : 'always',
'descend_message_rfc822_attachments' : True,
'archive_format' : 'tar.gz',
'archive_multipart_unrecognized': True,
'archive_multipart_parallel': True,
'archive_multipart_related': True,
'generate_filename' : 'if_missing' }
class ParseMessage(object):
"""
This class provides a very simple representation of an email
message. It is basically a wrapper around the class ParseMessage
provided by the Email package that comes with Python.
It is designed to give simple access to the body text, attachments
etc. without the programmer having to consider the evil
complexities of MIME. It READ ONLY. ie. Don't expect to produce a
new email by mutating the data returned by the class methods!
Instance properties:
self.headers
Returns the headers of the message as a Python dictionary
object.
The data structure _headers might look as follows:
_headers = { 'to' : [u"alice@example.com, bob@example.org"],
'recieved' : [u"from cernfe02.cern.ch ([137.138 etc...",
u"from client.cern.ch ([137.138. etc..."],
'date' : [u"Wed, 4 Aug 2004 15:07:17 +0200 (W. Europe Daylight Time)"] }
ie. It is a python dictionary: the keys are headers and the
values are lists of header values (note that an email
(RFC822) message may contain duplicate headers). Each list
contains the header values in the relative order they appear
in the original message. rfc822 headers are case-insensitive
so we store them in lowercase.
Header processing decodes each header from its RFC2047 encoded
format then further decodes it from the native charsets into
unicode. Hence the list values in the data structure are
unicode strings. Note that the _keys_ are just regular ascii
strings, since we should be able to rely on header keys being
7-bit ascii only.
self.received_data
self.primary_message
Returns the best guess at what the intended message is.
self.original_message
Returns the orignal message as supplied to the constructor.
self.attachments
self.inline_attachments
self.from_header
self.subject
self.from_name
self.from_email
self.message_id
self.date_sent_utc
Returns an ISO8601 formatted unicode string of the date the
email was sent (in UST/GMT). ISO8601 strings look like this:
"YYYY-MM-DD HH:MM:SS". If the Date: header is not present or
unparsable, the current time on the system (in GMT) is
substituted instead.
"""
def __init__(self, message_string, strict=True, hints=_default_handling_hints):
# message_string is a string representing an email (aka rfc822
# message). strict determines +++++++++++++
# Save the original message string (can be accessed later by
# self.origMessage method)
self.original_message = message_string
# Create an email.Message object from the plain text.
msg = email.message_from_string(message_string)
# Now populate self.headers; intended to be accessed later by
# self.headers method. The data structure is described in the
# .headers method docstring.
self.headers = _process_headers(msg, msg.items(), force_processing=(not strict))
# Now we move on to calculating _from_name, _from_email
# Of course, there might not be a From: header in a very
# broken email, so we raise a FromHeaderError if this is the
# case.
try:
# KeyError means email is missing 'from' field:
from_header = self.headers['from'][0] # If mutliple From: fields, use 1st.
self.from_addr = from_header
# from_header could be None if we are operating with
# strict=False and we failed to decode the header:
if from_header is None: raise FromHeaderParsingError(msg)
(from_name, from_email) = _parse_from_header(msg, from_header)
except KeyError:
if strict:
raise FromHeaderMissingError(msg)
else:
from_name = None
from_email = None
except FromHeaderParsingError:
if strict:
raise # Reraise the error.
else:
from_name = None
from_email = None
self.from_name = from_name
self.from_email = from_email
try:
self.subject = self.headers['subject'][0]
except KeyError:
self.subject = '' # Should we put None here?
try:
self.message_id = self.headers['message-id'][0]
except KeyError:
self.message_id = '' # Should we put None here?
# Process the received headers, extracting the 'received from' host and ip address:
try:
self.received_data = map(_received_ip_and_host, self.headers['received'])
except KeyError:
# There were no recieved headers; should this be an error
# in strict mode or not?
# I think not, since people can save email locally without sending it.
self.received_data = None
# Now calculate _date_sent_utc. Test to see if there actually
# is a date header and if we can parse it. If running in
# strict mode, then we throw an error. If not, then simply use
# the localtime.
try:
date_in_rfc2822_format = self.headers['date'][0]
remote_struct_time_with_utc_offset = email.Utils.parsedate_tz(date_in_rfc2822_format)
# email.Utils.parsedate_tz returns None on failure.
if remote_struct_time_with_utc_offset is None: raise _ParseDateError()
remote_struct_time = remote_struct_time_with_utc_offset[0:9]
(remote_offset_from_utc_in_seconds,) = remote_struct_time_with_utc_offset[9:10]
if remote_offset_from_utc_in_seconds is None: raise _ParseDateError()
except (KeyError, _ParseDateError):
if strict: raise ParseDataError(msg)
else:
# Use local time on error.
remote_struct_time = time.gmtime()
remote_offset_from_utc_in_seconds = 0
date_time_args = remote_struct_time[0:6] # datetime constructor only needs first 6 parts of struct_time tuple
# filter(lambda x: x is None: date_time_args)
# if filter != []: raise ParseDateError(msg)
remote_time = datetime.datetime(*date_time_args)
remote_utc_delta = datetime.timedelta(seconds=remote_offset_from_utc_in_seconds)
# local_utc_delta = datetime.timedelta(seconds= -time.timezone)
utc_time = remote_time - remote_utc_delta
# local_time = utc_time + local_utc_delta
# Now that we have the date sent in utc, we just format it to
# an ISO8601 string and convert that to a unicode
# object. Since the ISO8601 string will only contain us-ascii,
# this conversion should not fail and so we need not check for
# decoding errors.
self.date_sent_utc = unicode(utc_time.isoformat(sep=' '), 'us-ascii')
# self._date_sent_local = local_time.isoformat(sep=' ')
# Now we parse the email and attempt to calculate what the
# primary message (ie. what would pop-up in the message pane
# of your email client) would be.
(self.attachments,
self.inline_attachments,
self.primary_message) = _get_msg_structure(msg, strict, hints)
def contents(filename):
f = file(filename, "r")
p = email.Parser.Parser()
msg = p.parse(f)
def walk_email(msg,indent=0):
print "-"*indent, msg.get_content_type()
if msg.is_multipart():
for part in msg.get_payload():
walk_email(part,indent+8)
walk_email(msg)
f.close()
####### __main__
# f = open('blower.eml','r')
# e = f.read()
# f = open('testSpliter/torture-test.eml','r')
# tort = f.read()
# f = open('just_text.eml','r')
# e2 = f.read()
# f = open('hello.eml','r')
# e3 = f.read()
# f = open('rtf2.eml')
# e4 = f.read()
# f = open('attached_msg.eml')
# e5 = f.read()
# f = open('/tmp/eg/example.jpg','r')
# jpg = f.read()
# f = open('/tmp/eg/example.msword.doc','r')
# word = f.read()
# f = open('/tmp/eg/example.xls','r')
# excel = f.read()
# f = open('/tmp/eg/example.pdf','r')
# pdf = f.read()
# f = open('/tmp/eg/example.reg.gz','r')
# reg = f.read()
# f = open('/tmp/eg/example.wk3','r')
# lotus = f.read()
# f = open('/tmp/eg/example.xml','r')
# xml = f.read()
# f = open('/tmp/eg/example.tar.gz','r')
# targz = f.read()
# f = open('/tmp/eg/example.tar','r')
# tar = f.read()
# f = open('/tmp/eg/example.zip','r')
# zip_data = f.read()
# f = open('/tmp/eg/example.xml.bz2','r')
# bz2eg = f.read()
# Support functions.
def _received_ip_and_host(received_header):
host_re = re.compile(r"""from\ ( # from marks the start of the received target
[a-z0-9]+(?:[a-z0-9_.-]+[a-z0-9])? # Match a domain string.
) # Allow illegal but common underscores
# (eg. the famous dear_raed.blogspot.com)
[)\s] # Terminate with space or a closing bracket depending on the format.
""",re.VERBOSE|re.IGNORECASE)
ipad_re = re.compile(r"""[[(] # match opening bracket or parenthesis
# (should be a bracket if following standards)
((?:\d{1,3}\.){3} # match three octets with dots
\d{1,3}) # match a single octet with no dot
[])] # match the closing bracket/parenthesis
""", re.VERBOSE|re.IGNORECASE)
host_match = host_re.search(received_header)
if host_match is not None:
host = host_match.group(1)
else:
host = None
ipad_match = ipad_re.search(received_header)
if ipad_match is not None:
ipad = ipad_match.group(1)
else:
ipad = None
return (host, ipad)
def _basic_email_info(msg):
"""
Takes an email.Message object and returns a dictionary, formatted
like the following example, containing a basic subset of
information about the message:
{ from: u'Ann Other <person@example.org>'
from_email : u'person@example.org',
from_name : u'Ann Other',
subject : u'This email is about...',
message-id : u'1234567890@host.example.com', }
Any header which cannot be decoded to unicode will be returned in
it original encoded form. Check with type(value) = unicode.
This function can be used when throwing an error to gather just
enough information about the message so clients of the
elmsubmit_EZEmail.ParseMessage class can respond to the email author
reporting the error.
"""
# Items we want to try and return:
# If you wish to tailor this list, note that basic_headers MUST
# have 'from' in it, otherwise the following code breaks!
basic_headers = ['from', 'subject', 'message-id'] # 'from_name' and 'from_email' aren't headers;
# they are derivatives of the 'from' header.
# The hash to be built up and returned:
return_dict = {}
# Get all header/value pairs for which the header is also in list
# basic_headers (case insensitively):
f = lambda (k,v): k.lower() in basic_headers
basic_items = filter(f, msg.items())
# Now attempt to decode the basic headers to unicode objects:
basic_decoded_headers = _process_headers(msg=None, header_value_pairs=basic_items, force_processing=True)
# Since we're just using this for error output, we don't need to
# worry about headers with the same header key; just accept the
# first one present (and note that the list of headers in
# basic_headers are all ones which _should_ only be appearing
# once).
g = lambda (k,v): (k,v[0])
basic_decoded_headers = dict(map(g, basic_decoded_headers.items()))
try:
# If the from header is missing this access will cause
# KeyError:
from_value = basic_decoded_headers['from']
# If from_header is None, we couldn't decode it and so can't
# proceed in splitting it into from_name and from_email. Raise
# TypeError.
if from_value is None: raise TypeError
# Could cause FromHeaderParsingError:
(from_name, from_email) = _parse_from_header(msg, from_value)
return_dict.update({ 'from_name': from_name,
'from_email': from_email })
except (TypeError, KeyError, FromHeaderParsingError):
return_dict.update({ 'from_name': None,
'from_email': None })
# This loops over basic_headers and tries to index
# basic_decoded_headers by each value. Anything that isn't present
# (ie. we've failed to decode), we look up directly in the orginal
# msg object (and return the value as a string in whatever charset
# and RFC2047 encoding it arrived in) if _that_ fails (ie. the
# header is missing from the message altogether) we set the value
# in the hash to None.
for header in basic_headers:
value = basic_decoded_headers.get(header, None)
if value == None:
value = msg.get(header, None)
return_dict[header] = value
return return_dict
def _native2unicode(value_nc, native_charset=None, strict=True):
"""
Function native2unicode is a wrapper around builtin function
unicode. The difference is that native2unicode will accept a
charset of None which will cause it to default to decoding from
us-ascii.
It also raises a custom error _UnicodeDecodingError which returns
the problem value and charset, rather than LookupError/ValueError
raised by the unicode builtin.
"""
errors = { True : 'strict',
False: 'replace'}[strict]
# Non-RFC2047 encoded parts return charset as None; we assume then
# that they are us-ascii bytes.
if native_charset is None: native_charset = 'us-ascii'
# Remove RFC2123 language specification from document if present.
# This is delimited from the charset by the '*' character. eg. We
# might have
# native_charset = 'us-ascii*en'
# and we need to remove '*en'.
# This is the key reason we have function _native2unicode, and
# aren't just calling .decode(charset)!
native_charset = re.sub(r'\*.*$', '', native_charset)
# Search this document for RFC2123 for more information.
# unicode function might not recognize the native_charset and
# hence throw a LookupError. Or it might fail to do the conversion
# and throw a UnicodeError
try:
return unicode(value_nc, native_charset, errors)
except (LookupError, UnicodeError):
raise _UnicodeDecodingError(value_nc, native_charset)
def _process_headers(msg, header_value_pairs, force_processing=False):
f = lambda headers, (header,value): _process_header(msg, headers, header, value, force_processing)
return reduce(f, header_value_pairs, {})
def _decode_rfc2231_tuple(msg, value):
try:
try:
(charset, lang_specification, encoded_value) = value
# If charset is unspecified, then we can assume us-ascii:
if charset == '': charset = 'us-ascii'
return _native2unicode(encoded_value, charset, strict=True)
except ValueError:
# Data was not RFC2231 encoded. ie. value should be just an
# ascii-string.
# Note however that some broken email clients mistakenly use
# RFC2047 encoding in parameterized header fields such as
# Content-Type and Content-Disposition. This is disallowed by
# RFC2047:
# > + An 'encoded-word' MUST NOT be used in parameter of a
# > MIME Content-Type or Content-Disposition field, or in any
# > structured field body except within a 'comment' or
# > 'phrase'.
# In order to support these clients, if we get a string back
# which wasn't RFC2231 encoded, we check instead to see if it
# can be RFC2047 decoded.
# Note that header='rfc2231_param' is just a dummy value;
# we're not really decoding an rfc2047 encoded header;
# just trying to support clients that mistakenly use
# rfc2047 encoding for parameters _within_ structured
# headers.
return _decode_rfc2047_header(msg, header='rfc2231_param', value=value)
except (_UnicodeDecodingError, HeaderCharsetError, HeaderRFC2047Error):
return None
def _decode_and_join_structured_header_pair(msg, key, value):
# Take input that looks like this:
#
# key = 'title'
# value = ('us-ascii', 'en', "This is even more ***fun*** isn't it!")
#
# And return it looking like this:
#
# u'title="This is even more ***fun*** isn't it!"'
# The key should always be just a us-ascii string:
try:
decoded_key = _native2unicode(key, 'us-ascii')
except _UnicodeDecodingError:
raise _StructuredHeaderPairError(key, value)
if value == '':
# We have a structured entry that is not in key=value form. eg. The multipart/mixed in
# 'Content-Type: multipart/mixed; boundary="------------050902070901080909090201"'
return decoded_key
else:
decoded_value = _decode_rfc2231_tuple(msg, value)
if decoded_value is None: raise _StructuredHeaderPairError(key, value)
# Now escape string for addition of quotes either side:
# Escape backslashes:
decoded_value = re.sub(r'\\', r'\\\\', decoded_value)
# Escape quotes:
decoded_value = re.sub(r'"', r'\\"', decoded_value)
return decoded_key + '="' + decoded_value + '"'
def _decode_rfc2231_header(msg, header, value, force_processing=False):
# We get the key/value pairs from the structured header by calling
# the email.ParseMessage class's get_params method. This method deals
# with all of the RFC2231 decoding for us, and so we just have to
# reconstruct the tuples it gives us into a unicode string.
# This means these headers are no longer suitable for parsing by
# machine, but does make them suitable for display (which is
# prefered from two mutually incompatable options; if you want to
# start parsing Content-Type parameters, then you want to be using
# the Python email package directly!).
# Take a value that looks like:
# value =
# And turn it into a unicode string that looks like:
# u'"This is even more ***fun*** isn't it!"'
# The values in the tuple are from left to right are a charset,
# language specification and string of encoded text.
# We ignore the language specification. See list of module
# shortcomings.
# """
params = msg.get_params(None, header)
# param should never return failobj None since we have already
# verified the header we are requesting exists.
if params is None: raise _EmailPackageError
try:
f = lambda (k,v): _decode_and_join_structured_header_pair(msg, k, v)
joined_pairs = map(f, params)
unicode_value = '; '.join(joined_pairs)
except _StructuredHeaderPairError, e:
if force_processing:
unicode_value = None
else:
raise HeaderRFC2231Error(msg, header, value, e.key, e.value)
return unicode_value
def _decode_rfc2047_header(msg, header, value, force_processing=False):
"""
Take an rfc2047 encoded string and convert it to unicode.
"""
# For each header value two decoding steps happen:
# 1. We decode the header from its RFC2047 encoded format.
# 2. We decode the resulting information from its native
# charset to a unicode object.
# decode_header takes the RFC2047 encoded form and returns a list
# of tuples (string_in_native_charset, charset_name). It is a
# *list* not a single tuple, since it is permissible to use
# multiple charsets in a single header value!
# Although undocumented in the python library documentation,
# looking at the email.Header source suggests decode_header might
# raise an 'email.Errors.HeaderParseError'. We catch this and
# raise our own 'HeaderRFC2047Error'.
try:
decoded_parts = email.Header.decode_header(value)
# The _native2unicode function might not recognise one of the
# charsets and so throw a private _UnicodeDecodingError. If we
# get one, then we catch it and raise public error
# "HeaderCharsetError".
f = lambda (value, charset): _native2unicode(value, charset, not force_processing)
unicode_decoded_parts = map(f, decoded_parts)
# Since all members of decoded_parts are now in unicode we can
# concatenate them into a single header value string.
unicode_value = u''.join(unicode_decoded_parts)
except email.Errors.HeaderParseError:
if force_processing:
unicode_value = None
else:
raise HeaderRFC2047Error(msg, header, value)
except _UnicodeDecodingError, e:
if force_processing:
unicode_value = None
else:
raise HeaderCharsetError(msg, header, value, e.value, e.charset)
return unicode_value
def _process_header(msg, headers, header, value, force_processing=False):
# Function _process_header takes a partial headers dictionary
# and a header/value pair and updates the dictionary with this
# pair.
# Headers are decoded from their RFC2231 encoding and turned into
# unicode strings.
# For Content-Type and Content-Disposition headers only, an
# alternative decoding step happens; we attempt to decode these
# structured headers from their RFC2231 encoding and rebuild them
# as unicode strings.
if header.lower() in ('content-type', 'content-disposition'):
unicode_value = _decode_rfc2231_header(msg, header, value, force_processing)
else:
unicode_value = _decode_rfc2047_header(msg, header, value, force_processing)
# Repeated header keys are legal, so we store dictionary
# values as a list. Therefore we must check if this header
# key has already been initialized in the dictionary.
header = header.lower()
headers.setdefault(header, []) # If key header isn't present, add it with value []
headers[header].append(unicode_value)
return headers
def _parse_from_header(msg, from_header):
### !!! Need to do some thinking about internationalized email
### !!! addresses and domain names to check what problems
### !!! these may cause.
(from_name, from_email) = email.Utils.parseaddr(from_header)
# Check we were able to parse the From: field
# (email.Utils.parseaddr returns ('','') on failure) and that
# from_email is not empty. Otherwise raise a FromHeaderParsingError
# empty from_name is OK, since we just use from_email as the
# author's 'name'.
if (from_name, from_email) == ('','') or from_email == '':
raise FromHeaderParsingError(msg)
elif from_name == '':
from_name = from_email
return (from_name, from_email)
def _get_msg_structure(msg, strict, hints):
mime_helper = _MimeHelper(msg)
# mime_helper.maintype = 'multipart'
# mime_helper.subtype = 'parallel'
mime_handler = _get_mime_handler(mime_helper.maintype, mime_helper.subtype)
nominal_attachments = mime_handler(msg, mime_helper, strict, hints)
attachments = []
inline_attachments = []
primary_msg = ''
for item in nominal_attachments:
if item['disposition'] != 'attachment':
if item['maintype'] == 'text' and item['downgrading_to_text'] is None:
primary_msg += _force_ends_in_newline(item['file'])
inline_attachments.append(item)
elif item['downgrading_to_text'] is not None:
primary_msg += _force_ends_in_newline(item['downgrading_to_text'])
inline_attachments.append(item)
else:
attachments.append(item)
else:
attachments.append(item)
return (attachments, inline_attachments, primary_msg)
def _force_ends_in_newline(string):
if string == '' or string[-1] != '\n':
return string + '\n'
else:
return string
def _get_mime_handler(maintype, subtype):
try:
handler = _mime_handler_map[maintype][subtype]
except KeyError:
try:
handler = _mime_handler_map_unrecognized_subtype[maintype]
except KeyError:
handler = _mime_handler_unrecognized_maintype
# Create a 'wrapper' function which does preparatory checks we
# want to happen for all mime type before executing the real mime
# handler (possibly we could have used a class based approach to
# allow for more levels of wrapping, but I think this may have
# been a sledgehammer on nut):
def parent_handler(msg, mhe, strict, hints):
if mhe.decoded_payload is None: # and not mhe.msg_part.is_multipart():
if strict:
raise MIMEPartError(msg, mhe, 'cte_decoding')
else:
return []
if mhe.filename == ['FilenameDecodingError']:
if strict:
raise MIMEPartError(msg, mhe, 'filename_decoding')
else:
mhe.filename = None
if maintype == 'text':
# Make sure text data has unix newline conventions.
mhe.decoded_payload = _cr2lf(mhe.decoded_payload)
try:
mhe.file = _native2unicode(mhe.decoded_payload, mhe.charset, strict)
except _UnicodeDecodingError:
if strict:
raise MIMEPartError(msg, mhe, 'unicode_conversion')
else:
return []
return handler(msg, mhe, strict, hints)
return parent_handler
# Generate filename values: never, always, if_missing
def _format_msg_part_data(mhe, hints):
part_info = {}
part_info['file'] = mhe.file #'UNCOMMENT THIS TO SEE FILE!!!!!' #mhe.file
part_info['downgrading_to_text'] = mhe.downgrading_to_text
part_info['maintype'] = mhe.maintype
part_info['subtype'] = mhe.subtype
part_info['filename'] = mhe.filename
part_info['disposition'] = mhe.disposition
if mhe.maintype == 'text':
part_info['original_charset'] = mhe.charset
part_info['signature'] = mhe.signature
part_info['encrypted'] = mhe.encrypted
part_info['mac_resource_fork'] = mhe.mac_resource_fork
part_info['rejected_alternatives'] = mhe.rejected_alternatives
# Now see if we need to generate a filename:
gf = hints['generate_filename']
if gf == 'always' or (gf == 'if_missing' and (mhe.filename is None or mhe.filename == '')):
generated_filename = _generate_filename(file=mhe.decoded_payload, content_type=(mhe.maintype + '/' + mhe.subtype))
else:
generated_filename = None
part_info['generated_filename'] = generated_filename
return part_info
def _get_part_disposition(msg_part):
"""
Look to see whether this part is designated as inline, attachment
or something else.
"""
# BNF of Content-Disposition header quoted from RFC2183:
# disposition := "Content-Disposition" ":"
# disposition-type
# *(";" disposition-parm)
#
# disposition-type := "inline"
# / "attachment"
# / extension-token
# ; values are not case-sensitive
# The BNF states only "inline" or "attachment" are valid tokens
# for disposition-type, so there is now need to worry about
# RFC2231 encoded data. (And any extension tokens should be
# similarly restricted to simple ascii).
# This dictates that the disposition-type must be the first element in
# the header. get_params returns something like this:
# >>> msg_part.get_params(None, 'Content-Disposition')
# [('inline', ''), ('filename', 'email.txt')]
# So we have to index by [0][0] to get the disposition-type keyword.
try:
return msg_part.get_params(None, 'Content-Disposition')[0][0]
except (TypeError, IndexError):
return None
def _get_part_filename(msg_part):
"""
Attempt to discover a filename associated with a message body
part.
Note that the filename, if it exists, is returned as a unicode
string. Filenames may not be as simple as you expect; what you get
may be a string of Arabic characters.
"""
# Note, we could just use the email.ParseMessage method get_filename to
# try and discover a filename. However, this only checks the
# Content-Disposition header for the filename parameter whereas we
# would like to support crufty old clients which are still using
# the Content-Type name parameter.
missing = []
#First try content-disposition:
filename = msg_part.get_param('filename', missing, 'content-disposition')
if filename != missing:
filename = _decode_rfc2231_tuple(msg_part, filename)
if filename is None:
return ['FilenameDecodingError']
else:
return filename
else:
# If filename parameter of content-disposition is not
# available, try name parameter of content-type:
filename = msg_part.get_param('name', missing, 'content-type')
if filename != missing:
filename = _decode_rfc2231_tuple(msg_part, filename)
if filename is None:
return ['FilenameDecodingError']
else:
# No filename available:
return None
def _cte_decode(msg_part):
"""
Return a message part's payload, decoded from its content
transfer encoding.
"""
# Note that it is possible to use
# msg_part.get_payload(decode=True) to do the CTE
# decoding. Unfortunately, the error reporting of this method is
# not very helpful; if CTE decoding fails, it just returns the
# undecoded payload. This makes it hard to tell if there has been
# success or not. Initially I thought decoding failure could be
# identified by checking if:
# msg_part.get_payload(decode=True) == msg_part.get_payload(decode=False)
# But this method would flag false errors. For example, if text
# contains no 'nasty characters' it will be the same both before
# and after quoted-printable encoding (see the quoted-printable
# RFC for a definition of 'nasty characters!); ie. for such text
# quoted-printable encoding is an identity map.
# The following function is essentially a cut-and-paste of the
# Email.Message.Message class's get_payload method, edited to
# raise _CTEDecodingError upon decoding failure.
# In the case we are passed a multipart message part, we cannot
# decode it and so throw _MultipartCTEDecodingAttempt:
if msg_part.is_multipart(): raise _MultipartCTEDecodingAttempt
payload = msg_part.get_payload(decode=False)
cte = msg_part.get('content-transfer-encoding', '').lower()
try:
if cte == 'quoted-printable':
# Could cause binascii.Error/Incomplete
payload = quopri.decodestring(payload)
elif cte == 'base64':
# Could cause
payload = _base64decode(payload)
elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'):
sfp = StringIO()
uu.decode(StringIO(payload+'\n'), sfp)
payload = sfp.getvalue()
except (binascii.Error, binascii.Incomplete, uu.Error):
raise _CTEDecodingError
return payload
def _base64decode(s):
"""
Decode bas64 encoded string.
"""
# This is a cut and paste of email.Utils._bdecode. We can't call
# _bdecode directly, because its a private function of the Utils
# modules and therefore not safe to import.
# We can't quite use base64.encodestring() since it tacks on a "courtesy
# newline". Blech!
if not s:
return s
value = base64.decodestring(s)
if not s.endswith('\n') and value.endswith('\n'):
return value[:-1]
return value
# MIME Handlers:
def _get_flattened_payload(msg_part, with_mime_headers=False):
flattened_data = msg_part.as_string(unixfrom=False)
# if with_mime_headers is False, then remove them:
if not with_mime_headers:
# Regex should remove from the start of the string up to the
# first double newline '\n\n', with possibly space in-between
# the newlines. This should chop of the mime_headers.
# (?s) in the regex sets the DOTALL flag; ie. '.' matches everything including newline.
flattened_data = re.sub(r'(?s)(.*?\n\n)', r'', flattened_data, count=1)
return flattened_data
def _email_structure_to_directory_structure(email_structure, directory_base=''):
files = []
used_random = {}
alt_part_number = 0
for item in email_structure:
try:
# Is it a list? (ie. a list of alternative parts):
item.append # Does this throw AttributeError? If not, it is list like.
alt_part_number += 1
files.extend(_email_structure_to_directory_structure(email_structure=item,
directory_base=os.path.join(directory_base,
('alternative_data_' + str(alt_part_number)))))
except AttributeError:
# Or a dictionary? (ie. an actual part):
possible_filenames = [item['filename'],
item['generated_filename'],
'unamed_part_' + _get_unused_random(lambda: _random_alphanum_string(length=8), used_random)]
available_filenames = filter(lambda x: x is not None, possible_filenames)
filename = available_filenames[0]
if item['file'] is not None:
files.append((os.path.join(directory_base, filename), item['file']))
else:
files.append((filename, ''))
if item['downgrading_to_text'] is not None:
files.append((os.path.join(directory_base, filename + '.txt'), item['downgrading_to_text']))
return files
def _archive_part(msg, mhe, strict, hints):
processed_parts = _get_mime_handler('multipart', 'mixed')(msg, mhe, strict, hints)
files = _email_structure_to_directory_structure(processed_parts)
mhe.file = elmsubmit_EZArchive.create(files, input_disposition='named_byte_strings',
compress_to='byte_string',
compression=hints['archive_format'],
force_file_permissions=0664,
force_dir_permissions=0775)
mhe.filename = '_'.join([_random_alphanum_string(length=8), mhe.maintype, mhe.subtype,
'archive.' + hints['archive_format']])
def _pick_from_alternatives(processed_parts):
processed_parts.sort(multipart_alternative_sort)
return (processed_parts[0], processed_parts[1:])
def multipart_alternative_sort(part1, part2):
# We deal with multipart/alternative by prefering in descending
# order:
# text/plain, score 6
# text/html, score 5
# text/enriched, score 4
# text/richtext, score 3
# text/rtf, score 2
# application/rtf, score 1
# (the later five we make use of their 'downgrading_to_text')
# Although text/richtext is a simpler format than text/html, it
# has theoretically been obsoleted by text/enriched and so comes
# lower in order of preference.
# A note on the rich text mess: "Why are their four types of rich
# text? Surely they're all the same thing?" Unfortunately not...
# - RFC1341 defines a simple text markup for mime type
# 'text/richtext'.
# - RFC1896 (and some RFCS before it which 1896 obsoletes) defines
# 'text/enriched' which is designed to solve the shortcomings of
# 'text/richtext'; use of 'text/richtext' is deprecated in
# favour of 'text/enriched'
# - 'text/rtf' and 'application/rtf' refer to Microsoft's RTF file
# format, and are not specified in any RFC (that I know of). They
# are the same file format; it's just that the registration got
# duplicated (people weren't sure whether to describe rtf as a
# plaintext format; ie. readable when unparsed by humans, or
# application (ie. needs to be parsed to make any sense of)!
# Some useful reading:
# http://mango.human.cornell.edu/kens/etf.html (text/enriched primer)
# http://www.faqs.org/rfcs/rfc1896.html (text/enriched RFC)
# http://www.faqs.org/rfcs/rfc1341.html (text/richtext RFC)
# News message ID: <199306081944.AA13622@mudhoney.micro.umn.edu>
# (the thread this message sits in contains the
# registrations of text/rtf and application/rtf)
liked_formats = [ 'text/plain',
'text/html',
'text/enriched',
'text/richtext',
'text/rtf',
'application/rtf' ]
scorecard = dict(zip(liked_formats, range(len(liked_formats), 0, -1)))
# Create something that looks like this:
# {'application/rtf': 1,
# 'text/enriched': 4,
# 'text/html': 5,
# 'text/plain': 6,
# 'text/richtext': 3,
# 'text/rtf': 2}
# Doing the calculation instead of hardcoding allows liked_formats
# to be rearranged more easily!
# Part types not in this list get score 0.
score1 = scorecard.get(part1['maintype'] + '/' + part1['subtype'], 0)
score2 = scorecard.get(part2['maintype'] + '/' + part2['subtype'], 0)
# We want the list in reverse order, big down to small:
return cmp(score2, score1)
def _get_unused_random(rand_function, used_random):
r = rand_function()
while used_random.has_key(r):
r = rand_function()
used_random[r] = True
return r
class _MimeHelper(object):
def __init__(self, msg_part):
self.msg_part = msg_part
self.maintype = msg_part.get_content_maintype()
self.subtype = msg_part.get_content_subtype()
if self.maintype == 'text':
self.charset = msg_part.get_content_charset('us-ascii')
else:
self.charset = None
self.disposition = _get_part_disposition(msg_part)
self.filename = _get_part_filename(msg_part)
self.signed = False
self.signature = None
self.encrypted = False
self.mac_resource_fork = None
self.downgrading_to_text = None
self.rejected_alternatives = None
if msg_part.is_multipart():
# If multipart, get the flattened payload.
self.decoded_payload = _get_flattened_payload(msg_part, with_mime_headers=False)
else:
# If its not multipart, attempt CTE decoding and store
# result:
try:
self.decoded_payload = _cte_decode(msg_part)
except (_CTEDecodingError, _MultipartCTEDecodingAttempt):
self.decoded_payload = None
def _mime_handler_application_applefile(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet'}]
def _mime_handler_application_octetstream(msg, mhe, strict, hints):
# application/octet-stream requires no special handling. All of
# the necessary work has been done in the parent handler.
mhe.file = mhe.decoded_payload
return [ _format_msg_part_data(mhe, hints) ]
def _mime_handler_application_pgpencrypted(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
def _mime_handler_application_pgpkeys(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
def _mime_handler_application_pgpsignature(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
def _mime_handler_application_rtf(msg, mhe, strict, hints):
# application/rtf is same as text/rtf, so call _get_mime_handler
# to retrieve correct handler.
# Note that we can't just execute _mime_handler_text_rtf directly,
# because this would miss the neccessary parent_handler code,
# which depends on knowing if maintype is 'text' (which the
# misregistered application/rtf would hide):
return _get_mime_handler('text', 'rtf')(msg, mhe, strict, hints)
def _mime_handler_message_externalbody(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
# def _mime_handler_message_news(msg, mhe, strict, hints):
# pass
# Currently just treat as application/octet-stream.
def _mime_handler_message_partial(msg, mhe, strict, hints):
if strict:
raise MIMEPartError(msg, mhe, 'not_implemented')
else:
return []
def _mime_handler_message_rfc822(msg, mhe, strict, hints):
if not hints['descend_message_rfc822_attachments']:
# Treat as a binary attachment.
return _get_mime_handler('application', 'octet-stream')(msg, mhe, strict, hints)
else:
# Descend into the message as if it were a multipart/mixed
# type.
return _get_mime_handler('multipart', 'mixed')(msg, mhe, strict, hints)
def _mime_handler_multipart_alternative(msg, mhe, strict, hints):
# We handle multipart alternative just like multipart mixed, but
# then pick our prefered alternative, storing the remaining
# alternatives in mhe.rejected_alternatives.
(prefered, rejects) = _pick_from_alternatives(_get_mime_handler('multipart', 'mixed')(msg, mhe, strict, hints))
prefered['rejected_alternatives'] = rejects
return [ prefered ]
def _mime_handler_multipart_appledouble(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
def _mime_handler_multipart_encrypted(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
def _mime_handler_multipart_mixed(msg, mhe, strict, hints):
# We ignore Content-Disposition for multipart/mixed parts, as want
# to process them the same regardless.
# Generate mime helpers for each part of the multipart collection:
mime_helpers = map(_MimeHelper, mhe.msg_part.get_payload())
# Get a mime handler for each part, and execute it:
f = lambda mhe: _get_mime_handler(mhe.maintype, mhe.subtype)(msg, mhe, strict, hints)
list_of_lists_of_processed_parts = map(f, mime_helpers)
# Flatten the results:
return _concat(list_of_lists_of_processed_parts)
def _mime_handler_multipart_signed(msg, mhe, strict, hints):
return [{mhe.maintype : 'not implemented yet', mhe.subtype : 'problems!'}]
def _mime_handler_multipart_unrecognized(msg, mhe, strict, hints):
if hints['archive_multipart_unrecognized']:
_archive_part(msg, mhe, strict, hints)
return [ _format_msg_part_data(mhe, hints) ]
else:
# Descend into the message as if it were a multipart/mixed
# type.
return _get_mime_handler('multipart', 'mixed')(msg, mhe, strict, hints)
def _mime_handler_multipart_parallel(msg, mhe, strict, hints):
if hints['archive_multipart_parallel']:
_archive_part(msg, mhe, strict, hints)
return [ _format_msg_part_data(mhe, hints) ]
else:
# Descend into the message as if it were a multipart/mixed
# type.
return _get_mime_handler('multipart', 'mixed')(msg, mhe, strict, hints)
def _mime_handler_multipart_related(msg, mhe, strict, hints):
if hints['archive_multipart_related']:
_archive_part(msg, mhe, strict, hints)
return [ _format_msg_part_data(mhe, hints) ]
else:
# Descend into the message as if it were a multipart/mixed
# type.
return _get_mime_handler('multipart', 'mixed')(msg, mhe, strict, hints)
def _mime_handler_text_enriched(msg, mhe, strict, hints):
# Covert the text/enriched data to plain text and store it:
# mhe.file is already a unicode string.
# enriched2txt function doesn't have any public errors:
mhe.downgrading_to_text = _enriched2txt.enriched2txt(_native2unicode(mhe.decoded_payload, native_charset=mhe.charset, strict=strict))
return [ _format_msg_part_data(mhe, hints) ]
def _mime_handler_text_html(msg, mhe, strict, hints):
# Covert the text/richtext data to plain text and store it. We
# pass richtext2txt the original non-unicode text string and it
# will pass us back a unicode string:
try:
# html2txt expects unicode in, and spits unicode out:
mhe.downgrading_to_text = _html2txt.html2txt(_native2unicode(mhe.decoded_payload, native_charset=mhe.charset, strict=strict), cols=72)
except _html2txt.HTMLParsingFailed:
if strict:
raise MIMEPartError(msg, mhe, 'downgrading_to_text')
else:
mhe.downgrading_to_text = None
return [ _format_msg_part_data(mhe, hints) ]
def _mime_handler_text_plain(msg, mhe, strict, hints):
return [ _format_msg_part_data(mhe, hints) ]
def _mime_handler_text_richtext(msg, mhe, strict, hints):
# Covert the text/richtext data to plain text and store it. We
# pass richtext2txt the original non-unicode text string and it
# will pass us back a unicode string:
try:
# richtext2txt always returns unicode for us:
mhe.downgrading_to_text = _richtext2txt.richtext2txt(mhe.decoded_payload, charset=mhe.charset,
convert_iso_8859_tags=True, force_conversion=(not strict))
except _richtext2txt.RichTextConversionError:
if strict:
raise MIMEPartError(msg, mhe, 'downgrading_to_text')
else:
mhe.downgrading_to_text = None
return [ _format_msg_part_data(mhe, hints) ]
def _mime_handler_text_rtf(msg, mhe, strict, hints):
# Note: This parser has some unicode issues which need to be
# fixed! The project seems fairly active...
# Use RtfLib to convert rtf string to text.
try:
mhe.downgrading_to_text = rtf.Rtf2Txt.getTxt(_native2unicode(mhe.decoded_payload, native_charset=mhe.charset, strict=strict))
except _RtfException:
if strict:
raise MIMEPartError(msg, mhe, 'downgrading_to_text')
else:
mhe.downgrading_to_text = None
return [ _format_msg_part_data(mhe, hints) ]
# Content-Type to Handler mappings:
_mime_handler_map_application = { 'applefile' : _mime_handler_application_applefile,
'octet-stream' : _mime_handler_application_octetstream,
'pgp-encrypted' : _mime_handler_application_pgpencrypted,
'pgp-keys' : _mime_handler_application_pgpkeys,
'pgp-signature' : _mime_handler_application_pgpsignature,
'rtf' : _mime_handler_application_rtf }
_mime_handler_map_audio = { } # No special audio handlers defined.
_mime_handler_map_image = { } # No special image handlers defined.
_mime_handler_map_message = { 'external-body' : _mime_handler_message_externalbody,
# 'news' : _mime_handler_application_octetstream,
'partial' : _mime_handler_message_partial, # not supported!
'rfc822' : _mime_handler_message_rfc822 }
_mime_handler_map_model = { } # No special models handlers defined.
_mime_handler_map_multipart = { 'alternative' : _mime_handler_multipart_alternative,
'appledouble' : _mime_handler_multipart_appledouble,
'encrypted' : _mime_handler_multipart_encrypted,
'mixed' : _mime_handler_multipart_mixed,
'parallel' : _mime_handler_multipart_parallel,
'related' : _mime_handler_multipart_related,
'signed' : _mime_handler_multipart_signed }
_mime_handler_map_text = { 'enriched' : _mime_handler_text_enriched,
'html' : _mime_handler_text_html,
'plain' : _mime_handler_text_plain,
'richtext' : _mime_handler_text_richtext,
'rtf' : _mime_handler_text_rtf }
_mime_handler_map_video = { } # No special video handlers defined.
_mime_handler_map = { 'application' : _mime_handler_map_application,
'audio' : _mime_handler_map_audio,
'image' : _mime_handler_map_image,
'message' : _mime_handler_map_message,
'model' : _mime_handler_map_model,
'multipart' : _mime_handler_map_multipart,
'text' : _mime_handler_map_text,
'video' : _mime_handler_map_video }
# Unrecognized types are handled according to the recomendations of
# RFC2046 which mandates that unrecognized parts of given maintype be
# dealt with as follows:
# application -> application/octet-stream
# audio -> application/octet-stream
# image -> application/octet-stream
# message -> application/octet-stream
# model -> application/octet-stream
# In the multipart case, however, we give the module client two
# choices of how to treat unrecognized multipart sections: either as
# multipart/mixed, or to wrap up each of the sub-parts into a tar.gz
# and present this as if it had been a single attachment.
# multipart -> multipart/mixed
# text -> text/plain
# video -> application/octet-stream
_mime_handler_map_unrecognized_subtype = { 'application' : _mime_handler_application_octetstream,
'audio' : _mime_handler_application_octetstream,
'image' : _mime_handler_application_octetstream,
'message' : _mime_handler_application_octetstream,
'model' : _mime_handler_application_octetstream,
'multipart' : _mime_handler_multipart_unrecognized,
'text' : _mime_handler_text_plain,
'video' : _mime_handler_application_octetstream }
_mime_handler_unrecognized_maintype = _mime_handler_application_octetstream
# Message Creation:
# Whereas ParseMessage is a class, CreateMessage is just a function
# which returns the email as an ascii byte string.
# Creation is an order of magnitude simpler than parsing. When parsing
# we have to try and be able to cope with everything seen out 'in the
# wild'. With creation, we can simply restrict what is allowed to be
# created to a sensible set of options.
# CreateMessage restricts you to a single plain text body plus any
# number of attached files and any number of attached emails. This
# will all be stuffed into a single multipart/mixed container (unless
# there is only a single part to be added, in which case we skip the
# multipart/mixed container). This is how email should be sent by good
# internet citizens. If this doesn't fit your needs, then your needs
# are esoteric (and if you want to send html email, then you're just
# plain evil)!
def CreateMessage(_from,
to,
subject,
cc=None,
bcc=None,
message=None,
attach_messages=[],
attach_files=[],
message_id=None,
references=None,
in_reply_to=None,
date=None,
wrap_message=False,
cols=80):
"""
Returns a byte string containing the email constructed from the
following arguments:
_from: Either: 1. An ascii string already suitable for inclusion
in this email header (eg. a string you have
torn directory out of another email.
2. A 2-tuple (name, email_address), where name is
a persons name and email_address is their
email address. name must be a unicode object.
email_address can be either a unicode object
or a byte string.
to,
cc,
bcc: Either: 1. An ascii string already suitable for inclusion
in this email header (eg. a string you have
torn directory out of another email.
2. A _list_ of items defined in the same way as
_from option 1.
subject: Either: 1. An ascii string already suitable for inclusion
in this email header (eg. a string you have
torn directory out of another email.
2. A unicode object.
message: A unicode object containing what will be the
message body text.
attach_files: A list of 2-tuples, (filename, open_file_object)
where filename must be a unicode object and
open_file_object must be an open python file
object in mode 'rb'.
message_id: An ascii string containing a message-id.
references: A list of objects defined like argument message_id.
in_reply_to: A list of objects defined like argument message_id.
date: A ascii string containing an rfc822 formatted date string.
wrap_message: True/False whether you want to have the message body
wrapped to the width given in argument cols.
cols: A integer column width.
"""
if message is not None:
mime_message = [_mimeify_message(message, wrap_message, cols)]
else:
mime_message = []
mime_attached_messages = map(_mimeify_attach_message, attach_messages)
mime_attached_files = map(_mimeify_attach_file, attach_files)
mime_parts = mime_message + mime_attached_messages + mime_attached_files
if mime_parts == []:
raise EZEmailCreateError("At least one of message, attach_messages or attach_files must be specified.")
elif len(mime_parts) == 1:
# Only one payload, so don't need multipart.
main_part = mime_parts[0]
else:
main_part = email.MIMEMultipart.MIMEMultipart()
map(main_part.attach, mime_parts)
main_part.preamble = 'This message requires a mime aware email reader to be viewed correctly.\n'
# Force ending in newline:
main_part.epilogue = ''
eH = email.Header.Header
# The .encode() call here shouldn't be doing any encoding other
# splitting the header onto multiple continuation lines, since we
# are already providing eH with safely asciified strings.
main_part['From'] = eH(_mimeify_address(_from)).encode()
main_part['Subject'] = eH(_mimeify_unstructured(subject)).encode()
for (header, value) in [('To', to),('Cc', cc), ('Bcc', bcc)]:
if value is None:
continue
if isinstance(value, str):
main_part[header] = eH(value).encode()
else:
main_part[header] = eH(', '.join(map(_mimeify_address, value))).encode()
if message_id is not None:
main_part['Message-ID'] = eH(message_id).encode()
else:
main_part['Message-ID'] = email.Utils.make_msgid()
if references is not None:
main_part['References'] = eH(', '.join(references)).encode()
if in_reply_to is not None:
main_part['In-Reply-To'] = eH(in_reply_to).encode()
if date is not None:
main_part['Date'] = eH(date).encode()
else:
main_part['Date'] = email.Utils.formatdate()
# s = smtplib.SMTP()
# print ">>>fnah"
# s.connect(host='smtp.ox.ac.uk')
# s.sendmail('one@tes.la', 'foo@tes.la', main_part.as_string())
# s.close()
return main_part.as_string()
def _mimeify_message(message, wrap_message, cols):
if wrap_message:
message = _wrap_text(message, cols)
if _just_ascii(message):
charset = 'us-ascii'
else:
charset = 'utf8'
msg_part = email.MIMEText.MIMEText(_text=message.encode(charset),
_subtype='plain',
_charset=charset)
msg_part.add_header('Content-Disposition', 'inline')
return msg_part
def _mimeify_attach_message(message_rfc822):
message_rfc822 = email.message_from_string(message_rfc822)
return email.MIMEMessage.MIMEMessage(message_rfc822, 'rfc822')
def _mimeify_attach_file((filename_unicode, fh)):
# fh = python file handle
# Guess the content type based on file extension.
content_type, encoding = mimetypes.guess_type(filename_unicode)
if encoding == 'gzip':
content_type = 'application/x-gzip'
elif encoding == 'compress':
content_type = 'application/x-gzip'
elif encoding is not None:
# we don't recognize the encoding:
content_type = 'application/octet-stream'
else:
# encoding is None; we are safe to use the content_type
# returned by mimetypes.
pass
# Check that mimetypes actually returned a content_type:
if content_type is None:
content_type = 'application/octet-stream'
maintype, subtype = content_type.split('/', 1)
if maintype == 'text':
# This is what we should be doing:
# msg_part = email.MIMEText.MIMEText(fh.read(), _subtype=subtype)
# but until I gather together character encoding detection,
# everything text is going to be attached as
# application/octet-stream.
msg_part = email.MIMEBase.MIMEBase('application', 'octet-stream')
msg_part.set_payload(fh.read())
# Encode the payload using Base64
email.Encoders.encode_base64(msg_part)
elif maintype == 'image':
msg_part = email.MIMEImage.MIMEImage(fh.read(), _subtype=subtype)
elif maintype == 'audio':
msg_part = email.MIMEAudio.MIMEAudio(fh.read(), _subtype=subtype)
else:
msg_part = email.MIMEBase.MIMEBase(maintype, subtype)
msg_part.set_payload(fh.read())
# Encode the payload using Base64
email.Encoders.encode_base64(msg_part)
# Set the filename parameter
msg_part.add_header('Content-Disposition', 'attachment')
_set_filename(msg_part, filename_unicode)
return msg_part
def _mimeify_address(address):
if isinstance(address, str):
return address
else:
(name, email_addr) = address
return email.Utils.formataddr((_mimeify_unstructured(name), email_addr))
def _set_filename(msg_part, filename_unicode):
# Filename parameter of structured header gets rfc2231 encoded:
if _just_ascii(filename_unicode):
filename = filename_unicode.encode('us-ascii')
msg_part.set_param(param='filename', value=filename,
header='Content-Disposition')
else:
charset = 'utf8'
filename = filename_unicode.encode('utf8')
msg_part.set_param(param='filename', value=filename,
header='Content-Disposition', charset=charset)
def _mimeify_unstructured(string):
if not isinstance(string, unicode):
# Unstructured fields get RFC2047 encoded.
return string
elif _just_ascii(string):
return string.encode('us-ascii')
else:
return str(email.Header.make_header([(string.encode('utf8'), 'utf8')]))
def _just_ascii(unicode_string):
# Are are the objects in the unicode string ascii character?:
return unicode_string.encode('utf8') == unicode_string.encode('us-ascii', 'ignore')
# Error classes.
class _EmailPackageError(Exception):
"""
Private error that will only be thrown for suspected programming
errors in the Python email package.
"""
class EZEmailError(Exception):
pass
class EZEmailParseError(EZEmailError):
"""
An emtpy parent class for all public errors in this module.
"""
def __init__(self, msg):
"""
"""
self.basic_email_info = _basic_email_info(msg)
Exception.__init__(self)
class EZEmailCreateError(Exception):
pass
class _EZEmailPrivateError(Exception):
"""
An emtpy parent class for all private errors in this module.
"""
pass
class _UnicodeDecodingError(_EZEmailPrivateError):
"""
This is a private error which can be raised if attempting to use
the unicode builtin fails because the charset we try to decode
from isn't recognized.
"""
def __init__(self, value, charset):
"""
Constructor takes single argument; a string giving the name of
the problem charset.
"""
self.value = value
self.charset = charset
class _StructuredHeaderPairError(_EZEmailPrivateError):
"""
This is a private error which will be raised if there is an error
trying to parse and rejoin a key/value pair from a structured
header.
"""
def __init__(self, key, value):
self.key = key
self.value = value
class HeaderRFC2231Error(EZEmailParseError):
"""
This error is raised if we can't decode a structured header
(eg. Content-Type or Content-Disposition) successfully.
"""
def __init__(self, msg, header, header_value, key, key_value):
self.header = header
self.header_value = header_value
self.key = key
self.key_value = key_value
EZEmailParseError.__init__(self, msg)
class HeaderCharsetError(EZEmailParseError):
"""
This error is raised if we can't recognize one of the charsets
used in a particular header.
"""
def __init__(self, msg, header, header_value, problem_part, charset):
"""
Constructor takes an email.Message message object and header,
value and charset (in their original rfc2047 encoding) as
arguments and stores them.
"""
self.header = header
self.header_value = header_value
self.problem_part = problem_part
self.charset = charset
EZEmailParseError.__init__(self, msg)
def __str__(self):
return "header: %s\nheader value: %s\nproblem part: %s\ncharset: %s" % (self.header, self.header_value, self.problem_part, self.charset)
class HeaderRFC2047Error(EZEmailParseError):
"""
This error is raised if we can't parse the RFC2047 encoding used
in a particular header.
"""
def __init__(self, msg, header, value):
"""
Constructor takes an email.Message message object and header,
value and charset (in their original rfc2047 encoding) as
arguments and stores them.
"""
self.header = header
self.value = value
EZEmailParseError.__init__(self)
def __str__(self):
return "\nheader: %s\nvalue: %s\ninfo: %s" % (self.header, self.value, self.basic_email_info)
class FromHeaderParsingError(EZEmailParseError):
"""
We have a From: header we can't parse.
"""
def __str__(self):
return "\ninfo: %s" % (self.basic_email_info)
class FromHeaderMissingError(EZEmailParseError):
"""
Somehow we have recieved a seriously broken email with no From: header. Reject!
"""
pass
class _ParseDateError(_EZEmailPrivateError):
"""
Private error raised when email.Utils.parsedate or
email.Utils.parsedate_tz fails to parse a date header value.
"""
pass
class ParseDateError(EZEmailParseError):
"""
Public error raised when email.Utils.parsedate or
email.Utils.parsedate_tz fails to parse a date header value.
"""
pass
class _CTEDecodingError(_EZEmailPrivateError):
pass
class _MultipartCTEDecodingAttempt(_EZEmailPrivateError):
"""
Raised if an attempt is made to CTE decode a multipart message
part.
"""
pass
class MIMEPartError(EZEmailParseError):
def __init__(self, msg, mhe, error_type):
self.maintype = mhe.maintype
self.subtype = mhe.subtype
self.filename = mhe.filename
if mhe.decoded_payload is None or mhe.msg_part.is_multipart():
# If we haven't decoded payload successfully, take sample
# from CTE encoded payload:
self.sample = mhe.msg_part.get_payload()[0:100]
else:
# Otherwise, take sample from CTE decoded payload:
self.sample = mhe.decoded_payload[0:100]
if error_type in self.valid_error_types:
self.error_type = error_type
else:
raise ValueError('Programming Error: error_type = \'' + error_type +
'\' is not valid for MIME parts')
EZEmailParseError.__init__(self, msg)
valid_error_types = ['cte_decoding', 'filename_decoding', 'downgrading_to_text',
'unicode_conversion', 'not_implemented']
def __str__(self):
return "maintype: %s\nsubtype: %s\nfilename: %s\nsample: %s\nerror_type: %s" % (self.maintype, self.subtype, self.filename, self.sample, self.error_type)
class EZEmailCreateError(EZEmailError):
pass
if __name__ == "__main__":
import sys
# import profile
def f():
for filename in sys.stdin.xreadlines():
print filename,
filename = filename[:-1]
contents(filename)
print "==="
a = ParseMessage(open(filename, 'rb').read(), strict=False)
print a.primary_message()
f()
# profile.run('f()')
diff --git a/modules/elmsubmit/lib/elmsubmit_config.py b/modules/elmsubmit/lib/elmsubmit_config.py
index 28194e0e0..5adc82eb9 100644
--- a/modules/elmsubmit/lib/elmsubmit_config.py
+++ b/modules/elmsubmit/lib/elmsubmit_config.py
@@ -1,92 +1,92 @@
## $Id$</protect>
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
# elmsubmit configuration file:
files = {'prefix': '/soft/cdsware-PCDH23',
'localstatedir': '/soft/cdsware-PCDH23/var',
'storagedir': '/soft/cdsware-PCDH23/var/data/submit/storage',
'maildir': '/soft/cdsware-PCDH23/var/data/submit/storage/mail'}
# Messages we need to send to the user, before we've identified the
# correct language to talk to them in (so we assume English!):
nolangmsgs = {'bad_email': 'Your email could not be parsed correctly to discover a submission. Please check your email client is functioning correctly.',
'bad_submission': 'The submission data that you have provided could not be parsed correctly. Please visit <http://pcdh23.cern.ch> for a description of the correct format.',
'missing_type': 'The submission data that you have provided does not contain a TYPE field. This is mandatory for all submissions.',
'unsupported_type': 'The TYPE field of your submission does not contain a recognized value.',
'missing_fields_1': 'Your submission of type',
'missing_fields_2': 'does not contain all the required fields:',
'bad_field': 'This field does not validate correctly:',
'correct_format': 'It must be formatted as follows:',
'missing_attachment': 'We could not find the following file attached to your submission email:',
'temp_problem': 'There is a temporary problem with CDSware\'s email submission interface. Please retry your submission again shortly.'}
servers = {'smtp': 'localhost'}
people = {'admin': 'cds.support@cern.ch'}
# fields required in the submission mail
required_fields = ['title',
'author',
'date',
'files']
# defines the mapping of metadata fields to their marc codes
# mapping code as a list means the first element is mapped to the first element
# of the list, and the rest to the second
marc_mapping = {'author': ['100__a','700__a'],
'title': '245__a',
'subtitle': '245__b',
'photocaption': '246__b',
'subject': '65017a',
'secondary_subject': '65027a',
'email': '8560_f',
'files': ['FFT__a','FFT__a'],
'affiliation': ['100__u', '700__u'],
'language': '041__a',
'abstract': '520__a',
'keywords': '6531_a',
'OAIid': '909COo',
'PrimaryReportNumber': '037__a',
'AdditionalReportNumber': '088__a',
'series': ['490__a','490__v'],
'year': '260__a',
'note': '500__a',
#test tags used in test cases
'test1': '111__a',
'test2': '111__b',
'test3': '111__c',
'test4': '111__d',
'test5': '111__e'
}
# the list of the fields determines which subfields should be joined into a
# single datafield
marc_fields_joined = {'700__': [['a', 'u']],
'100__': [['a', 'u']],
#test tags
'111__': [['a','c'],['b','d']]
}
diff --git a/modules/elmsubmit/lib/elmsubmit_doctype_test.py b/modules/elmsubmit/lib/elmsubmit_doctype_test.py
index ad729d167..23c5352ad 100644
--- a/modules/elmsubmit/lib/elmsubmit_doctype_test.py
+++ b/modules/elmsubmit/lib/elmsubmit_doctype_test.py
@@ -1,76 +1,76 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import cdsware.elmsubmit as elmsubmit
import cdsware.websubmit_engine as websubmit_engine
from cdsware.elmsubmit_misc import dict2file as _dict2file
import os.path
required_fields = ['title',
'author',
'date',
'files']
doctype = 'TEST'
def handler(msg, submission_dict, elmconf):
# Process the files list:
elmsubmit.process_files(msg, submission_dict)
# Get a submission directory:
storage_dir = elmsubmit.get_storage_dir(msg, doctype)
access = os.path.basename(storage_dir)
# Write the neccessary data format out to submission directory:
try:
_dict2file(submission_dict, storage_dir)
except EnvironmentError:
response_email = elmconf.nolangmsgs.temp_problem
admin_response_email = "There was a problem writing data to directory %s." % (storage_dir)
error = elmsubmit.elmsubmitError("There was a problem writing data to directory %s." % (storage_dir))
return (response_email, admin_response_email, error)
# Pass the submission to CDSware proper:
try:
websubmit_engine.simpleendaction(doctype=doctype, act="SBI", startPg=1,
indir=os.path.basename(elmconf.files.maildir),
access=access)
except websubmit_engine.functionError, e:
response_email = elmconf.nolangmsgs.temp_problem
admin_response_email = None
error = elmsubmit.elmsubmitError("elmsubmit encountered websubmit functionError error: " + e.value)
return (response_email, admin_response_email, error)
except websubmit_engine.functionStop, e:
response_email = elmconf.nolangmsgs.temp_problem
admin_response_email = "elmsubmit encountered websubmit error: " + e.value
error = elmsubmit.elmsubmitError("elmsubmit encountered websubmit functionStop error: " + e.value)
return (response_email, admin_response_email, error)
# CDSWare proper will now email the user for us.
return (None, None, None)
diff --git a/modules/elmsubmit/lib/elmsubmit_enriched2txt.py b/modules/elmsubmit/lib/elmsubmit_enriched2txt.py
index d9e822b38..ee7f264f5 100644
--- a/modules/elmsubmit/lib/elmsubmit_enriched2txt.py
+++ b/modules/elmsubmit/lib/elmsubmit_enriched2txt.py
@@ -1,227 +1,227 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
A text/enriched to text/plain converter.
This is a module exporting a single function enriched2txt which
takes as its argument a string of 'enriched text' and returns its
conversion to 'plain text'. 'enriched text' is the text format as
specified in RFC1896 for use as an email payload with mime type
text/enriched.
Note that it is somewhat simpler than the text/richtext converter (see
elmsubmit_richtext2txt.py); this is largely thanks to the enriched
text specification attempting to remove many of the complexities found
in text/richtext; eg. superscript tags, iso-8859-x tags.
If you hand enriched2txt a regular string, the algorithm assumes
7-bit ascii. If you wish to parse internationalized text, make sure
you either:
1. Use an encoding that can be treated safely as if it were 7-bit
ascii (eg. utf-8)
or better:
2. Pass in a unicode object.
This function is a direct conversion of the C code from the appendix
of RFC1896 which gives a sample enriched text to plain text
converter. This is a quick conversion job, since text/enriched email
payload is fairly rare these days and so not worth too much time
considering. I haven't paid much thought as to the quality of the
original algorithm --- hopefully the RFC writer had his thinking cap
on straight; it seems to produce fairly reasonable output on test
documents.
Note that one difference in the python version of the parser is that
it allows markup tokens of unlimited size.
Unlike the specification for text/richtext (see RFC1341), only one
charset is allowed in any text/enriched file. Quoting RFC1896:
> 1 For cases where the different types of non-ASCII text can be
> limited to their own paragraphs with distinct formatting, a
> multipart message can be used with each part having a Content-Type
> of text/enriched and a different charset parameter. The one caveat
> to using this method is that each new part must start in the initial
> state for a text/enriched document. That means that all of the
> text/enriched commands in the preceding part must be properly
> balanced with ending commands before the next text/enriched part
> begins. Also, each text/enriched part must begin a new paragraph.
> 2 If different types of non-ASCII text are to appear in the same
> line or paragraph, or if text/enriched formatting (e.g. margins,
> typeface, justification) is required across several different types
> of non-ASCII text, a single text/enriched body part should be used
> with a character set specified that contains all of the required
> characters. For example, a charset parameter of "UNICODE-1-1-UTF-7"
> as specified in [RFC-1642] could be used for such purposes. Not only
> does UNICODE contain all of the characters that can be represented
> in all of the other registered ISO 8859 MIME character sets, but
> UTF-7 is fully compatible with other aspects of the text/enriched
> standard, including the use of the "<" character referred to
> below. Any other character sets that are specified for use in MIME
> which contain different types of non-ASCII text can also be used in
> these instances.
"""
def enriched2txt(string):
# f and g will be our input/output streams.
# We instantiate them as cStringIO objects for speed if the input
# string is not unicode (ie. its a normal string type). Otherwise
# we make them StringIO objects.
if type(string) != unicode:
import cStringIO
# Create file like object from string for input file.
f = cStringIO.StringIO(string)
# Create another file like object from string for output file.
g = cStringIO.StringIO()
else:
import StringIO
# Create file like object from string for input file.
f = StringIO.StringIO(string)
# Create another file like object from string for output file.
g = StringIO.StringIO(u'')
# From here on in we are almost identical to the RFC1896 code, except substitute:
# STDIN -> object f
# STDOUT -> object g
# EOF -> ''
# ungetc -> seek(-1,1)
paramct = 0
newlinect = 0
nofill = 0
c = f.read(1)
while c != '':
if (c == '<'):
if newlinect == 1: g.write(' ')
newlinect = 0;
c = f.read(1)
if (c == '<'):
if paramct <= 0: g.write(c)
else:
f.seek(-1,1)
token = ""
c = f.read(1)
while c != '' and c!= '>':
token += c
c = f.read(1)
if c == '': break
token = token.lower()
if token == 'param':
paramct += 1
elif token == 'nofill':
nofill += 1
elif token == '/param':
paramct -= 1
elif token == '/nofill':
nofill -= 1
else:
if paramct > 0:
pass # ignore params
elif c == '\n' and nofill <= 0:
newlinect += 1
if newlinect > 1: g.write(c)
else:
if newlinect == 1: g.write(' ')
newlinect = 0
g.write(c)
c = f.read(1)
g.write('\n')
return g.getvalue()
# The original C code direct from RFC1896 appendix.
# See: http://people.qualcomm.com/presnick/textenriched.html
# #include <ctype.h>
# #include <stdio.h>
# #include <stdlib.h>
# #include <string.h>
# main() {
# int c, i, paramct=0, newlinect=0, nofill=0;
# char token[62], *p;
# while ((c=getc(stdin)) != EOF) {
# if (c == '<') {
# if (newlinect == 1) putc(' ', stdout);
# newlinect = 0;
# c = getc(stdin);
# if (c == '<') {
# if (paramct <= 0) putc(c, stdout);
# } else {
# ungetc(c, stdin);
# for (i=0, p=token; (c=getc(stdin)) != EOF && c != '>'; i++) {
# if (i < sizeof(token)-1)
# *p++ = isupper(c) ? tolower(c) : c;
# }
# *p = '\0';
# if (c == EOF) break;
# if (strcmp(token, "param") == 0)
# paramct++;
# else if (strcmp(token, "nofill") == 0)
# nofill++;
# else if (strcmp(token, "/param") == 0)
# paramct--;
# else if (strcmp(token, "/nofill") == 0)
# nofill--;
# }
# } else {
# if (paramct > 0)
# ; /* ignore params */
# else if (c == '\n' && nofill <= 0) {
# if (++newlinect > 1) putc(c, stdout);
# } else {
# if (newlinect == 1) putc(' ', stdout);
# newlinect = 0;
# putc(c, stdout);
# }
# }
# }
# /* The following line is only needed with line-buffering */
# putc('\n', stdout);
# exit(0);
# }
diff --git a/modules/elmsubmit/lib/elmsubmit_field_validation.py b/modules/elmsubmit/lib/elmsubmit_field_validation.py
index 6461debe3..d354df13e 100644
--- a/modules/elmsubmit/lib/elmsubmit_field_validation.py
+++ b/modules/elmsubmit/lib/elmsubmit_field_validation.py
@@ -1,94 +1,94 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import re
def author(value):
"""
The author list must be in the following format:
Put one author per line, and a comma ',' (with no preceding
space) between the name and the firstname initial letters.
The name is going first, followed by the firstname initial
letters. Precede each initial by a single space. Place only a
single space between surnames.
Example: Put
Le Meur, J Y
Baron, T
for
Le Meur Jean-Yves & Baron Thomas.
"""
# Strip each line of leading/trainling whitespace and remove blank lines.
value = '\n'.join(filter(lambda line: line != '', map(lambda line: line.strip(), value.splitlines())))
# txt = txt.replace("\r\n", "\n") # Change to unix newline conventions.
# Allow names like:
# 'MacDonald Schlüter Wolsey-Smith, P J'
hyphenated_word = r'\w+(-\w+)*'
author_surname = r'%s( %s)*' % (hyphenated_word, hyphenated_word)
comma_space = r', '
initials = r'\w( \w)*'
author_re = author_surname + comma_space + initials
# Allow multiline list with no trailing spaces, and only single
# (optional) terminating newline:
author_list = r'(?u)^%s(\n%s)*?$' % (author_re, author_re)
if re.compile(author_list).search(value):
return (author.__doc__, value, True)
else:
return (author.__doc__, value, False)
def date(value):
"""
The date field must be in dd/mm/yyyy format.
eg. 01/03/2010
"""
value = value.strip()
day = '(3[01]|[12][0-9]|0[1-9])'
month = '(1[012]|0[1-9])'
year = '(\d\d\d\d)'
date_re = r'^%s/%s/%s(?!\n)$' % (day, month, year)
if re.compile(date_re).search(value):
return (date.__doc__, value, True)
else:
return (date.__doc__, value, False)
def files(value):
# Strip each line of leading/trainling whitespace and remove blank lines.
# Lowercase each filename.
value = '\n'.join(filter(lambda line: line != '', map(lambda line: line.strip().lower(), value.splitlines())))
return (files.__doc__, value, True)
diff --git a/modules/elmsubmit/lib/elmsubmit_filename_generator.py b/modules/elmsubmit/lib/elmsubmit_filename_generator.py
index 10d8134ab..519da4a61 100644
--- a/modules/elmsubmit/lib/elmsubmit_filename_generator.py
+++ b/modules/elmsubmit/lib/elmsubmit_filename_generator.py
@@ -1,226 +1,226 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import sys
import os.path
_this_module = sys.modules[__name__]
_this_module_dir = os.path.abspath(os.path.dirname(_this_module.__file__))
import random
import tempfile
import re
import os
import mimetypes
try:
import magic.magic as magic
_got_magic = True
except ImportError:
import mimetypes
_got_magic = False
import gzip
import bz2
from cdsware.elmsubmit_misc import open_tempfile as _open_tempfile
from cdsware.elmsubmit_misc import random_alphanum_string as _random_alphanum_string
from cdsware.elmsubmit_misc import remove_tempfile as _remove_tempfile
def generate_filename(filename=None, file=None, content_type=None, no_rand_chars=8, prefix='', postfix=''):
name_stub = _random_alphanum_string(no_rand_chars)
name_ext = calculate_filename_extension(filename, file, content_type)
return prefix + name_stub + postfix + '.' + name_ext
def calculate_filename_extension(filename=None, file=None, content_type=None):
# If libmagic is installed and ./magic/magic.so has been
# successfully built, then we use a python interface to libmagic
# (man libmagic) to calculate a file extension using a specially
# prepared magic data file (./magic/magic.ext) which maps
# magic tests to file extensions. Otherwise we use the mimetypes
# module from the standard Python distribution.
if (filename is None) and (file is None) and (content_type is None):
raise TypeError('at least one of filename, file or content_type must be specified')
elif (file is None) and (filename is None):
# We only have content_type:
return calculate_filename_ext_mimetypes(content_type)
# We have at least one of file and filename, so we try to use libmagic
elif _got_magic:
return calculate_filename_ext_libmagic(filename, file)
# We haven't got libmagic, so must use mimetypes:
else:
# But mimetypes requires content_type:
if content_type is None:
raise ImportError('Failed to import magic module. If no content-type is given, then magic module is required.')
else:
return calculate_filename_ext_mimetypes(content_type)
def calculate_filename_ext_libmagic(filename=None, file=None):
# See comments in magic/magic.ext for details of the format
# of the data file. All file extensions if recognized by a magic
# test will be returned in the form "file_ext:{xyz}"; this lets us
# detect the "file_ext:{}" marker and know we have a successful
# guess at the correct extension. The reason we need this marker
# is that libmagic has many tests whose return value is not
# governed through the magic data file and so we need some way of
# being sure a file extension has been returned. eg:
# >>> magician.file('/etc/init.d')
# "symbolic link to `rc.d/init.d'"
if filename is None and file is None: raise ValueError('at least one of file or content_type must be specified')
if not _got_magic: raise ImportError('magic module did not import successfully')
magician = magic.open(magic.MAGIC_NONE)
magic_data_file = os.path.join(_this_module_dir, 'magic/magic.ext')
ret_load = magician.load(magic_data_file)
# Throw private error if the magic data file is corrupt, or
# doesn't exist.
if ret_load != 0: raise _MagicDataError()
if filename is None:
# then we have only been given file as binary string.
# Get a temporary file and write file variable out to it
# because the magic module expects to be handed the name of a
# real file.
tf, tf_name = _open_tempfile(mode='wb')
tf.write(file)
tf.close()
delete_file = True
else:
os.stat(filename) # Make sure we can stat the file.
tf_name = filename
delete_file = False
ext_info = magician.file(tf_name)
# Now process ext_info to see if we can find a file extension
# contained in it.
file_ext_re = re.compile(r'file_ext:{(.+?)}')
file_ext_match = file_ext_re.search(ext_info)
if file_ext_match:
name_ext = file_ext_match.group(1)
# See if we have a compressed file type we can deal
# with. If so, uncompress it and call ourself to get more
# info:
# Note that we could use the magic.MAGIC_COMPRESS flag to
# get libmagic to do the decompression for us but:
# 1. It only supports gzip
# 2. The implementation has a nasty bug which has only
# been fixed in very recent releases of libmagic.
if name_ext == 'gz':
try:
# Decompress the stream:
decomp_file = gzip.open(tf_name).read()
except zlib.error:
# Couldn't decompress sucessfully, so just stick
# with extension we have.
pass
else:
# Guess an extension of the decompressed stream and
# tack current '.gz' on the end:
name_ext = calculate_filename_ext_libmagic(file=decomp_file) + '.' + name_ext
elif name_ext == 'bz2':
try:
# Decompress the file:
decomp_file = bz2.BZ2File(tf_name).read()
except IOError:
# Couldn't decompress sucessfully, so just stick
# with extension we have.
pass
else:
# Guess an extension of the decompressed stream and
# tack current '.bz2' on the end:
name_ext = calculate_filename_ext_libmagic(file=decomp_file) + '.' + name_ext
# Otherwise, look for special results from libmagic's
# 'internal tests' that we recognize:
elif ext_info.lower().rfind('tar archive') != -1:
name_ext = 'tar'
elif ext_info.lower().rfind('text') != -1:
name_ext = 'txt'
# Can't guess a filetype so use generic extension .dat
else:
name_ext = 'dat'
# Identification done so get rid of the temp file, assuming we created the file:
if delete_file: _remove_tempfile(tf_name)
return name_ext
mimetypes.types_map = {}
mimetypes.init([os.path.join(_this_module_dir, 'mime.types.edited')])
def calculate_filename_ext_mimetypes(content_type):
# mimetypes.types_map contains many 'builtin' maps. We empty
# it because we only want to use the maps from our edited
# mime.types file:
name_ext = mimetypes.guess_extension(content_type)
# Use '.dat' as generic file extension.
if name_ext is None: name_ext = '.dat'
# Remove leading dot produced by mimetypes.
name_ext = name_ext[1:]
return name_ext
# Errors:
# This module may also produce IOError from it use of temporary
# files.
# REMEMBER TO DOCUMENT THIS ERROR POTENTIAL
class _MagicDataError(Exception):
"""
Private error raised when we cannot compile and load the magic
data file successfully. This will only occur if there is a problem
with the module's installation.
"""
pass
diff --git a/modules/elmsubmit/lib/elmsubmit_generate_marc.py b/modules/elmsubmit/lib/elmsubmit_generate_marc.py
index 1f3af695e..ca3ce0f2e 100644
--- a/modules/elmsubmit/lib/elmsubmit_generate_marc.py
+++ b/modules/elmsubmit/lib/elmsubmit_generate_marc.py
@@ -1,200 +1,200 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import os
from string import split
import cdsware.elmsubmit_config as elmsubmit_config
def generate_marc(submission_dict):
""" method generates a marc xml file from the submission dict
"""
marc_dict = {}
for field in submission_dict.keys():
# print "field", field, submission_dict[field]
# marc_dict should cotain a dictionary {'marc_code', value, ...}
generate_data_field(field, submission_dict[field], marc_dict)
# generate an xml file from marc_dict
# print 'MARC DICT', marc_dict
full_marc = print_marc(marc_dict)
return full_marc
def print_marc(marc_dict):
""" method prints the xml file from the transformed dictionary
"""
marc_text = '<record>\n'
# extract the ind1 and ind2 tags
for key in marc_dict.keys():
tag = key[0:3]
if key[3] != '_':
ind1 = key[3]
else:
ind1 =''
if key[4] != '_':
ind2 = key[4]
else:
ind2 = ''
# subfields joined into one field
if key in elmsubmit_config.marc_fields_joined.keys():
tuple_list = marc_dict[key]
prefix_list = []
prefix_dict = {}
# make a list and a dictionary with occurance numbers
for subfield_tuple in marc_dict[key]:
prefix_list.append(subfield_tuple[0])
if prefix_dict.has_key(subfield_tuple[0]) == 1:
prefix_dict[subfield_tuple[0]] = prefix_dict[subfield_tuple[0]] + 1
else:
prefix_dict[subfield_tuple[0]] = 1
for linked_prefix_list in elmsubmit_config.marc_fields_joined[key]:
#we found a list of prefixes to join, build a field out of them
while (contains_elements(linked_prefix_list, prefix_dict.keys()) == True):
marc_text = marc_text + '<datafield tag ="' + tag + '" ind1="' + ind1 + '" ind2="' + ind2 + '">\n'
for prefix in linked_prefix_list:
tuple_index = prefix_list.index(prefix)
sub_tuple = tuple_list[tuple_index]
marc_text = marc_text + '<subfield code="' + sub_tuple[0] + '">' + sub_tuple[1] + '</subfield>\n'
del tuple_list[tuple_index]
del prefix_list[tuple_index]
prefix_dict[prefix] = prefix_dict[prefix] - 1
if prefix_dict[prefix] == 0:
del prefix_dict[prefix]
marc_text = marc_text + '</datafield>\n'
# append the actual datafields
for sub_tuple in tuple_list:
marc_text = marc_text + '<datafield tag ="' + tag + '" ind1="' + ind1 +'" ind2="' + ind2 + '">\n'
marc_text = marc_text + '<subfield code="' + sub_tuple[0] + '">' + sub_tuple[1] + '</subfield>\n'
prefix_dict[sub_tuple[0]] = prefix_dict[sub_tuple[0]] - 1
if prefix_dict[sub_tuple[0]] == 0:
del prefix_dict[sub_tuple[0]]
marc_text = marc_text + '</datafield>\n'
del tuple_list
del prefix_list
else:
# simply create the datafield
for subfield_tuple in marc_dict[key]:
marc_text = marc_text + '<datafield tag ="' + tag + '" ind1="' + ind1 + '" ind2="' + ind2 + '">\n'
marc_text = marc_text + '<subfield code="' + subfield_tuple[0] + '">' + subfield_tuple[1] + '</subfield>\n'
marc_text = marc_text + '</datafield>\n'
marc_text = marc_text + '</record>'
return marc_text
def contains_elements(small_list, big_list):
"""function checking if all elements of list a are in list b
"""
for element in small_list:
try:
a = big_list.index(element)
except ValueError:
return False
return True
def generate_data_field(field, value, marc_dict):
""" for a given data field, determine if it is in the marc dictionary dictionary and update marc_dict accordingly
"""
if (field in elmsubmit_config.marc_mapping):
# print "field:", field
# field is a normal field
if isinstance(elmsubmit_config.marc_mapping[field], list) == False:
for value_part in value:
(datafield, subfield) = process_marc(elmsubmit_config.marc_mapping[field])
if marc_dict.has_key(datafield) == 1:
marc_dict[datafield].append((subfield, value_part))
else:
marc_dict[datafield] = [(subfield, value_part)]
else:
# field is a list
#determine the length
for value_part in value:
if value.index(value_part) == 0:
(datafield, subfield) = process_marc(elmsubmit_config.marc_mapping[field][0])
if marc_dict.has_key(datafield) == 1:
marc_dict[datafield].append((subfield, value_part))
else:
marc_dict[datafield] = [(subfield, value_part)]
else:
(datafield, subfield) = process_marc(elmsubmit_config.marc_mapping[field][1])
if marc_dict.has_key(datafield) == 1:
marc_dict[datafield].append((subfield, value_part))
else:
marc_dict[datafield] = [(subfield, value_part)]
else:
pass
#print "field_not_in Marc:", field
def process_marc(marc_code):
""" extract the datafield and subfield from a Marc field
"""
# print "marc_code", marc_code
datafield = marc_code[0:5]
subfield = marc_code[5]
# print "datafield", datafield, "subfield", subfield
return (datafield, subfield)
diff --git a/modules/elmsubmit/lib/elmsubmit_html2txt.py b/modules/elmsubmit/lib/elmsubmit_html2txt.py
index 7e781c3b5..72025f535 100644
--- a/modules/elmsubmit/lib/elmsubmit_html2txt.py
+++ b/modules/elmsubmit/lib/elmsubmit_html2txt.py
@@ -1,184 +1,184 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import StringIO
import formatter
import htmllib
import sgmllib
import os
from cdsware.elmsubmit_misc import write_to_and_return_tempfile_name as _write_to_and_return_tempfile_name
from cdsware.elmsubmit_misc import remove_tempfile as _remove_tempfile
from cdsware.elmsubmit_misc import mapmany as _mapmany
# Search down to ###!!! See here !!!### for editable stuff.
# Parser classes:
class UnicodeHTMLParser(htmllib.HTMLParser):
def unknown_charref(self, ref):
# Take the HTML character reference and convert it to unicode.
try:
self.handle_data(unichr(int(ref)))
except(OverflowError, ValueError):
raise HTMLParsingFailed
# myhtmlentitydefs.py should be found in the dir with this file:
from myhtmlentitydefs import entitydefs
class NativeParser:
# NativeParser doesn't really need to be wrapped in a class, but
# we need to provide the same parser_instance.parse() interface as
# used for command line parsers.
def parse(self, html, cols):
file = StringIO.StringIO(u'')
# Create HTML parser:
writer = formatter.DumbWriter(file, maxcol=cols)
myformatter = formatter.AbstractFormatter(writer)
p = UnicodeHTMLParser(myformatter)
try:
p.feed(html)
except sgmllib.SGMLParseError:
raise HTMLParsingFailed
p.close()
return file.getvalue()
class CLParser:
# Provide a generic interface to command line parsers.
# We could have saved some work by avoiding writing html to a temp
# file for those command line parsers which allow input of html
# documents on stdin. However, not all of them do and a uniform
# interface was simplest.
def __init__(self, commandline_list):
self.commandline_list = commandline_list
def parse(self, html, cols):
if not isinstance(html, unicode): raise UnicodeInputRequired
utf8html = html.encode('utf8')
tf_name = _write_to_and_return_tempfile_name(utf8html)
# Replace cols marker:
f = lambda x: ((x == ['cols']) and str(cols)) or x
# Replace filename marker:
g = lambda x: ((x == ['filename']) and tf_name) or x
commandline_list = _mapmany([f,g], self.commandline_list)
commandline = ''.join(commandline_list)
# Run the process using popen3; possibly dodgy on Windows!
# Need popen3 rather other popen function because we want to
# grab stderr and hide it from the clients console.
(stdin, stdout, stderr) = os.popen3(commandline, 'r')
utf8output = stdout.read()
exit_status = stdout.close()
_remove_tempfile(tf_name)
# Just in case the parser outputs bogus utf8:
# Check the return code:
if exit_status is not None: raise HTMLParsingFailed
# Convert back to unicode object and return:
try:
output = unicode(utf8output, 'utf8')
return output
except (LookupError, UnicodeError):
raise HTMLParsingFailed
###!!! See here !!!###
# Parsers:
parser_native = NativeParser()
# These can be reinstated some time down the line when command line
# parsers have worked out their charset support a little better
# (rather than the current 'if you get lynx with this patch available
# from some guys website, then recompile...'):
# It appears w3m requires patches to support utf8:
# parser_w3m = CLParser(["w3m -dump -cols ", ['cols'], " -T 'text/html' file://", ['filename']])
# It appear lynx doesn't support charsets:
# parser_lynx = CLParser(['lynx -dump -force-html -width=', ['cols'], ' file://', ['filename']])
# elinks works OK, except it appear not to support &#{unicoderef} tags, but these are rare(ish):
# Actually, trying
# parser_elinks = CLParser([ 'elinks -dump -dump-charset "utf-8" -force-html -dump-width ', ['cols'], ' file://', ['filename']])
# The version (2.1pre13) on my system of the other 'famous' command
# line browser name links doesn't seem to have a dump option!
available_parsers = [ # parser_w3m,
# parser_lynx,
# parser_elinks,
parser_native ]
# Key function:
def html2txt(html, use_parsers=available_parsers, cols=72):
# Try each parser in turn (given in the list use_parsers) to see
# if they work:
for parser in use_parsers:
try:
text = parser.parse(html, cols)
except HTMLParsingFailed:
continue
else:
return text
# None of the parsers worked.
raise HTMLParsingFailed
# Errors:
class HTMLParsingFailed(Exception):
"""
Raised if HTML parsing fails for any reason.
"""
pass
class UnicodeInputRequired(Exception):
"""
Raised if attempt is made to parse anything other than unicode.
"""
diff --git a/modules/elmsubmit/lib/elmsubmit_misc.py b/modules/elmsubmit/lib/elmsubmit_misc.py
index 2fa49d26a..b1d81eb71 100644
--- a/modules/elmsubmit/lib/elmsubmit_misc.py
+++ b/modules/elmsubmit/lib/elmsubmit_misc.py
@@ -1,574 +1,574 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Miscellaneous utlity functions that have the potential for re-use.
"""
import tempfile
import os
import os.path
import random
import stat
import ConfigParser
import textwrap
import re
def concat(list_of_lists):
return [item for list in list_of_lists for item in list]
def cleave_pair(list):
# Should really generalize this to the nth case; but I only need
# pairs right now!
"""
[1,2,3,4,5,6,7]
becomes
([1,3,5,7], [2,4,6])
"""
lefts = []
rights = []
k = (lefts, rights)
for x in range(0, len(list)):
k[x % 2].append(list[x])
return (lefts, rights)
def merge_pair(lefts, rights):
"""
[1,3,5,7], [2,4,6]
becomes
[1,2,3,4,5,6,7]
"""
k = (lefts, rights)
list = []
for x in range(0, len(lefts) + len(rights)):
(d, m) = divmod(x, 2)
list.append(k[m][d])
return list
def cr2lf(file):
"""
Replace CRLF with LF. ie. Convert text file from DOS to Unix end
of line conventions.
"""
return file.replace("\r\n", "\n")
# Directory backup using mirrordir:
def backup_directory(original_directory, backup_directory):
# Backing up the directory requires GNU mirrordir to be installed;
# shutil.copytree won't do the job if there are pipes or fifos
# etc. in my_directory.
# Implementing mirrordir directly in python would be a
# good project!
# mkdir will throw the correct errors for us:
os.mkdir(backup_directory)
commandline = 'mirrordir ' + original_directory + ' ' + backup_directory
# Run the process using popen3; possibly dodgy on Windows!
# Need popen3 rather other popen function because we want to
# grab stderr and hide it from the clients console.
(stdin, stdout, stderr) = os.popen3(commandline, 'r')
# Close straight away; mirrordir expects no input.
# return the exist status:
return stdout.close()
# Tempfile stuff:
def open_tempfile(mode='wb'):
# We open in binary mode and write a non-unicode string and so
# can be sure that python will write the data verbatim,
# without fiddling with CRLFs etc.
(tf_file_descriptor, tf_name) = tempfile.mkstemp()
tf = os.fdopen(tf_file_descriptor, mode)
return (tf, tf_name)
def write_to_and_return_tempfile_name(data):
(tf, tf_name) = open_tempfile()
tf.write(data)
tf.close()
return tf_name
def remove_tempfile(filename):
"""
Tries to unlink the named tempfile. Catches the OSError if
unlinking fails.
"""
try:
os.unlink(filename)
except OSError:
# Couldn't delete temp file; no big problem.
pass
# Random string stuff:
def random_alphanum_string(length, chars='abcdefghijklmnopqrstuvwxyz' ):
"""
Create a random string of given length, choosing each character
with equal probability from the list given in string chars. For
example: chars='aab' would cause each character to be 'a' with 2/3
probability and 'b' with 1/3 probability (pseudorandomly
speaking).
"""
alphanums = list(chars)
# Replicate list into a list of lists and map the random choice
# function over it:
choices = map(random.choice, [alphanums] * length)
# Concat the choices into a string:
return ''.join(choices)
def mapmany(functions, in_list):
# If functions equals [phi, ... , alpha, beta, gamma] return
# map(phi, ... map(alpha, map(beta, map(gamma, in_list))) ... )
functions.reverse()
g = lambda list, f: map(f, list)
return reduce(g, functions, in_list)
def dict2file(dictionary, directory):
"""
Take any dictionary, eg.:
{ 'title' : 'The loveliest title.',
'name' : 'Pete the dog.',
'info' : { 'age' : '21', 'evil' : 'yes' }
}
and create a set of files in the given directory:
directory/title
directory/name
directory/info/age
directory/info/evil
so that each filename is a dictionary key, and the contents of
each file is the value that the key pointed to.
"""
def f((path, dictionary_or_data)):
fullpath = os.path.join(directory, path)
try:
dictionary_or_data.has_key
except AttributeError:
open(fullpath, 'wb').write(dictionary_or_data)
else:
os.mkdir(fullpath)
dict2file(dictionary_or_data, fullpath)
print 'dict.items', dictionary.items()
map(f, dictionary.items())
return None
def recursive_dir_contents(dir):
files = []
def f(arg, dirname, fnames):
files.extend(map(lambda file: os.path.join(dirname, file), fnames))
os.path.walk(dir, f, None)
return files
def count_dotdot(path):
path_parts = path.split(os.sep)
dotdots = filter(lambda part: part == '..', path_parts)
return len(dotdots)
def common_prefix(seq, default_empty=''):
try:
leng = 0
for tuple in zip(*seq):
if tuple[1:] != tuple[:-1]: break
leng += 1
return seq[0][:leng]
except TypeError: return default_empty
def split_common_path(thePaths):
# sanitze paths:
f = lambda x: os.path.normpath(os.path.expanduser(x))
thePaths = map(f, thePaths)
# thePaths is a list of paths (strings)
thePaths = map(lambda p: p.split(os.sep), thePaths)
# chop common part off the paths
theBase = common_prefix(thePaths, [])
thePaths = map(lambda p, c=len(theBase): p[c:], thePaths)
# convert back to strings
if theBase == ['']:
theBase = '/'
else:
theBase = os.sep.join(theBase)
thePaths = map(os.sep.join, thePaths)
return (theBase, thePaths)
def mkdir_parents(path):
tree = dirtree(path)
tree.reverse()
for parent in tree:
if os.path.exists(parent):
if os.path.isdir(parent):
continue
else:
# This will raise the correct OSError for us.
os.chdir(parent)
else:
os.mkdir(parent)
def dirtree(dir):
# sanitize path:
dir = os.path.normpath(os.path.expanduser(dir))
return _dirtree(dir)
def _dirtree(dir):
"""
An example will explain:
>>> elmsubmit_misc.dirtree('/hof/wim/sif/eff/hoo')
['/hof/wim/sif/eff/hoo',
'/hof/wim/sif/eff',
'/hof/wim/sif',
'/hof/wim',
'/hof',
'/']
"""
# POSIX allows // or / for the root dir.
# And it seems the rules say you aren't allowed to collapse // into /.
# I don't know why this is!
if dir == '//' or dir == '/':
return [dir]
elif dir == '':
return []
else:
return [dir] + _dirtree(os.path.dirname(dir))
def provide_dir_with_perms_then_exec(dir, function, perms, barrier_dir):
# This function won't allow you to alter the root directories'
# permissions: if your going to be changing the permissions on
# your root directory, you probably need to do it more carefully
# than with a python function!
# sanitize path:
dir = os.path.abspath(os.path.normpath(os.path.expanduser(dir)))
# Check to see if we're already in the state we want to be in:
try:
targets_current_perms = get_perms(dir)
targets_current_owner_uid = get_owner_uid(dir)
except OSError, e:
if e.errno == 2:
# dir definitely doesn't exist.
raise
elif e.errno == 13:
# don't have sufficient permissions to read the
# permissions.
dir_info_read = False
else:
dir_info_read = True
if dir_info_read and targets_current_owner_uid != os.geteuid():
# We don't own the file:
raise OSError("file %s not owned by this process's effective user: cannot proceed" % (dir))
elif dir_info_read and targets_current_perms & perms == perms:
# This directory already has user bits set to at least perms,
# so execute the given function:
return function()
# If we haven't exited the function already, we need to change the target dirs
# permissions (or simply couldn't read the permissions!)
# Get a list of all of the dirs parents:
dir_list = dirtree(dir)
if barrier_dir is not None:
# sanitize path:
barrier_dir = os.path.abspath(os.path.normpath(os.path.expanduser(barrier_dir)))
# Check the barrier dir is one of the parents of dir:
if not barrier_dir in dir_list[1:]:
raise ValueError('argument barrier_dir must be a proper parent directory of argument dir')
# Get a list of all the directories that lie between the
# barrier dir and the target dir, including the barrier dir,
# but excluding the target dir:
barrier_dir_list = dirtree(barrier_dir)
g = lambda d: (d == barrier_dir) or (not (d in barrier_dir_list or d == dir))
operable_parent_dirs = filter(g, dir_list)
else:
operable_parent_dirs = dir_list
# Make sure we have at least wx permissions on parent:
parents_old_states = _get_perms_on(operable_parent_dirs, perms=0300)
# Now stat the target dir if we didn't manage previously:
if not dir_info_read:
try:
targets_current_perms = get_perms(dir)
targets_current_owner_uid = get_owner_uid(dir)
except OSError, e:
if e.errno == 2:
# race condition:
raise OSError("Directory structure altered during processing: %s removed during processing" % (dir))
elif e.errno == 13:
# race condition:
raise OSError("Directory structure %s altered during processing: permissions changed during processing" % (dirlist))
if targets_current_owner_uid != os.geteuid():
# We don't own this file and so can't chmod it: We
# couldn't see this previously because we didn't
# have permission to stat the dir. Undo the
# permission changes we've already made and report
# the error:
_safely_chmod_dirlist(parents_old_states)
raise OSError("file %s not owned by this process's effective user: cannot proceed" % (dir))
elif targets_current_perms & perms == perms:
# We already have the perms we need.
try:
return_value = function()
finally:
_safely_chmod_dirlist(parents_old_states)
return return_value
# Now change the permissions of our target directory:
try:
os.chmod(dir, perms | targets_current_perms)
except OSError:
# race condition:
raise OSError("Directory structure %s altered during processing: permissions changed during processing" % (dirlist))
try:
# Now permissions are open, exec our function:
return_value = function()
finally:
# Close up the permissions we had to open:
_safely_chmod_dirlist([[dir, targets_current_perms]] + parents_old_states)
# Return the input functions return value:
return return_value
def _get_perms_on(dirlist, perms=0300):
# Note: any comment labelling a particular error as "race
# condition" is meant to indicate an error that can only arise if
# another process is attempting to alter the directory strucutre
# at the same time as us - this function _must not_ be used if
# such a situation is possible.
# User perms < rx doesn't make sense for this function. You need
# at least wx bits on a directory to change the permissions on its
# child directories.
if perms < 0300: raise ValueError("argument perms must be >= 3 in the user byte")
dir = dirlist[0]
remaining_dirs = dirlist[1:]
try:
targets_current_perms = get_perms(dir)
targets_current_owner_uid = get_owner_uid(dir)
except OSError, e:
if e.errno == 2:
# dir definitely doesn't exist.
raise
elif e.errno == 13:
# don't have sufficient permissions to read the
# permissions.
dir_info_read = False
else:
dir_info_read = True
if dir_info_read and targets_current_owner_uid != os.geteuid():
# We don't own the file:
raise OSError("file %s not owned by this process's effective user: cannot proceed" % (dir))
elif dir_info_read and targets_current_perms & perms == perms:
# This directory already has user bits set to at least perms,
# so nothing to do:
return []
elif dir_info_read and targets_current_perms & perms != perms:
# We need to adjust the permissions. See if the parent will
# let us:
if remaining_dirs == []:
# We have no parents available:
raise OSError("no members of the given dirtree have sufficient permissions for us to chmod")
else:
parent = remaining_dirs[0]
# Figure out if we're the owner of the parent and have permissions
try:
parents_current_perms = get_perms(parent)
parents_current_owner_uid = get_owner_uid(parent)
except OSError, e:
if e.errno == 2:
# dir definitely doesn't exist.
raise
elif e.errno == 13:
# don't have sufficient permissions to read the
# permissions.
parent_dir_info_read = False
else:
parent_dir_info_read = True
if parent_dir_info_read and parents_current_owner_uid == os.geteuid() and parents_current_perms & 0300 == 0300:
# We own the parent and have sufficient permission to chmod its contents:
try:
os.chmod(dir, perms | targets_current_perms)
except OSError:
# race condition:
raise OSError("Directory structure %s altered during processing: permissions changed during processing" % (dirlist))
return [[dir, targets_current_perms]]
else:
# We need to step down a level:
pass
else: # dir info was not read.
if remaining_dirs == []:
raise OSError("no members of the given dirtree have sufficient permissions for us to chmod")
# If the prior if-then-else didn't return or throw an error then
# either we couldn't stat the given dir or we don't have
# permission to change its permissions, so therefore we need to
# step down a level:
parents_old_states = _get_perms_on(remaining_dirs, perms)
if not dir_info_read:
try:
targets_current_perms = get_perms(dir)
targets_current_owner_uid = get_owner_uid(dir)
except OSError, e:
if e.errno == 2:
# race condition:
raise OSError("Directory structure altered during processing: %s removed during processing" % (dir))
elif e.errno == 13:
# race condition:
raise OSError("Directory structure %s altered during processing: permissions changed during processing" % (dirlist))
if targets_current_owner_uid != os.geteuid():
# We don't own this file and so can't chmod it: We
# couldn't see this previously because we didn't
# have permission to stat the dir. Undo the
# permission changes we've already made and report
# the error:
_safely_chmod_dirlist(parents_old_states)
raise OSError("file %s not owned by this process's effective user: cannot proceed" % (dir))
elif targets_current_perms & perms == perms:
# current directory already has the permissions we
# want; previously the parent's perms were preventing
# us from seeing this:
return parents_old_states
else:
# current directory's permissions need altering:
# Set the user bits to at least perms:
try:
os.chmod(dir, perms | targets_current_perms)
except OSError:
# race condition:
raise OSError("Directory structure %s altered during processing: permissions changed during processing" % (dirlist))
return [[dir, targets_current_perms]] + parents_old_states
else:
# current directory's permissions need altering:
# Set the user bits to at least perms:
try:
os.chmod(dir, perms | targets_current_perms)
except OSError:
# race condition:
raise OSError("Directory structure %s altered during processing: permissions changed during processing" % (dirlist))
return [[dir, targets_current_perms]] + parents_old_states
def _safely_chmod_dirlist(dirlist):
f = lambda (dir, perms): os.chmod(dir, perms)
map(f, dirlist)
def get_perms(path):
return stat.S_IMODE(os.stat(path)[stat.ST_MODE])
def get_owner_uid(path):
return os.stat(path)[stat.ST_UID]
# Text utils:
def wrap_text(text, cols=80):
print "text", text
parts = re.split(r'(\n(?:\s*\n))+', text)
(paragraphs, whitespace) = cleave_pair(parts)
for x in parts:
print ">>", x
print "paras", paragraphs
print "white", whitespace
wrapped_paragraphs = map(lambda t: textwrap.fill(t, width=cols), paragraphs)
print wrapped_paragraphs
return ''.join(merge_pair(wrapped_paragraphs, whitespace))
# Module utils:
def import_dots(string):
"""
Note that if you execute:
mod = __import__('one.two.three')
then variable mod will point to module one, not module
'one.two.three'.
whereas:
mod = import_dots('one.two.three')
will point to module 'one.two.three'.
"""
mod = __import__(string)
components = string.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
diff --git a/modules/elmsubmit/lib/elmsubmit_richtext2txt.py b/modules/elmsubmit/lib/elmsubmit_richtext2txt.py
index 6992d6c24..d13e7b5cf 100644
--- a/modules/elmsubmit/lib/elmsubmit_richtext2txt.py
+++ b/modules/elmsubmit/lib/elmsubmit_richtext2txt.py
@@ -1,475 +1,475 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
A text/richtext to text/plain converter.
Always returns a unicode string.
This is a module exporting a single function 'richtext2txt' which takes
a string of 'enriched text' and returns its conversion to 'plain
text'. 'rich text' is the text format as specified in RFC1341 for
use as an email payload with mime type text/richtext.
The code is based on the example parser given in appendix D of
RFC1341. It is a quite heavily modified version; the new code (aside
from being in Python not C):
1. Takes account of the <np> tag.
2. Deals better with soft newlines.
3. Deals better with the paragraph tag.
4. Takes account of the <iso-8859-x> tag.
The resulting code is something of a mishmash of the functional style
of programming that I prefer and the 'big while loop' proceedural
style in which the original C code is written.
With reference to point 4: Richtext is a pain because it allows
<ISO-8859-X></ISO-8859-X> markup tags to change charsets inside a
document. This means that if we get a text/richtext email payload
with 'Content-type' header specifying a charset e.g. 'us-ascii', we
can't simply decode to a unicode object; it is possible that bytes
inside the <ISO-8859-X></ISO-8859-X> will break the
unicode(str,'us-ascii') function call!
This is frustrating because:
1. Why bother to have a charset declaration outside a document only to
go and break it inside?
This might be understandable if text/richtext was designed
independantly of MIME and its Content-Type declarations but:
2. text/richtext is specified in the SAME RFC as the Content-type:
MIME header!
In fairness to the RFC writer(s), they were working at a time when
unicode/iso10646 was still in flux and so it was common for people
writing bilingual texts to want to use two charsets in one
document. It is interesting to note that the later text/enriched
specification (written when unicode had petrified) removes the
possibility of charset switching.
The existence of <iso-8859-x> tags makes the parser rather more
complicated.
Treatment notes:
> Second, the command "<nl>" is used to represent a required
> line break. (Otherwise, CRLFs in the data are treated as
> equivalent to a single SPACE character.)
2.
The RFC doesn't say to treat spaces as a special character; ie. that
they should be reproduced verbatim. This leads to the odd effect that
a string such as follows (where $SPACE$ in reality would be a space
character):
"<paragraph>Some text...</paragraph>$SPACE$<paragraph>More text...</paragraph>"
Is rendered as:
"Some text...
$SPACE$
More text..."
ie. The space is considered a string of text which must be separated
from the displayed paragraphs. This seems fairly odd behaviour to me,
but the RFC seems to suggest this is correct treatment.
"""
import re
import StringIO
def richtext2txt(str, charset='us-ascii', convert_iso_8859_tags=False, force_conversion=False):
return _richtext2txt(str, charset, convert_iso_8859_tags, force_conversion)
"""
Document options somewhere here.
##### 5. Make a note that the parsers assume \n not CRLF conventions so preconvert!!!
##### -------------------------------------------------------------------------------
"""
def _richtext2txt(string, charset='us-ascii', convert_iso_8859_tags=False, force_conversion=False,
recursive=False, just_closed_para=True, output_file=None):
if type(string) == unicode and convert_iso_8859_tags:
# Doesn't make sense to have a unicode string
# containing mixed charsets.
raise ValueError("function richtext2txt cannot have both unicode input string and convert_iso_8859_tags=True.")
# f and g will be our input/output streams.
# Create file like object from string for input file.
f = StringIO.StringIO(string)
# Create another file like object from string for output file,
# unless we have been handed one by recursive call.
if output_file is None:
g = StringIO.StringIO(u'')
else:
g = output_file
# When comparing to the RFC1341 code, substitute:
# STDIN -> object f
# STDOUT -> object g
# EOF -> ''
# ungetc -> seek(-1,1)
# If we're not calling ourself from ISO-8859-X tag, then eat
# leading newlines:
if not recursive: _eat_all(f,'\n')
c = f.read(1)
# compile re for use in if then else. Matches 'iso-8859-XX' tags
# where xx are digits.
iso_re = re.compile(r'^iso-8859-([1-9][0-9]?)$', re.IGNORECASE)
iso_close_re = re.compile(r'^/iso-8859-([1-9][0-9]?)$', re.IGNORECASE)
while c != '':
if c == '<':
c, token = _read_token(f)
if c == '': break
if token == 'lt':
g.write('<')
just_closed_para = False
elif token == 'nl':
g.write('\n')
# Discard all 'soft newlines' following <nl> token:
_eat_all(f,'\n')
elif token == 'np':
g.write('\n\n\n')
# Discard all 'soft newlines' following <np> token:
_eat_all(f,'\n')
just_closed_para = True
elif token == 'paragraph':
# If we haven't just closed a paragraph tag, or done
# equivalent (eg. output an <np> tag) then produce
# newlines to offset paragraph:
if not just_closed_para: g.write('\n\n')
elif token == '/paragraph':
g.write('\n\n')
# Discard all 'soft newlines' following </paragraph> token:
_eat_all(f,'\n')
just_closed_para = True
elif token == 'comment':
commct=1
while commct > 0:
c = _throw_away_until(f,'<') # Bin characters until we get a '<'
if c == '': break
c, token = _read_token(f)
if c == '': break
if token == '/comment':
commct -= 1
elif token == 'comment':
commct += 1
elif iso_re.match(token):
if not convert_iso_8859_tags:
if not force_conversion:
raise ISO8859TagError("<iso-8859-x> tag found when convert_iso_8859_tags=False")
else:
pass
else:
# Read in from the input file, stopping to look at
# each tag. Keep reading until we have a balanced pair
# of <iso-8859-x></iso-8859-x> tags. Use tag_balance
# to keep track of how many open iso-8859 tags we
# have, since nesting is legal. When tag_balance hits
# 0 we have found a balanced pair.
tag_balance = 1
iso_str = ''
while tag_balance != 0:
c, next_str = _read_to_next_token(f)
iso_str += next_str
if c == '': break
c, next_token = _read_token(f)
if c == '': break
if next_token == token:
tag_balance += 1
elif next_token == '/' + token:
tag_balance -= 1
if tag_balance != 0:
iso_str += ('<' + next_token + '>')
# We now have a complete string of text in the
# foreign charset in iso_str, so we call ourself
# to process it. No need to consider return
# value, since we pass g and all the output gets
# written to this.
_richtext2txt(iso_str, charset, convert_iso_8859_tags, force_conversion,
True, just_closed_para, output_file=g)
#^^^^ = recursive
elif iso_close_re.match(token):
if force_conversion:
pass
else:
if convert_iso_8859_tags:
raise ISO8859TagError("closing </iso-8859-x> tag before opening tag")
else:
raise ISO8859TagError("</iso-8859-x> tag found when convert_iso_8859_tags=False")
else:
# Ignore unrecognized token.
pass
elif c == '\n':
# Read in contiguous string of newlines and output them as
# single space, unless we hit EOF, in which case output
# nothing.
_eat_all(f,'\n')
if _next_char(f) == '': break
# If we have just written a newline out, soft newlines
# should do nothing:
if _last_char(g) != '\n': g.write(' ')
else:
# We have a 'normal char' so just write it out:
_unicode_write(g, c, charset, force_conversion)
just_closed_para = False
c = f.read(1)
# Only output the terminating newline if we aren't being called
# recursively.
if not recursive:
g.write('\n')
return g.getvalue()
def _read_token(f):
"""
Read in token from inside a markup tag.
"""
token = ""
c = f.read(1)
while c != '' and c!= '>':
token += c
c = f.read(1)
token = token.lower()
return c, token
def _read_to_next_token(f):
out = ''
c = f.read(1)
while c != '<' and c != '':
out += c
c = f.read(1)
return c, out
def _eat_all(f,d):
"""
Discard all characters from input stream f of type d until we hit
a character that is not of type d. Return the most recent bit read
from the file.
"""
got_char = False
if _next_char(f) == d: got_char = True
while _next_char(f) == d: f.read(1)
if got_char:
return d
else:
return None
def _throw_away_until(f,d):
"""
Discard all characters from input stream f until we hit a
character of type d. Discard this char also. Return the most
recent bit read from the file (which will either be d or EOF).
"""
c = f.read(1)
while c != d and c != '': c = f.read(1)
return c
def _next_char(f):
"""
Return the next char in the file.
"""
# Get the char:
c = f.read(1)
# If it wasn't an EOF, backup one, otherwise stay put:
if c != '': f.seek(-1,1)
return c
def _last_char(g):
"""
Look at what the last character written to a file was.
"""
pos = g.tell()
if pos == 0:
# At the start of the file.
return None
else:
# Written at least one character, so step back one and read it
# off.
g.seek(-1,1)
return g.read(1)
def _unicode_write(g, string, charset, force_conversion):
strictness = { True : 'strict',
False: 'replace'}[force_conversion]
# Could raise a UnicodeDecodingError!
unicode_str = unicode(string, charset, strictness)
g.write(unicode_str)
class RichTextConversionError(Exception):
"""
An emtpy parent class for all errors in this module.
"""
pass
class ISO8859TagError(RichTextConversionError):
"""
This error is raised when we are doing a conversion with
strict=True, the input string is unicode and we get an iso-8859-x
tag. Unicode should not contain mixed charsets.
"""
pass
# The original C code direct from RFC1341, appendix D
# See: http://www.faqs.org/rfcs/rfc1341.html
# #include <stdio.h>
# #include <ctype.h>
# main() {
# int c, i;
# char token[50];
# while((c = getc(stdin)) != EOF) {
# if (c == '<') {
# for (i=0; (i<49 && (c = getc(stdin)) != '>' && c != EOF); ++i) {
# token[i] = isupper(c) ? tolower(c) : c;
# }
# if (c == EOF) break;
# if (c != '>') while ((c = getc(stdin)) != '>' && c != EOF) {;}
# if (c == EOF) break;
# token[i] = '\0';
# if (!strcmp(token, "lt")) {
# putc('<', stdout);
# } else if (!strcmp(token, "nl")) {
# putc('\n', stdout);
# } else if (!strcmp(token, "/paragraph")) {
# fputs("\n\n", stdout);
# } else if (!strcmp(token, "comment")) {
# int commct=1;
# while (commct > 0) {
# while ((c = getc(stdin)) != '<'
# && c != EOF) ;
# if (c == EOF) break;
# for (i=0; (c = getc(stdin)) != '>'
# && c != EOF; ++i) {
# token[i] = isupper(c) ?
# tolower(c) : c;
# }
# if (c== EOF) break;
# token[i] = NULL;
# if (!strcmp(token, "/comment")) --commct;
# if (!strcmp(token, "comment")) ++commct;
# }
# } /* Ignore all other tokens */
# } else if (c != '\n') putc(c, stdout);
# }
# putc('\n', stdout); /* for good measure */
# }
# data = open('sample.rtx','r')
# t = data.read()
diff --git a/modules/elmsubmit/lib/elmsubmit_submission_parser.py b/modules/elmsubmit/lib/elmsubmit_submission_parser.py
index ef99efd53..59d0b665e 100644
--- a/modules/elmsubmit/lib/elmsubmit_submission_parser.py
+++ b/modules/elmsubmit/lib/elmsubmit_submission_parser.py
@@ -1,200 +1,200 @@
# -*- coding: utf-8 -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
parse_submission takes text like this:
--------------
cdson:::
_language_
eng
_type_
test
_title_
Blathering on About More Scientific Crap
_author_
Owen, R
_num_
69
_date_
01/01/2004
_keywords_
science forgery vitriol
_abstract_
This is possibly the best document to come out of space in a long
time. Aliens have really improved their scientific writing abilites.
Brillig things about this document:
One: I wrote it.
Two: It smells of cheese.
Three: Fnah!
_note_
Not musical, but informative.
_refnums_
AA11x-madeup_ref
_files_
info.pdf
foo.txt
cdsoff:::
Dear Sir,
Here is the rest of the email.
Sincerely,
Jonathon Bloggs.
--
Tel: 555 111 234567
IT-UDS CERN
--------------
This is turned into a 2-tuple. The first entry in the tuple is a
Python dictionary containing the submission info. The second entry is
the trailing text that follows the submission (the submission MUST be
at the top of the text).
({'abstract': 'This is possibly the best document to come out of space in a long\ntime. Aliens have really improved their scientific writing abilites.\n\nBrillig things about this document:\nOne: I wrote it.\nTwo: It smells of cheese.\nThree: Fnah!',
'author': 'Owen, R',
'date': '01/01/2004',
'files': 'info.pdf\nfoo.txt',
'keywords': 'science forgery vitriol',
'language': 'eng',
'note': 'Not musical, but informative.',
'num': '69',
'refnums': 'AA11x-madeup_ref',
'title': 'Blathering on About More Scientific Crap',
'type': 'test'},
'\nDear Sir,\n\nHere is the rest of the email.\n\nSincerely, \nJonathon Bloggs.\n\n--\nTel: 555 111 234567\nIT-UDS CERN')
It is fairly robust when treating misformatted submissions, so should
hopefully protect against misformatting due to evil smtp servers /
conversion from HTML email producing clients, etc. For example, we can
process the following OK:
----------------
cdson:::
_language_
eng
_type_
test
_title_
Blathering on About More Scientific Crap
__author__
Owen, R
_num_
69
_date_
01/01/2004
_keywords_
science forgery vitriol
cdsoff:::
---------------------
"""
# text values determining begin and end of submission
submission_frame_values = ['cdson:::', 'cdsoff:::']
def parse_submission(string):
# function extracts the metadata from the string representing the mail content
# split the mail into lines
list_of_lines = string.splitlines()
# strip the lines from trailing whitespaces
list_of_lines = map(lambda x: x.strip(), list_of_lines)
# throw out the empty lines
list_of_lines = filter(None, list_of_lines)
submission_dict = {}
# indicator that the submission content has begun
submission_start = 0
# indicator that the submission content has ended
submission_end = 0
# current keyword
current_keyword = ''
for line in list_of_lines:
# end of submission
if (submission_end == 1):
break
# submission in progress
if (submission_start == 1):
# found a keyword
if (line[0] == '_' and line[-1] == '_'):
current_keyword = line[1:-1]
# found end of submission
elif (line == submission_frame_values[1]):
submission_end = 1
# adding content to dictionary
elif (current_keyword <> ''):
submission_dict.setdefault(current_keyword, []).append(line)
else:
# found beginning of submission
if (line == submission_frame_values[0]):
submission_start = 1
return submission_dict
class SubmissionParserError(Exception):
pass
diff --git a/modules/elmsubmit/lib/elmsubmit_tests.py b/modules/elmsubmit/lib/elmsubmit_tests.py
index b36e2005f..49d784a21 100644
--- a/modules/elmsubmit/lib/elmsubmit_tests.py
+++ b/modules/elmsubmit/lib/elmsubmit_tests.py
@@ -1,247 +1,247 @@
# -*- coding: utf-8 -*-
## $Id$
## CDSware elmsubmit unit tests.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the elmsubmit."""
__version__ = "$Id$"
import unittest
import re
from string import expandtabs, replace
import xml.dom.minidom
from cdsware import elmsubmit
class MarcTest(unittest.TestCase):
""" elmsubmit - test for sanity """
def test_simple_marc(self):
""" parse a simple email - generate Marc """
print 'started testing'
f=open('/home/kjedrzej/testmails/test1','r')
email = f.read()
f.close()
# let's try to parse an example email and compare it with the appropriate marc xml
x = elmsubmit.process_email(email)
y = """<record>
<datafield tag ="245" ind1="" ind2="">
<subfield code="a">something</subfield>
</datafield>
<datafield tag ="100" ind1="" ind2="">
<subfield code="a">Simko, T</subfield>
<subfield code="u">CERN</subfield>
</datafield>
<datafield tag ="FFT" ind1="" ind2="">
<subfield code="a">/soft/cdsware-PCDH23/var/data/submit/storage/mail/wndyvcmzfhsqcgs/in.txt</subfield>
</datafield>
</record>"""
# in order to properly compare the marc files we have to remove the FFT node, it includes a random generated file path
dom_x = xml.dom.minidom.parseString(x)
datafields = dom_x.getElementsByTagName("datafield")
#remove all the FFT datafields
for node in datafields:
if (node.hasAttribute("tag") and node.getAttribute("tag") == "FFT"):
node.parentNode.removeChild(node)
node.unlink()
datafields = dom_x.getElementsByTagName("datafield")
new_x = dom_x.toprettyxml("","\n")
# the same with the other xml
dom_y = xml.dom.minidom.parseString(y)
datafields = dom_y.getElementsByTagName("datafield")
for node in datafields:
if (node.hasAttribute("tag") and node.getAttribute("tag") == "FFT"):
node.parentNode.removeChild(node)
node.unlink()
datafields = dom_y.getElementsByTagName("datafield")
new_y = dom_y.toprettyxml("","\n")
# 'normalize' the two XML MARC files for the purpose of comparing
new_x = expandtabs(new_x)
new_y = expandtabs(new_y)
new_x = new_x.replace(' ','')
new_y = new_y.replace(' ','')
# compare the two xml marcs
self.assertEqual(new_x,new_y)
def test_complex_marc(self):
""" parse multiple fields """
f=open('/home/kjedrzej/testmails/test2','r')
email = f.read()
f.close()
# let's try to reproduce the demo XML MARC file by parsing it and printing it back:
x = elmsubmit.process_email(email)
y = """<record>
<datafield tag ="245" ind1="" ind2="">
<subfield code="a">something</subfield>
</datafield>
<datafield tag ="700" ind1="" ind2="">
<subfield code="a">Le Meur, J Y</subfield>
<subfield code="u">MIT</subfield>
</datafield>
<datafield tag ="700" ind1="" ind2="">
<subfield code="a">Jedrzejek, K J</subfield>
<subfield code="u">CERN2</subfield>
</datafield>
<datafield tag ="700" ind1="" ind2="">
<subfield code="a">Favre, G</subfield>
<subfield code="u">CERN3</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="a">test11</subfield>
<subfield code="c">test31</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="a">test12</subfield>
<subfield code="c">test32</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="a">test13</subfield>
<subfield code="c">test33</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="b">test21</subfield>
<subfield code="d">test41</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="b">test22</subfield>
<subfield code="d">test42</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="a">test14</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="e">test51</subfield>
</datafield>
<datafield tag ="111" ind1="" ind2="">
<subfield code="e">test52</subfield>
</datafield>
<datafield tag ="100" ind1="" ind2="">
<subfield code="a">Simko, T</subfield>
<subfield code="u">CERN</subfield>
</datafield>
<datafield tag ="FFT" ind1="" ind2="">
<subfield code="a">/soft/cdsware-PCDH23/var/data/submit/storage/mail/qgifhtwzczykwji/in2.txt</subfield>
</datafield>
<datafield tag ="FFT" ind1="" ind2="">
<subfield code="a">/soft/cdsware-PCDH23/var/data/submit/storage/mail/qgifhtwzczykwji/in.txt</subfield>
</datafield>
</record>"""
# in order to properly compare the marc files we have to remove the FFT node, it includes a random generated file path
dom_x = xml.dom.minidom.parseString(x)
datafields = dom_x.getElementsByTagName("datafield")
#remove all the FFT datafields
for node in datafields:
if (node.hasAttribute("tag") and node.getAttribute("tag") == "FFT"):
node.parentNode.removeChild(node)
node.unlink()
new_x = dom_x.toprettyxml("","\n")
# the same with the other xml
dom_y = xml.dom.minidom.parseString(y)
datafields = dom_y.getElementsByTagName("datafield")
for node in datafields:
if (node.hasAttribute("tag") and node.getAttribute("tag") == "FFT"):
node.parentNode.removeChild(node)
node.unlink()
new_y = dom_y.toprettyxml("","\n")
# 'normalize' the two XML MARC files for the purpose of comparing
new_x = expandtabs(new_x)
new_y = expandtabs(new_y)
new_x = new_x.replace(' ','')
new_y = new_y.replace(' ','')
# compare the two xml marcs
self.assertEqual(new_x,new_y)
class FileStorageTest(unittest.TestCase):
""" testing proper storage of files """
def test_read_text_files(self):
f=open('/home/kjedrzej/testmails/test2','r')
email = f.read()
f.close()
# let's try to see if the files were properly stored:
xml_marc = elmsubmit.process_email(email)
dom = xml.dom.minidom.parseString(xml_marc)
datafields = dom.getElementsByTagName("datafield")
# get the file addresses
file_list = []
for node in datafields:
if (node.hasAttribute("tag") and node.getAttribute("tag") == "FFT"):
children = node.childNodes
for child in children:
if (child.hasChildNodes()):
file_list.append(child.firstChild.nodeValue)
f=open(file_list[0], 'r')
x = f.read()
f.close()
x.lstrip()
x.rstrip()
y = """second attachment\n"""
self.assertEqual(x,y)
f=open(file_list[1], 'r')
x = f.read()
f.close()
x.lstrip()
x.rstrip()
y = """some attachment\n"""
self.assertEqual(x,y)
def create_test_suite():
"""Return test suite for the elmsubmit module"""
return unittest.TestSuite((unittest.makeSuite(MarcTest,'test'), unittest.makeSuite(FileStorageTest,'test')))
# unittest.makeSuite(BadInputTreatmentTest,'test'),
# unittest.makeSuite(GettingFieldValuesTest,'test'),
# unittest.makeSuite(AccentedUnicodeLettersTest,'test')))
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/elmsubmit/lib/magic/Makefile.am b/modules/elmsubmit/lib/magic/Makefile.am
index 72dc42a11..0bc62e52b 100644
--- a/modules/elmsubmit/lib/magic/Makefile.am
+++ b/modules/elmsubmit/lib/magic/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware/magic
pylib_DATA = __init__.py compile_magic.py magic.ext magic.ext.mgc
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/elmsubmit/lib/magic/compile_magic.py b/modules/elmsubmit/lib/magic/compile_magic.py
index cb06b706e..0996f8ab2 100644
--- a/modules/elmsubmit/lib/magic/compile_magic.py
+++ b/modules/elmsubmit/lib/magic/compile_magic.py
@@ -1,41 +1,41 @@
# -*- coding: utf-8 -*-
#! /usr/bin/env python
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Compile magic files listed on the command line. Print name of compiled file.
"""
import sys
import os
import magic.magic as magic
magician = magic.open(magic.MAGIC_NONE)
for filename in sys.argv[1:]:
if os.path.isdir(filename):
print filename, "is Directory!"
continue
if magician.compile(filename) == 0:
print filename, "compiled OK."
else:
print filename, "failed to compile."
diff --git a/modules/miscutil/Makefile.am b/modules/miscutil/Makefile.am
index c74225d38..4dcdfabb2 100644
--- a/modules/miscutil/Makefile.am
+++ b/modules/miscutil/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin lib demo sql web doc
CLEANFILES = *~
diff --git a/modules/miscutil/bin/Makefile.am b/modules/miscutil/bin/Makefile.am
index 33e0b3279..c420b634c 100644
--- a/modules/miscutil/bin/Makefile.am
+++ b/modules/miscutil/bin/Makefile.am
@@ -1,33 +1,33 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = dbexec testsuite
noinst_SCRIPTS = dbtest
EXTRA_DIST = dbexec.in testsuite.in dbtest.in
all:
chmod u+x ./dbtest ./dbexec
install-data-local:
chmod u+x ./dbtest ./dbexec
./dbtest
CLEANFILES = *~ *.tmp
diff --git a/modules/miscutil/bin/dbexec.in b/modules/miscutil/bin/dbexec.in
index 982b99e4d..84e7cff9e 100644
--- a/modules/miscutil/bin/dbexec.in
+++ b/modules/miscutil/bin/dbexec.in
@@ -1,47 +1,47 @@
#!/bin/sh
## -*- mode: script; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## fill config variables:
VERSION='$Id$'
MYSQL="@MYSQL@"
DBHOST="@DBHOST@"
DBNAME="@DBNAME@"
DBUSER="@DBUSER@"
DBPASS="@DBPASS@"
# is help called?
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "Usage: $0"
echo "General options:"
echo " -h, --help Print this help."
echo " -V, --version Print version information."
exit 0
fi
# is version called?
if [ "$1" = "-V" ] || [ "$1" = "--version" ]; then
echo $VERSION
exit 0
fi
## okay, call MySQL client:
$MYSQL -B --host="$DBHOST" --user="$DBUSER" --password="$DBPASS" $DBNAME
diff --git a/modules/miscutil/bin/dbtest.in b/modules/miscutil/bin/dbtest.in
index cfc4252f5..e9195a2af 100644
--- a/modules/miscutil/bin/dbtest.in
+++ b/modules/miscutil/bin/dbtest.in
@@ -1,68 +1,68 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## fill config variables:
dbhost = "@DBHOST@"
dbname = "@DBNAME@"
dbuser = "@DBUSER@"
dbpass = "@DBPASS@"
## import modules:
try:
import MySQLdb
import sys
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
## try to connect to the DB server:
try:
db = MySQLdb.connect(host=dbhost, db=dbname, user=dbuser, passwd=dbpass)
except MySQLdb.Error, e:
print "Database connectivity error %d: %s" % (e.args[0], e.args[1])
print "Probably you do not have proper MySQL user credentials."
print "You need to fix this error before continuing!"
sys.exit(1)
## execute test query:
try:
cursor = db.cursor()
cursor.execute("SELECT * FROM collection")
row = cursor.fetchone()
except MySQLdb.Error, e:
print """
*************************************************
** DATABASE QUERY ERROR %d: %s.
*************************************************
** Perhaps you need to create CDSware tables? **
** If yes, then run 'make create-tables' now. **
** If not, then read the above error message **
** and fix the problem before continuing! **
*************************************************
""" % (e.args[0], e.args[1])
sys.exit(1)
## close connection:
cursor.close()
db.close()
diff --git a/modules/miscutil/bin/testsuite.in b/modules/miscutil/bin/testsuite.in
index 3c39a1854..b13fdd279 100644
--- a/modules/miscutil/bin/testsuite.in
+++ b/modules/miscutil/bin/testsuite.in
@@ -1,101 +1,101 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Run CDSware test suite."""
__version__ = "$Id$"
try:
import getopt
import unittest
import sys
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
try:
from cdsware.config import version
from cdsware import search_engine_tests
from cdsware import bibindex_engine_tests
from cdsware import bibindex_engine_stemmer_tests
from cdsware import bibrecord_tests
from cdsware import bibrank_citation_indexer_tests
from cdsware import bibrank_citation_searcher_tests
from cdsware import bibrank_downloads_indexer_tests
from cdsware import bibrank_record_sorter_tests
from cdsware import bibrank_tag_based_indexer_tests
from cdsware import oai_repository_tests
from cdsware import bibconvert_tests
from cdsware import errorlib_tests
from cdsware import elmsubmit_tests
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
def usage():
"""Print usage info on standard error output."""
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.stderr.write("Description: run CDSware test suite.\n")
return
def create_all_test_suites():
"""Return all tests suites for all CDSware modules."""
return unittest.TestSuite((search_engine_tests.create_test_suite(),
bibindex_engine_tests.create_test_suite(),
bibindex_engine_stemmer_tests.create_test_suite(),
bibrecord_tests.create_test_suite(),
bibrank_citation_indexer_tests.create_test_suite(),
bibrank_citation_searcher_tests.create_test_suite(),
bibrank_downloads_indexer_tests.create_test_suite(),
bibrank_record_sorter_tests.create_test_suite(),
bibrank_tag_based_indexer_tests.create_test_suite(),
oai_repository_tests.create_test_suite(),
bibconvert_tests.create_test_suite(),
errorlib_tests.create_test_suite(),
elmsubmit_tests.create_test_suite()))
def print_info_line():
"""Prints info line about tests to be executed."""
info_line = """CDSware v%s test suite results:""" % version
print info_line
print "=" * len(info_line)
if __name__ == "__main__":
try:
opts, args = getopt.getopt(sys.argv[1:], "hV", ["help", "version"])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt in opts:
if opt[0] in ("-V","--version"):
print __version__
sys.exit(0)
elif opt[0] in ("-h","--help"):
usage()
sys.exit(0)
print_info_line()
unittest.TextTestRunner(verbosity=2).run(create_all_test_suites())
diff --git a/modules/miscutil/demo/Makefile.am b/modules/miscutil/demo/Makefile.am
index 0cc3885d6..130e849fc 100644
--- a/modules/miscutil/demo/Makefile.am
+++ b/modules/miscutil/demo/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
noinst_DATA=democfgdata.sql
tmpdir = $(prefix)/var/tmp
tmp_DATA = demobibdata.xml
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%) demobibdata.xml
CLEANFILES = $(noinst_DATA) *~ *.tmp democfgdata.sql
%: %.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o $@ $<
\ No newline at end of file
diff --git a/modules/miscutil/doc/Makefile.am b/modules/miscutil/doc/Makefile.am
index 6daa39033..0f779fb0b 100644
--- a/modules/miscutil/doc/Makefile.am
+++ b/modules/miscutil/doc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = hacking
diff --git a/modules/miscutil/doc/hacking/Makefile.am b/modules/miscutil/doc/hacking/Makefile.am
index 39c0314ac..da9e3f221 100644
--- a/modules/miscutil/doc/hacking/Makefile.am
+++ b/modules/miscutil/doc/hacking/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/miscutil
doc_DATA=index.html dbquery.html errorlib.html dateutils.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/miscutil/doc/hacking/dateutils.html.wml b/modules/miscutil/doc/hacking/dateutils.html.wml
index a45651e3f..074ce2445 100644
--- a/modules/miscutil/doc/hacking/dateutils.html.wml
+++ b/modules/miscutil/doc/hacking/dateutils.html.wml
@@ -1,182 +1,182 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Date library" \
navbar_name="hacking-miscutil-dateutils" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/miscutil/index.html>MiscUtil Internals</a> " \
navbar_select="hacking-miscutil-dateutils"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<p>These are the functions and methodologies for date handling in CDSware.</p>
<h2>Contents</h2>
<ol>
<li><a href="#overview">Overview</a></li>
<li><a href="#converting">Converting dates</a></li>
<li><a href="#i18n">Internationalizing parts of dates</a></li>
<li><a href="#generating">Generating GUI elements</a></li>
</ol>
<h2>1. <a name="overview">Overview</a></h2>
Three ways of representing dates are handled by this library:
<dl>
<dt><b>datetext:</b></dt>
<dd>textual format =&gt; <code>'YEAR-MONTH-DAY HOUR:MINUTE:SECOND'</code><br />
e.g. <code>'2005-11-16 15:11:44'</code><br />
default value: <code>'0000-00-00 00:00:00'</code><br />
This format is the the one used by current Database for storing dates.
</dd>
<dt><b>datestruct:</b></dt>
<dd>
tuple format =&gt; see <a href="http://docs.python.org/lib/module-time.html">Python reference</a> <br />
<code>(YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEKDAY, YEARDAY, DAYLIGHT)</code><br />
e.g. <code>(2005, 11, 16, 15, 11, 44, 2, 320, 0)</code><br />
default value: <code>(0, 0, 0, 0, 0, 0, 0, 0, 0)</code><br />
This format is the one used by python. Time module provides methods for
calculations.
</dd>
<dt><b>dategui:</b></dt>
<dd>
textual format for output =&gt; <code>'DAY MONTH YEAR, HOUR:MINUTE'</code><br />
e.g. <code>'16 nov 2005, 15:11'</code>
default value: <code>&#95;("N/A")</code>
</dd>
</dl>
<p>The dateutils python module provides ways of converting between these formats.
The default value is used whenever a date is non-valid (for python, dates before
epoch are unvalid!).</p>
<h2>2. <a name="converting">Converting dates</a></h2>
The functions for conversion are listed below.
<dl>
<dt><b><code>convert&#95;datestruct&#95;to&#95;dategui(datestruct, ln=cdslang)</code></b></dt>
<dd>
<code>(2005, 11, 16, 15, 11, 44, 2, 320, 0) =&gt; '16 nov 2005, 15:11'</code><br/>
Month is internationalized
</dd>
<dt><b><code>convert&#95;datestruct&#95;to&#95;datetext(datestruct)</code></b></dt>
<dd>
<code>(2005, 11, 16, 15, 11, 44, 2, 320, 0) =&gt; '2005-11-16 15:11:57'</code>
</dd>
<dt><b><code>convert&#95;datetext&#95;to&#95;dategui(datetext, ln=cdslang)</code></b></dt>
<dd>
<code>'2005-11-16 15:11:57' =&gt; '16 nov 2005, 15:11'</code><br />
Month is internationalized
</dd>
<dt><b><code>convert&#95;datetext&#95;to&#95;datestruct(datetext)</code></b></dt>
<dd>
<code>'2005-11-16 15:11:57' =&gt; (2005, 11, 16, 15, 11, 44, 2, 320, 0)</code>
</dd>
<dt><b><code>get&#95;datestruct(year, month, day)</code></b></dt>
<dd>
<code>year=2005, month=11, day=16 =&gt; (2005, 11, 16, 0, 0, 0, 2, 320, -1)</code>
</dd>
<dt><b><code>get&#95;datetext(year, month, day)</code></b></dt>
<dd>
<code>year=2005, month=11, day=16 =&gt; '2005-11-16 00:00:00'</code>
</dd>
</dl>
<h2>3. <a name="i18n">Internationalizing parts of dates</a></h2>
The following functions provide means of internationalizing part of dates.
<dl>
<dt>
<b><code>get&#95;i18n&#95;day&#95;name(day&#95;nb, display='short', ln=cdslang)</code></b>
</dt>
<dd>
get the string representation of a weekday, internationalized<br />
<code>
@param day&#95;nb: number of weekday UNIX like. =&gt; 0=Sunday<br />
@param ln: language for output<br />
@return the string representation of the day
</code>
</dd>
<dt>
<b><code>get&#95;i18n&#95;month&#95;name(month&#95;nb, display='short', ln=cdslang)</code></b>
</dt>
<dd>
get a non-numeric representation of a month, internationalized.<br />
<code>
@param month&#95;nb: number of month, (1 based!) =&gt; 1=jan,..,12=dec<br />
@param ln: language for output<br />
@return the string representation of month
</code>
</dd>
</dl>
<h2>4. <a name="generating">Generating GUI elements</a></h2>
The following functions create HTML fields for date selection:
<dl>
<dt>
<b><code>create&#95;day&#95;selectbox(name, selected&#95;day=0, ln=cdslang)</code></b>
</dt>
<dd>Creates an HTML menu for day selection. (<code>0..31</code> values).<br />
<code>@param name: name of the control (i.e. name of the var you'll get)<br />
@param selected&#95;day: preselect a day. Use 0 for the label 'Day'<br />
@param ln: language of the menu<br />
@return html as string
</code>
</dd>
<dt>
<b><code>create&#95;month&#95;selectbox(name, selected&#95;month=0, ln=cdslang)</code></b>
</dt>
<dd>Creates an HTML menu for month selection. Value of selected field is numeric<br />
<code>@param name: name of the control (your form will be sent with name=value...)<br />
@param selected&#95;month: preselect a month. use 0 for the Label 'Month'<br />
@param ln: language of the menu<br />
@return html as string
</code>
</dd>
<dt>
<b><code>create&#95;year&#95;inputbox(name, value=0)</code></b>
</dt>
<dd>
Creates an HTML field (simple input) for year selection.<br />
<code>@param name: name of the control (i.e. name of the variable you'll get)<br />
@param value: prefilled value (int)<br />
@return html as string
</code>
<dt>
<b><code>create&#95;year&#95;selectbox(name, from&#95;year=-1, length=10, selected&#95;year=0, ln=cdslang)</code></b>
</dt>
<dd>
Creates an HTML menu (dropdownbox) for year selection.<br />
<code>@param name: name of control( i.e. name of the variable you'll get)<br />
@param from&#95;year: year on which to begin. if <0 assume it is current year<br />
@param length: number of items in menu<br />
@param selected&#95;year: initial selected year (if in range), else: label is selected<br />
@param ln: language<br />
@return html as string
</code>
</dl>
diff --git a/modules/miscutil/doc/hacking/dbquery.html.wml b/modules/miscutil/doc/hacking/dbquery.html.wml
index f5908868c..09c6b93f1 100644
--- a/modules/miscutil/doc/hacking/dbquery.html.wml
+++ b/modules/miscutil/doc/hacking/dbquery.html.wml
@@ -1,96 +1,96 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Database access API" \
navbar_name="hacking-miscutil" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/miscutil/index.html>MiscUtil Internals</a> " \
navbar_select="hacking-miscutil-dbquery"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<p>
DBQuery handles connection to database and queries.
</p>
<h2>Contents</h2>
<ol>
<li><a href="#overview">Overview</a></li>
<li><a href="#usage">Usage</a></li>
<li><a href="#notes">Notes</a></li>
</ol>
<h2>1. <a name="overview">Overview</a></h2>
<p>DBQuery provides a method, <code>run&#95;sql</code> which handles SQL requests. It establishes
a connection if necessary, sends requests and returns tuples.</p>
<h2>2. <a name="usage">Usage</a></h2>
<p>As DBQuery automatically handles connection establishment, usage of a single
function is necessary:</p>
<pre>
run&#95;sql(sql, param=None, n=0, with&#95;desc=0)
Run SQL on the server and returns result.
@param param: tuple of string params to insert in the query
(see notes below)
@param n: number of tuples in result (0 for unbounded)
@param with&#95;desc: if true, will return a
DB API 7-tuple describing columns in query
@return: if SELECT, SHOW, DESCRIBE statements: tuples of data, followed
by description if parameter
provided
if INSERT: last row id.
else: SQL result as provided by database
</pre>
<h2>3. <a name="notes">Notes</a></h2>
<h3>3.1 Params</h3>
As said before, params must be of type string. Trying to pass non character data
may lead to an error. Developers should consider converting to string, or render
string before sending, giving no param:
<pre>
initial&#95;params=(1234,)
query = "SELECT id FROM user where id>%s"
params = (str(initial&#95;params[0]),)
run&#95;sql(query, params)
</pre>
or
<pre>
query = "SELECT id FROM user where id>%d" % 1234
run&#95;sql(query)
</pre>
<p>When using this last technique, be careful with SQL injection problem. One should
use the <code>MySQLdb.escape&#95;string()</code> method.
<h3>3.2 Dates</h3>
<p>Switching from MySQLdb 0.9 to MySQLdb 1.2, while using Python 2.2 or 2.3
led to discovery of incompatibilities</p>
<p>If a date field is in the received tuple, its format will be:</p>
<ul>
<li>string with MySQLdb 0.9</li>
<li>datetime with MySQLdb 1.2</li>
</ul>
<p>As Python 2.2 doesn't provide <code>datetime</code> class, handling of this
problem should be done for backwards compatibility reasons. The
solution is to force MySQL to convert date to a textual format:</p>
<pre>
SELECT DATE&#95;FORMAT(date&#95;field,'%%Y-%%m-%%d %%H:%%i:%%s') FROM table
</pre>
<p>This conversion will return a datetext format as described in <a href="./dateutils.html">dateutils library</a><code>(YEAR-MONTH-DAY HOUR:MINUTE:SECOND)</code></p>
diff --git a/modules/miscutil/doc/hacking/errorlib.html.wml b/modules/miscutil/doc/hacking/errorlib.html.wml
index 726501e07..56f84e631 100644
--- a/modules/miscutil/doc/hacking/errorlib.html.wml
+++ b/modules/miscutil/doc/hacking/errorlib.html.wml
@@ -1,322 +1,322 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Error Library" \
navbar_name="hacking-miscutil" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/miscutil/index.html>MiscUtil Internals</a> " \
navbar_select="hacking-miscutil-error-management"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<p>
These are the functions and methodologies for error handling in CDSware.
</p>
<h2>Contents</h2>
<ol>
<li><a href="#overview">Overview</a></li>
<li><a href="#creating">Creating errors</a></li>
<li><a href="#using">Using error library</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
</ol>
<h2>1. <a name="overview">Overview</a></h2>
<p>This API handles two concepts: Errors and Warnings.
<p>An error is an unexpected behavior that leads to the stopping of current process.
Discussing of web pages, errors should be displayed by instead of the
requested page. Errors are logged into <code>cdsware/var/log/cdsware.err</code>.
Errors can be logged with client information and a tracestack.</p>
<p>A warning is an unexpected behavior that can be ignored. Warnings are logged into
<code>cdsware/var/log/cdsware.log</code> with just the warning message.</p>
<p>Errors and warnings should be internationalized (see <a href="#i18n">below</a>).</p>
<h2>2. <a name="creating">Creating errors</a></h2>
<h3>2.1 Configuration file</h3>
<p>Every module should create a file containing error definitions, warning
definitions, variables avoiding &quot;magic&quot; number or strings, etc.</p>
<p>This file has to be named against a convention:</p>
<pre>
&lt;module-name&gt;&#95;config.py
</pre>
<p>e.g. <code>webmessage&#95;config.py</code> for the WebMessage module.</p>
<h3>2.2 Dictionaries of errors</h3>
<p>Errors and warnings are eventually stored into dictionaries. The dictionaries
are to be named against the following convention:</p>
<pre>
cfg&#95;&lt;module-name&gt;&#95;error&#95;messages and
cfg&#95;&lt;module-name&gt;&#95;warning&#95;messages
</pre>
<p>These two dictionaries (one can choose to implement only one if he doesn&apos;t
need warnings, for example) contain an error-name -&gt; displayable message
association.</p>
<p>Errors are to be named against the following convention:</p>
<pre>
ERR&#95;&lt;MODULE-NAME&gt;&#95;ERROR&#95;NAME
</pre>
<p>Please note the use of uppercase.</p>
<p>Warnings can also be named as errors if convenient, and so have to
follow one of these rules:</p>
<pre>
WRN&#95;&lt;MODULE-NAME&gt;&#95;WARNING&#95;NAME or
ERR&#95;&lt;MODULE-NAME&gt;&#95;WARNING&#95;NAME
</pre>
<p>The associated message can obviously contain substituted variables like <code>%s</code>, <code>%d</code>...
<h3><a name="i18n">Internationalization</a></h3>
<p>Errors should also be internationalized. As the config file cannot receive
parameters, this is done by the error handling library. The convenient way that has
been chosen is to nest the classical <code>&#95;()</code> function inside the string.</p>
<p>An internationalized error message should look like this:</p>
<pre>
'&#95;("Internationalized error (%s) message")'
</pre>
<p>A complete example of correct dictionary is given below:</p>
<pre>
cfg&#95;webcomment&#95;error&#95;messages =
{ 'ERR&#95;WEBCOMMENT&#95;RECID&#95;INVALID' : '&#95;("%i is an invalid record ID")',
'ERR&#95;WEBCOMMENT&#95;RECID&#95;NAN' : '&#95;("Record ID %i is not a number")',
'ERR&#95;WEBCOMMENT&#95;UID&#95;INVALID' : '&#95;("%i is an invalid user ID")'
}
</pre>
<h2>3. <a name="using">Using error library</a></h2>
<h3>3.1 From a web interface</h3>
<p>When displaying a page, the <code>modules/webstyle/lib/webpage.py</code> python module should
be used. This module provides a <code>page()</code> function, convenient for webpage output,
which can handle errors (display and log).<br />
A call to this function should use the following arguments, assuming that language
information is stored in a variable called <code>ln</code>, and request information
are stored in req (will be used for IP logging, for example):</p>
<pre>
page(...,
req=req,
language=ln,
errors=error&#95;list,
warnings=warnings&#95;list,
...)
</pre>
<p>list of errors and warnings are behaving the same way. They are lists of tuples:</p>
<pre>
[(error&#95;name, param1, ..., paramN), ...]
</pre>
<p>The params are used to represent substitued values in messages. For example if
you want to throw one of the errors above, error&#95;list should look like this:</p>
<pre>
error&#95;list = [('ERR&#95;WEBCOMMENT&#95;RECID&#95;INVALID', 123456)]
</pre>
<h4>Example</h4>
<p>Business logic should be separated from web interface. We consider three files in the
following (real) example:
<ol>
<li><code>yourmessages.py</code>, which is the page as viewed by a browser,</li>
<li><code>webmessage.py</code>, which contains the business logic,</li>
<li><code>webmessage&#95;config</code>, which contains error definitions</li>
</ol>
<p>In this example, a user tries to read a message. We must ensure he doesn't
read another's message, and that this message really exist in the system. For
a more convenient reading, some (non error-related) parts of code have been suppressed.</p>
<h5>webmessage&#95;config.py</h5>
<pre>
&#35; error messages. (should not happen, except in case of reload, or url altering)
cfg&#95;webmessage&#95;error&#95;messages = \
{ 'ERR&#95;WEBMESSAGE&#95;NOTOWNER': '&#95;("This message is not in your mailbox")',
'ERR&#95;WEBMESSAGE&#95;NONICKNAME':'&#95;("No nickname or user for uid #%s")',
'ERR&#95;WEBMESSAGE&#95;NOMESSAGE': '&#95;("This message doesn\'t exist")'
}
</pre>
<h5>webmessage.py: business logic</h5>
<pre>
from cdsware.webmessage&#95;config import cfg&#95;webmessage&#95;error&#95;messages
def perform&#95;request&#95;display&#95;msg(uid, msgid, ln=cdslang):
uid = wash&#95;url&#95;argument(uid, 'int')
msgid = wash&#95;url&#95;argument(msgid, 'int')
ln = wash&#95;language(ln)
errors = []
warnings = []
body = ""
if (check&#95;user&#95;owns&#95;message(uid, msgid) == 0):
&#35; The user doesn't own this message
errors.append(('ERR&#95;WEBMESSAGE&#95;NOTOWNER',))
else:
(msg&#95;id, ...) = get&#95;message(uid, msgid)
if (msg&#95;id == ""):
&#35; The message exists in table user&#95;msgMESSAGE
&#35; but not in table msgMESSAGE => table inconsistency
errors.append(('ERR&#95;WEBMESSAGE&#95;NOMESSAGE',))
else:
body = webmessage&#95;templates.tmpl&#95;display&#95;msg( ... )
return (body, errors, warnings)
</pre>
<h5>yourmessages.py: web interface</h5>
<pre>
from cdsware.webpage import page
from cdsware.webmessage import perform&#95;request&#95;display&#95;msg
def display&#95;msg(req, msgid=-1, ln=cdslang):
&#95; = gettext&#95;set&#95;language(ln)
# Generate content
(body, errors, warnings) = perform&#95;request&#95;display&#95;msg(uid, msgid, ln)
title = &#95;("Read a message")
return page(title = title,
body = body,
navtrail = get&#95;navtrail(ln, title),
uid = uid,
lastupdated = &#95;&#95;lastupdated&#95;&#95;,
req = req,
language = ln,
errors = errors,
warnings = warnings)
</pre>
<h3>3.2 From a command line interface</h3>
<p>The following functions can be useful (see source code for other functions):</p>
<pre>
get&#95;msgs&#95;for&#95;code&#95;list(code&#95;list, file='error', ln=cdslang)
Returns formatted strings for the given errors
@param code&#95;list: list of tuples [(err&#95;name, arg1, ..., argN), ...]
@param file: 'error' or 'warning'
@return list of tuples of length 2 [('ERR&#95;...', err&#95;msg), ...]
if code&#95;list empty, will return None.
if errors retrieving error messages, will append an error to
the list
register&#95;errors(errors&#95;or&#95;warnings&#95;list, file, req=None)
log errors to cdsware.err and warnings to cdsware.log
errors will be logged with client information (if req is given)
and a tracestack
warnings will be logged with just the warning message
@param errors&#95;or&#95;warnings&#95;list: list of tuples (err&#95;name, err&#95;msg)
@param file: 'error' or 'warning'
@param req = mod&#95;python request
@return integer 1 if successfully wrote to file, integer 0 if not
will append another error to errors&#95;list if unsuccessful
send&#95;error&#95;report&#95;to&#95;admin(header, url, time, browser, client,
error, sys&#95;error, traceback)
Sends an email to the admin with client info and tracestack
</pre>
<h4>Example</h4>
<p>In the following example, two files are used:</p>
<ol>
<li><code>webmessage&#95;config</code>, containing error messages</li>
<li><code>webmessage&#95;example&#95;bin.py</code>, containing business logic</li>
</ol>
<p>Scenario: a function receives an error and wants to register it only if it is not a
messaging error</p>
<h5>webmessage&#95;config.py</h5>
<pre>
&#35; error messages. (should not happen, except in case of reload, or url altering)
cfg&#95;webmessage&#95;error&#95;messages = \
{ 'ERR&#95;WEBMESSAGE&#95;NOTOWNER': '&#95;("This message is not in your mailbox")',
'ERR&#95;WEBMESSAGE&#95;NONICKNAME':'&#95;("No nickname or user for uid #%s")',
'ERR&#95;WEBMESSAGE&#95;NOMESSAGE': '&#95;("This message doesn\'t exist")'
}
</pre>
<h5>webmessage&#95;example&#95;bin.py</h5>
<pre>
from cdsware.webmessage&#95;config import cfg&#95;webmessage&#95;error&#95;messages
from cdsware.errorlib import get&#95;msgs&#95;for&#95;code&#95;list, register&#95;errors
def handle&#95;error(error):
errorlist = get&#95;msgs&#95;for&#95;code&#95;list([error])
&#35; error is a tuple of error name, arguments => we only need the name
if cfg&#95;webmessage&#95;error&#95;messages[error[0]]:
print("Error in webmessage: %s" % errorlist[0][1])
else:
for error in errorlist:
print("Error: %s" % error[1])
register&#95;errors(errorlist, 'error')
</pre>
<h2>4. <a name="troubleshooting">Troubleshooting</a></h2>
<p>MiscUtil can generate errors. See miscutil&#95;config.py for a complete list.
One can see below some usual errors and their solutions:</p>
<dl>
<dt><b><code>ERR&#95;MISCUTIL&#95;IMPORT&#95;ERROR</code></b></dt>
<dd>The <code>&lt;module-name&gt;&#95;config.py</code> file has not been found. Check it
has the correct name and is deployed.<br />
Check that the error is named following this pattern:
<pre>
WRN&#95;&lt;MODULE-NAME&gt;&#95;WARNING&#95;NAME or
ERR&#95;&lt;MODULE-NAME&gt;&#95;WARNING&#95;NAME
</pre>
</dd>
<dt><b><code>ERR&#95;MISCUTIL&#95;NO&#95;DICT</code></b></dt>
<dd>No dictionary could be found in <code>&lt;module-name&gt;&#95;config.py</code>. Check
that your dictionary is correctly named:
<pre>
cfg&#95;&lt;module-name&gt;&#95;error&#95;messages
</pre>
You could also have inverted errors and warnings if only one dictionary was provided.<br/>
This can also happen when using direct API if the <code>file</code> argument is misspelled.
</dd>
<dt><b><code>ERR&#95;MISCUTIL&#95;NO&#95;MESSAGE&#95;IN&#95;DICT</code></b></dt>
<dd>A dictionary was found but not the error in it. You probably misspelled
<code>error&#95;name</code>, or inverted errors and warnings dictionaries.
</dd>
<dt><b><code>ERR&#95;MISCUTIL&#95;UNDEFINED&#95;ERROR</code></b></dt>
<dd>The library couldn't guess the name of module. Check that the error name is beginning
with <code>ERR&#95;MODULE-NAME&#95;</code> or <code>WRN&#95;MODULE-NAME&#95;</code>. This library uses
underscores as separators to guess module name.
</dd>
<dt><b><code>ERR&#95;MISCUTIL&#95;TOO&#95;MANY&#95;ARGUMENT</code></b></dt>
<dd>As the library was rendering the display of error, a surnumerous text substitute was
found (surnumerous are ignored for final rendering, and this error is appened to list of errors):
<pre>
# Module knights:
'ERR&#95;KNIGHTS': '&#95;("We are the knights who say %s!")'
errors = ('ERR&#95;KNIGHTS', 'ni', 'ni')
</pre>
</dd>
<dt><b><code>ERR&#95;MISCUTIL&#95;TOO&#95;FEW&#95;ARGUMENT</code></b></dt>
<dd>Not enough arguments (text substitutes) were given for an error. Missing ones are
replaced by <code>'???'</code>:
<pre>
# Module knights
'ERR&#95;KNIGHTS': '&#95;("We are the knights who say %s! We demand a %s")'
errors = ('ERR&#95;KNIGHTS', 'ni') # so, where is the shrubbery??
</pre>
</dd>
<dt><b><code>ERR&#95;MISCUTIL&#95;BAD&#95;ARGUMENT&#95;TYPE</code></b></dt>
<dd>Your arguments (text substitutes) did not match with the error declaration<br />
e.g. inversion between integer (<code>%i</code>) and string (<code>%s</code>)
</dd>
</dl>
diff --git a/modules/miscutil/doc/hacking/index.html.wml b/modules/miscutil/doc/hacking/index.html.wml
index b053c5349..74fbce68a 100644
--- a/modules/miscutil/doc/hacking/index.html.wml
+++ b/modules/miscutil/doc/hacking/index.html.wml
@@ -1,40 +1,40 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="MiscUtil Internals" \
navbar_name="hacking-miscutil" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a>" \
navbar_select="hacking-miscutil-index"
This page summarizes all the information suitable to dig inside
the MiscUtil internals.
<blockquote>
<dl>
<dt><a href="dbquery.html">Database access API</a> </dt>
<dd>Explains how to access CDSware database from your Python programs.</dd>
<dt><a href="errorlib.html">Error handling library</a> </dt>
<dd>Explains how to create errors and warnings and how to manage them.</dd>
<dt><a href="dateutils.html">Date handling library</a> </dt>
<dd>Explains how to handle dates in CDSware. All mentioned functions are represented with signature and additional explanations.</dd>
</dl>
</blockquote>
diff --git a/modules/miscutil/lib/Makefile.am b/modules/miscutil/lib/Makefile.am
index d61dfb4a7..1cf011585 100644
--- a/modules/miscutil/lib/Makefile.am
+++ b/modules/miscutil/lib/Makefile.am
@@ -1,63 +1,63 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = __init__.py \
errorlib.py \
errorlib_tests.py \
config.py \
dbquery.py \
miscutil_config.py \
messages.py \
textutils.py \
dateutils.py \
urlutils.py
phplibdir = $(libdir)/php/cdsware/errors
phplib_DATA = errorHandling.php
EXTRA_DIST = __init__.py \
errorlib.py \
errorlib_tests.py \
miscutil_config.py \
config.py.wml \
dbquery.py.wml \
messages.py.wml \
errorHandling.php.wml \
textutils.py \
dateutils.py \
urlutils.py
CLEANFILES = config.py dbquery.py messages.py $(phplib_DATA) *~ *.tmp *.pyc
config.py: config.py.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml \
$(top_srcdir)/config/cdswmllib.wml
$(WML) -o $@ $<
dbquery.py: dbquery.py.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml \
$(top_srcdir)/config/cdswmllib.wml
$(WML) -o $@ $<
messages.py: messages.py.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml \
$(top_srcdir)/config/cdswmllib.wml
$(WML) -o $@ $<
errorHandling.php: errorHandling.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml \
$(top_srcdir)/config/cdswmllib.wml
$(WML) -o $@ $<
diff --git a/modules/miscutil/lib/config.py.wml b/modules/miscutil/lib/config.py.wml
index a81e920fe..e21076e20 100644
--- a/modules/miscutil/lib/config.py.wml
+++ b/modules/miscutil/lib/config.py.wml
@@ -1,177 +1,177 @@
## $Id$
## CDSware config file, to be read by all Python programs.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
## start Python:
<protect>## -*- coding: utf-8 -*-</protect>
<protect>## $Id$</protect>
<protect>## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.</protect>
"""CDSware config file, to be read by all Python programs."""
## fill all the generally-interesting config variables from WML:
cdsname = "<CDSNAME>"
cdslang = "<CDSLANG>"
supportemail = "<SUPPORTEMAIL>"
adminemail = "<ADMINEMAIL>"
alertengineemail = "<ALERTENGINEEMAIL>"
webdir = "<WEBDIR>"
weburl = "<WEBURL>"
bindir = "<BINDIR>"
pylibdir = "<LIBDIR>/python"
cachedir = "<CACHEDIR>"
logdir = "<LOGDIR>"
tmpdir = "<TMPDIR>"
etcdir = "<ETCDIR>"
version = "<VERSION>"
cfg_template_skin = "<CFG_TEMPLATE_SKIN>"
localedir = "<LOCALEDIR>"
## intl versions of CDSNAME of this installation:
cdsnameintl = {}
<de>cdsnameintl['de'] = "<CDSNAMEINTL>"</de>
<en>cdsnameintl['en'] = "<CDSNAMEINTL>"</en>
<es>cdsnameintl['es'] = "<CDSNAMEINTL>"</es>
<ca>cdsnameintl['ca'] = "<CDSNAMEINTL>"</ca>
<pt>cdsnameintl['pt'] = "<CDSNAMEINTL>"</pt>
<fr>cdsnameintl['fr'] = "<CDSNAMEINTL>"</fr>
<it>cdsnameintl['it'] = "<CDSNAMEINTL>"</it>
<ru>cdsnameintl['ru'] = "<CDSNAMEINTL>"</ru>
<sk>cdsnameintl['sk'] = "<CDSNAMEINTL>"</sk>
<cs>cdsnameintl['cs'] = "<CDSNAMEINTL>"</cs>
<no>cdsnameintl['no'] = "<CDSNAMEINTL>"</no>
<sv>cdsnameintl['sv'] = "<CDSNAMEINTL>"</sv>
<el>cdsnameintl['el'] = "<CDSNAMEINTL>"</el>
<uk>cdsnameintl['uk'] = "<CDSNAMEINTL>"</uk>
<ja>cdsnameintl['ja'] = "<CDSNAMEINTL>"</ja>
<pl>cdsnameintl['pl'] = "<CDSNAMEINTL>"</pl>
## Apache password/group files:
cfg_apache_password_file = "<CFG_APACHE_PASSWORD_FILE>"
cfg_apache_group_file = "<CFG_APACHE_GROUP_FILE>"
## are we running CERN specifics?
cfg_cern_site = <CFG_CERN_SITE>
## page elements:
cdspageheader = """<CDSPAGEHEADER>"""
cdspageboxlefttop = """<CDSPAGEBOXLEFTTOP>"""
cdspageboxleftbottom = """<CDSPAGEBOXLEFTBOTTOM>"""
cdspageboxrighttop = """<CDSPAGEBOXRIGHTTOP>"""
cdspageboxrightbottom = """<CDSPAGEBOXRIGHTBOTTOM>"""
cdspagefooter = """<CDSPAGEFOOTER>"""
## helper programs:
pdftotext = "<PDFTOTEXT>"
pstotext = "<PSTOTEXT>"
pstoascii = "<PSTOASCII>"
antiword = "<ANTIWORD>"
catdoc = "<CATDOC>"
wvtext = "<WVTEXT>"
ppthtml = "<PPTHTML>"
xlhtml = "<XLHTML>"
htmltotext = "<HTMLTOTEXT>"
gfile = "<GFILE>"
gzip = "<GZIP>"
tar = "<TAR>"
gunzip = "<GUNZIP>"
acroread = "<ACROREAD>"
distiller = "<DISTILLER>"
convert = "<CONVERT>"
## for search_engine_config:
cfg_max_recID = <CFG_MAX_RECID>
cfg_instant_browse = <CFG_NB_LATEST_ADDITIONS>
cfg_author_et_al_threshold = <CFG_AUTHOR_ET_AL_THRESHOLD>
cfg_search_cache_size = <CFG_SEARCH_CACHE_SIZE>
cfg_nb_records_to_sort = <CFG_NB_RECORDS_TO_SORT>
cfg_call_bibformat = <CFG_CALL_BIBFORMAT>
cfg_use_aleph_sysnos = <CFG_USE_OLD_SYSNOS>
cfg_fields_convert = <CFG_FIELDS_CONVERT>
cfg_simplesearch_pattern_box_width = <CFG_SIMPLESEARCH_PATTERN_BOX_WIDTH>
cfg_advancedsearch_pattern_box_width = <CFG_ADVANCEDSEARCH_PATTERN_BOX_WIDTH>
cfg_narrow_search_show_grandsons = <CFG_NARROW_SEARCH_SHOW_GRANDSONS>
cfg_oaiidtag = "<OAIIDTAG>"
cfg_create_similarly_named_authors_link_box = <CFG_CREATE_SIMILARLY_NAMED_AUTHORS_LINK_BOX>
cfg_google_box = <CFG_GOOGLE_BOX>
cfg_google_box_servers = <CFG_GOOGLE_BOX_SERVERS>
## for websubmit_config:
images = "<WEBURL>/img"
urlpath = "<WEBURL>"
accessurl = "<WEBURL>/search.py"
counters = "<CFG_SUBMIT_COUNTER>"
storage = "<CFG_SUBMIT_DIR>"
filedir = "<CFG_FILE_DIR>"
filedirsize = <CFG_FILE_DIR_SIZE>
bibupload = "<BINDIR>/bibupload"
bibformat = "<BINDIR>/bibformat"
bibwords = "<BINDIR>/bibwords"
bibconvert = "<BINDIR>/bibconvert"
bibconvertconf = "<ETCDIR>/bibconvert/config"
htdocsurl = "<WEBURL>"
## for access_control_config:
CFG_ACCESS_CONTROL_LEVEL_SITE = <CFG_ACCESS_CONTROL_LEVEL_SITE>
CFG_ACCESS_CONTROL_LEVEL_GUESTS = <CFG_ACCESS_CONTROL_LEVEL_GUESTS>
CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS = <CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS>
CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN = "<CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN>"
CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS = <CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS>
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT = <CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT>
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION = <CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION>
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION = <CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION>
## for oai_repository_config:
oaiidprefix = "<OAIIDPREFIX>"
oaisampleidentifier = "<OAISAMPLEIDENTIFIER>"
oaiidentifydescription = """<OAIIDENTIFYDESCRIPTION>"""
oaiidfield = "<OAIIDTAG>"
oaisetfield = "<OAISETTAG>"
oaideleted = "<OAIDELETEDPOLICY>"
oai_rt_expire = <OAIEXPIRE>
oai_sleep = <OAISLEEP>
nb_records_in_resume = <OAILOAD>
nb_identifiers_in_resume = <OAILOAD>
## for bibindex_engine_config:
cfg_bibindex_fulltext_index_local_files_only = <CFG_BIBINDEX_FULLTEXT_INDEX_LOCAL_FILES_ONLY>
cfg_bibindex_stemmer_default_language = "<CFG_BIBINDEX_STEMMER_DEFAULT_LANGUAGE>"
cfg_bibindex_remove_stopwords = <CFG_BIBINDEX_REMOVE_STOPWORDS>
cfg_bibindex_path_to_stopwords_file = "<CFG_BIBINDEX_PATH_TO_STOPWORDS_FILE>"
cfg_bibindex_chars_alphanumeric_separators = r"[<CFG_BIBINDEX_CHARS_ALPHANUMERIC_SEPARATORS>]"
cfg_bibindex_chars_punctuation = r"[<CFG_BIBINDEX_CHARS_PUNCTUATION>]"
cfg_bibindex_remove_html_markup = <CFG_BIBINDEX_REMOVE_HTML_MARKUP>
cfg_bibindex_min_word_length = <CFG_BIBINDEX_MIN_WORD_LENGTH>
cfg_bibindex_urlopener_username = "<CFG_BIBINDEX_URLOPENER_USERNAME>"
cfg_bibindex_urlopener_password = "<CFG_BIBINDEX_URLOPENER_PASSWORD>"
## for commenting:
cfg_webcomment_allow_comments = 1
cfg_webcomment_allow_reviews = 1
cfg_webcomment_nb_reports_before_send_email_to_admin = 5
cfg_webcomment_nb_comments_in_detailed_view = 1
cfg_webcomment_nb_reviews_in_detailed_view = 1
cfg_webcomment_admin_notification_level = 1
cfg_webcomment_timelimit_processing_comments_in_seconds = 20
cfg_webcomment_timelimit_processing_reviews_in_seconds = 20
cfg_webcomment_timelimit_vote_validity_in_days = 365
cfg_webcomment_timelimit_report_validity_in_days = 100
diff --git a/modules/miscutil/lib/dateutils.py b/modules/miscutil/lib/dateutils.py
index f6ab8a6f4..ebd4bf0c0 100644
--- a/modules/miscutil/lib/dateutils.py
+++ b/modules/miscutil/lib/dateutils.py
@@ -1,269 +1,269 @@
# -*- coding: utf-8 -*-
## $Id$
##
## Some functions about dates
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
API for date conversion and date related GUI creation.
Lexicon
datetext:
textual format => 'YEAR-MONTH-DAY HOUR:MINUTE:SECOND'
e.g. '2005-11-16 15:11:44'
default value: '0000-00-00 00:00:00'
datestruct:
tuple format => see http://docs.python.org/lib/module-time.html
(YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEKDAY, YEARDAY, DAYLIGHT)
e.g. (2005, 11, 16, 15, 11, 44, 2, 320, 0)
default value: (0, 0, 0, 0, 0, 0, 0, 0, 0)
dategui:
textual format for output => 'DAY MONTH YEAR, HOUR:MINUTE'
e.g. '16 nov 2005, 15:11'
default value: _("N/A")
"""
# External imports
from time import strptime, strftime, localtime
# CDSware imports
from cdsware.config import cdslang
from cdsware.messages import gettext_set_language
datetext_default = '0000-00-00 00:00:00'
datestruct_default = (0, 0, 0, 0, 0, 0, 0, 0, 0)
datetext_format = "%Y-%m-%d %H:%M:%S"
def convert_datetext_to_dategui(datetext, ln=cdslang):
"""
Convert:
'2005-11-16 15:11:57' => '16 nov 2005, 15:11'
Month is internationalized
"""
try:
datestruct = convert_datetext_to_datestruct(datetext)
if datestruct == datestruct_default:
raise ValueError
month = get_i18n_month_name(datestruct[1], ln=ln)
output_format = "%d " + month + " %Y, %H:%M"
return strftime(output_format, datestruct)
except:
_ = gettext_set_language(ln)
return _("N/A")
def convert_datetext_to_datestruct(datetext):
"""
Convert:
'2005-11-16 15:11:57' => (2005, 11, 16, 15, 11, 44, 2, 320, 0)
"""
try:
return strptime(datetext, datetext_format)
except:
return datestruct_default
def convert_datestruct_to_dategui(datestruct, ln=cdslang):
"""
Convert:
(2005, 11, 16, 15, 11, 44, 2, 320, 0) => '16 nov 2005, 15:11'
Month is internationalized
"""
try:
if datestruct[0] and datestruct[1] and datestruct[2]:
month = get_i18n_month_name(datestruct[1], ln=ln)
output_format = "%d " + month + " %Y, %H:%M"
return strftime(output_format, datestruct)
else:
raise ValueError
except:
_ = gettext_set_language(ln)
return _("N/A")
def convert_datestruct_to_datetext(datestruct):
"""
Convert:
(2005, 11, 16, 15, 11, 44, 2, 320, 0) => '2005-11-16 15:11:57'
"""
try:
return strftime(datetext_format, datestruct)
except:
return datetext_default
def get_datetext(year, month, day):
"""
year=2005, month=11, day=16 => '2005-11-16 00:00:00'
"""
input_format = "%Y-%m-%d"
try:
datestruct = strptime("%i-%i-%i"% (year, month, day), input_format)
return strftime(datetext_format, datestruct)
except:
return datetext_default
def get_datestruct(year, month, day):
"""
year=2005, month=11, day=16 => (2005, 11, 16, 0, 0, 0, 2, 320, -1)
"""
input_format = "%Y-%m-%d"
try:
return strptime("%i-%i-%i"% (year, month, day), input_format)
except ValueError or TypeError:
return datestruct_default
def get_i18n_day_name(day_nb, display='short', ln=cdslang):
"""
get the string representation of a weekday, internationalized
@param day_nb: number of weekday UNIX like.
=> 0=Sunday
@param ln: language for output
@return the string representation of the day
"""
_ = gettext_set_language(ln)
if display == 'short':
days = {0: _("Sun"),
1: _("Mon"),
2: _("Tue"),
3: _("Wed"),
4: _("Thu"),
5: _("Fri"),
6: _("Sat")}
else:
days = {0: _("Sunday"),
1: _("Monday"),
2: _("Tuesday"),
3: _("Wednesday"),
4: _("Thursday"),
5: _("Friday"),
6: _("Saturday")}
return days[day_nb]
def get_i18n_month_name(month_nb, display='short', ln=cdslang):
"""
get a non-numeric representation of a month, internationalized.
@param month_nb: number of month, (1 based!)
=>1=jan,..,12=dec
@param ln: language for output
@return the string representation of month
"""
_ = gettext_set_language(ln)
if display == 'short':
monthes = {0: _("Month"),
1: _("Jan"),
2: _("Feb"),
3: _("Mar"),
4: _("Apr"),
5: _("May"),
6: _("Jun"),
7: _("Jul"),
8: _("Aug"),
9: _("Sep"),
10: _("Oct"),
11: _("Nov"),
12: _("Dec")}
else:
monthes = {0: _("Month"),
1: _("January"),
2: _("February"),
3: _("March"),
4: _("April"),
5: _("May"),
6: _("June"),
7: _("July"),
8: _("August"),
9: _("September"),
10: _("October"),
11: _("November"),
12: _("December")}
return monthes[month_nb]
def create_day_selectbox(name, selected_day=0, ln=cdslang):
"""
Creates an HTML menu for day selection. (0..31 values).
@param name: name of the control (i.e. name of the var you'll get)
@param selected_day: preselect a day. Use 0 for the label 'Day'
@param ln: language of the menu
@return html a string
"""
_ = gettext_set_language(ln)
out = "<select name=\"%s\">\n"% name
for i in range(0, 32):
out += " <option value=\"%i\""% i
if (i == selected_day):
out += " selected=\"selected\""
if (i == 0):
out += ">%s</option>\n"% _("Day")
else:
out += ">%i</option>\n"% i
out += "</select>\n"
return out
def create_month_selectbox(name, selected_month=0, ln=cdslang):
"""
Creates an HTML menu for month selection. Value of selected field is numeric
@param name: name of the control (your form will be sent with name=value...)
@param selected_month: preselect a month. use 0 for the Label 'Month'
@param ln: language of the menu
@return html as string
"""
out = "<select name=\"%s\">\n"% name
for i in range(0, 13):
out += "<option value=\"%i\""% i
if (i == selected_month):
out += " selected=\"selected\""
out += ">%s</option>\n"% get_i18n_month_name(i, ln)
out += "</select>\n"
return out
def create_year_inputbox(name, value=0):
"""
Creates an HTML field (simple input) for year selection.
@param name: name of the control (i.e. name of the variable you'll get)
@param value: prefilled value (int)
@return html as string
"""
out = "<input type=\"text\" name=\"%s\" value=\"%i\" maxlength=\"4\" size=\"4\"/>\n"% (name, value)
return out
def create_year_selectbox(name, from_year=-1, length=10, selected_year=0, ln=cdslang):
"""
Creates an HTML menu (dropdownbox) for year selection.
@param name: name of control( i.e. name of the variable you'll get)
@param from_year: year on which to begin. if <0 assume it is current year
@param length: number of items in menu
@param selected_year: initial selected year (if in range), else: label is selected
@param ln: language
@return html as string
"""
_ = gettext_set_language(ln)
if from_year < 0:
from_year = localtime()[0]
out = "<select name=\"%s\">\n"% name
out += ' <option value="0"'
if selected_year == 0:
out += ' selected="selected"'
out += ">%s</option>\n"% _("Year")
for i in range(from_year, from_year + length):
out += "<option value=\"%i\""% i
if (i == selected_year):
out += " selected=\"selected\""
out += ">%i</option>\n"% i
out += "</select>\n"
return out
diff --git a/modules/miscutil/lib/dbquery.py.wml b/modules/miscutil/lib/dbquery.py.wml
index 4ee9ed856..85a49cef5 100644
--- a/modules/miscutil/lib/dbquery.py.wml
+++ b/modules/miscutil/lib/dbquery.py.wml
@@ -1,116 +1,116 @@
## $Id$
## CDSware utility to run SQL queries. The core is taken from
## modpython FAQ and modified to suit our needs. The insert_id() is
## inspired by Erik Forsberg's mod_python slides.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
"""CDSware utility to run SQL queries."""
import MySQLdb
import string
## FIXME: these are read here and not in config.py in order to prevent
## them to show up in case some mod_python web script uses ``from
## config import *''. If we waterproof all mod_python web scripts,
## then it may possibly be moved there. But it's safer to read them
## only here.
dbhost = "<DBHOST>"
dbname = "<DBNAME>"
dbuser = "<DBUSER>"
dbpass = "<DBPASS>"
__version__ = "$Id$"
def _db_login(relogin = 0):
"""Login to the database."""
global DB_CONN
if relogin:
DB_CONN = MySQLdb.connect(host=dbhost, db=dbname, user=dbuser, passwd=dbpass)
return DB_CONN
else:
try:
d = DB_CONN
return d
except NameError:
DB_CONN = MySQLdb.connect(host=dbhost, db=dbname, user=dbuser, passwd=dbpass)
return DB_CONN
def run_sql(sql, param=None, n=0, with_desc=0):
"""Run SQL on the server and returns result."""
### log_sql_query(sql, param) ### UNCOMMENT ONLY IF you REALLY want to log all queries
db = _db_login()
if param:
param = tuple(param)
try:
cur = db.cursor()
rc = cur.execute(sql, param)
except MySQLdb.OperationalError, e: # unexpected disconnect, bad malloc error, etc
# FIXME: now reconnect is always forced, we may perhaps want to ping() first?
db = _db_login(relogin = 1)
cur = db.cursor()
rc = cur.execute(sql, param)
if string.upper(string.split(sql)[0]) in ("SELECT", "SHOW", "DESC", "DESCRIBE"):
if n:
recset = cur.fetchmany(n)
else:
recset = cur.fetchall()
if with_desc:
return recset, cur.description
else:
return recset
else:
if string.upper(string.split(sql)[0]) == "INSERT":
rc = cur.lastrowid
return rc
def blob_to_string(ablob):
"""Return string representation of ABLOB. Useful to treat MySQL
BLOBs in the same way for both recent and old MySQLdb versions.
"""
if type(ablob) is str:
# BLOB is already a string in MySQLdb 0.9.2
return ablob
else:
# BLOB is array.array in MySQLdb 1.0.0 and later
return ablob.tostring()
def log_sql_query(sql, param=None):
"""Log SQL query into prefix/var/dbquery.log log file. In order
to enable logging of all SQL queries, please uncomment one line
in run_sql() above. Useful for fine-level debugging only!
"""
from cdsware.config import logdir
from cdsware.dateutils import convert_datestruct_to_datetext
import time
from cdsware.textutils import indent_text
log_path = logdir + '/dbquery.log'
date_of_log = convert_datestruct_to_datetext(time.localtime())
message = date_of_log + '-->\n'
message += indent_text('Query:\n' + indent_text(str(sql),2),2)
message += indent_text('Params:\n' + indent_text(str(param),2),2)
message += '-----------------------------\n\n'
try:
log_file = open(log_path, 'a+')
log_file.writelines(message)
log_file.close()
except:
pass
diff --git a/modules/miscutil/lib/errorHandling.php.wml b/modules/miscutil/lib/errorHandling.php.wml
index c24052a6f..9550185a9 100644
--- a/modules/miscutil/lib/errorHandling.php.wml
+++ b/modules/miscutil/lib/errorHandling.php.wml
@@ -1,100 +1,100 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
$ADMINEMAIL = "<ADMINEMAIL>";
$CFG_CERN_SITE = <CFG_CERN_SITE>;
#######################################################
#
# Name: errorHandling.php
# Type: php script
# Description: EDS v2.0 - Error handling script
# Author: T.Baron
#
# Created: 01/11/2001
# Last modified: 09/04/2002 T. Baron
#
# INPUT: -
# OUTPUT:-
#
#######################################################
// This function outputs an error message
// and sends it to the ADMIN of the system
// The calling script is stopped
function outError($text)
{
global $ADMINEMAIL;
$text = stripslashes($text);
// first send an email to the support people
mail ("$ADMINEMAIL","WebSubmit - ERROR REPORT","$text");
// Then display an error message
print '
<div align="center">
<br><br>
<table border="1" summary="">
<tr>
<td>
<font size="+1" color="red"><b>Error:</b></font><br><br><font size="-1"><b>
'.$text.'
</b><br><br>
<i>
Please note an email has been automatically sent to the support group.<br>Everything will be done to correct the tool as soon as possible.
</i>
</td>
</tr>
</table>
</div>';
print "</td></tr></table>";
exit;
}
// This function outputs a warning message
// The calling script can go on
function outWarning($text)
{
$text = stripslashes($text);
// Simply display a warning message
print '
<center>
<br>
<table border=1>
<tr>
<td>
<font size=+1 color=green><b>Warning:</b></font><br><br><font size=-1><b>
'.$text.'
</b><br>&nbsp;
</td>
</tr>
</table>
</center>';
}
?>
diff --git a/modules/miscutil/lib/errorlib.py b/modules/miscutil/lib/errorlib.py
index 4c6b2f07e..93df0b7fc 100644
--- a/modules/miscutil/lib/errorlib.py
+++ b/modules/miscutil/lib/errorlib.py
@@ -1,294 +1,294 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Error handling library """
__lastupdated__ = """$Date$"""
# CDSware imports
from cdsware.config import cdslang, logdir, alertengineemail, adminemail, supportemail
from cdsware.miscutil_config import cfg_miscutil_error_messages
from cdsware.urlutils import wash_url_argument
from cdsware.messages import wash_language, gettext_set_language
from cdsware.dateutils import convert_datestruct_to_datetext
#External imports
import traceback
import sys
import time
def get_client_info(req):
"""
Returns a dictionary with client information
@param req: mod_python request
"""
try:
return \
{ 'host' : req.hostname,
'url' : req.unparsed_uri,
'time' : convert_datestruct_to_datetext(time.localtime()),
'browser' : req.headers_in.has_key('User-Agent') and req.headers_in['User-Agent'] or "N/A",
'client_ip' : req.connection.remote_ip
}
except:
return {}
def get_tracestack():
"""
If an exception has been caught, return the system tracestack or else return tracestack of what is currently in the stack
"""
if traceback.format_tb(sys.exc_info()[2]):
delimiter = "\n"
tracestack_pretty = "Traceback: \n%s" % delimiter.join(traceback.format_tb(sys.exc_info()[2]))
else:
tracestack = traceback.extract_stack()[:-1] #force traceback except for this call
tracestack_pretty = "%sForced traceback (most recent call last)" % (' '*4,)
for trace_tuple in tracestack:
tracestack_pretty += '''
File "%(file)s", line %(line)s, in %(function)s
%(text)s''' % \
{ 'file' : trace_tuple[0],
'line' : trace_tuple[1],
'function' : trace_tuple[2],
'text' : trace_tuple[3] is None and "" or "%s" % trace_tuple[3]
}
return tracestack_pretty
def register_errors(errors_or_warnings_list, file, req=None):
"""
log errors to cdsware.err and warnings to cdsware.log
errors will be logged with client information (if req is given) and a tracestack
warnings will be logged with just the warning message
@param errors_or_warnings_list: list of tuples (err_name, err_msg)
err_name = ERR_ + %(module_directory_name)s + _ + %(error_name)s #ALL CAPS
err_name must be stored in file: module_directory_name + _config.py
as the key for dict with name: cfg_ + %(module_directory_name)s + _error_messages
@param req = mod_python request
@return tuple integer 1 if successfully wrote to file, integer 0 if not
will append another error to errors_list if unsuccessful
"""
client_info_dict = ""
if file == "error":
# call the stack trace now
tracestack_pretty = get_tracestack()
# if req is given, get client info
if req:
client_info_dict = get_client_info(req)
if client_info_dict:
client_info = \
'''URL: http://%(host)s%(url)s
Browser: %(browser)s
Client: %(client_ip)s''' % client_info_dict
else:
client_info = "No client information available"
else:
client_info = "No client information available"
# check arguments
errors_or_warnings_list = wash_url_argument(errors_or_warnings_list, 'list')
file = wash_url_argument(file, 'str')
for etuple in errors_or_warnings_list:
etuple = wash_url_argument(etuple, 'tuple')
# check file arg, if error default to warnings file + add error
if file == 'error':
file = 'err'
elif file == 'warning':
file = 'log'
else:
file = 'log'
error = 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED'
errors_or_warnings_list.append((error, eval(cfg_miscutil_error_messages[error])% file))
# update log_errors
file_pwd = logdir + '/cdsware.' + file
errors = ''
for etuple in errors_or_warnings_list:
try:
errors += "%s%s : %s \n " % (' '*4*7+' ', etuple[0], etuple[1])
except:
errors += "%s%s \n " % (' '*4*7+' ', etuple)
if errors:
errors = errors[(4*7+1):-3] # get rid of begining spaces and last '\n'
msg = '''
%(time)s --> %(errors)s%(error_file)s''' % \
{ 'time' : client_info_dict and client_info_dict['time'] or time.strftime("%Y-%m-%d %H:%M:%S"),
'errors' : errors,
'error_file' : file=='err' and "\n%s%s\n%s\n" % (' '*4, client_info, tracestack_pretty) or ""
}
try:
file_to_write = open(file_pwd, 'a+')
file_to_write.writelines(msg)
file_to_write.close()
return_value = 1
except :
error = 'ERR_MISCUTIL_WRITE_FAILED'
errors_or_warnings_list.append((error, cfg_miscutil_error_messages[error] % file_pwd))
return_value = 0
return return_value
def get_msg_associated_to_code(err_code, file='error'):
"""
Returns string of code
@param code: error or warning code
@param file: 'error' or 'warning'
@return tuple (err_code, formatted_message)
"""
err_code = wash_url_argument(err_code, 'str')
file = wash_url_argument(file, 'str')
try:
module_directory_name = err_code.split('_')[1].lower()
module_config = module_directory_name + '_config'
module_dict_name = "cfg_" + module_directory_name + "_%s_messages" % file
module = __import__(module_config, globals(), locals(), [module_dict_name])
module_dict = getattr(module, module_dict_name)
err_msg = module_dict[err_code]
except ImportError:
error = 'ERR_MISCUTIL_IMPORT_ERROR'
err_msg = cfg_miscutil_error_messages[error] % (err_code,
module_config)
err_code = error
except AttributeError:
error = 'ERR_MISCUTIL_NO_DICT'
err_msg = cfg_miscutil_error_messages[error] % (err_code,
module_config,
module_dict_name)
err_code = error
except KeyError:
error = 'ERR_MISCUTIL_NO_MESSAGE_IN_DICT'
err_msg = cfg_miscutil_error_messages[error] % (err_code,
module_config + '.' + module_dict_name)
err_code = error
except:
error = 'ERR_MISCUTIL_UNDEFINED_ERROR'
err_msg = cfg_miscutil_error_messages[error] % err_code
err_code = error
return (err_code, err_msg)
def get_msgs_for_code_list(code_list, file='error', ln=cdslang):
"""
@param code_list: list of tuples [(err_name, arg1, ..., argN), ...]
err_name = ERR_ + %(module_directory_name)s + _ + %(error_name)s #ALL CAPS
err_name must be stored in file: module_directory_name + _config.py
as the key for dict with name: cfg_ + %(module_directory_name)s + _error_messages
For warnings, same thing except:
err_name can begin with either 'ERR' or 'WRN'
dict name ends with _warning_messages
@return list of tuples of length 2 [('ERR_...', err_msg), ...]
if code_list empty, will return None.
if errors retrieving error messages, will append an error to the list
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
out = []
if type(code_list) is None:
return None
code_list = wash_url_argument(code_list, 'list')
file = wash_url_argument(file, 'str')
for code_tuple in code_list:
if not(type(code_tuple) is tuple):
code_tuple = (code_tuple,)
nb_tuple_args = len(code_tuple) - 1
err_code = code_tuple[0]
if file == 'error' and not err_code.startswith('ERR'):
error = 'ERR_MISCUTIL_NO_ERROR_MESSAGE'
out.append((error, eval(cfg_miscutil_error_messages[error])))
continue
elif file == 'warning' and not (err_code.startswith('ERR') or err_code.startswith('WRN')):
error = 'ERR_MISCUTIL_NO_WARNING_MESSAGE'
out.append((error, eval(cfg_miscutil_error_messages[error])))
continue
(new_err_code, err_msg) = get_msg_associated_to_code(err_code, file)
if err_msg[:2] == '_(' and err_msg[-1] == ')':
# err_msg is internationalized
err_msg = eval(err_msg)
nb_msg_args = err_msg.count('%') - err_msg.count('%%')
parsing_error = ""
if new_err_code != err_code or nb_msg_args == 0:
# undefined_error or immediately displayable error
out.append((new_err_code, err_msg))
continue
try:
if nb_msg_args == nb_tuple_args:
err_msg = err_msg % code_tuple[1:]
elif nb_msg_args < nb_tuple_args:
err_msg = err_msg % code_tuple[1:nb_msg_args+1]
parsing_error = 'ERR_MISCUTIL_TOO_MANY_ARGUMENT'
parsing_error_message = eval(cfg_miscutil_error_messages[parsing_error])
parsing_error_message %= code_tuple[0]
elif nb_msg_args > nb_tuple_args:
code_tuple = list(code_tuple)
for i in range(nb_msg_args - nb_tuple_args):
code_tuple.append('???')
code_tuple = tuple(code_tuple)
err_msg = err_msg % code_tuple[1:]
parsing_error = 'ERR_MISCUTIL_TOO_FEW_ARGUMENT'
parsing_error_message = eval(cfg_miscutil_error_messages[parsing_error])
parsing_error_message %= code_tuple[0]
except:
parsing_error = 'ERR_MISCUTIL_BAD_ARGUMENT_TYPE'
parsing_error_message = eval(cfg_miscutil_error_messages[parsing_error])
parsing_error_message %= code_tuple[0]
out.append((err_code, err_msg))
if parsing_error:
out.append((parsing_error, parsing_error_message))
if not(out):
out = None
return out
def send_error_report_to_admin(header, url, time_msg,
browser, client, error,
sys_error, traceback_msg):
"""
Sends an email to the admin with client info and tracestack
"""
from_addr = 'CDS Alert Engine <%s>' % alertengineemail
to_addr = adminemail
body = """
The following error was seen by a user and sent to you.
%(contact)s
%(header)s
%(url)s
%(time)s
%(browser)s
%(client)s
%(error)s
%(sys_error)s
%(traceback)s
Please see the %(logdir)s/errors.log for traceback details.""" % \
{ 'header' : header,
'url' : url,
'time' : time_msg,
'browser' : browser,
'client' : client,
'error' : error,
'sys_error' : sys_error,
'traceback' : traceback_msg,
'logdir' : logdir,
'contact' : "Please contact %s quoting the following information:" % (supportemail,) #! is support email always cds?
}
from cdsware.alert_engine import send_email
send_email(from_addr, to_addr, body)
diff --git a/modules/miscutil/lib/errorlib_tests.py b/modules/miscutil/lib/errorlib_tests.py
index 13a72973d..03cc73b33 100644
--- a/modules/miscutil/lib/errorlib_tests.py
+++ b/modules/miscutil/lib/errorlib_tests.py
@@ -1,171 +1,171 @@
# -*- coding: utf-8 -*-
## $Id$
## CDSware ErrorLib unit tests.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Test unit for the miscutil/errorlib module. """
__lastupdated__ = """$Date$"""
from cdsware.errorlib import get_msg_associated_to_code, get_msgs_for_code_list
import unittest
class TestInternalErrorlibErrors(unittest.TestCase):
"""
Class for testing!
"""
messages = []
def test_correct_association(self):
"""errorlib - code association: correct code"""
# correct input
input_err_code = 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED'
(output_err_code, err_msg) = get_msg_associated_to_code(input_err_code, 'error')
self.assertEqual(output_err_code, input_err_code)
def test_no_module(self):
"""errorlib - code association: no <module>_config"""
# no file module_config
input_err_code ='ERR_BADMODULEIDENTIFIER_WITH_BAD_ERRORNAME'
(output_err_code, err_msg) = get_msg_associated_to_code(input_err_code, 'error')
expected_output_err_code = 'ERR_MISCUTIL_IMPORT_ERROR'
self.assertEqual(output_err_code, expected_output_err_code)
def test_no_dictionary(self):
"""errorlib - code association: no error dictionary"""
# file exists, but no dictionary
input_err_code ='ERR_MISCUTIL_NODICTIONARY'
(output_err_code, err_msg) = get_msg_associated_to_code(input_err_code, 'nodict')
expected_output_err_code = 'ERR_MISCUTIL_NO_DICT'
self.assertEqual(output_err_code, expected_output_err_code)
def test_no_identifier(self):
"""errorlib - code association: no identifier"""
# identifier not in dictionary
input_err_code ='ERR_MISCUTIL_IDENTIFIER_WONT_BE_FOUND_IN_DICTIONNARY'
(output_err_code, err_msg) = get_msg_associated_to_code(input_err_code, 'error')
expected_output_err_code = 'ERR_MISCUTIL_NO_MESSAGE_IN_DICT'
self.assertEqual(output_err_code, expected_output_err_code)
def test_not_an_error(self):
"""errorlib - code association: badly named error"""
# identifier does not begin with ERR or WRN
input_err_code = 'STRANGEERROR'
(output_err_code, err_msg) = get_msg_associated_to_code(input_err_code, 'error')
expected_output_err_code = 'ERR_MISCUTIL_UNDEFINED_ERROR'
self.assertEqual(output_err_code, expected_output_err_code)
def test_correct_argument_validation(self):
"""errorlib - single argument"""
# displayable error
error = 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED'
output_list = get_msgs_for_code_list((error, 'junk'))
self.assertEqual(1, len(output_list))
self.assertEqual(2, len(output_list[0]))
self.assertEqual(error, output_list[0][0])
self.messages.append(output_list[0][1])
def test_correct_arguments_validation(self):
"""errorlib - multiple errors"""
# displayable errors
error = 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED'
output_list = get_msgs_for_code_list([(error, 'junk'), (error, 'junk')])
self.assertEqual(2, len(output_list))
self.assertEqual(2, len(output_list[0]))
self.assertEqual(2, len(output_list[1]))
self.assertEqual(error, output_list[0][0])
self.assertEqual(error, output_list[1][0])
# store error message for further tests
self.messages.append(output_list[0][1])
self.messages.append(output_list[1][1])
def test_undefined_error(self):
"""errorlib - no underscore in error"""
# undefined error
error = 'ERRMISCUTIL'
expected_error = 'ERR_MISCUTIL_UNDEFINED_ERROR'
output_list = get_msgs_for_code_list([(error)])
self.assertEqual(1, len(output_list))
self.assertEqual(2, len(output_list[0]))
self.assertEqual(expected_error, output_list[0][0])
# store error messages for further tests
self.messages.append(output_list[0][1])
def test_too_many_arguments(self):
"""errorlib - arguments: too many arguments"""
# too many arguments
error = 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED'
other_error = 'ERR_MISCUTIL_TOO_MANY_ARGUMENT'
output_list = get_msgs_for_code_list([(error, 'junk', 'junk', 'junk')])
self.assertEqual(2, len(output_list))
self.assertEqual(2, len(output_list[0]))
self.assertEqual(2, len(output_list[1]))
self.assertEqual(error, output_list[0][0])
self.assertEqual(other_error, output_list[1][0])
# store error messages for further tests
self.messages.append(output_list[0][1])
self.messages.append(output_list[1][1])
def test_too_few_arguments(self):
"""errorlib - arguments: too few arguments"""
# too few argument
error = 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED'
other_error = 'ERR_MISCUTIL_TOO_FEW_ARGUMENT'
output_list = get_msgs_for_code_list([(error)])
self.assertEqual(2, len(output_list))
self.assertEqual(2, len(output_list[0]))
self.assertEqual(2, len(output_list[1]))
self.assertEqual(error, output_list[0][0])
self.assertEqual(other_error, output_list[1][0])
# store error messages for further tests
self.messages.append(output_list[0][1])
self.messages.append(output_list[1][1])
def test_bad_type(self):
"""errorlib - arguments: bad argument type"""
# bad argument type
error = 'ERR_MISCUTIL_DEBUG'
other_error = 'ERR_MISCUTIL_BAD_ARGUMENT_TYPE'
output_list = get_msgs_for_code_list([(error, 'should be an int')])
self.assertEqual(2, len(output_list))
self.assertEqual(2, len(output_list[0]))
self.assertEqual(2, len(output_list[1]))
self.assertEqual(error, output_list[0][0])
self.assertEqual(other_error, output_list[1][0])
# z because this function must execute lately for more interesting results
def test_zsubstitution(self):
"""errorlib - arguments: every argument substituted"""
# string replacement
testmessages = reduce(lambda x, y: str(x) + str(y), self.messages)
self.assertEqual(0, testmessages.count('%') - testmessages.count('%%'))
# z because this function must also execute lately for more interesting results
def test_zinternationalization(self):
"""errorlib - internationalization"""
# string internationalization
testmessages = reduce(lambda x, y: str(x) + str(y), self.messages)
self.assertEqual(0, testmessages.count('_('))
def create_test_suite():
"""
Return test suite for the search engine.
"""
return unittest.TestSuite((unittest.makeSuite(TestInternalErrorlibErrors, 'test'),))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/miscutil/lib/messages.py.wml b/modules/miscutil/lib/messages.py.wml
index 18fb2c20f..64d4e63b1 100644
--- a/modules/miscutil/lib/messages.py.wml
+++ b/modules/miscutil/lib/messages.py.wml
@@ -1,92 +1,92 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "config.wml"
#include "cdswmllib.wml"
<protect>## -*- coding: utf-8 -*-</protect>
<protect>## $Id$
<protect>## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.</protect>
"""CDSware international messages functions, to be used by all I18N interfaces.
Typical usage in the caller code is:
from messages import gettext_set_language
[...]
def square(x, ln=cdslang):
_ = gettext_set_language(ln)
print _("Hello there!")
print _("The square of %s is %s.") % (x, x*x)
In the caller code, all output strings should be made translatable via
the _() convention.
For more information, see ABOUT-NLS file.
"""
import string
import sre
from cdsware.config import localedir
import gettext
lang = {}
for ln in <: print generate_language_list_for_python(); :>:
lang[ln] = gettext.translation('cdsware', localedir, languages = [ln], fallback = True)
def gettext_set_language(ln):
"""
Set the _ gettext function in every caller function
Usage::
_ = gettext_set_language(ln)
"""
return lang[ln].gettext
def wash_language(ln):
"""Look at LN and check if it is one of allowed languages for the interface.
Return it in case of success, return the default language otherwise."""
if ln in <: print generate_language_list_for_python(); :>:
return ln
else:
return '<CDSLANG>'
def create_language_selection_box(urlargs="", language="en"):
"""Take URLARGS and LANGUAGE and return textual language
selection box for the given page."""
_ = gettext_set_language(language)
out = ""
for (lang, lang_namelong) in <: print generate_language_list_for_python("long"); :>:
if lang == language:
out += """ <span class="langinfo">%s</span> &nbsp; """ % lang_namelong
else:
if urlargs:
urlargs = sre.sub(r'ln=.*?(&|$)', '', urlargs)
if urlargs:
if urlargs.endswith('&'):
urlargs += "ln=%s" % lang
else:
urlargs += "&ln=%s" % lang
else:
urlargs = "ln=%s" % lang
out += """ <a class="langinfo" href="?%s">%s</a> &nbsp; """ % (urlargs, lang_namelong)
return _("This site is also available in the following languages:") + "<br>" + out
def language_list_long():
return <: print generate_language_list_for_python("long"); :>
diff --git a/modules/miscutil/lib/miscutil_config.py b/modules/miscutil/lib/miscutil_config.py
index 47378e8d9..02b10ebdf 100644
--- a/modules/miscutil/lib/miscutil_config.py
+++ b/modules/miscutil/lib/miscutil_config.py
@@ -1,39 +1,39 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Configuration file for miscutil module.
- Contains standard error messages for errorlib
e.g. No error message given, etc.
"""
__lastupdated__ = """$Date$"""
cfg_miscutil_error_messages = \
{ 'ERR_MISCUTIL_BAD_FILE_ARGUMENT_PASSED': '_("Invalid argument %s was passed")',
'ERR_MISCUTIL_WRITE_FAILED': '_("Unable to write to file %s")',
'ERR_MISCUTIL_NO_ERROR_MESSAGE': '_("Trying to write a non error message to error log")',
'ERR_MISCUTIL_NO_WARNING_MESSAGE': '_("Trying to write a non error message or non warning message to error log")',
'ERR_MISCUTIL_TOO_MANY_ARGUMENT': '_("Unable to display error: Too many arguments given for error %s")',
'ERR_MISCUTIL_TOO_FEW_ARGUMENT':'_("Unable to display error: Too few arguments given for error %s")',
'ERR_MISCUTIL_IMPORT_ERROR': '_("An undefined error has occured (%s). \'%s\' does not exist")',
'ERR_MISCUTIL_NO_DICT': '_("An undefined error has occured (%s). %s does not contain %s")',
'ERR_MISCUTIL_NO_MESSAGE_IN_DICT': '_("An undefined error has occured. %s not defined in %s")',
'ERR_MISCUTIL_UNDEFINED_ERROR': '_("An undefined error has occured (%s)")',
'ERR_MISCUTIL_BAD_ARGUMENT_TYPE': '_("Unable to display error: Arguments do not match for error %s")',
'ERR_MISCUTIL_DEBUG': 'Error nb %i'
}
diff --git a/modules/miscutil/lib/textutils.py b/modules/miscutil/lib/textutils.py
index 6f71c502e..c82ad5b9c 100644
--- a/modules/miscutil/lib/textutils.py
+++ b/modules/miscutil/lib/textutils.py
@@ -1,44 +1,44 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Functions for text handling:
- indenting
- ...
"""
def indent_text(text,
nb_tabs=0,
tab_str=" ",
linebreak_input="\n",
linebreak_output="\n"):
"""
add tabs to each line of text
@param text: the text to indent
@param nb_tabs: number of tabs to add
@param tab_str: type of tab (could be, for example "\t", default: 2 spaces
@param linebreak_input: linebreak on input
@param linebreak_output: linebreak on output
@return indented text as string
"""
lines = text.split(linebreak_input)
tabs = nb_tabs*tab_str
output = ""
for line in lines:
output += tabs + line + linebreak_output
return output
diff --git a/modules/miscutil/lib/urlutils.py b/modules/miscutil/lib/urlutils.py
index bfdc5b9fc..9c39a4056 100644
--- a/modules/miscutil/lib/urlutils.py
+++ b/modules/miscutil/lib/urlutils.py
@@ -1,113 +1,113 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" urlutils: tools for managing URL related problems:
- washing,
- redirection
"""
__lastupdated__ = """$Date$"""
__version__ = "$Id$"
try:
from mod_python import apache
except ImportError:
pass
def wash_url_argument(var, new_type):
"""
Wash argument into 'new_type', that can be 'list', 'str', 'int', 'tuple' or 'dict'.
If needed, the check 'type(var) is not None' should be done before calling this function.
@param var: variable value
@param new_type: variable type, 'list', 'str', 'int', 'tuple' or 'dict'
@return as much as possible, value var as type new_type
If var is a list, will change first element into new_type.
If int check unsuccessful, returns 0
"""
out = []
if new_type == 'list': # return lst
if type(var) is list:
out = var
else:
out = [var]
elif new_type == 'str': # return str
if type(var) is list:
try:
out = "%s" % var[0]
except:
out = ""
elif type(var) is str:
out = var
else:
out = "%s" % var
elif new_type == 'int': # return int
if type(var) is list:
try:
out = int(var[0])
except:
out = 0
elif type(var) is int:
out = var
elif type(var) is str:
try:
out = int(var)
except:
out = 0
else:
out = 0
elif new_type == 'tuple': # return tuple
if type(var) is tuple:
out = var
else:
out = (var,)
elif new_type == 'dict': # return dictionary
if type(var) is dict:
out = var
else:
out = {0:var}
return out
def redirect_to_url(req, url):
"""
Redirect current page to url.
@param req: request as received from apache
@param url: url to redirect to"""
req.err_headers_out.add("Location", url)
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
def get_client_ip_address(req):
""" Returns IP address as string from an apache request. """
return str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
def get_referer(req, replace_ampersands=1):
""" Return the referring page of a request.
Referer (wikipedia): Referer is a common misspelling of the word "referrer";
so common, in fact, that it made it into the official specification of HTTP.
When visiting a webpage, the referer or referring page is the URL of the
previous webpage from which a link was followed.
@param req: request
@param replace_ampersands: if 1, replace & by &amp; in url (correct HTML cannot contain & characters alone).
"""
try:
referer = req.headers_in['Referer']
if replace_ampersands==1:
return referer.replace('&', '&amp;')
return referer
except KeyError:
return ''
diff --git a/modules/miscutil/sql/Makefile.am b/modules/miscutil/sql/Makefile.am
index 4886ddaf4..88a370191 100644
--- a/modules/miscutil/sql/Makefile.am
+++ b/modules/miscutil/sql/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
noinst_DATA=tabfill.sql
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%) tabcreate.sql tabdrop.sql tabbibclean.sql
CLEANFILES = $(noinst_DATA) *~ *.tmp tabfill.sql
%: %.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o $@ $<
\ No newline at end of file
diff --git a/modules/miscutil/sql/tabcreate.sql b/modules/miscutil/sql/tabcreate.sql
index 4352ca760..0af31a176 100644
--- a/modules/miscutil/sql/tabcreate.sql
+++ b/modules/miscutil/sql/tabcreate.sql
@@ -1,3013 +1,3013 @@
-- $Id$
-- Create tables for the CDS Software.
-- This file is part of the CERN Document Server Software (CDSware).
--- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+-- Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
--
-- The CDSware 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.
--
-- The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-- tables for bibliographic records:
CREATE TABLE IF NOT EXISTS bibrec (
id mediumint(8) unsigned NOT NULL auto_increment,
creation_date datetime NOT NULL default '0000-00-00',
modification_date datetime NOT NULL default '0000-00-00',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib00x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib01x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib02x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib03x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib04x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib05x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib06x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib07x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib08x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib09x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib10x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib11x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib12x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib13x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib14x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib15x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib16x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib17x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib18x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib19x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib20x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib21x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib22x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib23x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib24x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib25x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib26x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib27x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib28x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib29x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib30x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib31x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib32x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib33x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib34x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib35x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib36x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib37x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib38x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib39x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib40x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib41x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib42x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib43x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib44x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib45x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib46x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib47x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib48x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib49x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib50x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib51x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib52x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib53x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib54x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib55x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib56x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib57x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib58x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib59x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib60x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib61x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib62x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib63x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib64x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib65x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib66x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib67x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib68x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib69x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib70x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib71x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib72x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib73x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib74x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib75x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib76x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib77x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib78x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib79x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib80x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib81x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib82x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib83x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib84x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib85x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib86x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib87x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib88x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib89x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib90x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib91x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib92x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib93x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib94x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib95x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib96x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib97x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib98x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bib99x (
id mediumint(8) unsigned NOT NULL auto_increment,
tag varchar(6) NOT NULL default '',
value text NOT NULL,
PRIMARY KEY (id),
KEY kt (tag),
KEY kv (value(35))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib00x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib01x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib02x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib03x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib04x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib05x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib06x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib07x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib08x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib09x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib10x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib11x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib12x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib13x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib14x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib15x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib16x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib17x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib18x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib19x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib20x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib21x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib22x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib23x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib24x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib25x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib26x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib27x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib28x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib29x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib30x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib31x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib32x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib33x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib34x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib35x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib36x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib37x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib38x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib39x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib40x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib41x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib42x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib43x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib44x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib45x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib46x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib47x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib48x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib49x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib50x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib51x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib52x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib53x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib54x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib55x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib56x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib57x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib58x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib59x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib60x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib61x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib62x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib63x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib64x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib65x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib66x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib67x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib68x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib69x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib70x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib71x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib72x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib73x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib74x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib75x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib76x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib77x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib78x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib79x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib80x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib81x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib82x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib83x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib84x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib85x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib86x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib87x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib88x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib89x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib90x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib91x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib92x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib93x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib94x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib95x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib96x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib97x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib98x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bib99x (
id_bibrec mediumint(8) unsigned NOT NULL default '0',
id_bibxxx mediumint(8) unsigned NOT NULL default '0',
field_number smallint(5) unsigned default NULL,
KEY id_bibxxx (id_bibxxx),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
-- tables for bibliographic records formatted:
CREATE TABLE IF NOT EXISTS bibfmt (
id mediumint(8) unsigned NOT NULL auto_increment,
id_bibrec int(8) unsigned NOT NULL default '0',
format varchar(10) NOT NULL default '',
last_updated datetime NOT NULL default '0000-00-00',
value longblob,
PRIMARY KEY (id),
KEY id_bibrec (id_bibrec),
KEY format (format)
) TYPE=MyISAM;
-- tables for index files:
CREATE TABLE IF NOT EXISTS idxINDEX (
id mediumint(9) unsigned NOT NULL,
name varchar(50) NOT NULL default '',
description varchar(255) NOT NULL default '',
last_updated datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
UNIQUE KEY name (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxINDEXNAME (
id_idxINDEX mediumint(9) unsigned NOT NULL,
ln char(2) NOT NULL default '',
type char(3) NOT NULL default 'sn',
value varchar(255) NOT NULL,
PRIMARY KEY (id_idxINDEX,ln,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxINDEX_field (
id_idxINDEX mediumint(9) unsigned NOT NULL,
id_field mediumint(9) unsigned NOT NULL,
regexp_punctuation varchar(255) NOT NULL default "[\.\,\:\;\?\!\"]",
regexp_alphanumeric_separators varchar(255) NOT NULL default "[\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~]",
PRIMARY KEY (id_idxINDEX,id_field)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD01F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD01R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD02F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD02R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD03F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD03R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD04F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD04R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD05F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD05R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD06F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD06R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD07F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD07R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD08F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD08R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD09F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD09R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD10F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxWORD10R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE01F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE01R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE02F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE02R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE03F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE03R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE04F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE04R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE05F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE05R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE06F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE06R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE07F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE07R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE08F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE08R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE09F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE09R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE10F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS idxPHRASE10R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
-- tables for ranking:
CREATE TABLE IF NOT EXISTS rnkMETHOD (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(20) NOT NULL default '',
last_updated datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
UNIQUE KEY name (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkMETHODNAME (
id_rnkMETHOD mediumint(9) unsigned NOT NULL,
ln char(2) NOT NULL default '',
type char(3) NOT NULL default 'sn',
value varchar(255) NOT NULL,
PRIMARY KEY (id_rnkMETHOD,ln,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkMETHODDATA (
id_rnkMETHOD mediumint(9) unsigned NOT NULL,
relevance_data longblob,
PRIMARY KEY (id_rnkMETHOD)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS collection_rnkMETHOD (
id_collection mediumint(9) unsigned NOT NULL,
id_rnkMETHOD mediumint(9) unsigned NOT NULL,
score tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id_collection,id_rnkMETHOD)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkWORD01F (
id mediumint(9) unsigned NOT NULL auto_increment,
term varchar(50) default NULL,
hitlist longblob,
PRIMARY KEY (id),
UNIQUE KEY term (term)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkWORD01R (
id_bibrec mediumint(9) unsigned NOT NULL,
termlist longblob,
type enum('CURRENT','FUTURE','TEMPORARY') NOT NULL default 'CURRENT',
PRIMARY KEY (id_bibrec,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkPAGEVIEWS (
id_bibrec mediumint(8) unsigned default NULL,
id_user int(15) unsigned default '0',
client_host int(10) unsigned default NULL,
view_time datetime default '0000-00-00 00:00:00',
KEY view_time (view_time),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkDOWNLOADS (
id_bibrec mediumint(8) unsigned default NULL,
download_time datetime default '0000-00-00 00:00:00',
client_host int(10) unsigned default NULL,
id_user int(15) unsigned default NULL,
id_bibdoc mediumint(8) unsigned default NULL,
file_version smallint(2) unsigned default NULL,
file_format text,
KEY download_time (download_time),
KEY id_bibrec (id_bibrec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS rnkCITATIONDATA (
citation_data longblob,
citation_data_reversed longblob
) TYPE=MyISAM;
-- tables for collections and collection tree:
CREATE TABLE IF NOT EXISTS collection (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
dbquery text,
nbrecs int(10) unsigned default '0',
reclist longblob,
restricted varchar(255) default NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name),
KEY dbquery (dbquery(50))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS collectionname (
id_collection mediumint(9) unsigned NOT NULL,
ln char(2) NOT NULL default '',
type char(3) NOT NULL default 'sn',
value varchar(255) NOT NULL,
PRIMARY KEY (id_collection,ln,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS collection_collection (
id_dad mediumint(9) unsigned NOT NULL,
id_son mediumint(9) unsigned NOT NULL,
type char(1) NOT NULL default 'r',
score tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id_dad,id_son)
) TYPE=MyISAM;
-- tables for OAI sets:
CREATE TABLE IF NOT EXISTS oaiSET (
id mediumint(9) unsigned NOT NULL auto_increment,
setName varchar(255) NOT NULL default '',
setSpec varchar(255) NOT NULL default '',
setDescription text,
setDefinition text NOT NULL default '',
setRecList longblob,
PRIMARY KEY (id),
UNIQUE KEY setSpec (setSpec)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS oaiARCHIVE (
id mediumint(9) unsigned NOT NULL auto_increment,
setName varchar(255) NOT NULL default '',
setSpec varchar(255) NOT NULL default '',
setCollection varchar(255) NOT NULL default '',
setDescription text,
p1 text,
f1 text,
m1 text,
p2 text,
f2 text,
m2 text,
p3 text,
f3 text,
m3 text,
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS oaiHARVEST (
id mediumint(9) unsigned NOT NULL auto_increment,
baseurl varchar(255) NOT NULL default '',
metadataprefix varchar(255) NOT NULL default 'oai_dc',
arguments text,
comment text,
bibconvertcfgfile varchar(255),
name varchar(255) NOT NULL,
lastrun datetime,
frequency mediumint(12) NOT NULL default '0',
postprocess varchar(5) NOT NULL default 'h__',
PRIMARY KEY (id)
) TYPE=MyISAM;
-- tables for portal elements:
CREATE TABLE IF NOT EXISTS collection_portalbox (
id_collection mediumint(9) unsigned NOT NULL,
id_portalbox mediumint(9) unsigned NOT NULL,
ln char(2) NOT NULL default '',
position char(3) NOT NULL default 'top',
score tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id_collection,id_portalbox,ln)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS portalbox (
id mediumint(9) unsigned NOT NULL auto_increment,
title text NOT NULL,
body text NOT NULL,
UNIQUE KEY id (id)
) TYPE=MyISAM;
-- tables for search examples:
CREATE TABLE IF NOT EXISTS collection_example (
id_collection mediumint(9) unsigned NOT NULL,
id_example mediumint(9) unsigned NOT NULL,
score tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id_collection,id_example)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS example (
id mediumint(9) unsigned NOT NULL auto_increment,
type text NOT NULL default '',
body text NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
-- tables for collection formats:
CREATE TABLE IF NOT EXISTS collection_format (
id_collection mediumint(9) unsigned NOT NULL,
id_format mediumint(9) unsigned NOT NULL,
score tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id_collection,id_format)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS format (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
code varchar(6) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY code (code)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS formatname (
id_format mediumint(9) unsigned NOT NULL,
ln char(2) NOT NULL default '',
type char(3) NOT NULL default 'sn',
value varchar(255) NOT NULL,
PRIMARY KEY (id_format,ln,type)
) TYPE=MyISAM;
-- tables for search options and MARC tags:
CREATE TABLE IF NOT EXISTS collection_field_fieldvalue (
id_collection mediumint(9) unsigned NOT NULL,
id_field mediumint(9) unsigned NOT NULL,
id_fieldvalue mediumint(9) unsigned,
type char(3) NOT NULL default 'src',
score tinyint(4) unsigned NOT NULL default '0',
score_fieldvalue tinyint(4) unsigned NOT NULL default '0',
KEY id_collection (id_collection),
KEY id_field (id_field),
KEY id_fieldvalue (id_fieldvalue)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS field (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
code varchar(255) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY code (code)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS fieldname (
id_field mediumint(9) unsigned NOT NULL,
ln char(2) NOT NULL default '',
type char(3) NOT NULL default 'sn',
value varchar(255) NOT NULL,
PRIMARY KEY (id_field,ln,type)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS fieldvalue (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
value text NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS field_tag (
id_field mediumint(9) unsigned NOT NULL,
id_tag mediumint(9) unsigned NOT NULL,
score tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id_field,id_tag)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS tag (
id mediumint(9) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
value char(6) NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
-- tables for file management
CREATE TABLE IF NOT EXISTS bibdoc (
id mediumint(9) unsigned NOT NULL auto_increment,
status varchar(50) NOT NULL default '',
docname varchar(250) NOT NULL default 'file',
creation_date datetime NOT NULL default '0000-00-00',
modification_date datetime NOT NULL default '0000-00-00',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibrec_bibdoc (
id_bibrec mediumint(9) unsigned NOT NULL default '0',
id_bibdoc mediumint(9) unsigned NOT NULL default '0',
type varchar(255),
KEY (id_bibrec),
KEY (id_bibdoc)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bibdoc_bibdoc (
id_bibdoc1 mediumint(9) unsigned NOT NULL,
id_bibdoc2 mediumint(9) unsigned NOT NULL,
type varchar(255),
KEY (id_bibdoc1),
KEY (id_bibdoc2)
) TYPE=MyISAM;
-- tables for publication requests:
CREATE TABLE IF NOT EXISTS publreq (
id int(11) NOT NULL auto_increment,
host varchar(255) NOT NULL default '',
date varchar(255) NOT NULL default '',
name varchar(255) NOT NULL default '',
email varchar(255) NOT NULL default '',
address text NOT NULL,
publication text NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
-- table for sessions and users:
CREATE TABLE IF NOT EXISTS session (
session_key varchar(32) NOT NULL default '',
session_expiry int(11) unsigned NOT NULL default '0',
session_object blob,
uid int(15) unsigned NOT NULL,
UNIQUE KEY session_key (session_key),
KEY uid (uid)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS user (
id int(15) unsigned NOT NULL auto_increment,
email varchar(255) NOT NULL default '',
password varchar(20) default NULL,
note varchar(255) default NULL,
settings varchar(255) default NULL,
nickname varchar(255) NOT NULL default '',
last_login datetime NOT NULL default '0000-00-00 00:00:00',
UNIQUE KEY id (id),
KEY email (email),
KEY nickname (nickname)
) TYPE=MyISAM;
-- tables for usergroups
CREATE TABLE IF NOT EXISTS usergroup (
id int(15) unsigned NOT NULL auto_increment,
name varchar(50) NOT NULL default '',
description text default '',
join_policy tinyint(4) unsigned NOT NULL default '0',
PRIMARY KEY (id),
KEY name (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS user_usergroup (
id_user int(15) unsigned NOT NULL default '0',
id_usergroup int(15) unsigned NOT NULL default '0',
user_status tinyint(4) NOT NULL default '0',
user_status_date datetime NOT NULL default '0000-00-00 00:00:00',
KEY id_user (id_user),
KEY id_usergroup (id_usergroup)
) TYPE=MyISAM;
-- tables for access control engine
CREATE TABLE IF NOT EXISTS accROLE (
id int(15) unsigned NOT NULL auto_increment,
name varchar(32),
description varchar(255),
PRIMARY KEY (id),
UNIQUE KEY name (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS user_accROLE (
id_user int(15) unsigned NOT NULL,
id_accROLE int(15) unsigned NOT NULL,
PRIMARY KEY (id_user, id_accROLE)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS accACTION (
id int(15) unsigned NOT NULL auto_increment,
name varchar(32),
description varchar(255),
allowedkeywords varchar(255),
optional ENUM ('yes', 'no') NOT NULL default 'no',
PRIMARY KEY (id),
UNIQUE KEY name (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS accARGUMENT (
id int(15) unsigned NOT NULL auto_increment,
keyword varchar (32),
value varchar(64),
PRIMARY KEY (id),
KEY KEYVAL (keyword, value)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS accROLE_accACTION_accARGUMENT (
id_accROLE int(15),
id_accACTION int(15),
id_accARGUMENT int(15),
argumentlistid mediumint(8),
KEY id_accROLE (id_accROLE),
KEY id_accACTION (id_accACTION),
KEY id_accARGUMENT (id_accARGUMENT)
) TYPE=MyISAM;
-- tables for personal/collaborative features (baskets, alerts, searches, messages, usergroups):
CREATE TABLE IF NOT EXISTS user_query (
id_user int(15) unsigned NOT NULL default '0',
id_query int(15) unsigned NOT NULL default '0',
hostname varchar(50) default 'unknown host',
date datetime default NULL,
KEY id_user (id_user,id_query)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS query (
id int(15) unsigned NOT NULL auto_increment,
type char(1) NOT NULL default 'r',
urlargs text NOT NULL,
PRIMARY KEY (id),
KEY urlargs (urlargs(100))
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS user_query_basket (
id_user int(15) unsigned NOT NULL default '0',
id_query int(15) unsigned NOT NULL default '0',
id_basket int(15) unsigned NOT NULL default '0',
frequency varchar(5) NOT NULL default '',
date_creation date default NULL,
date_lastrun date default '0000-00-00',
alert_name varchar(30) NOT NULL default '',
notification char(1) NOT NULL default 'y',
PRIMARY KEY (id_user,id_query,frequency,id_basket),
KEY alert_name (alert_name)
) TYPE=MyISAM;
-- baskets
CREATE TABLE IF NOT EXISTS bskBASKET (
id int(15) unsigned NOT NULL auto_increment,
id_owner int(15) unsigned NOT NULL default '0',
name varchar(50) NOT NULL default '',
date_modification datetime NOT NULL default '0000-00-00 00:00:00',
nb_views int(15) NOT NULL default '0',
PRIMARY KEY (id),
KEY id_owner (id_owner),
KEY name (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bskREC (
id_bibrec_or_bskEXTREC int(16) NOT NULL default '0',
id_bskBASKET int(15) unsigned NOT NULL default '0',
id_user_who_added_item int(15) NOT NULL default '0',
score int(15) NOT NULL default '0',
date_added datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id_bibrec_or_bskEXTREC,id_bskBASKET),
KEY id_bibrec_or_bskEXTREC (id_bibrec_or_bskEXTREC),
KEY id_bskBASKET (id_bskBASKET),
KEY score (score),
KEY date_added (date_added)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bskEXTREC (
id int(15) unsigned NOT NULL default '0',
creation_date datetime NOT NULL default '0000-00-00 00:00:00',
modification_date datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (id),
KEY id (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS user_bskBASKET (
id_user int(15) unsigned NOT NULL default '0',
id_bskBASKET int(15) unsigned NOT NULL default '0',
topic varchar(50) NOT NULL default '',
PRIMARY KEY (id_user,id_bskBASKET),
KEY id_user (id_user),
KEY id_bskBASKET (id_bskBASKET)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS usergroup_bskBASKET (
id_usergroup int(15) unsigned NOT NULL default '0',
id_bskBASKET int(15) unsigned NOT NULL default '0',
topic varchar(50) NOT NULL default '',
date_shared datetime NOT NULL default '0000-00-00 00:00:00',
share_level char(2) NOT NULL default '',
PRIMARY KEY (id_usergroup,id_bskBASKET),
KEY id_usergroup (id_usergroup),
KEY id_bskBASKET (id_bskBASKET)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS bskRECORDCOMMENT (
id int(15) unsigned NOT NULL auto_increment,
id_bibrec_or_bskEXTREC int(16) NOT NULL default '0',
id_bskBASKET int(15) unsigned NOT NULL default '0',
id_user int(15) unsigned NOT NULL default '0',
title varchar(255) NOT NULL default '',
body text NOT NULL,
date_creation datetime NOT NULL default '0000-00-00 00:00:00',
priority int(15) NOT NULL default '0',
PRIMARY KEY (id),
KEY id (id),
KEY id_bskBASKET (id_bskBASKET),
KEY id_bibrec_or_bskEXTREC (id_bibrec_or_bskEXTREC),
KEY date_creation (date_creation)
) TYPE=MyISAM;
-- tables for messaging system
CREATE TABLE IF NOT EXISTS msgMESSAGE (
id int(15) unsigned NOT NULL auto_increment,
id_user_from int(15) unsigned NOT NULL default '0',
sent_to_user_nicks text NOT NULL default '',
sent_to_group_names text NOT NULL default '',
subject text NOT NULL default '',
body text default NULL,
sent_date datetime NOT NULL default '0000-00-00 00:00:00',
received_date datetime NULL default '0000-00-00 00:00:00',
PRIMARY KEY id (id),
KEY id_user_from (id_user_from)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS user_msgMESSAGE (
id_user_to int(15) unsigned NOT NULL default '0',
id_msgMESSAGE int(15) unsigned NOT NULL default '0',
status char(1) NOT NULL default 'N',
PRIMARY KEY id (id_user_to, id_msgMESSAGE),
KEY id_user_to (id_user_to),
KEY id_msgMESSAGE (id_msgMESSAGE)
) TYPE=MyISAM;
--tables for WebComment
CREATE TABLE IF NOT EXISTS cmtRECORDCOMMENT (
id int(15) unsigned NOT NULL auto_increment,
id_bibrec int(15) unsigned NOT NULL default '0',
id_user int(15) unsigned NOT NULL default '0',
title varchar(255) NOT NULL default '',
body text NOT NULL default '',
date_creation datetime NOT NULL default '0000-00-00 00:00:00',
star_score tinyint(5) unsigned NOT NULL default '0',
nb_votes_yes int(10) NOT NULL default '0',
nb_votes_total int(10) unsigned NOT NULL default '0',
nb_abuse_reports int(10) NOT NULL default '0',
PRIMARY KEY (id),
KEY id_bibrec (id_bibrec),
KEY id_user (id_user)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS cmtACTIONHISTORY (
id_cmtRECORDCOMMENT int(15) unsigned NULL,
id_bibrec int(15) unsigned NULL,
id_user int(15) unsigned NULL default NULL,
client_host int(10) unsigned NOT NULL,
action_time datetime NOT NULL default '0000-00-00 00:00:00',
action_code char(1) NOT NULL,
KEY id_cmtRECORDCOMMENT (id_cmtRECORDCOMMENT),
KEY client_host (client_host),
KEY id_user (id_user),
KEY action_code (action_code)
) TYPE=MyISAM;
-- tables for BibFormat, formely known as FlexElink:
CREATE TABLE IF NOT EXISTS flxFORMATS (
name varchar(255) NOT NULL default '',
value text,
doc text,
serialized longtext,
PRIMARY KEY (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxKBS (
kb_name varchar(255) NOT NULL default '',
kb_table varchar(255) NOT NULL default '',
doc text,
PRIMARY KEY (kb_name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxKBDBCOLLID2COLL (
vkey varchar(255) NOT NULL default '',
value text,
PRIMARY KEY (vkey)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxKBDBCOLLID2BIBTEX (
vkey varchar(255) NOT NULL default '',
value text,
PRIMARY KEY (vkey)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxKBEJOURNALS (
vkey varchar(255) NOT NULL default '',
value text,
PRIMARY KEY (vkey)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxLINKTYPES (
linktype varchar(255) NOT NULL default '',
check_exists enum('Y','N') NOT NULL default 'N',
solvingtype enum('INT','EXT') NOT NULL default 'EXT',
base_file varchar(255) NOT NULL default '',
base_url varchar(255) NOT NULL default '',
PRIMARY KEY (linktype)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxLINKTYPECONDITIONS (
linktype varchar(255) NOT NULL default '',
eval_order int(11) NOT NULL default '0',
el_condition text NOT NULL,
el_action text NOT NULL,
solvingtype enum('INT','EXT') NOT NULL default 'EXT',
base_file varchar(255) NOT NULL default '',
base_url varchar(255) NOT NULL default '',
PRIMARY KEY (linktype,eval_order)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxLINKTYPECONDITIONSACTIONS (
linktype varchar(255) NOT NULL default '',
eval_order int(11) NOT NULL default '0',
apply_order int(11) NOT NULL default '0',
el_code text,
PRIMARY KEY (linktype,eval_order,apply_order)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxLINKTYPECONDITIONSFILEFORMATS (
linktype varchar(255) NOT NULL default '',
eval_order int(11) NOT NULL default '0',
fname varchar(30) NOT NULL default '',
PRIMARY KEY (linktype,eval_order,fname)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxFILEFORMATS (
name varchar(30) NOT NULL default '',
text varchar(255) default '',
extensions text,
PRIMARY KEY (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxLINKTYPEPARAMS (
linktype varchar(255) NOT NULL default '',
pname varchar(78) NOT NULL default '',
ord tinyint(4) NOT NULL default '0',
PRIMARY KEY (linktype,pname),
UNIQUE KEY IDX_LINKTYPE_PARAMS_ORD (linktype,ord)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxXMLMARCEXTRULES (
type varchar(8) NOT NULL default '',
varname varchar(50) NOT NULL default '',
att_id varchar(150) default NULL,
att_i1 varchar(150) default NULL,
att_i2 varchar(150) default NULL,
mvalues enum('S','N') NOT NULL default 'S',
ftype enum("DATAFIELD", "CONTROLFIELD") not null,
PRIMARY KEY (type,varname)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxXMLMARCEXTRULESUBFIELDS (
type varchar(8) NOT NULL default '',
varname varchar(50) NOT NULL default '',
sfname varchar(50) NOT NULL default '',
att_label varchar(150) default NULL,
PRIMARY KEY (type,varname,sfname)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxBEHAVIORCONDITIONSACTIONS (
otype varchar(40) NOT NULL default '',
eval_order int(11) NOT NULL default '0',
apply_order int(11) NOT NULL default '0',
locator text,
el_code text,
PRIMARY KEY (otype,eval_order,apply_order)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxBEHAVIORCONDITIONS (
otype varchar(40) NOT NULL default '',
eval_order int(11) NOT NULL default '0',
el_condition text NOT NULL,
PRIMARY KEY (otype,eval_order)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxBEHAVIORS (
name varchar(40) NOT NULL default '',
type enum('NORMAL','IENRICH') NOT NULL default 'NORMAL',
doc text,
PRIMARY KEY (name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxUDFS (
fname varchar(100) NOT NULL default '',
code text NOT NULL,
rtype enum('STRING','BOOL') NOT NULL default 'STRING',
doc text,
PRIMARY KEY (fname)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxUDFPARAMS (
fname varchar(100) NOT NULL default '',
pname varchar(100) NOT NULL default '',
ord tinyint(4) NOT NULL default '0',
PRIMARY KEY (fname,pname),
UNIQUE KEY IDX_UDFS_PARAMS_ORD (fname,ord)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxUSERS (
id int(11) NOT NULL default '0',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS flxREFORMAT (
id int(10) unsigned NOT NULL auto_increment,
user varchar(50) NOT NULL,
date DATETIME NOT NULL,
reg_select text,
otypes varchar(40) not null,
state varchar(20),
PRIMARY KEY (id)
) TYPE=MyISAM;
-- tables for webSubmit:
CREATE TABLE IF NOT EXISTS sbmACTION (
lactname text,
sactname char(3) NOT NULL default '',
dir text,
cd date default NULL,
md date default NULL,
actionbutton text,
statustext text,
PRIMARY KEY (sactname)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmALLFUNCDESCR (
function varchar(40) NOT NULL default '',
description tinytext,
PRIMARY KEY (function)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmAPPROVAL (
doctype varchar(10) NOT NULL default '',
categ varchar(50) NOT NULL default '',
rn varchar(50) NOT NULL default '',
status varchar(10) NOT NULL default '',
dFirstReq datetime NOT NULL default '0000-00-00 00:00:00',
dLastReq datetime NOT NULL default '0000-00-00 00:00:00',
dAction datetime NOT NULL default '0000-00-00 00:00:00',
access varchar(20) NOT NULL default '0',
PRIMARY KEY (rn)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmCOLLECTION (
id int(11) NOT NULL auto_increment,
name varchar(100) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS sbmCOLLECTION_sbmCOLLECTION (
id_father int(11) NOT NULL default '0',
id_son int(11) NOT NULL default '0',
catalogue_order int(11) NOT NULL default '0'
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS sbmCOLLECTION_sbmDOCTYPE (
id_father int(11) NOT NULL default '0',
id_son char(10) NOT NULL default '0',
catalogue_order int(11) NOT NULL default '0'
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS sbmCATEGORIES (
doctype varchar(10) NOT NULL default '',
sname varchar(75) NOT NULL default '',
lname varchar(75) NOT NULL default '',
KEY sname (sname)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmCHECKS (
chname varchar(15) NOT NULL default '',
chdesc text,
cd date default NULL,
md date default NULL,
chefi1 text,
chefi2 text,
PRIMARY KEY (chname)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmDOCTYPE (
ldocname text,
sdocname varchar(10) default NULL,
cd date default NULL,
md date default NULL,
description text
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmFIELD (
subname varchar(10) default NULL,
pagenb int(11) default NULL,
fieldnb int(11) default NULL,
fidesc varchar(15) default NULL,
fitext text,
level char(1) default NULL,
sdesc text,
checkn text,
cd date default NULL,
md date default NULL,
fiefi1 text,
fiefi2 text
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmFIELDDESC (
name varchar(15) NOT NULL default '',
alephcode varchar(50) default NULL,
marccode varchar(50) NOT NULL default '',
type char(1) default NULL,
size int(11) default NULL,
rows int(11) default NULL,
cols int(11) default NULL,
maxlength int(11) default NULL,
val text,
fidesc text,
cd date default NULL,
md date default NULL,
modifytext text,
fddfi2 text,
cookie int(11) default '0',
PRIMARY KEY (name)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmFORMATEXTENSION (
FILE_FORMAT text NOT NULL,
FILE_EXTENSION text NOT NULL
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmFUNCTIONS (
action varchar(10) NOT NULL default '',
doctype varchar(10) NOT NULL default '',
function varchar(40) NOT NULL default '',
score int(11) NOT NULL default '0',
step tinyint(4) NOT NULL default '1'
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmFUNDESC (
function varchar(40) NOT NULL default '',
param varchar(40) default NULL
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmGFILERESULT (
FORMAT text NOT NULL,
RESULT text NOT NULL
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmIMPLEMENT (
docname varchar(10) default NULL,
actname char(3) default NULL,
displayed char(1) default NULL,
subname varchar(13) default NULL,
nbpg int(11) default NULL,
cd date default NULL,
md date default NULL,
buttonorder int(11) default NULL,
statustext text,
level char(1) NOT NULL default '',
score int(11) NOT NULL default '0',
stpage int(11) NOT NULL default '0',
endtxt varchar(100) NOT NULL default ''
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmPARAMETERS (
doctype varchar(10) NOT NULL default '',
name varchar(20) NOT NULL default '',
value varchar(200) NOT NULL default '',
PRIMARY KEY (doctype,name)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS sbmPUBLICATION (
doctype varchar(10) NOT NULL default '',
categ varchar(50) NOT NULL default '',
rn varchar(50) NOT NULL default '',
status varchar(10) NOT NULL default '',
dFirstReq datetime NOT NULL default '0000-00-00 00:00:00',
dLastReq datetime NOT NULL default '0000-00-00 00:00:00',
dAction datetime NOT NULL default '0000-00-00 00:00:00',
accessref varchar(20) NOT NULL default '',
accessedi varchar(20) NOT NULL default '',
access varchar(20) NOT NULL default '',
referees varchar(50) NOT NULL default '',
authoremail varchar(50) NOT NULL default '',
dRefSelection datetime NOT NULL default '0000-00-00 00:00:00',
dRefRec datetime NOT NULL default '0000-00-00 00:00:00',
dEdiRec datetime NOT NULL default '0000-00-00 00:00:00',
accessspo varchar(20) NOT NULL default '',
journal varchar(100) default NULL,
PRIMARY KEY (doctype,categ,rn)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmPUBLICATIONCOMM (
id int(11) NOT NULL auto_increment,
id_parent int(11) default '0',
rn varchar(100) NOT NULL default '',
firstname varchar(100) default NULL,
secondname varchar(100) default NULL,
email varchar(100) default NULL,
date varchar(40) NOT NULL default '',
synopsis varchar(255) NOT NULL default '',
commentfulltext text,
PRIMARY KEY (id)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmPUBLICATIONDATA (
doctype varchar(10) NOT NULL default '',
editoboard varchar(250) NOT NULL default '',
base varchar(10) NOT NULL default '',
logicalbase varchar(10) NOT NULL default '',
spokesperson varchar(50) NOT NULL default '',
PRIMARY KEY (doctype)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmREFEREES (
doctype varchar(10) NOT NULL default '',
categ varchar(10) NOT NULL default '',
name varchar(50) NOT NULL default '',
address varchar(50) NOT NULL default '',
rid int(11) NOT NULL auto_increment,
PRIMARY KEY (rid)
) TYPE=MyISAM PACK_KEYS=1;
CREATE TABLE IF NOT EXISTS sbmSUBMISSIONS (
email varchar(50) NOT NULL default '',
doctype varchar(10) NOT NULL default '',
action varchar(10) NOT NULL default '',
status varchar(10) NOT NULL default '',
id varchar(30) NOT NULL default '',
reference varchar(40) NOT NULL default '',
cd datetime NOT NULL default '0000-00-00 00:00:00',
md datetime NOT NULL default '0000-00-00 00:00:00'
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS sbmCOOKIES (
id int(15) unsigned NOT NULL auto_increment,
name varchar(100) NOT NULL,
value text,
uid int(15) NOT NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
-- Scheduler tables
CREATE TABLE IF NOT EXISTS schTASK (
id int(15) unsigned NOT NULL auto_increment,
proc varchar(20) NOT NULL,
host varchar(255) NOT NULL,
user varchar(50) NOT NULL,
runtime datetime NOT NULL,
sleeptime varchar(20),
arguments longtext,
status varchar(50),
progress varchar(255),
PRIMARY KEY (id)
) TYPE=MyISAM;
-- webMessage tables
-- end of file
diff --git a/modules/miscutil/sql/tabdrop.sql b/modules/miscutil/sql/tabdrop.sql
index 013262da7..5760d1e8f 100644
--- a/modules/miscutil/sql/tabdrop.sql
+++ b/modules/miscutil/sql/tabdrop.sql
@@ -1,366 +1,366 @@
-- $Id$
-- Drop tables for the CDS Software.
-- This file is part of the CERN Document Server Software (CDSware).
--- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+-- Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
--
-- The CDSware 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.
--
-- The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
DROP TABLE IF EXISTS bibrec;
DROP TABLE IF EXISTS bib00x;
DROP TABLE IF EXISTS bib01x;
DROP TABLE IF EXISTS bib02x;
DROP TABLE IF EXISTS bib03x;
DROP TABLE IF EXISTS bib04x;
DROP TABLE IF EXISTS bib05x;
DROP TABLE IF EXISTS bib06x;
DROP TABLE IF EXISTS bib07x;
DROP TABLE IF EXISTS bib08x;
DROP TABLE IF EXISTS bib09x;
DROP TABLE IF EXISTS bib10x;
DROP TABLE IF EXISTS bib11x;
DROP TABLE IF EXISTS bib12x;
DROP TABLE IF EXISTS bib13x;
DROP TABLE IF EXISTS bib14x;
DROP TABLE IF EXISTS bib15x;
DROP TABLE IF EXISTS bib16x;
DROP TABLE IF EXISTS bib17x;
DROP TABLE IF EXISTS bib18x;
DROP TABLE IF EXISTS bib19x;
DROP TABLE IF EXISTS bib20x;
DROP TABLE IF EXISTS bib21x;
DROP TABLE IF EXISTS bib22x;
DROP TABLE IF EXISTS bib23x;
DROP TABLE IF EXISTS bib24x;
DROP TABLE IF EXISTS bib25x;
DROP TABLE IF EXISTS bib26x;
DROP TABLE IF EXISTS bib27x;
DROP TABLE IF EXISTS bib28x;
DROP TABLE IF EXISTS bib29x;
DROP TABLE IF EXISTS bib30x;
DROP TABLE IF EXISTS bib31x;
DROP TABLE IF EXISTS bib32x;
DROP TABLE IF EXISTS bib33x;
DROP TABLE IF EXISTS bib34x;
DROP TABLE IF EXISTS bib35x;
DROP TABLE IF EXISTS bib36x;
DROP TABLE IF EXISTS bib37x;
DROP TABLE IF EXISTS bib38x;
DROP TABLE IF EXISTS bib39x;
DROP TABLE IF EXISTS bib40x;
DROP TABLE IF EXISTS bib41x;
DROP TABLE IF EXISTS bib42x;
DROP TABLE IF EXISTS bib43x;
DROP TABLE IF EXISTS bib44x;
DROP TABLE IF EXISTS bib45x;
DROP TABLE IF EXISTS bib46x;
DROP TABLE IF EXISTS bib47x;
DROP TABLE IF EXISTS bib48x;
DROP TABLE IF EXISTS bib49x;
DROP TABLE IF EXISTS bib50x;
DROP TABLE IF EXISTS bib51x;
DROP TABLE IF EXISTS bib52x;
DROP TABLE IF EXISTS bib53x;
DROP TABLE IF EXISTS bib54x;
DROP TABLE IF EXISTS bib55x;
DROP TABLE IF EXISTS bib56x;
DROP TABLE IF EXISTS bib57x;
DROP TABLE IF EXISTS bib58x;
DROP TABLE IF EXISTS bib59x;
DROP TABLE IF EXISTS bib60x;
DROP TABLE IF EXISTS bib61x;
DROP TABLE IF EXISTS bib62x;
DROP TABLE IF EXISTS bib63x;
DROP TABLE IF EXISTS bib64x;
DROP TABLE IF EXISTS bib65x;
DROP TABLE IF EXISTS bib66x;
DROP TABLE IF EXISTS bib67x;
DROP TABLE IF EXISTS bib68x;
DROP TABLE IF EXISTS bib69x;
DROP TABLE IF EXISTS bib70x;
DROP TABLE IF EXISTS bib71x;
DROP TABLE IF EXISTS bib72x;
DROP TABLE IF EXISTS bib73x;
DROP TABLE IF EXISTS bib74x;
DROP TABLE IF EXISTS bib75x;
DROP TABLE IF EXISTS bib76x;
DROP TABLE IF EXISTS bib77x;
DROP TABLE IF EXISTS bib78x;
DROP TABLE IF EXISTS bib79x;
DROP TABLE IF EXISTS bib80x;
DROP TABLE IF EXISTS bib81x;
DROP TABLE IF EXISTS bib82x;
DROP TABLE IF EXISTS bib83x;
DROP TABLE IF EXISTS bib84x;
DROP TABLE IF EXISTS bib85x;
DROP TABLE IF EXISTS bib86x;
DROP TABLE IF EXISTS bib87x;
DROP TABLE IF EXISTS bib88x;
DROP TABLE IF EXISTS bib89x;
DROP TABLE IF EXISTS bib90x;
DROP TABLE IF EXISTS bib91x;
DROP TABLE IF EXISTS bib92x;
DROP TABLE IF EXISTS bib93x;
DROP TABLE IF EXISTS bib94x;
DROP TABLE IF EXISTS bib95x;
DROP TABLE IF EXISTS bib96x;
DROP TABLE IF EXISTS bib97x;
DROP TABLE IF EXISTS bib98x;
DROP TABLE IF EXISTS bib99x;
DROP TABLE IF EXISTS bibrec_bib00x;
DROP TABLE IF EXISTS bibrec_bib01x;
DROP TABLE IF EXISTS bibrec_bib02x;
DROP TABLE IF EXISTS bibrec_bib03x;
DROP TABLE IF EXISTS bibrec_bib04x;
DROP TABLE IF EXISTS bibrec_bib05x;
DROP TABLE IF EXISTS bibrec_bib06x;
DROP TABLE IF EXISTS bibrec_bib07x;
DROP TABLE IF EXISTS bibrec_bib08x;
DROP TABLE IF EXISTS bibrec_bib09x;
DROP TABLE IF EXISTS bibrec_bib10x;
DROP TABLE IF EXISTS bibrec_bib11x;
DROP TABLE IF EXISTS bibrec_bib12x;
DROP TABLE IF EXISTS bibrec_bib13x;
DROP TABLE IF EXISTS bibrec_bib14x;
DROP TABLE IF EXISTS bibrec_bib15x;
DROP TABLE IF EXISTS bibrec_bib16x;
DROP TABLE IF EXISTS bibrec_bib17x;
DROP TABLE IF EXISTS bibrec_bib18x;
DROP TABLE IF EXISTS bibrec_bib19x;
DROP TABLE IF EXISTS bibrec_bib20x;
DROP TABLE IF EXISTS bibrec_bib21x;
DROP TABLE IF EXISTS bibrec_bib22x;
DROP TABLE IF EXISTS bibrec_bib23x;
DROP TABLE IF EXISTS bibrec_bib24x;
DROP TABLE IF EXISTS bibrec_bib25x;
DROP TABLE IF EXISTS bibrec_bib26x;
DROP TABLE IF EXISTS bibrec_bib27x;
DROP TABLE IF EXISTS bibrec_bib28x;
DROP TABLE IF EXISTS bibrec_bib29x;
DROP TABLE IF EXISTS bibrec_bib30x;
DROP TABLE IF EXISTS bibrec_bib31x;
DROP TABLE IF EXISTS bibrec_bib32x;
DROP TABLE IF EXISTS bibrec_bib33x;
DROP TABLE IF EXISTS bibrec_bib34x;
DROP TABLE IF EXISTS bibrec_bib35x;
DROP TABLE IF EXISTS bibrec_bib36x;
DROP TABLE IF EXISTS bibrec_bib37x;
DROP TABLE IF EXISTS bibrec_bib38x;
DROP TABLE IF EXISTS bibrec_bib39x;
DROP TABLE IF EXISTS bibrec_bib40x;
DROP TABLE IF EXISTS bibrec_bib41x;
DROP TABLE IF EXISTS bibrec_bib42x;
DROP TABLE IF EXISTS bibrec_bib43x;
DROP TABLE IF EXISTS bibrec_bib44x;
DROP TABLE IF EXISTS bibrec_bib45x;
DROP TABLE IF EXISTS bibrec_bib46x;
DROP TABLE IF EXISTS bibrec_bib47x;
DROP TABLE IF EXISTS bibrec_bib48x;
DROP TABLE IF EXISTS bibrec_bib49x;
DROP TABLE IF EXISTS bibrec_bib50x;
DROP TABLE IF EXISTS bibrec_bib51x;
DROP TABLE IF EXISTS bibrec_bib52x;
DROP TABLE IF EXISTS bibrec_bib53x;
DROP TABLE IF EXISTS bibrec_bib54x;
DROP TABLE IF EXISTS bibrec_bib55x;
DROP TABLE IF EXISTS bibrec_bib56x;
DROP TABLE IF EXISTS bibrec_bib57x;
DROP TABLE IF EXISTS bibrec_bib58x;
DROP TABLE IF EXISTS bibrec_bib59x;
DROP TABLE IF EXISTS bibrec_bib60x;
DROP TABLE IF EXISTS bibrec_bib61x;
DROP TABLE IF EXISTS bibrec_bib62x;
DROP TABLE IF EXISTS bibrec_bib63x;
DROP TABLE IF EXISTS bibrec_bib64x;
DROP TABLE IF EXISTS bibrec_bib65x;
DROP TABLE IF EXISTS bibrec_bib66x;
DROP TABLE IF EXISTS bibrec_bib67x;
DROP TABLE IF EXISTS bibrec_bib68x;
DROP TABLE IF EXISTS bibrec_bib69x;
DROP TABLE IF EXISTS bibrec_bib70x;
DROP TABLE IF EXISTS bibrec_bib71x;
DROP TABLE IF EXISTS bibrec_bib72x;
DROP TABLE IF EXISTS bibrec_bib73x;
DROP TABLE IF EXISTS bibrec_bib74x;
DROP TABLE IF EXISTS bibrec_bib75x;
DROP TABLE IF EXISTS bibrec_bib76x;
DROP TABLE IF EXISTS bibrec_bib77x;
DROP TABLE IF EXISTS bibrec_bib78x;
DROP TABLE IF EXISTS bibrec_bib79x;
DROP TABLE IF EXISTS bibrec_bib80x;
DROP TABLE IF EXISTS bibrec_bib81x;
DROP TABLE IF EXISTS bibrec_bib82x;
DROP TABLE IF EXISTS bibrec_bib83x;
DROP TABLE IF EXISTS bibrec_bib84x;
DROP TABLE IF EXISTS bibrec_bib85x;
DROP TABLE IF EXISTS bibrec_bib86x;
DROP TABLE IF EXISTS bibrec_bib87x;
DROP TABLE IF EXISTS bibrec_bib88x;
DROP TABLE IF EXISTS bibrec_bib89x;
DROP TABLE IF EXISTS bibrec_bib90x;
DROP TABLE IF EXISTS bibrec_bib91x;
DROP TABLE IF EXISTS bibrec_bib92x;
DROP TABLE IF EXISTS bibrec_bib93x;
DROP TABLE IF EXISTS bibrec_bib94x;
DROP TABLE IF EXISTS bibrec_bib95x;
DROP TABLE IF EXISTS bibrec_bib96x;
DROP TABLE IF EXISTS bibrec_bib97x;
DROP TABLE IF EXISTS bibrec_bib98x;
DROP TABLE IF EXISTS bibrec_bib99x;
DROP TABLE IF EXISTS bibfmt;
DROP TABLE IF EXISTS idxINDEX;
DROP TABLE IF EXISTS idxINDEXNAME;
DROP TABLE IF EXISTS idxINDEX_field;
DROP TABLE IF EXISTS idxWORD01F;
DROP TABLE IF EXISTS idxWORD02F;
DROP TABLE IF EXISTS idxWORD03F;
DROP TABLE IF EXISTS idxWORD04F;
DROP TABLE IF EXISTS idxWORD05F;
DROP TABLE IF EXISTS idxWORD06F;
DROP TABLE IF EXISTS idxWORD07F;
DROP TABLE IF EXISTS idxWORD08F;
DROP TABLE IF EXISTS idxWORD09F;
DROP TABLE IF EXISTS idxWORD10F;
DROP TABLE IF EXISTS idxWORD01R;
DROP TABLE IF EXISTS idxWORD02R;
DROP TABLE IF EXISTS idxWORD03R;
DROP TABLE IF EXISTS idxWORD04R;
DROP TABLE IF EXISTS idxWORD05R;
DROP TABLE IF EXISTS idxWORD06R;
DROP TABLE IF EXISTS idxWORD07R;
DROP TABLE IF EXISTS idxWORD08R;
DROP TABLE IF EXISTS idxWORD09R;
DROP TABLE IF EXISTS idxWORD10R;
DROP TABLE IF EXISTS idxPHRASE01F;
DROP TABLE IF EXISTS idxPHRASE02F;
DROP TABLE IF EXISTS idxPHRASE03F;
DROP TABLE IF EXISTS idxPHRASE04F;
DROP TABLE IF EXISTS idxPHRASE05F;
DROP TABLE IF EXISTS idxPHRASE06F;
DROP TABLE IF EXISTS idxPHRASE07F;
DROP TABLE IF EXISTS idxPHRASE08F;
DROP TABLE IF EXISTS idxPHRASE09F;
DROP TABLE IF EXISTS idxPHRASE10F;
DROP TABLE IF EXISTS idxPHRASE01R;
DROP TABLE IF EXISTS idxPHRASE02R;
DROP TABLE IF EXISTS idxPHRASE03R;
DROP TABLE IF EXISTS idxPHRASE04R;
DROP TABLE IF EXISTS idxPHRASE05R;
DROP TABLE IF EXISTS idxPHRASE06R;
DROP TABLE IF EXISTS idxPHRASE07R;
DROP TABLE IF EXISTS idxPHRASE08R;
DROP TABLE IF EXISTS idxPHRASE09R;
DROP TABLE IF EXISTS idxPHRASE10R;
DROP TABLE IF EXISTS rnkMETHOD;
DROP TABLE IF EXISTS rnkMETHODNAME;
DROP TABLE IF EXISTS rnkMETHODDATA;
DROP TABLE IF EXISTS rnkWORD01F;
DROP TABLE IF EXISTS rnkWORD01R;
DROP TABLE IF EXISTS rnkPAGEVIEWS;
DROP TABLE IF EXISTS rnkDOWNLOADS;
DROP TABLE IF EXISTS rnkCITATIONDATA;
DROP TABLE IF EXISTS collection_rnkMETHOD;
DROP TABLE IF EXISTS collection;
DROP TABLE IF EXISTS collectionname;
DROP TABLE IF EXISTS oaiSET;
DROP TABLE IF EXISTS oaiARCHIVE;
DROP TABLE IF EXISTS oaiHARVEST;
DROP TABLE IF EXISTS collection_collection;
DROP TABLE IF EXISTS collection_portalbox;
DROP TABLE IF EXISTS portalbox;
DROP TABLE IF EXISTS collection_example;
DROP TABLE IF EXISTS example;
DROP TABLE IF EXISTS collection_format;
DROP TABLE IF EXISTS format;
DROP TABLE IF EXISTS formatname;
DROP TABLE IF EXISTS collection_field_fieldvalue;
DROP TABLE IF EXISTS field;
DROP TABLE IF EXISTS fieldname;
DROP TABLE IF EXISTS fieldvalue;
DROP TABLE IF EXISTS field_tag;
DROP TABLE IF EXISTS tag;
DROP TABLE IF EXISTS publreq;
DROP TABLE IF EXISTS session;
DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS accROLE;
DROP TABLE IF EXISTS user_accROLE;
DROP TABLE IF EXISTS accACTION;
DROP TABLE IF EXISTS accARGUMENT;
DROP TABLE IF EXISTS accROLE_accACTION_accARGUMENT;
DROP TABLE IF EXISTS user_query;
DROP TABLE IF EXISTS query;
DROP TABLE IF EXISTS user_basket;
DROP TABLE IF EXISTS basket;
DROP TABLE IF EXISTS basket_record;
DROP TABLE IF EXISTS record;
DROP TABLE IF EXISTS user_query_basket;
DROP TABLE IF EXISTS cmtRECORDCOMMENT;
DROP TABLE IF EXISTS flxFORMATS;
DROP TABLE IF EXISTS flxKBS;
DROP TABLE IF EXISTS flxKBDBCOLLID2COLL;
DROP TABLE IF EXISTS flxKBDBCOLLID2BIBTEX;
DROP TABLE IF EXISTS flxKBEJOURNALS;
DROP TABLE IF EXISTS flxLINKTYPES;
DROP TABLE IF EXISTS flxLINKTYPECONDITIONS;
DROP TABLE IF EXISTS flxLINKTYPECONDITIONSACTIONS;
DROP TABLE IF EXISTS flxLINKTYPECONDITIONSFILEFORMATS;
DROP TABLE IF EXISTS flxFILEFORMATS;
DROP TABLE IF EXISTS flxLINKTYPEPARAMS;
DROP TABLE IF EXISTS flxXMLMARCEXTRULES;
DROP TABLE IF EXISTS flxXMLMARCEXTRULESUBFIELDS;
DROP TABLE IF EXISTS flxBEHAVIORCONDITIONSACTIONS;
DROP TABLE IF EXISTS flxBEHAVIORCONDITIONS;
DROP TABLE IF EXISTS flxBEHAVIORS;
DROP TABLE IF EXISTS flxUDFS;
DROP TABLE IF EXISTS flxUDFPARAMS;
DROP TABLE IF EXISTS flxUSERS;
DROP TABLE IF EXISTS flxREFORMAT;
DROP TABLE IF EXISTS sbmACTION;
DROP TABLE IF EXISTS sbmALLFUNCDESCR;
DROP TABLE IF EXISTS sbmAPPROVAL;
DROP TABLE IF EXISTS sbmCOLLECTION;
DROP TABLE IF EXISTS sbmCOLLECTION_sbmCOLLECTION;
DROP TABLE IF EXISTS sbmCOLLECTION_sbmDOCTYPE;
DROP TABLE IF EXISTS sbmCATEGORIES;
DROP TABLE IF EXISTS sbmCHECKS;
DROP TABLE IF EXISTS sbmCOOKIES;
DROP TABLE IF EXISTS sbmDOCTYPE;
DROP TABLE IF EXISTS sbmFIELD;
DROP TABLE IF EXISTS sbmFIELDDESC;
DROP TABLE IF EXISTS sbmFORMATEXTENSION;
DROP TABLE IF EXISTS sbmFUNCTIONS;
DROP TABLE IF EXISTS sbmFUNDESC;
DROP TABLE IF EXISTS sbmGFILERESULT;
DROP TABLE IF EXISTS sbmIMPLEMENT;
DROP TABLE IF EXISTS sbmPARAMETERS;
DROP TABLE IF EXISTS sbmPUBLICATION;
DROP TABLE IF EXISTS sbmPUBLICATIONCOMM;
DROP TABLE IF EXISTS sbmPUBLICATIONDATA;
DROP TABLE IF EXISTS sbmREFEREES;
DROP TABLE IF EXISTS sbmSUBMISSIONS;
DROP TABLE IF EXISTS schTASK;
DROP TABLE IF EXISTS bibdoc;
DROP TABLE IF EXISTS bibdoc_bibdoc;
DROP TABLE IF EXISTS bibrec_bibdoc;
DROP TABLE IF EXISTS usergroup;
DROP TABLE IF EXISTS user_usergroup;
DROP TABLE IF EXISTS user_basket;
DROP TABLE IF EXISTS msgMESSAGE;
DROP TABLE IF EXISTS user_msgMESSAGE;
-- end of file
diff --git a/modules/miscutil/sql/tabfill.sql.wml b/modules/miscutil/sql/tabfill.sql.wml
index 2aeb44d69..0629ab6bf 100644
--- a/modules/miscutil/sql/tabfill.sql.wml
+++ b/modules/miscutil/sql/tabfill.sql.wml
@@ -1,1623 +1,1623 @@
## -*- mode: sql; coding: utf-8; -*-
## $Id$
## Fills configuration tables with defaults.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
## local defaults, i.e. WML config variables are to be used:
INSERT INTO collection VALUES (1,'<CDSNAME>',NULL,NULL,NULL,NULL);
<en>INSERT INTO collectionname VALUES (1,'en','ln','<CDSNAMEINTL>');</en>
<fr>INSERT INTO collectionname VALUES (1,'fr','ln','<CDSNAMEINTL>');</fr>
<de>INSERT INTO collectionname VALUES (1,'de','ln','<CDSNAMEINTL>');</de>
<es>INSERT INTO collectionname VALUES (1,'es','ln','<CDSNAMEINTL>');</es>
<ca>INSERT INTO collectionname VALUES (1,'ca','ln','<CDSNAMEINTL>');</ca>
<pl>INSERT INTO collectionname VALUES (1,'pl','ln','<CDSNAMEINTL>');</pl>
<pt>INSERT INTO collectionname VALUES (1,'pt','ln','<CDSNAMEINTL>');</pt>
<it>INSERT INTO collectionname VALUES (1,'it','ln','<CDSNAMEINTL>');</it>
<ja>INSERT INTO collectionname VALUES (1,'ja','ln','<CDSNAMEINTL>');</ja>
<ru>INSERT INTO collectionname VALUES (1,'ru','ln','<CDSNAMEINTL>');</ru>
<sk>INSERT INTO collectionname VALUES (1,'sk','ln','<CDSNAMEINTL>');</sk>
<cs>INSERT INTO collectionname VALUES (1,'cs','ln','<CDSNAMEINTL>');</cs>
<no>INSERT INTO collectionname VALUES (1,'no','ln','<CDSNAMEINTL>');</no>
<sv>INSERT INTO collectionname VALUES (1,'sv','ln','<CDSNAMEINTL>');</sv>
<el>INSERT INTO collectionname VALUES (1,'el','ln','<CDSNAMEINTL>');</el>
<uk>INSERT INTO collectionname VALUES (1,'uk','ln','<CDSNAMEINTL>');</uk>
INSERT INTO user VALUES (1, '<ADMINEMAIL>', '', NULL, NULL, 'admin', '');
INSERT INTO flxLINKTYPES VALUES ('AUTHOR_SEARCH','N','EXT','','');
INSERT INTO flxLINKTYPES VALUES ('KEYWORD_SEARCH','N','EXT','','');
INSERT INTO flxLINKTYPECONDITIONS VALUES ('AUTHOR_SEARCH',0,' \"\"=\"\" ','\"<WEBURL>/search.py?f=author&p=\" urlencode($author)','EXT','','');
INSERT INTO flxLINKTYPECONDITIONS VALUES ('KEYWORD_SEARCH',0,' \"\"=\"\" ','\"<WEBURL>/search.py?f=keyword&p=\" urlencode($keyword)','EXT','','');
INSERT INTO flxLINKTYPECONDITIONSACTIONS VALUES ('AUTHOR_SEARCH',0,0,'\"<WEBURL>/search.py?f=author&p=\" urlencode($author)');
INSERT INTO flxLINKTYPECONDITIONSACTIONS VALUES ('KEYWORD_SEARCH',0,0,'\"<WEBURL>/search.py?f=keyword&p=\" urlencode($keyword)');
INSERT INTO flxLINKTYPEPARAMS VALUES ('AUTHOR_SEARCH','AUTHOR',0);
INSERT INTO flxLINKTYPEPARAMS VALUES ('KEYWORD_SEARCH','KEYWORD',0);
## generally suitable defaults:
INSERT INTO rnkMETHOD (id,name,last_updated) VALUES (1,'wrd','0000-00-00 00:00:00');
INSERT INTO collection_rnkMETHOD (id_collection,id_rnkMETHOD,score) VALUES (1,1,100);
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'en','ln','word similarity');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'fr','ln','similarité de mots');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'de','ln','Wortähnlichkeit');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'es','ln','similitud de palabras');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'ca','ln','semblança de paraules');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'pl','ln','word similarity');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'pt','ln','similaridade por palavra');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'it','ln','word similarity');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'ja','ln','word similarity');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'ru','ln','word similarity');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'sk','ln','podobnosť slov');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'cs','ln','podobnost slov');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'no','ln','ord-likhet');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'sv','ln','ord-likhet');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'el','ln','ομοιότητα λέξης');
INSERT INTO rnkMETHODNAME (id_rnkMETHOD,ln,type,value) VALUES (1,'uk','ln','подібні слова');
<protect>
INSERT INTO field VALUES (1,'any field','anyfield');
INSERT INTO field VALUES (2,'title','title');
INSERT INTO field VALUES (3,'author','author');
INSERT INTO field VALUES (4,'abstract','abstract');
INSERT INTO field VALUES (5,'keyword','keyword');
INSERT INTO field VALUES (6,'report number','reportnumber');
INSERT INTO field VALUES (7,'subject','subject');
INSERT INTO field VALUES (8,'reference','reference');
INSERT INTO field VALUES (9,'fulltext','fulltext');
INSERT INTO field VALUES (10,'collection','collection');
INSERT INTO field VALUES (11,'division','division');
INSERT INTO field VALUES (12,'year','year');
INSERT INTO field VALUES (13,'experiment','experiment');
INSERT INTO field VALUES (14,'record ID','recid');
INSERT INTO fieldname VALUES (1,'en','ln','any field');
INSERT INTO fieldname VALUES (1,'fr','ln','tous les champs');
INSERT INTO fieldname VALUES (1,'de','ln','alle Felder');
INSERT INTO fieldname VALUES (1,'es','ln','cualquier campo');
INSERT INTO fieldname VALUES (1,'ca','ln','qualsevol camp');
INSERT INTO fieldname VALUES (1,'pl','ln','dowolne pole');
INSERT INTO fieldname VALUES (1,'pt','ln','qualquer campo');
INSERT INTO fieldname VALUES (1,'it','ln','tutti i campi');
INSERT INTO fieldname VALUES (1,'ru','ln','любое поле');
INSERT INTO fieldname VALUES (1,'sk','ln','všetky polia');
INSERT INTO fieldname VALUES (1,'cs','ln','všechna pole');
INSERT INTO fieldname VALUES (1,'no','ln','alle felt');
INSERT INTO fieldname VALUES (1,'sv','ln','samtliga fält');
INSERT INTO fieldname VALUES (1,'el','ln','οποιοδήποτε πεδίο');
INSERT INTO fieldname VALUES (1,'uk','ln','всі поля');
INSERT INTO fieldname VALUES (1,'ja','ln','だれでも分野');
INSERT INTO fieldname VALUES (2,'en','ln','title');
INSERT INTO fieldname VALUES (2,'fr','ln','titre');
INSERT INTO fieldname VALUES (2,'de','ln','Titel');
INSERT INTO fieldname VALUES (2,'es','ln','título');
INSERT INTO fieldname VALUES (2,'ca','ln','títol');
INSERT INTO fieldname VALUES (2,'pl','ln','tytuł');
INSERT INTO fieldname VALUES (2,'pt','ln','título');
INSERT INTO fieldname VALUES (2,'it','ln','titolo');
INSERT INTO fieldname VALUES (2,'ru','ln','название');
INSERT INTO fieldname VALUES (2,'sk','ln','názov');
INSERT INTO fieldname VALUES (2,'cs','ln','název');
INSERT INTO fieldname VALUES (2,'no','ln','tittel');
INSERT INTO fieldname VALUES (2,'sv','ln','titel');
INSERT INTO fieldname VALUES (2,'el','ln','τίτλος');
INSERT INTO fieldname VALUES (2,'uk','ln','назва');
INSERT INTO fieldname VALUES (2,'ja','ln','タイトル');
INSERT INTO fieldname VALUES (3,'en','ln','author');
INSERT INTO fieldname VALUES (3,'fr','ln','auteur');
INSERT INTO fieldname VALUES (3,'de','ln','Autor');
INSERT INTO fieldname VALUES (3,'es','ln','autor');
INSERT INTO fieldname VALUES (3,'ca','ln','autor');
INSERT INTO fieldname VALUES (3,'pl','ln','autor');
INSERT INTO fieldname VALUES (3,'pt','ln','autor');
INSERT INTO fieldname VALUES (3,'it','ln','autore');
INSERT INTO fieldname VALUES (3,'ru','ln','автор');
INSERT INTO fieldname VALUES (3,'sk','ln','autor');
INSERT INTO fieldname VALUES (3,'cs','ln','autor');
INSERT INTO fieldname VALUES (3,'no','ln','forfatter');
INSERT INTO fieldname VALUES (3,'sv','ln','författare');
INSERT INTO fieldname VALUES (3,'el','ln','συγγραφέας');
INSERT INTO fieldname VALUES (3,'uk','ln','автор');
INSERT INTO fieldname VALUES (3,'ja','ln','著者');
INSERT INTO fieldname VALUES (4,'en','ln','abstract');
INSERT INTO fieldname VALUES (4,'fr','ln','abstract');
INSERT INTO fieldname VALUES (4,'de','ln','Abstrakt');
INSERT INTO fieldname VALUES (4,'es','ln','resumen');
INSERT INTO fieldname VALUES (4,'ca','ln','resum');
INSERT INTO fieldname VALUES (4,'pl','ln','abstrakt');
INSERT INTO fieldname VALUES (4,'pt','ln','resumo');
INSERT INTO fieldname VALUES (4,'it','ln','riassunto');
INSERT INTO fieldname VALUES (4,'ru','ln','абстракт');
INSERT INTO fieldname VALUES (4,'sk','ln','abstrakt');
INSERT INTO fieldname VALUES (4,'cs','ln','abstrakt');
INSERT INTO fieldname VALUES (4,'no','ln','sammendrag');
INSERT INTO fieldname VALUES (4,'sv','ln','sammanfattning');
INSERT INTO fieldname VALUES (4,'el','ln','περίληψη');
INSERT INTO fieldname VALUES (4,'uk','ln','резюме');
INSERT INTO fieldname VALUES (4,'ja','ln','概要');
INSERT INTO fieldname VALUES (5,'en','ln','keyword');
INSERT INTO fieldname VALUES (5,'fr','ln','mot clé');
INSERT INTO fieldname VALUES (5,'de','ln','Kennwort');
INSERT INTO fieldname VALUES (5,'es','ln','palabra clave');
INSERT INTO fieldname VALUES (5,'ca','ln','paraula clau');
INSERT INTO fieldname VALUES (5,'pl','ln','słowo kluczowe');
INSERT INTO fieldname VALUES (5,'pt','ln','palavra chave');
INSERT INTO fieldname VALUES (5,'it','ln','parola chiave');
INSERT INTO fieldname VALUES (5,'ru','ln','ключевое слово');
INSERT INTO fieldname VALUES (5,'sk','ln','kľúčové slovo');
INSERT INTO fieldname VALUES (5,'cs','ln','klíčové slovo');
INSERT INTO fieldname VALUES (5,'no','ln','nøkkelord');
INSERT INTO fieldname VALUES (5,'sv','ln','nyckelord');
INSERT INTO fieldname VALUES (5,'el','ln','λέξη κλειδί');
INSERT INTO fieldname VALUES (5,'uk','ln','ключеве слово');
INSERT INTO fieldname VALUES (5,'ja','ln','キーワード');
INSERT INTO fieldname VALUES (6,'en','ln','report number');
INSERT INTO fieldname VALUES (6,'fr','ln','numéro de rapport');
INSERT INTO fieldname VALUES (6,'de','ln','Reportnummer');
INSERT INTO fieldname VALUES (6,'es','ln','número de reporte');
INSERT INTO fieldname VALUES (6,'ca','ln','número d\'informe');
INSERT INTO fieldname VALUES (6,'pl','ln','numer raportu');
INSERT INTO fieldname VALUES (6,'pt','ln','número de registro');
INSERT INTO fieldname VALUES (6,'it','ln','numero del rapporto');
INSERT INTO fieldname VALUES (6,'ru','ln','номер документа');
INSERT INTO fieldname VALUES (6,'sk','ln','číslo správy');
INSERT INTO fieldname VALUES (6,'cs','ln','číslo zprávy');
INSERT INTO fieldname VALUES (6,'no','ln','rapportnummer');
INSERT INTO fieldname VALUES (6,'sv','ln','rapportnummer');
INSERT INTO fieldname VALUES (6,'el','ln','αριθμός αναφοράς');
INSERT INTO fieldname VALUES (6,'uk','ln','номер документа');
INSERT INTO fieldname VALUES (6,'ja','ln','レポート数');
INSERT INTO fieldname VALUES (7,'en','ln','subject');
INSERT INTO fieldname VALUES (7,'fr','ln','sujet');
INSERT INTO fieldname VALUES (7,'de','ln','Thema');
INSERT INTO fieldname VALUES (7,'es','ln','materia');
INSERT INTO fieldname VALUES (7,'ca','ln','matèria');
INSERT INTO fieldname VALUES (7,'pl','ln','temat');
INSERT INTO fieldname VALUES (7,'pt','ln','assunto');
INSERT INTO fieldname VALUES (7,'it','ln','soggetto');
INSERT INTO fieldname VALUES (7,'ru','ln','');
INSERT INTO fieldname VALUES (7,'sk','ln','predmet');
INSERT INTO fieldname VALUES (7,'cs','ln','předmět');
INSERT INTO fieldname VALUES (7,'no','ln','emne');
INSERT INTO fieldname VALUES (7,'sv','ln','');
INSERT INTO fieldname VALUES (7,'el','ln','θέμα');
INSERT INTO fieldname VALUES (7,'uk','ln','тема');
INSERT INTO fieldname VALUES (7,'ja','ln','ツ 主題');
INSERT INTO fieldname VALUES (8,'en','ln','reference');
INSERT INTO fieldname VALUES (8,'fr','ln','référence');
INSERT INTO fieldname VALUES (8,'de','ln','Referenz');
INSERT INTO fieldname VALUES (8,'es','ln','referencia');
INSERT INTO fieldname VALUES (8,'ca','ln','referència');
INSERT INTO fieldname VALUES (8,'pl','ln','odnośnik');
INSERT INTO fieldname VALUES (8,'pt','ln','referência');
INSERT INTO fieldname VALUES (8,'it','ln','referenza');
INSERT INTO fieldname VALUES (8,'ru','ln','ссылка');
INSERT INTO fieldname VALUES (8,'sk','ln','referencie');
INSERT INTO fieldname VALUES (8,'cs','ln','reference');
INSERT INTO fieldname VALUES (8,'no','ln','referanse');
INSERT INTO fieldname VALUES (8,'sv','ln','referens');
INSERT INTO fieldname VALUES (8,'el','ln','αναφορά');
INSERT INTO fieldname VALUES (8,'uk','ln','посилання');
INSERT INTO fieldname VALUES (8,'ja','ln','参照');
INSERT INTO fieldname VALUES (9,'en','ln','fulltext');
INSERT INTO fieldname VALUES (9,'fr','ln','fulltext');
INSERT INTO fieldname VALUES (9,'de','ln','Volltext');
INSERT INTO fieldname VALUES (9,'es','ln','texto completo');
INSERT INTO fieldname VALUES (9,'ca','ln','text complert');
INSERT INTO fieldname VALUES (9,'pl','ln','pełny tekst');
INSERT INTO fieldname VALUES (9,'pt','ln','texto completo');
INSERT INTO fieldname VALUES (9,'it','ln','testo completo');
INSERT INTO fieldname VALUES (9,'ru','ln','полный текст');
INSERT INTO fieldname VALUES (9,'sk','ln','plný text');
INSERT INTO fieldname VALUES (9,'cs','ln','plný text');
INSERT INTO fieldname VALUES (9,'no','ln','fulltekst');
INSERT INTO fieldname VALUES (9,'sv','ln','fulltext');
INSERT INTO fieldname VALUES (9,'el','ln','πλήρες κείμενο');
INSERT INTO fieldname VALUES (9,'uk','ln','повний текст');
INSERT INTO fieldname VALUES (9,'ja','ln','フルテキスト');
INSERT INTO fieldname VALUES (10,'en','ln','collection');
INSERT INTO fieldname VALUES (10,'fr','ln','collection');
INSERT INTO fieldname VALUES (10,'de','ln','Sammlung');
INSERT INTO fieldname VALUES (10,'es','ln','colección');
INSERT INTO fieldname VALUES (10,'ca','ln','col·lecció');
INSERT INTO fieldname VALUES (10,'pl','ln','zbiór');
INSERT INTO fieldname VALUES (10,'pt','ln','coleção');
INSERT INTO fieldname VALUES (10,'it','ln','collezione');
INSERT INTO fieldname VALUES (10,'ru','ln','набор');
INSERT INTO fieldname VALUES (10,'sk','ln','kolekcia');
INSERT INTO fieldname VALUES (10,'cs','ln','kolekce');
INSERT INTO fieldname VALUES (10,'no','ln','samling');
INSERT INTO fieldname VALUES (10,'sv','ln','samlingen');
INSERT INTO fieldname VALUES (10,'el','ln','συλλογή');
INSERT INTO fieldname VALUES (10,'uk','ln','розділ');
INSERT INTO fieldname VALUES (10,'ja','ln','コレクション');
INSERT INTO fieldname VALUES (11,'en','ln','division');
INSERT INTO fieldname VALUES (11,'fr','ln','division');
INSERT INTO fieldname VALUES (11,'de','ln','Abteilung');
INSERT INTO fieldname VALUES (11,'es','ln','división');
INSERT INTO fieldname VALUES (11,'ca','ln','divisió');
INSERT INTO fieldname VALUES (11,'pl','ln','podział');
INSERT INTO fieldname VALUES (11,'pt','ln','divisão');
INSERT INTO fieldname VALUES (11,'it','ln','divisione');
INSERT INTO fieldname VALUES (11,'ru','ln','');
INSERT INTO fieldname VALUES (11,'sk','ln','oddelenie');
INSERT INTO fieldname VALUES (11,'cs','ln','oddělení');
INSERT INTO fieldname VALUES (11,'no','ln','divisjon');
INSERT INTO fieldname VALUES (11,'sv','ln','');
INSERT INTO fieldname VALUES (11,'el','ln','τμήμα');
INSERT INTO fieldname VALUES (11,'uk','ln','підрозділ');
INSERT INTO fieldname VALUES (11,'ja','ln','部');
INSERT INTO fieldname VALUES (12,'en','ln','year');
INSERT INTO fieldname VALUES (12,'fr','ln','année');
INSERT INTO fieldname VALUES (12,'de','ln','Jahr');
INSERT INTO fieldname VALUES (12,'es','ln','año');
INSERT INTO fieldname VALUES (12,'ca','ln','any');
INSERT INTO fieldname VALUES (12,'pl','ln','rok');
INSERT INTO fieldname VALUES (12,'pt','ln','ano');
INSERT INTO fieldname VALUES (12,'it','ln','anno');
INSERT INTO fieldname VALUES (12,'ru','ln','год');
INSERT INTO fieldname VALUES (12,'sk','ln','rok');
INSERT INTO fieldname VALUES (12,'cs','ln','rok');
INSERT INTO fieldname VALUES (12,'no','ln','Ã¥r');
INSERT INTO fieldname VALUES (12,'sv','ln','Ã¥r');
INSERT INTO fieldname VALUES (12,'el','ln','έτος');
INSERT INTO fieldname VALUES (12,'uk','ln','рік');
INSERT INTO fieldname VALUES (12,'ja','ln','å¹´');
INSERT INTO fieldname VALUES (13,'en','ln','experiment');
INSERT INTO fieldname VALUES (13,'fr','ln','expérience');
INSERT INTO fieldname VALUES (13,'de','ln','Experiment');
INSERT INTO fieldname VALUES (13,'es','ln','experimento');
INSERT INTO fieldname VALUES (13,'ca','ln','experiment');
INSERT INTO fieldname VALUES (13,'pl','ln','eksperyment');
INSERT INTO fieldname VALUES (13,'pt','ln','experimento');
INSERT INTO fieldname VALUES (13,'it','ln','esperimento');
INSERT INTO fieldname VALUES (13,'ru','ln','');
INSERT INTO fieldname VALUES (13,'sk','ln','experiment');
INSERT INTO fieldname VALUES (13,'cs','ln','experiment');
INSERT INTO fieldname VALUES (13,'no','ln','eksperiment');
INSERT INTO fieldname VALUES (13,'sv','ln','');
INSERT INTO fieldname VALUES (13,'el','ln','πείραμα');
INSERT INTO fieldname VALUES (13,'uk','ln','експеримент');
INSERT INTO fieldname VALUES (13,'ja','ln','実験');
INSERT INTO fieldname VALUES (14,'en','ln','record ID');
INSERT INTO fieldname VALUES (14,'fr','ln','notice ID');
INSERT INTO fieldname VALUES (14,'de','ln','Datensatz-ID');
INSERT INTO fieldname VALUES (14,'es','ln','registro núm.');
INSERT INTO fieldname VALUES (14,'ca','ln','registre núm.');
INSERT INTO fieldname VALUES (14,'pl','ln','ID rekordu');
INSERT INTO fieldname VALUES (14,'pt','ln','ID do registro');
INSERT INTO fieldname VALUES (14,'it','ln','ID della notizia');
INSERT INTO fieldname VALUES (14,'ru','ln','');
INSERT INTO fieldname VALUES (14,'sk','ln','ID záznamu');
INSERT INTO fieldname VALUES (14,'cs','ln','ID záznamu');
INSERT INTO fieldname VALUES (14,'no','ln','post ID');
INSERT INTO fieldname VALUES (14,'sv','ln','');
INSERT INTO fieldname VALUES (14,'el','ln','record ID');
INSERT INTO fieldname VALUES (14,'uk','ln','номер запису');
INSERT INTO fieldname VALUES (14,'ja','ln','記録的なID');
INSERT INTO field_tag VALUES (1,100,10);
INSERT INTO field_tag VALUES (1,101,10);
INSERT INTO field_tag VALUES (1,102,10);
INSERT INTO field_tag VALUES (1,103,10);
INSERT INTO field_tag VALUES (1,104,10);
INSERT INTO field_tag VALUES (1,105,10);
INSERT INTO field_tag VALUES (1,106,10);
INSERT INTO field_tag VALUES (1,107,10);
INSERT INTO field_tag VALUES (1,108,10);
INSERT INTO field_tag VALUES (1,109,10);
INSERT INTO field_tag VALUES (1,110,10);
INSERT INTO field_tag VALUES (1,111,10);
INSERT INTO field_tag VALUES (1,112,10);
INSERT INTO field_tag VALUES (1,113,10);
INSERT INTO field_tag VALUES (1,114,10);
INSERT INTO field_tag VALUES (1,16,10);
INSERT INTO field_tag VALUES (1,17,10);
INSERT INTO field_tag VALUES (1,18,10);
INSERT INTO field_tag VALUES (1,19,10);
INSERT INTO field_tag VALUES (1,20,10);
INSERT INTO field_tag VALUES (1,21,10);
INSERT INTO field_tag VALUES (1,22,10);
INSERT INTO field_tag VALUES (1,23,10);
INSERT INTO field_tag VALUES (1,24,10);
INSERT INTO field_tag VALUES (1,25,10);
INSERT INTO field_tag VALUES (1,26,10);
INSERT INTO field_tag VALUES (1,27,10);
INSERT INTO field_tag VALUES (1,28,10);
INSERT INTO field_tag VALUES (1,29,10);
INSERT INTO field_tag VALUES (1,30,10);
INSERT INTO field_tag VALUES (1,31,10);
INSERT INTO field_tag VALUES (1,32,10);
INSERT INTO field_tag VALUES (1,33,10);
INSERT INTO field_tag VALUES (1,34,10);
INSERT INTO field_tag VALUES (1,35,10);
INSERT INTO field_tag VALUES (1,36,10);
INSERT INTO field_tag VALUES (1,37,10);
INSERT INTO field_tag VALUES (1,38,10);
INSERT INTO field_tag VALUES (1,39,10);
INSERT INTO field_tag VALUES (1,40,10);
INSERT INTO field_tag VALUES (1,41,10);
INSERT INTO field_tag VALUES (1,42,10);
INSERT INTO field_tag VALUES (1,43,10);
INSERT INTO field_tag VALUES (1,44,10);
INSERT INTO field_tag VALUES (1,45,10);
INSERT INTO field_tag VALUES (1,46,10);
INSERT INTO field_tag VALUES (1,47,10);
INSERT INTO field_tag VALUES (1,48,10);
INSERT INTO field_tag VALUES (1,49,10);
INSERT INTO field_tag VALUES (1,50,10);
INSERT INTO field_tag VALUES (1,51,10);
INSERT INTO field_tag VALUES (1,52,10);
INSERT INTO field_tag VALUES (1,53,10);
INSERT INTO field_tag VALUES (1,54,10);
INSERT INTO field_tag VALUES (1,55,10);
INSERT INTO field_tag VALUES (1,56,10);
INSERT INTO field_tag VALUES (1,57,10);
INSERT INTO field_tag VALUES (1,58,10);
INSERT INTO field_tag VALUES (1,59,10);
INSERT INTO field_tag VALUES (1,60,10);
INSERT INTO field_tag VALUES (1,61,10);
INSERT INTO field_tag VALUES (1,62,10);
INSERT INTO field_tag VALUES (1,63,10);
INSERT INTO field_tag VALUES (1,64,10);
INSERT INTO field_tag VALUES (1,65,10);
INSERT INTO field_tag VALUES (1,66,10);
INSERT INTO field_tag VALUES (1,67,10);
INSERT INTO field_tag VALUES (1,68,10);
INSERT INTO field_tag VALUES (1,69,10);
INSERT INTO field_tag VALUES (1,70,10);
INSERT INTO field_tag VALUES (1,71,10);
INSERT INTO field_tag VALUES (1,72,10);
INSERT INTO field_tag VALUES (1,73,10);
INSERT INTO field_tag VALUES (1,74,10);
INSERT INTO field_tag VALUES (1,75,10);
INSERT INTO field_tag VALUES (1,76,10);
INSERT INTO field_tag VALUES (1,77,10);
INSERT INTO field_tag VALUES (1,78,10);
INSERT INTO field_tag VALUES (1,79,10);
INSERT INTO field_tag VALUES (1,80,10);
INSERT INTO field_tag VALUES (1,81,10);
INSERT INTO field_tag VALUES (1,82,10);
INSERT INTO field_tag VALUES (1,83,10);
INSERT INTO field_tag VALUES (1,84,10);
INSERT INTO field_tag VALUES (1,85,10);
INSERT INTO field_tag VALUES (1,86,10);
INSERT INTO field_tag VALUES (1,87,10);
INSERT INTO field_tag VALUES (1,88,10);
INSERT INTO field_tag VALUES (1,89,10);
INSERT INTO field_tag VALUES (1,90,10);
INSERT INTO field_tag VALUES (1,91,10);
INSERT INTO field_tag VALUES (1,92,10);
INSERT INTO field_tag VALUES (1,93,10);
INSERT INTO field_tag VALUES (1,94,10);
INSERT INTO field_tag VALUES (1,95,10);
INSERT INTO field_tag VALUES (1,96,10);
INSERT INTO field_tag VALUES (1,97,10);
INSERT INTO field_tag VALUES (1,98,10);
INSERT INTO field_tag VALUES (1,99,10);
INSERT INTO field_tag VALUES (10,11,100);
INSERT INTO field_tag VALUES (11,14,100);
INSERT INTO field_tag VALUES (12,15,10);
INSERT INTO field_tag VALUES (13,116,10);
INSERT INTO field_tag VALUES (2,3,100);
INSERT INTO field_tag VALUES (2,4,90);
INSERT INTO field_tag VALUES (3,1,100);
INSERT INTO field_tag VALUES (3,2,90);
INSERT INTO field_tag VALUES (4,5,100);
INSERT INTO field_tag VALUES (5,6,100);
INSERT INTO field_tag VALUES (6,7,30);
INSERT INTO field_tag VALUES (6,8,10);
INSERT INTO field_tag VALUES (6,9,20);
INSERT INTO field_tag VALUES (7,12,100);
INSERT INTO field_tag VALUES (7,13,90);
INSERT INTO field_tag VALUES (8,10,100);
INSERT INTO field_tag VALUES (9,115,100);
INSERT INTO field_tag VALUES (14,117,100);
INSERT INTO format VALUES (1,'HTML brief','hb');
INSERT INTO format VALUES (2,'HTML detailed','hd');
INSERT INTO format VALUES (6,'portfolio','hp');
INSERT INTO format VALUES (7,'photo captions only','hc');
INSERT INTO format VALUES (8,'BibTeX','hx');
INSERT INTO format VALUES (4,'Dublin Core','xd');
INSERT INTO format VALUES (3,'MARC','hm');
INSERT INTO format VALUES (5,'MARCXML','xm');
INSERT INTO tag VALUES (1,'first author','100__%');
INSERT INTO tag VALUES (2,'additional author','700__%');
INSERT INTO tag VALUES (3,'main title','245__%');
INSERT INTO tag VALUES (4,'additional title','246__%');
INSERT INTO tag VALUES (5,'abstract','520__%');
INSERT INTO tag VALUES (6,'keyword','6531_a');
INSERT INTO tag VALUES (7,'primary report number','037__a');
INSERT INTO tag VALUES (8,'additional report number','088__a');
INSERT INTO tag VALUES (9,'added report number','909C0r');
INSERT INTO tag VALUES (10,'reference','999C5%');
INSERT INTO tag VALUES (11,'collection identifier','980__%');
INSERT INTO tag VALUES (12,'main subject','65017a');
INSERT INTO tag VALUES (13,'additional subject','65027a');
INSERT INTO tag VALUES (14,'division','909C0p');
INSERT INTO tag VALUES (15,'year','909C0y');
INSERT INTO tag VALUES (16,'00x','00%');
INSERT INTO tag VALUES (17,'01x','01%');
INSERT INTO tag VALUES (18,'02x','02%');
INSERT INTO tag VALUES (19,'03x','03%');
INSERT INTO tag VALUES (20,'04x','04%');
INSERT INTO tag VALUES (21,'05x','05%');
INSERT INTO tag VALUES (22,'06x','06%');
INSERT INTO tag VALUES (23,'07x','07%');
INSERT INTO tag VALUES (24,'08x','08%');
INSERT INTO tag VALUES (25,'09x','09%');
INSERT INTO tag VALUES (26,'10x','10%');
INSERT INTO tag VALUES (27,'11x','11%');
INSERT INTO tag VALUES (28,'12x','12%');
INSERT INTO tag VALUES (29,'13x','13%');
INSERT INTO tag VALUES (30,'14x','14%');
INSERT INTO tag VALUES (31,'15x','15%');
INSERT INTO tag VALUES (32,'16x','16%');
INSERT INTO tag VALUES (33,'17x','17%');
INSERT INTO tag VALUES (34,'18x','18%');
INSERT INTO tag VALUES (35,'19x','19%');
INSERT INTO tag VALUES (36,'20x','20%');
INSERT INTO tag VALUES (37,'21x','21%');
INSERT INTO tag VALUES (38,'22x','22%');
INSERT INTO tag VALUES (39,'23x','23%');
INSERT INTO tag VALUES (40,'24x','24%');
INSERT INTO tag VALUES (41,'25x','25%');
INSERT INTO tag VALUES (42,'26x','26%');
INSERT INTO tag VALUES (43,'27x','27%');
INSERT INTO tag VALUES (44,'28x','28%');
INSERT INTO tag VALUES (45,'29x','29%');
INSERT INTO tag VALUES (46,'30x','30%');
INSERT INTO tag VALUES (47,'31x','31%');
INSERT INTO tag VALUES (48,'32x','32%');
INSERT INTO tag VALUES (49,'33x','33%');
INSERT INTO tag VALUES (50,'34x','34%');
INSERT INTO tag VALUES (51,'35x','35%');
INSERT INTO tag VALUES (52,'36x','36%');
INSERT INTO tag VALUES (53,'37x','37%');
INSERT INTO tag VALUES (54,'38x','38%');
INSERT INTO tag VALUES (55,'39x','39%');
INSERT INTO tag VALUES (56,'40x','40%');
INSERT INTO tag VALUES (57,'41x','41%');
INSERT INTO tag VALUES (58,'42x','42%');
INSERT INTO tag VALUES (59,'43x','43%');
INSERT INTO tag VALUES (60,'44x','44%');
INSERT INTO tag VALUES (61,'45x','45%');
INSERT INTO tag VALUES (62,'46x','46%');
INSERT INTO tag VALUES (63,'47x','47%');
INSERT INTO tag VALUES (64,'48x','48%');
INSERT INTO tag VALUES (65,'49x','49%');
INSERT INTO tag VALUES (66,'50x','50%');
INSERT INTO tag VALUES (67,'51x','51%');
INSERT INTO tag VALUES (68,'52x','52%');
INSERT INTO tag VALUES (69,'53x','53%');
INSERT INTO tag VALUES (70,'54x','54%');
INSERT INTO tag VALUES (71,'55x','55%');
INSERT INTO tag VALUES (72,'56x','56%');
INSERT INTO tag VALUES (73,'57x','57%');
INSERT INTO tag VALUES (74,'58x','58%');
INSERT INTO tag VALUES (75,'59x','59%');
INSERT INTO tag VALUES (76,'60x','60%');
INSERT INTO tag VALUES (77,'61x','61%');
INSERT INTO tag VALUES (78,'62x','62%');
INSERT INTO tag VALUES (79,'63x','63%');
INSERT INTO tag VALUES (80,'64x','64%');
INSERT INTO tag VALUES (81,'65x','65%');
INSERT INTO tag VALUES (82,'66x','66%');
INSERT INTO tag VALUES (83,'67x','67%');
INSERT INTO tag VALUES (84,'68x','68%');
INSERT INTO tag VALUES (85,'69x','69%');
INSERT INTO tag VALUES (86,'70x','70%');
INSERT INTO tag VALUES (87,'71x','71%');
INSERT INTO tag VALUES (88,'72x','72%');
INSERT INTO tag VALUES (89,'73x','73%');
INSERT INTO tag VALUES (90,'74x','74%');
INSERT INTO tag VALUES (91,'75x','75%');
INSERT INTO tag VALUES (92,'76x','76%');
INSERT INTO tag VALUES (93,'77x','77%');
INSERT INTO tag VALUES (94,'78x','78%');
INSERT INTO tag VALUES (95,'79x','79%');
INSERT INTO tag VALUES (96,'80x','80%');
INSERT INTO tag VALUES (97,'81x','81%');
INSERT INTO tag VALUES (98,'82x','82%');
INSERT INTO tag VALUES (99,'83x','83%');
INSERT INTO tag VALUES (100,'84x','84%');
INSERT INTO tag VALUES (101,'85x','85%');
INSERT INTO tag VALUES (102,'86x','86%');
INSERT INTO tag VALUES (103,'87x','87%');
INSERT INTO tag VALUES (104,'88x','88%');
INSERT INTO tag VALUES (105,'89x','89%');
INSERT INTO tag VALUES (106,'90x','90%');
INSERT INTO tag VALUES (107,'91x','91%');
INSERT INTO tag VALUES (108,'92x','92%');
INSERT INTO tag VALUES (109,'93x','93%');
INSERT INTO tag VALUES (110,'94x','94%');
INSERT INTO tag VALUES (111,'95x','95%');
INSERT INTO tag VALUES (112,'96x','96%');
INSERT INTO tag VALUES (113,'97x','97%');
INSERT INTO tag VALUES (114,'98x','98%');
INSERT INTO tag VALUES (115,'url','8564_u');
INSERT INTO tag VALUES (116,'experiment','909C0e');
INSERT INTO tag VALUES (117,'record ID','001');
INSERT INTO idxINDEX VALUES (1,'global','This index contains words/phrases from global fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (2,'collection','This index contains words/phrases from collection identifiers fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (3,'abstract','This index contains words/phrases from abstract fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (4,'author','This index contains words/phrases from author fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (5,'keyword','This index contains words/phrases from keyword fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (6,'reference','This index contains words/phrases from references fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (7,'reportnumber','This index contains words/phrases from report numbers fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (8,'title','This index contains words/phrases from title fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (9,'fulltext','This index contains words/phrases from fulltext fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX VALUES (10,'year','This index contains words/phrases from year fields.','0000-00-00 00:00:00');
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (1,1);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (2,10);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (3,4);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (4,3);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (5,5);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (6,8);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (7,6);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (8,2);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (9,9);
INSERT INTO idxINDEX_field (id_idxINDEX, id_field) VALUES (10,12);
INSERT INTO flxFORMATS VALUES ('DEFAULT_HTML_BRIEF','\"<strong>\" format(\"_DEFAULT_TITLE\") \"</strong> \"\r\nif(count($100.a)!=\"0\" || count($700.a)!=\"0\")\r\n{\r\n \" / \" format(\"_DEFAULT_AUTHORS\") \" \"\r\n}\r\nforall($088.a)\r\n{ \" <small class=quicknote> [\" $088.a \"]</small> \" }\r\nforall($037.a)\r\n{ \" <small class=quicknote> [\" $037.a \"]</small> \" }\r\nforall($520.a)\r\n{ \"<br><small>\" format(\"_DEFAULT_ABSTRACT_FIRST_SENTENCE\") \"</small>\" }\r\nforall($8564.u)\r\n{ \"<br><small>\" format(\"_DEFAULT_URL\") \"</small>\" }','This is the default brief HTML format.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"<strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"_DEFAULT_TITLE\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"</strong> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\" / \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:16:\"_DEFAULT_AUTHORS\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:26:\" <small class=quicknote> [\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"]</small> \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:26:\" <small class=quicknote> [\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"]</small> \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"<br><small>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:32:\"_DEFAULT_ABSTRACT_FIRST_SENTENCE\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"</small>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"<br><small>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"_DEFAULT_URL\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"</small>\";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_DEFAULT_AUTHORS',' if(gt(sum( count($700.a), count($100.a) ),\"4\")!=\"\") \r\n{ \r\n if(count($100.a)!=\"0\") \r\n { \r\n link(\"author_search\", $100.a)\r\n {\r\n \"<a href=\\\"\" $link \"\\\">\" $100.a \"</a>\"\r\n if($100.e!=\"\") { \" (\" $100.e \")\" }\r\n \" <em> et al</em> \" \r\n } \r\n } \r\n else \r\n { \r\n if(count($700.a)!=\"0\") \r\n { \r\n link(\"author_search\", $700.a)\r\n { \r\n \"<a href=\\\"\" $link \"\\\">\" $700.a \"</a>\"\r\n if($700.e!=\"\") { \" (\" $700.e \")\" }\r\n \" et al.\" \r\n } \r\n } \r\n } \r\n} \r\nelse \r\n{ \r\n forall($100) \r\n { \r\n if($100.a!=\"\") \r\n { \r\n link(\"author_search\", $100.a){\"<a href=\\\"\" $link \"\\\">\" $100.a \"</a>\" } \r\n separator(\"; \") \r\n } \r\n } \r\n if(count($100.a)!=\"0\") \r\n { \r\n if(count($700.a)!=\"0\") \r\n { \"; \" } \r\n } \r\n forall($700) \r\n { \r\n if($700.a!=\"\") \r\n { \r\n link(\"author_search\", $700.a){\"<a href=\\\"\" $link \"\\\">\" $700.a \"</a>\" } \r\n separator(\"; \") \r\n } \r\n } \r\n} ','This is the default subformat to format author lists.','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:2:\"GT\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:3:\"SUM\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"4\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"author_search\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\")\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:17:\" <em> et al</em> \";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"author_search\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\")\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\" et al.\";s:4:\"sons\";a:0:{}}}}}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"author_search\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"author_search\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_DEFAULT_TITLE','$245.a \r\nif($245.b!=\"\"){ \" : \" $245.b } \r\nif($250.a!=\"\"){ \" ; \" $250.a } ','HTML for displaying the title in brief formats','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\" : \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"250\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\" ; \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"250\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_DEFAULT_ABSTRACT_FIRST_SENTENCE','limw_l($520.a, \".\") \". [...]\"','This is the default subformat to yield the first sentence of the abstract.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:6:\"LIMW_L\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\".\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\". [...]\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxFORMATS VALUES ('DEFAULT_HTML_DETAILED','format(\"_full_topbanner\") \r\nformat(\"_full_title\") \r\n\"<p><center>\" \r\nformat(\"_full_author\")\r\nformat(\"_full_affiliation\")\r\nformat(\"_full_datedoc\") \"<br>\"\r\nformat(\"_full_imprint\")\r\n\"</center>\"\r\n\r\n\"<p style=\\\"margin-left: 15%; width: 70%\\\">\"\r\n\r\nformat(\"_full_abstract\")\r\nformat(\"_full_daterec\")\r\n\r\nformat(\"_full_keyword\")\r\n\r\nformat(\"_full_note\") \r\nformat(\"_full_publiinfo\")\r\n\"<br>\"\r\nformat(\"_full_url\")\r\nformat(\"_full_citedby\")\r\n\"<p>\" \r\nformat(\"_full_references\")\r\n','This is the default HTML detailed format.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"_full_topbanner\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"_full_title\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"<p><center>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"_full_author\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:17:\"_full_affiliation\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_datedoc\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_imprint\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"</center>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:40:\"<p style=\"margin-left: 15%; width: 70%\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"_full_abstract\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_daterec\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_keyword\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"_full_note\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"_full_publiinfo\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"_full_url\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_citedby\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"<p>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:16:\"_full_references\";s:4:\"sons\";a:0:{}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_ABSTRACT','if($520.a!=\"\"||$520.b!=\"\"){\r\n \"\r\n <small><strong>Abstract: </strong>\"\r\n $520.a\" <br>\"$520.b\" \"\r\n \"</small><br>\r\n \"\r\n} \r\nif($590.a!=\"\"||$590.b!=\"\"){\r\n \"\r\n <small><strong>Texte: </strong>\"\r\n $590.a\" <br>\"$590.b\r\n \"</small><br>\r\n \"\r\n} ','HTML Abstract display','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:37:\"\r\n <small><strong>Abstract: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" <br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"</small><br>\r\n \";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"590\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"590\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:34:\"\r\n <small><strong>Texte: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"590\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" <br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"590\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"</small><br>\r\n \";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_TITLE','if($245.a!=\"\"){\r\n \"<center><big><big><strong>\"\r\n $245.a\r\n if($245.b!=\"\"){ \": \" $245.b }\r\n \"</center></strong></big></big>\"\r\n}\r\n\r\nif($0248.a!=\"\"){\r\n \"<br><center><big><big><strong>\"\r\n $0248.a\r\n \"</center></strong></big></big>\"\r\n}\r\n\r\nif($246.a!=\"\"){\r\n \"<br><center><big><big><strong>\"\r\n $246.a\r\n \"</center></strong></big></big>\"\r\n}\r\n\r\nif($246_1.a!=\"\"){\r\n \"<br><center><big><big><strong><i>\"\r\n $246_1.a\r\n \"</i></center></strong></big></big>\"\r\n}\r\n\r\nif($210.a!=\"\"){\r\n \"<small>(\"\r\n $210.a\r\n \") </small>\"\r\n}\r\n','HTML Title display ','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:26:\"<center><big><big><strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\": \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:30:\"</center></strong></big></big>\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"0248\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:30:\"<br><center><big><big><strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"0248\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:30:\"</center></strong></big></big>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"246\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:30:\"<br><center><big><big><strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"246\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:30:\"</center></strong></big></big>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:33:\"<br><center><big><big><strong><i>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:34:\"</i></center></strong></big></big>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"210\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"<small>(\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"210\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\") </small>\";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('PICTURE_HTML_DETAILED','format(\"_full_topbanner\")\r\nformat(\"_full_title\")\r\n\r\nformat(\"_full_note\")\r\nif($260.c!=\"\"){\"<center>\" $260.c \"</center>\"}\r\nformat(\"_full_contact\")\r\nif($100.a!=\"\"){\r\n \"<center>Photographer: <small>\"\r\n format(\"_full_author\")\r\n \"</small></center>\"\r\n}\r\n\r\n\"<br>\"\r\n\r\nformat(\"_full_keyword\")\r\n\r\n\r\n\r\n\"\r\n<table> <tr>\r\n<td valign=\\\"top\\\" align=\\\"left\\\">\" \r\nif($909CP.s!=\"\"){\"<BR> <strong>Original ref.</strong>: \"$909CP.s\" \"}\r\nif($909CP.t!=\"\"){\"<BR><strong>Available pictures</strong>: \"$909CP.t\" \"}\r\n\r\nif ($520.a!=\"\"){\r\n \"</p><table><tr><td class=\\\"blocknote\\\"> \r\n Caption</td></tr></table>\" \r\n \"<small>\" \r\n $520.a\r\n \"</small></p>\"\r\n}\r\nif ($590.a!=\"\"){\r\n \"</p><table><tr><td class=\\\"blocknote\\\"> \r\n Légende</td></tr></table>\" \r\n \"<small>\" \r\n $590.a\r\n \"</small></p>\"\r\n}\r\n\r\nif ($909C4!=\"\"){\r\n \"</p><table><tr><td class=\\\"blocknote\\\">See also:</td></tr></table>\" \r\n}\r\nforall ($909C4){\r\n \"<small><a href=\\\"\" $909C4.d \"\\\">\" $909C4.p \"</a></small><br>\"\r\n}\r\n\r\n\"</td>\"\r\n\r\n\"<td valign=\\\"top\\\">\" \r\nformat(\"_full_photo_resources\")\r\n\"</td>\" \r\n\r\n\"</tr>\r\n\r\n<tr><td colspan=\\\"2\\\" class=\\\"blocknote\\\">\r\n <strong>© CERN Geneva: </strong>\r\n<small>The use of photos requires prior authorization (from <a href=\\\"http://wpedb.cern.ch/databases/Copyright/\\\">CERN copyright</a>). \r\nThe words CERN Photo must be quoted for each use. </small>\r\n</td>\r\n</tr>\r\n\r\n</table>\r\n</p>\"','The detailed HTML format suitable for displaying pictures.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"_full_topbanner\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"_full_title\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"_full_note\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"<center>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"</center>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_contact\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:29:\"<center>Photographer: <small>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"_full_author\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:17:\"</small></center>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"_full_keyword\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:46:\"\r\n<table> <tr>\r\n<td valign=\"top\" align=\"left\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"S\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:37:\"<BR> <strong>Original ref.</strong>: \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"S\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:41:\"<BR><strong>Available pictures</strong>: \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:67:\"</p><table><tr><td class=\"blocknote\"> \r\n Caption</td></tr></table>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"<small>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"</small></p>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"590\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:68:\"</p><table><tr><td class=\"blocknote\"> \r\n Légende</td></tr></table>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"<small>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"590\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"</small></p>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:64:\"</p><table><tr><td class=\"blocknote\">See also:</td></tr></table>\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:16:\"<small><a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"D\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:16:\"</a></small><br>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</td>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:17:\"<td valign=\"top\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:21:\"_full_photo_resources\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</td>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:310:\"</tr>\r\n\r\n<tr><td colspan=\"2\" class=\"blocknote\">\r\n <strong>© CERN Geneva: </strong>\r\n<small>The use of photos requires prior authorization (from <a href=\"http://wpedb.cern.ch/databases/Copyright/\">CERN copyright</a>). \r\nThe words CERN Photo must be quoted for each use. </small>\r\n</td>\r\n</tr>\r\n\r\n</table>\r\n</p>\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxFORMATS VALUES ('PICTURE_HTML_BRIEF',' \"<hr><table width=\\\"90%\\\"> \r\n <TR> \r\n <TD valign=\\\"top\\\" align=\\\"left\\\">\"\r\n\"<b>\" format(\"_DEFAULT_TITLE\") \"</b>\"\r\nforall($246_1.a)\r\n{ \"<BR> <b><i>\" $246_1.a\" </b></i>\" } \r\nforall($260.c)\r\n{ \"<BR> \" $260.c }\r\nforall($520.a) {\r\n rep_prefix(\"<p><i>Abstract</i>: \")\r\n format(\"_DEFAULT_ABSTRACT_FIRST_SENTENCE\")\r\n \"<p>\"\r\n}\r\nforall($6531.a)\r\n{ \r\n rep_prefix(\"<BR> <i>Keyword</i>: \") \r\n link(\"KEYWORD_SEARCH\", $6531.a)\r\n { \"<a href=\\\"\"$link\"\\\">\" $6531.a \"</a>\" } separator(\", \")\r\n}\r\nforall($037.a)\r\n{\"<BR><i>Picture number</i>: \" $037.a }\r\nforall($909CP.t)\r\n{ rep_prefix(\"<BR><I>Available picture(s)</i>:\") xml_text($909CP.t) }\r\n\r\n\"</td> <TD valign=\\\"top\\\" align=\\\"right\\\"> \"\r\nforall($8564)\r\n{ if(($8564.x=\"icon\")&&($8564.u=\"\"))\r\n { \"<P> <a href=\\\"search.py?recid=\"$001\"\\\"><IMG SRC=\"rep($8564.q,\" \",\"\")\"></a>\" }\r\n}\r\n\r\n\"<BR> <font size=-2><b>© CERN Geneva</b></font>\" \r\n\"<BR> \" link(\"EXT\", $8564.u, $8564.z){ $link }\r\n\" </td>\r\n </tr>\r\n</table>\"','The brief HTML format suitable for displaying pictures.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:69:\"<hr><table width=\"90%\"> \r\n <TR> \r\n <TD valign=\"top\" align=\"left\">\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"<b>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"_DEFAULT_TITLE\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</b>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"<BR> <b><i>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" </b></i>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"<BR> \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"520\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"REP_PREFIX\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:20:\"<p><i>Abstract</i>: \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:32:\"_DEFAULT_ABSTRACT_FIRST_SENTENCE\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"<p>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"6531\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"REP_PREFIX\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:21:\"<BR> <i>Keyword</i>: \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"KEYWORD_SEARCH\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"6531\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"6531\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\", \";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:27:\"<BR><i>Picture number</i>: \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"REP_PREFIX\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:32:\"<BR><I>Available picture(s)</i>:\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"XML_TEXT\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:38:\"</td> <TD valign=\"top\" align=\"right\"> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:6;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"X\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"icon\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:29:\"<P> <a href=\"search.py?recid=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"\"><IMG SRC=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:3:\"REP\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Q\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"></a>\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:47:\"<BR> <font size=-2><b>© CERN Geneva</b></font>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"<BR> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"EXT\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Z\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:29:\" </td>\r\n </tr>\r\n</table>\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_AUTHOR','if($700.a!=\"\"||$100.a!=\"\"||$270.p!=\"\"){\r\n\r\n forall($100){\r\n LINK(\"AUTHOR_SEARCH\",$100.a){\r\n \"<a href=\\\"\"$LINK\"\\\">\"$100.a\"</a> \"\r\n if ($100.e!=\"\"){\" (\"$100.e\")\"}\r\n separator(\"; \")\r\n }\r\n }\r\n if(count($100.a)!=\"0\") \r\n { \r\n if(count($700.a)!=\"0\") \r\n { \"; \" } \r\n } \r\n forall($700){\r\n LINK(\"AUTHOR_SEARCH\",$700.a){\r\n \" <a href=\\\"\"$LINK\"\\\">\"$700.a\"</a> \"\r\n if ($700.e!=\"\"){\" (\"$700.e\")\"}\r\n separator(\"; \")\r\n }\r\n } \r\n \r\n forall($270){\r\n LINK(\"AUTHOR_SEARCH\",$270.p){\r\n \" <a href=\\\"\"$LINK\"\\\">\"$270.p\"</a> \"\r\n if ($270.g!=\"\"){\r\n \" (\"\r\n $270.g\r\n \")\"\r\n }\r\n separator(\"; \")\r\n }\r\n }\r\n \r\n} ','HTML linked author display','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"270\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"AUTHOR_SEARCH\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</a> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\")\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:17;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"AUTHOR_SEARCH\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\" <a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</a> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\")\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"270\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"AUTHOR_SEARCH\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"270\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\" <a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"270\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</a> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"270\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"G\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"270\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"G\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\")\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_AFFILIATION','if($909C1.u!=\"\"){\r\n \"<br>\"\r\n forall($909C1){\r\n $909C1.u\" \"\r\n }\r\n} \r\n','HTML Affiliation display','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"<br>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:5:\"909C1\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\" \";s:4:\"sons\";a:0:{}}}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_DATEDOC','if($260.c!=\"\"){\r\n \"<br>\"\r\n $260.c\" \r\n \"\r\n} \r\n','HTML Imprint date','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"<br>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\" \r\n \";s:4:\"sons\";a:0:{}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_IMPRINT','if($260.b!=\"\"){\r\n if($260.b!=\"sine nomine\"){\r\n \"<small>\"\r\n $260.b\r\n if($260.a!=\"\"){\r\n if($260.a!=\"sine loco\"){\": \"$260.a}\r\n }\r\n \" </small>\"\r\n }\r\n}\r\n','HTML Imprint display (not the date)','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"sine nomine\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"<small>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"sine loco\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\": \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" </small>\";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_DATEREC','if($909C1.c!=\"\"){\r\n \"<br><small><strong>Arrived: </strong>\"\r\n $909C1.c\" </small>\"\r\n}\r\n','',NULL);
INSERT INTO flxFORMATS VALUES ('_FULL_KEYWORD','forall($6531.a){\r\n REP_PREFIX(\"<br><small><strong>Keyword(s): </strong></small>\")\r\n \"<small>\"\r\n LINK(\"KEYWORD_SEARCH\",$6531.a){ \r\n \"<a href=\\\"\"$LINK\"\\\">\"$6531.a\"</a> \"\r\n separator(\";\")\r\n }\r\n \"</small>\r\n \"\r\n} \r\n','HTML keyword display with search link','O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"6531\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"REP_PREFIX\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:48:\"<br><small><strong>Keyword(s): </strong></small>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"<small>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"KEYWORD_SEARCH\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"6531\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"<a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"6531\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</a> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\";\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"</small>\r\n \";s:4:\"sons\";a:0:{}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_NOTE','if($594.p!=\"\"){\r\n \"<br><small><strong>Note: </strong>\"\r\n xml_text($594.p)\" </small>\"\r\n}\r\nif($500.a!=\"\"){\r\n \"<br><small><strong>Note: </strong>\"\r\n forall($500){xml_text($500.a)\"; \"}\r\n \"</small>\"\r\n} \r\nif($502.a!=\"\"||$909CC.r!=\"\"||$909CP.n!=\"\"||$711.a!=\"\"){\r\n \"<br><small><strong>Note: </strong>\"\r\n $502.a\" \"\r\n $909CC.r\" \"\r\n $909CC.d\" \"\r\n $909CP.n\" \"\r\n $711.a \" </small>\"\r\n} \r\nif($596.a!=\"\"){\r\n \"<br><small><strong>Notes: </strong>\"\r\n $596.a \" </small>\"\r\n} \r\n\r\n','HTML note display (various note fields)','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"594\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:34:\"<br><small><strong>Note: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"XML_TEXT\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"594\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" </small>\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"500\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:34:\"<br><small><strong>Note: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"500\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"XML_TEXT\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"500\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"; \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"</small>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CC\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"R\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"711\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:34:\"<br><small><strong>Note: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CC\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"R\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CC\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"D\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909CP\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"711\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" </small>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"596\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:35:\"<br><small><strong>Notes: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"596\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" </small>\";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_PUBLIINFO','if($909C4.p!=\"\"){ \r\n \"<br><br><strong>Published in: </strong>\"\r\n if (KB($909C4.p,\"ejournals\")!=\"\") {\r\n if ($909C4.v!=\"\") { \r\n \"<a href=\\\"http://weblib.cern.ch/cgi-bin/ejournals?publication=\" \r\n REP($909C4.p,\" \",\"+\") \r\n \"&volume=\"$909C4.v\"&year=\"$909C4.y\"&page=\"filter_pagenr($909C4.c)\"\\\">\"$909C4.p\": \"\r\n $909C4.v \" (\"$909C4.y\") \"$909C4.c \r\n \"</a> \" \r\n } else {\r\n $909C4.p\": \"\r\n if($909C4.y!=\"\"){\" (\"$909C4.y\") \"}\r\n if($909C4.n!=\"\"){\"no. \"$909C4.n\", \"}\r\n if($909C4.c!=\"\"){\"pp.\"$909C4.c }\r\n }\r\n } else {\r\n $909C4.p \": \"\r\n if($909C4.v!=\"\"){ $909C4.v }\r\n if($909C4.y!=\"\"){\" (\"$909C4.y\") \"}\r\n if($909C4.n!=\"\"){\"no. \"$909C4.n\", \"}\r\n if($909C4.c!=\"\"){\"pp.\"$909C4.c } \r\n }\r\n}\r\n','HTML publication information display possibly with link to ejournal','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:39:\"<br><br><strong>Published in: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"ejournals\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:61:\"<a href=\"http://weblib.cern.ch/cgi-bin/ejournals?publication=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:3:\"REP\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"+\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"&volume=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"&year=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"&page=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:13:\"FILTER_PAGENR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\": \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\") \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</a> \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\": \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\") \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"no. \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\", \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"pp.\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\": \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\") \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"no. \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\", \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"pp.\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}}}}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_YEAR','if ($909C0.y!=\"\"){\"<br><strong>Year: </strong>\"\r\n $909C0.y\r\n}','HTML Year display','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C0\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:27:\"<br><strong>Year: </strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C0\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_TOPBANNER','\"<table border=\\\"0\\\" width=\\\"100%\\\"><tr class=\\\"blocknote\\\"> \r\n<td valign=\\\"left\\\">\"KB($980.a,\"dbcollid2coll\")\" <small>\"\r\nif($65017.a!=\"XX\"){\r\n \" / \" $65017.a\r\n}\r\n\" \"$65027.a\r\n\"</small></td>\" \r\nforall($088){\"<td><small><strong>\"$088.a\" </strong></small></td>\"} \r\nif($037.a!=\"\"){\"<td align=\\\"right\\\"><strong>\"$037.a\"</strong></td>\"} \r\n\"</tr></table><br>\" ','HTML top page banner containing category, rep. number, etc','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:74:\"<table border=\"0\" width=\"100%\"><tr class=\"blocknote\"> \r\n<td valign=\"left\">\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"dbcollid2coll\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\" <small>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"65017\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"XX\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\" / \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"65017\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"65027\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"</small></td>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:19:\"<td><small><strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:23:\" </strong></small></td>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:26:\"<td align=\"right\"><strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"</strong></td>\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:17:\"</tr></table><br>\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxFORMATS VALUES ('_DEFAULT_URL','\"<a class=\\\"note\\\" href=\\\"\" $8564.u \"\\\">\" $8564.u \"</a>\"','This is the default format for formatting URLs.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\"<a class=\"note\" href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_URL','forall($8564)\r\n{\r\n\"<br><strong>\" $8564.z \" : </strong> <small><a href=\\\"\" $8564.u \"\\\">\" $8564.u \"</a></small>\"\r\n}','HTML URL display','O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"<br><strong>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Z\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:29:\" : </strong> <small><a href=\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"</a></small>\";s:4:\"sons\";a:0:{}}}}}}');
INSERT INTO flxFORMATS VALUES ('DEFAULT_HTML_CAPTIONS','format(\"_default_title\")','HTML \"captions only\" format','O:7:\"aelnode\":3:{s:3:\"cat\";i:13;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\"_default_title\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxFORMATS VALUES ('DEFAULT_HTML_PORTFOLIO','forall($8564)\r\n{ if(($8564.x=\"icon\")&&($8564.u=\"\"))\r\n { \"<P> <a href=\\\"search.py?recid=\"$001\"\\\"><IMG SRC=\"rep($8564.q,\" \",\"\")\"></a>\" }\r\n} ','HTML \"portfolio\" format','O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:6;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"X\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"icon\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:29:\"<P> <a href=\"search.py?recid=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"\"><IMG SRC=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:3:\"REP\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Q\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"></a>\";s:4:\"sons\";a:0:{}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_PHOTO_RESOURCES','\"<table><tr><td class=\\\"blocknote\\\">Resources</td></tr></table>\"\r\n\r\nforall($8564)\r\n{ \r\n if(($8564.x=\"icon\")&&($8564.u=\"\")) { \r\n \"<P><IMG SRC=\"rep($8564.q,\" \",\"\")\">\" \r\n }\r\n if($8564.x=\"1\") {\r\n \"<br clear=\\\"all\\\">High resolution: <a href=\\\"\" $8564.q \"\\\">\" $8564.q \"</a>\"\r\n }\r\n \r\n}\r\n\r\n\"<BR> <font size=-2><b>© CERN Geneva</b></font>\" \r\n\"<BR> \" link(\"EXT\", $8564.u, $8564.z){ $link } \r\n','Prints image and link to photo resources.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:60:\"<table><tr><td class=\"blocknote\">Resources</td></tr></table>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:6;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"X\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"icon\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"<P><IMG SRC=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:3:\"REP\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Q\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\">\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"X\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"1\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:42:\"<br clear=\"all\">High resolution: <a href=\"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Q\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Q\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:47:\"<BR> <font size=-2><b>© CERN Geneva</b></font>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"<BR> \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:14;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"EXT\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:15;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"U\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"8564\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Z\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:4:\"LINK\";s:4:\"sons\";a:0:{}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_CITEDBY','if($037.a!=\"\" || $088.a!=\"\") {\r\n \"<br><br><strong>Cited by:</strong> try citation search for \"\r\n forall($037.a) {\r\n \"<a href=\\\"search.py?f=reference&p=\" $037.a \"\\\">\" $037.a \"</a>\"\r\n separator(\";\")\r\n }\r\n if($037.a!=\"\" && $088.a!=\"\") {\r\n \" ; \"\r\n }\r\n forall($088.a) {\r\n \"<a href=\\\"search.py?f=reference&p=\" $088.a \"\\\">\" $088.a \"</a>\"\r\n separator(\";\")\r\n }\r\n}','HTML \"cited by\" link creation, based on report numbers.','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:59:\"<br><br><strong>Cited by:</strong> try citation search for \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:33:\"<a href=\"search.py?f=reference&p=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\";\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:6;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\" ; \";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:33:\"<a href=\"search.py?f=reference&p=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"</a>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"SEPARATOR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\";\";s:4:\"sons\";a:0:{}}}}}}}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_REFERENCES','if ($999C5!=\"\") {\r\n\"<blockquote>\"\r\n\"<strong>References:</strong>\"\r\n\"<ul>\" \r\nforall($999C5){ \r\n\r\nif($999C5.o!=\"\")\r\n {\"<li><small> \"$999C5.o \" </small> \"} \r\n\r\nif ($999C5.m!=\"\")\r\n {\" <small> \" $999C5.m \" </small> \"}\r\n\r\nif ($999C5.r!=\"\")\r\n {\" <small> [<a href=\\\"search.py?f=reportnumber&p=\"$999C5.r\"\\\">\"$999C5.r\"</a>] </small> <br> \"} \r\n\r\nif ($999C5.t!=\"\")\r\n {if (KB($999C5.t,\"ejournals\")!=\"\")\r\n { \r\n \" <small> <a href=\\\"http://weblib.cern.ch/cgi-bin/ejournals?publication=\" \r\nREP($999C5.t,\" \",\"+\") \r\n \"&volume=\"$999C5.v\"&year=\"$999C5.y\"&page=\"filter_pagenr($999C5.p)\"\\\">\"$999C5.t\": \"$999C5.v\" (\"$999C5.y\") \"$999C5.p \r\n \"</a> </small> <br>\"\r\n } \r\n else\r\n {\" <small> \" $999C5.t\" \"$999C5.v\" \"$999C5.y\" \"$999C5.p \" </small> <br>\"\r\n }\r\n }\r\n\r\n} \r\n\"</ul>\"\r\n\r\n\"<p><small><i><b>Warning</b>: references are automatically extracted and standardized from the PDF document and may therefore contain errors. If you think they are incorrect or incomplete, look at the fulltext document itself.<br></i></small>\"\r\n\"</blockquote>\"\r\n}','HTML references','O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"<blockquote>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:28:\"<strong>References:</strong>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"<ul>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"O\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:12:\"<li><small> \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"O\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\" </small> \";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"M\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" <small> \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"M\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\" </small> \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"R\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:46:\" <small> [<a href=\"search.py?f=reportnumber&p=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"R\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"R\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:20:\"</a>] </small> <br> \";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"ejournals\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:70:\" <small> <a href=\"http://weblib.cern.ch/cgi-bin/ejournals?publication=\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:3:\"REP\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"+\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:8:\"&volume=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"&year=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"&page=\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:13:\"FILTER_PAGENR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"\">\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\": \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\" (\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\") \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:18:\"</a> </small> <br>\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\" <small> \";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"T\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\" \";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"999C5\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:14:\" </small> <br>\";s:4:\"sons\";a:0:{}}}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"</ul>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:241:\"<p><small><i><b>Warning</b>: references are automatically extracted and standardized from the PDF document and may therefore contain errors. If you think they are incorrect or incomplete, look at the fulltext document itself.<br></i></small>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"</blockquote>\";s:4:\"sons\";a:0:{}}}}}}');
INSERT INTO flxFORMATS VALUES ('_FULL_BIBTEX','\"<pre>\"\r\n\"@\" \r\n\r\nif (kb($980.a, \"DBCOLLID2BIBTEX\") = \"\"){\r\n \"article\"\r\n}else{\r\n kb($980.a, \"DBCOLLID2BIBTEX\")\r\n}\r\n\r\n\"{\"\r\n\r\nif($100.a != \"\"){\r\n GET_NAME($100.a) \":\" $001 \",<br>\"\r\n}else{\r\n if($700.a != \"\"){\r\n GET_NAME($700.a) \":\" $001 \",<br>\"\r\n }else{\r\n if($037.a != \"\"){\r\n $037.a \",<br>\"\r\n }else{\r\n if($088.a != \"\"){\r\n $088.a \",<br>\"\r\n }else{\r\n if($245.a != \"\"){\r\n GET_NAME($245.a) \":\" $001 \",<br>\"\r\n }else{\r\n $001 \",<br>\"\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"article\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"book\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"inproceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"misc\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"phdthesis\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"techreport\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"unpublished\"){\r\n if ($100.a != \"\" || $700.a != \"\" || $110.b != \"\" || $110.a != \"\" || $710.a != \"\"){\r\n STR_BUFFER(\"add\",\" author = \\\"\", \"0\", \"0\")\r\n\r\n if($100.a != \"\"){\r\n STR_BUFFER(\"add\", $100.a \" and \", \"0\", \"0\")\r\n }\r\n\r\n forall($700.a){\r\n if ($700.e != \"ed.\"){\r\n STR_BUFFER(\"add\", $700.a \" and \", \"0\", \"0\")\r\n }\r\n }\r\n\r\n forall($110.b){\r\n STR_BUFFER(\"add\", $110.b \" and \", \"0\", \"0\")\r\n }\r\n\r\n forall($110.a){\r\n STR_BUFFER(\"add\", $110.a \" and \", \"0\", \"0\")\r\n }\r\n\r\n forall($710.a){\r\n STR_BUFFER(\"add\", $710.a \" and \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"5\", \"22\"), \"72\", \"22\")\r\n }else{\r\n SPLIT_LINE(\" key = \\\"\" $001 \"\\\",<br>\", \"72\", \"22\")\r\n }\r\n}\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"inproceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"proceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"phdthesis\"){\r\n if ($700.a != \"\"){\r\n STR_BUFFER(\"add\", \" editor = \\\"\", \"0\", \"0\")\r\n\r\n forall($700){\r\n if ($700.e = \"ed.\"){\r\n STR_BUFFER(\"add\", $700.a \" and \", \"0\", \"0\")\r\n }\r\n }\r\n \r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"5\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif ($245.a != \"\" || $245.b != \"\" || $246.a != \"\" || $246_1.a != \"\"){\r\n\r\n STR_BUFFER(\"add\", \" title = \\\"\", \"0\", \"0\")\r\n\r\n if($245.a != \"\"){\r\n STR_BUFFER(\"add\", $245.a \". \", \"0\", \"0\")\r\n }\r\n\r\n if($245.b != \"\"){\r\n STR_BUFFER(\"add\", $245.b \". \", \"0\", \"0\")\r\n }\r\n\r\n if($246.a != \"\"){\r\n STR_BUFFER(\"add\", $246.a \". \", \"0\", \"0\")\r\n }\r\n\r\n if($246_1.a != \"\"){\r\n STR_BUFFER(\"add\", $246_1.a \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n}\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"techreport\"){\r\n if ($269.b != \"\"){\r\n SPLIT_LINE(\" institution = \\\"\" $269.b \"\\\",<br>\", \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"inproceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"proceedings\"){\r\n if ($260.b != \"\" || $269.b != \"\"){\r\n\r\n STR_BUFFER(\"add\", \" organization = \\\"\", \"0\", \"0\")\r\n\r\n if($260.b != \"\"){\r\n STR_BUFFER(\"add\", $260.b \". \", \"0\", \"0\")\r\n }\r\n\r\n if($269.b != \"\"){\r\n STR_BUFFER(\"add\", $269.b \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"book\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"inproceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"proceedings\"){\r\n if ($260.b != \"\" || $269.b != \"\" || $933.b != \"\" || $934.b != \"\"){\r\n\r\n STR_BUFFER(\"add\", \" publisher = \\\"\", \"0\", \"0\")\r\n\r\n if($260.b != \"\"){\r\n STR_BUFFER(\"add\", $260.b \". \", \"0\", \"0\")\r\n }\r\n\r\n if($269.b != \"\"){\r\n STR_BUFFER(\"add\", $269.b \". \", \"0\", \"0\")\r\n }\r\n\r\n if($933.b != \"\"){\r\n STR_BUFFER(\"add\", $933.b \". \", \"0\", \"0\")\r\n }\r\n\r\n if($934.b != \"\"){\r\n STR_BUFFER(\"add\", $934.b \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"article\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"\"){\r\n if ($773.p != \"\" || $909C4.p != \"\"){\r\n STR_BUFFER(\"add\", \" journal = \\\"\", \"0\", \"0\")\r\n\r\n if($909C4.p != \"\"){\r\n STR_BUFFER(\"add\", $909C4.p \". \", \"0\", \"0\")\r\n }\r\n\r\n if($773.p != \"\"){\r\n STR_BUFFER(\"add\", $773.p \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n\r\n }\r\n}\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"phdthesis\"){\r\n if ($502.b != \"\"){\r\n SPLIT_LINE(\" school = \\\"\" $502.b \"\\\",<br>\", \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"book\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"inproceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"proceedings\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"phdthesis\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"techreport\"){\r\n if ($260.a != \"\" || $269.a != \"\" || $933.a != \"\" || $934.a != \"\"){\r\n STR_BUFFER(\"add\", \" address = \\\"\", \"0\", \"0\")\r\n\r\n if($260.a != \"\"){\r\n STR_BUFFER(\"add\", $260.a \". \", \"0\", \"0\")\r\n }\r\n\r\n forall($269.a){\r\n STR_BUFFER(\"add\", $269.a \". \", \"0\", \"0\")\r\n }\r\n\r\n forall($933.a){\r\n STR_BUFFER(\"add\", $933.a \". \", \"0\", \"0\")\r\n }\r\n\r\n forall($934.a){\r\n STR_BUFFER(\"add\", $934.a \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"article\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"techreport\"){\r\n if ($037.a != \"\" || $088.a != \"\" || $773.n != \"\" || $909C4.n){\r\n\r\n STR_BUFFER(\"add\", \" number = \\\"\", \"0\", \"0\")\r\n\r\n if($037.a != \"\"){\r\n STR_BUFFER(\"add\", $037.a \". \", \"0\", \"0\")\r\n }\r\n\r\n forall($088.a) {\r\n if($088.a != \"\"){\r\n STR_BUFFER(\"add\", $088.a \". \", \"0\", \"0\")\r\n }\r\n }\r\n\r\n if($773.n != \"\"){\r\n STR_BUFFER(\"add\", $773.n \". \", \"0\", \"0\")\r\n }\r\n\r\n if($909C4.n != \"\"){\r\n STR_BUFFER(\"add\", $909C4.n \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"article\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"book\"){\r\n if ($773.v != \"\" || $909C4.v != \"\"){\r\n\r\n STR_BUFFER(\"add\",\" volume = \\\"\", \"0\", \"0\")\r\n\r\n if($909C4.v != \"\"){\r\n STR_BUFFER(\"add\", $909C4.v \". \", \"0\", \"0\")\r\n }\r\n\r\n if($773.v != \"\"){\r\n STR_BUFFER(\"add\", $773.v \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"book\"){\r\n if ($490.a != \"\"){\r\n SPLIT_LINE(\" series = \\\"\" $490.a \"\\\",<br>\", \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\nif (KB($980.a, \"DBCOLLID2BIBTEX\") = \"article\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"\" || KB($980.a, \"DBCOLLID2BIBTEX\") = \"inproceedings\"){\r\n if ($773.c != \"\" || $909C4.c != \"\" || $300.a != \"\"){\r\n\r\n STR_BUFFER(\"add\", \" pages = \\\"\", \"0\", \"0\")\r\n\r\n if($773.c != \"\"){\r\n STR_BUFFER(\"add\", $773.c \". \", \"0\", \"0\")\r\n }\r\n\r\n if($909C4.c != \"\"){\r\n STR_BUFFER(\"add\", $909C4.c \". \", \"0\", \"0\")\r\n }\r\n\r\n if($300.a != \"\"){\r\n STR_BUFFER(\"add\", $300.a \". \", \"0\", \"0\")\r\n }\r\n\r\n SPLIT_LINE(STR_BUFFER(\"print\", \"\\\",<br>\", \"2\", \"22\"), \"72\", \"22\")\r\n }\r\n}\r\n\r\n\r\n\r\nSTR_BUFFER(\"add\", \" month = \\\"\", \"0\", \"0\")\r\nif($269.c != \"\"){\r\n STR_BUFFER(\"add\", GET_MONTH($269.c), \"0\", \"0\")\r\n}else{\r\n if($260.c != \"\"){\r\n STR_BUFFER(\"add\", GET_MONTH($260.c), \"0\", \"0\")\r\n }else{\r\n if($502.c != \"\"){\r\n STR_BUFFER(\"add\", GET_MONTH($502.c), \"0\", \"0\")\r\n }\r\n }\r\n}\r\nSTR_BUFFER(\"print\", \"\\\",<br>\", \"0\", \"22\")\r\n\r\n\r\nSTR_BUFFER(\"add\", \" year = \\\"\", \"0\", \"0\")\r\nif($269.c != \"\"){\r\n STR_BUFFER(\"add\", GET_YEAR($269.c), \"0\", \"0\")\r\n}else{\r\n if($260.c != \"\"){\r\n STR_BUFFER(\"add\", GET_YEAR($260.c), \"0\", \"0\")\r\n }else{\r\n if($502.c != \"\"){\r\n STR_BUFFER(\"add\", GET_YEAR($502.c), \"0\", \"0\")\r\n }else{\r\n if($909C0.y != \"\"){\r\n STR_BUFFER(\"add\", GET_YEAR($909C0.y), \"0\", \"0\") \r\n }\r\n }\r\n }\r\n}\r\nSTR_BUFFER(\"print\", \"\\\",<br>\", \"0\", \"22\")\r\n\r\n\r\n\r\nif ($500.a != \"\"){\r\n SPLIT_LINE(\" note = \\\"\" $500.a \"\\\",<br>\", \"72\", \"22\")\r\n}\r\n\r\n\"}\"\r\n\"</pre>\"','Creates BibTeX format for a record.','O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"<pre>\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"@\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"article\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"{\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_NAME\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\":\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\",<br>\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_NAME\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\":\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\",<br>\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\",<br>\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\",<br>\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_NAME\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\":\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\",<br>\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\",<br>\";s:4:\"sons\";a:0:{}}}}}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"article\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"book\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"inproceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"misc\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"phdthesis\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"techreport\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"unpublished\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"110\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"110\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"710\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" author = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"100\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" and \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"ed.\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" and \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"110\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"110\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" and \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"110\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"110\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" and \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"710\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"710\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" and \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"5\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" key = \"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"001\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"inproceedings\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"proceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"phdthesis\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" editor = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:3:{i:0;N;i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"E\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"ed.\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"700\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\" and \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"5\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"246\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" title = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"245\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"246\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"246\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"246_1\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"techreport\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" institution = \"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"inproceedings\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"proceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" organization = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"book\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"inproceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"proceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"933\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"934\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" publisher = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"933\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"933\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"934\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"934\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"article\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" journal = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"P\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"phdthesis\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" school = \"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"B\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"book\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"inproceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:11:\"proceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:9:\"phdthesis\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"techreport\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"933\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"934\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" address = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"933\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"933\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"934\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"934\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"article\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:10:\"techreport\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" number = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"037\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:3;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}i:1;N;i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"088\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"N\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"article\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"book\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" volume = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"V\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:4:\"book\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"490\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" series = \"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"490\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:7:\"article\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:7;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:16;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:15:\"DBCOLLID2BIBTEX\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"980\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:13:\"inproceedings\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:5;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"300\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" pages = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"773\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C4\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"300\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"300\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\". \";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"2\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" month = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"GET_MONTH\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"GET_MONTH\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:9:\"GET_MONTH\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" year = \"\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_YEAR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"269\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_YEAR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"260\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_YEAR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"502\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"C\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C0\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:3:\"add\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:8:\"GET_YEAR\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:5:\"909C0\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"Y\";s:4:\"sons\";a:0:{}}}}}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}}}}}}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"STR_BUFFER\";s:4:\"sons\";a:4:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:5:\"print\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"0\";s:4:\"sons\";a:0:{}}i:3;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:4;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:8;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"500\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:2;s:3:\"lex\";s:10:\"SPLIT_LINE\";s:4:\"sons\";a:3:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:11;s:3:\"lex\";s:0:\"\";s:4:\"sons\";a:2:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:22:\" note = \"\";s:4:\"sons\";a:0:{}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:0;s:3:\"lex\";s:3:\"500\";s:4:\"sons\";a:1:{i:0;O:7:\"aelnode\":3:{s:3:\"cat\";i:12;s:3:\"lex\";s:1:\"A\";s:4:\"sons\";a:0:{}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"\",<br>\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"72\";s:4:\"sons\";a:0:{}}i:2;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:2:\"22\";s:4:\"sons\";a:0:{}}}}}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:1:\"}\";s:4:\"sons\";a:0:{}}}}i:1;O:7:\"aelnode\":3:{s:3:\"cat\";i:1;s:3:\"lex\";s:6:\"</pre>\";s:4:\"sons\";a:0:{}}}}');
INSERT INTO flxKBS VALUES ('DBCOLLID2COLL','flxKBDBCOLLID2COLL','DbCollID to Coll name correspondance.');
INSERT INTO flxKBS VALUES ('EJOURNALS','flxKBEJOURNALS','Knowledge base of all known electronic journals. Useful for reference linking.');
INSERT INTO flxKBS VALUES ('DBCOLLID2BIBTEX','flxKBDBCOLLID2BIBTEX','Mapping between the 980 field and BibTeX entry types.');
INSERT INTO flxKBDBCOLLID2COLL VALUES ('ARTICLE','Published Article');
INSERT INTO flxKBDBCOLLID2COLL VALUES ('PREPRINT','Preprint');
INSERT INTO flxKBDBCOLLID2COLL VALUES ('THESIS','Thesis');
INSERT INTO flxKBDBCOLLID2COLL VALUES ('BOOK','Book');
INSERT INTO flxKBDBCOLLID2COLL VALUES ('REPORT','Report');
INSERT INTO flxKBDBCOLLID2COLL VALUES ('PICTURE','Pictures');
INSERT INTO flxKBEJOURNALS VALUES ('AAS Photo Bull.','AAS Photo Bull.');
INSERT INTO flxKBEJOURNALS VALUES ('Accredit. Qual. Assur.','Accredit. Qual. Assur.');
INSERT INTO flxKBEJOURNALS VALUES ('Acoust. Phys.','Acoust. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Acoust. Res. Lett.','Acoust. Res. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Acta Astron.','Acta Astron.');
INSERT INTO flxKBEJOURNALS VALUES ('Adv. Comput. Math.','Adv. Comput. Math.');
INSERT INTO flxKBEJOURNALS VALUES ('Aequ. Math.','Aequ. Math.');
INSERT INTO flxKBEJOURNALS VALUES ('Afr. Skies','Afr. Skies');
INSERT INTO flxKBEJOURNALS VALUES ('Algorithmica','Algorithmica');
INSERT INTO flxKBEJOURNALS VALUES ('Am. J. Phys.','Am. J. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Ann. Phys.','Ann. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Annu. Rev. Astron. Astrophys.','Annu. Rev. Astron. Astrophys.');
INSERT INTO flxKBEJOURNALS VALUES ('Annu. Rev. Earth Planet. Sci.','Annu. Rev. Earth Planet. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Appl. Phys. Lett.','Appl. Phys. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Appl. Phys., A','Appl. Phys., A');
INSERT INTO flxKBEJOURNALS VALUES ('Appl. Phys., B','Appl. Phys., B');
INSERT INTO flxKBEJOURNALS VALUES ('Appl. Radiat. Isot.','Appl. Radiat. Isot.');
INSERT INTO flxKBEJOURNALS VALUES ('Appl. Surf. Sci.','Appl. Surf. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Arch. Appl. Mech.','Arch. Appl. Mech.');
INSERT INTO flxKBEJOURNALS VALUES ('Arch. Envir. Contam. Toxicol.','Arch. Envir. Contam. Toxicol.');
INSERT INTO flxKBEJOURNALS VALUES ('Arch. Rational Mech. Analys.','Arch. Rational Mech. Analys.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. Astrophys. Rev.','Astron. Astrophys. Rev.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. Astrophys.','Astron. Astrophys.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. Astrophys., Suppl.','Astron. Astrophys., Suppl.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. J.','Astron. J.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. Lett.','Astron. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. Nachr.','Astron. Nachr.');
INSERT INTO flxKBEJOURNALS VALUES ('Astron. Rep.','Astron. Rep.');
INSERT INTO flxKBEJOURNALS VALUES ('Astropart. Phys.','Astropart. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Astrophys. J.','Astrophys. J.');
INSERT INTO flxKBEJOURNALS VALUES ('Astrophys. Norvegica','Astrophys. Norvegica');
INSERT INTO flxKBEJOURNALS VALUES ('Balt. Astron.','Balt. Astron.');
INSERT INTO flxKBEJOURNALS VALUES ('Bioimaging','Bioimaging');
INSERT INTO flxKBEJOURNALS VALUES ('Biol. Cybern.','Biol. Cybern.');
INSERT INTO flxKBEJOURNALS VALUES ('Bull. Astron. Belgrade','Bull. Astron. Belgrade');
INSERT INTO flxKBEJOURNALS VALUES ('Bull. Astron. Inst. Czech.','Bull. Astron. Inst. Czech.');
INSERT INTO flxKBEJOURNALS VALUES ('Bull. Astron. Soc. India','Bull. Astron. Soc. India');
INSERT INTO flxKBEJOURNALS VALUES ('Bull. Eng. Geol. Environ.','Bull. Eng. Geol. Environ.');
INSERT INTO flxKBEJOURNALS VALUES ('Bull. Environ. Contam. Toxicol.','Bull. Environ. Contam. Toxicol.');
INSERT INTO flxKBEJOURNALS VALUES ('Calc. Var. Partial Differ. Equ.','Calc. Var. Partial Differ. Equ.');
INSERT INTO flxKBEJOURNALS VALUES ('Chaos','Chaos');
INSERT INTO flxKBEJOURNALS VALUES ('Chaos Solitons Fractals','Chaos Solitons Fractals');
INSERT INTO flxKBEJOURNALS VALUES ('Chem. Phys.','Chem. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Chem. Phys. Lett.','Chem. Phys. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Chin. Astron. Astrophys.','Chin. Astron. Astrophys.');
INSERT INTO flxKBEJOURNALS VALUES ('Chin. J. Astron. Astrophys.','Chin. J. Astron. Astrophys.');
INSERT INTO flxKBEJOURNALS VALUES ('Class. Quantum Gravity','Class. Quantum Gravity');
INSERT INTO flxKBEJOURNALS VALUES ('Clim. Dyn.','Clim. Dyn.');
INSERT INTO flxKBEJOURNALS VALUES ('Colloid Polym. Sci.','Colloid Polym. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Combinatorica','Combinatorica');
INSERT INTO flxKBEJOURNALS VALUES ('Combust. Theory Model.','Combust. Theory Model.');
INSERT INTO flxKBEJOURNALS VALUES ('Commun. Math. Phys.','Commun. Math. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Comment. Math. Helv.','Comment. Math. Helv.');
INSERT INTO flxKBEJOURNALS VALUES ('Comput. Mech.','Comput. Mech.');
INSERT INTO flxKBEJOURNALS VALUES ('Comput. Phys.','Comput. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Comput. Phys. Commun.','Comput. Phys. Commun.');
INSERT INTO flxKBEJOURNALS VALUES ('Comput. Sci. Eng.','Comput. Sci. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('Comput. Vis. Sci.','Comput. Vis. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Computing','Computing');
INSERT INTO flxKBEJOURNALS VALUES ('Constr. Approx.','Constr. Approx.');
INSERT INTO flxKBEJOURNALS VALUES ('Contin. Mech. Thermodyn.','Contin. Mech. Thermodyn.');
INSERT INTO flxKBEJOURNALS VALUES ('Contrib. Astron. Obs. Skaln. Pleso','Contrib. Astron. Obs. Skaln. Pleso');
INSERT INTO flxKBEJOURNALS VALUES ('Contrib. Astron. Obs. Skaln. Pleso Suppl.','Contrib. Astron. Obs. Skaln. Pleso Suppl.');
INSERT INTO flxKBEJOURNALS VALUES ('Cryogenics','Cryogenics');
INSERT INTO flxKBEJOURNALS VALUES ('Crystallogr. Rep.','Crystallogr. Rep.');
INSERT INTO flxKBEJOURNALS VALUES ('Curr. Appl. Phys.','Curr. Appl. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Curr. Opin. Solid State Mater. Sci.','Curr. Opin. Solid State Mater. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Discret. Comput. Geom.','Discret. Comput. Geom.');
INSERT INTO flxKBEJOURNALS VALUES ('Displays','Displays');
INSERT INTO flxKBEJOURNALS VALUES ('Distrib. Comput.','Distrib. Comput.');
INSERT INTO flxKBEJOURNALS VALUES ('Distrib. Syst. Eng.','Distrib. Syst. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('Dokl. Phys.','Dokl. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Electrochem. Solid State Lett.','Electrochem. Solid State Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Electron. Lett.','Electron. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Elem. Math.','Elem. Math.');
INSERT INTO flxKBEJOURNALS VALUES ('Environ. Geol.','Environ. Geol.');
INSERT INTO flxKBEJOURNALS VALUES ('Environ. Manage.','Environ. Manage.');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Biophys. J. Biophys. Lett.','Eur. Biophys. J. Biophys. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. J. Phys.','Eur. J. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Phys. J., A','Eur. Phys. J., A');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Phys. J., Appl. Phys.','Eur. Phys. J., Appl. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Phys. J., B','Eur. Phys. J., B');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Phys. J., C','Eur. Phys. J., C');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Phys. J., D','Eur. Phys. J., D');
INSERT INTO flxKBEJOURNALS VALUES ('Eur. Phys. J., E','Eur. Phys. J., E');
INSERT INTO flxKBEJOURNALS VALUES ('Europhys. Lett.','Europhys. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Europhys. News','Europhys. News');
INSERT INTO flxKBEJOURNALS VALUES ('Exp. Fluids','Exp. Fluids');
INSERT INTO flxKBEJOURNALS VALUES ('Few-Body Syst.','Few-Body Syst.');
INSERT INTO flxKBEJOURNALS VALUES ('Finan. Stoch.','Finan. Stoch.');
INSERT INTO flxKBEJOURNALS VALUES ('Fluid Dyn. Res.','Fluid Dyn. Res.');
INSERT INTO flxKBEJOURNALS VALUES ('Geom. Funct. Anal.','Geom. Funct. Anal.');
INSERT INTO flxKBEJOURNALS VALUES ('Heat Mass Transf.','Heat Mass Transf.');
INSERT INTO flxKBEJOURNALS VALUES ('High Energy Phys. Libr. Webzine','High Energy Phys. Libr. Webzine');
INSERT INTO flxKBEJOURNALS VALUES ('High Perform. Polym.','High Perform. Polym.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Circ. Devices Syst.','IEE Proc., Circ. Devices Syst.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Commun.','IEE Proc., Commun.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Comput. Digit. Tech.','IEE Proc., Comput. Digit. Tech.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Control Theory Appl.','IEE Proc., Control Theory Appl.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Electr. Power Appl.','IEE Proc., Electr. Power Appl.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Gener. Transm. Distrib.','IEE Proc., Gener. Transm. Distrib.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Microw. Antennas Propag.','IEE Proc., Microw. Antennas Propag.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Optoelectron.','IEE Proc., Optoelectron.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Radar, Sonar Navig.','IEE Proc., Radar, Sonar Navig.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Sci. Meas. Technol.','IEE Proc., Sci. Meas. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Softw. Eng.','IEE Proc., Softw. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('IEE Proc., Vis. Image Signal Process.','IEE Proc., Vis. Image Signal Process.');
INSERT INTO flxKBEJOURNALS VALUES ('Image Vis. Comput.','Image Vis. Comput.');
INSERT INTO flxKBEJOURNALS VALUES ('Inform. Forsch. Entwickl.','Inform. Forsch. Entwickl.');
INSERT INTO flxKBEJOURNALS VALUES ('Inform. Spektr.','Inform. Spektr.');
INSERT INTO flxKBEJOURNALS VALUES ('Infrared Phys. Technol.','Infrared Phys. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('Int. J. Digit. Libr.','Int. J. Digit. Libr.');
INSERT INTO flxKBEJOURNALS VALUES ('Int. J. Doc. Anal. Recogn.','Int. J. Doc. Anal. Recogn.');
INSERT INTO flxKBEJOURNALS VALUES ('Int. J. Nonlinear Mech.','Int. J. Nonlinear Mech.');
INSERT INTO flxKBEJOURNALS VALUES ('Int. J. Softw. Tools Technol. Transf.','Int. J. Softw. Tools Technol. Transf.');
INSERT INTO flxKBEJOURNALS VALUES ('Invent. Math.','Invent. Math.');
INSERT INTO flxKBEJOURNALS VALUES ('Inverse Probl.','Inverse Probl.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Acoust. Soc. Am.','J. Acoust. Soc. Am.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Aerosp. Eng.','J. Aerosp. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Alloys. Compounds','J. Alloys. Compounds');
INSERT INTO flxKBEJOURNALS VALUES ('J. Am. Assoc. Var. Star Obs.','J. Am. Assoc. Var. Star Obs.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Appl. Mech.','J. Appl. Mech.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Appl. Phys.','J. Appl. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Atmos. Solar Terrest. Phys.','J. Atmos. Solar Terrest. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Br. Astron. Assoc.','J. Br. Astron. Assoc.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Chem. Phys.','J. Chem. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Classif.','J. Classif.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Comput. Inf. Sci. Eng.','J. Comput. Inf. Sci. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Constr. Eng. Manage.','J. Constr. Eng. Manage.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Cryptol.','J. Cryptol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Cryst. Growth','J. Cryst. Growth');
INSERT INTO flxKBEJOURNALS VALUES ('J. Dyn. Syst. Meas. Control','J. Dyn. Syst. Meas. Control');
INSERT INTO flxKBEJOURNALS VALUES ('J. Electrochem. Soc.','J. Electrochem. Soc.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Electron Spectrosc. Relat. Phen.','J. Electron Spectrosc. Relat. Phen.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Electron. Imaging','J. Electron. Imaging');
INSERT INTO flxKBEJOURNALS VALUES ('J. Electron. Packag.','J. Electron. Packag.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Energy Eng.','J. Energy Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Energy Resour. Technol.','J. Energy Resour. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Eng. Mater. Technol.','J. Eng. Mater. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Eng. Mech.','J. Eng. Mech.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Environ. Eng.','J. Environ. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Exp. Theor. Phys., JETP','J. Exp. Theor. Phys., JETP');
INSERT INTO flxKBEJOURNALS VALUES ('J. Fluids Eng.','J. Fluids Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Geom. Phys.','J. Geom. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Heat Transf.','J. Heat Transf.');
INSERT INTO flxKBEJOURNALS VALUES ('J. High Energy Phys.','J. High Energy Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Korean Astron. Soc.','J. Korean Astron. Soc.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Lumin.','J. Lumin.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Magn. Magn. Mater.','J. Magn. Magn. Mater.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Manage. Eng.','J. Manage. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Manuf. Sci. Eng.','J. Manuf. Sci. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Mater. Civ. Eng.','J. Mater. Civ. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Math. Biol.','J. Math. Biol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Math. Phys.','J. Math. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Mech. Des.','J. Mech. Des.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Micromech. Microeng.','J. Micromech. Microeng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Opt.','J. Opt.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys., A','J. Phys., A');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys., B','J. Phys., B');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys., Condens. Matter','J. Phys., Condens. Matter');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys., D','J. Phys., D');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys., G','J. Phys., G');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys. I','J. Phys. I');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys. II','J. Phys. II');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys. III','J. Phys. III');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys. Chem. Ref. Data','J. Phys. Chem. Ref. Data');
INSERT INTO flxKBEJOURNALS VALUES ('J. Phys. Chem. Solids','J. Phys. Chem. Solids');
INSERT INTO flxKBEJOURNALS VALUES ('J. Quant. Spectrosc. Radiat. Transf.','J. Quant. Spectrosc. Radiat. Transf.');
INSERT INTO flxKBEJOURNALS VALUES ('J. R. Astron. Soc. Can.','J. R. Astron. Soc. Can.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Radio. Prot.','J. Radio. Prot.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Rheol.','J. Rheol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Solar Energy Eng.','J. Solar Energy Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Solid State Electrochem.','J. Solid State Electrochem.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Struct. Eng.','J. Struct. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Surv. Eng.','J. Surv. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Tribol.','J. Tribol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Turbomach.','J. Turbomach.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Vac. Sci. Technol.','J. Vac. Sci. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('J. Vac. Sci. Technol., A','J. Vac. Sci. Technol., A');
INSERT INTO flxKBEJOURNALS VALUES ('J. Vac. Sci. Technol., B','J. Vac. Sci. Technol., B');
INSERT INTO flxKBEJOURNALS VALUES ('J. Vib. Acoust.','J. Vib. Acoust.');
INSERT INTO flxKBEJOURNALS VALUES ('JETP','JETP');
INSERT INTO flxKBEJOURNALS VALUES ('JETP Lett.','JETP Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Low Temp. Phys.','Low Temp. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Mach. Vis. Appl.','Mach. Vis. Appl.');
INSERT INTO flxKBEJOURNALS VALUES ('Mater. Res. Innov.','Mater. Res. Innov.');
INSERT INTO flxKBEJOURNALS VALUES ('Mater. Sci. Eng., B','Mater. Sci. Eng., B');
INSERT INTO flxKBEJOURNALS VALUES ('Math. Ann.','Math. Ann.');
INSERT INTO flxKBEJOURNALS VALUES ('Math. Model. Numer. Anal.','Math. Model. Numer. Anal.');
INSERT INTO flxKBEJOURNALS VALUES ('Math. Program.','Math. Program.');
INSERT INTO flxKBEJOURNALS VALUES ('Math. Z.','Math. Z.');
INSERT INTO flxKBEJOURNALS VALUES ('Meas. Sci. Technol.','Meas. Sci. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('Med. Phys.','Med. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Meteorit. Planet. Sci.','Meteorit. Planet. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Microelectron. Eng.','Microelectron. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('Micron','Micron');
INSERT INTO flxKBEJOURNALS VALUES ('Microsc. Microanal.','Microsc. Microanal.');
INSERT INTO flxKBEJOURNALS VALUES ('Microsyst. Technol.','Microsyst. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('Mon. Not. R. Astron. Soc.','Mon. Not. R. Astron. Soc.');
INSERT INTO flxKBEJOURNALS VALUES ('Multim. Syst.','Multim. Syst.');
INSERT INTO flxKBEJOURNALS VALUES ('Nanotech.','Nanotech.');
INSERT INTO flxKBEJOURNALS VALUES ('Naturwiss.','Naturwiss.');
INSERT INTO flxKBEJOURNALS VALUES ('Network','Network');
INSERT INTO flxKBEJOURNALS VALUES ('New Astron.','New Astron.');
INSERT INTO flxKBEJOURNALS VALUES ('New Astron. Rev.','New Astron. Rev.');
INSERT INTO flxKBEJOURNALS VALUES ('Nonlinearity','Nonlinearity');
INSERT INTO flxKBEJOURNALS VALUES ('Nucl. Instrum. Methods Phys. Res., A','Nucl. Instrum. Methods Phys. Res., A');
INSERT INTO flxKBEJOURNALS VALUES ('Nucl. Instrum. Methods Phys. Res., B','Nucl. Instrum. Methods Phys. Res., B');
INSERT INTO flxKBEJOURNALS VALUES ('Nucl. Phys. B, Proc. Suppl.','Nucl. Phys. B, Proc. Suppl.');
INSERT INTO flxKBEJOURNALS VALUES ('Nucl. Phys., A','Nucl. Phys., A');
INSERT INTO flxKBEJOURNALS VALUES ('Nucl. Phys., B','Nucl. Phys., B');
INSERT INTO flxKBEJOURNALS VALUES ('Num. Math.','Num. Math.');
INSERT INTO flxKBEJOURNALS VALUES ('Nuovo Cimento, A','Nuovo Cimento, A');
INSERT INTO flxKBEJOURNALS VALUES ('Nuovo Cimento, B','Nuovo Cimento, B');
INSERT INTO flxKBEJOURNALS VALUES ('Nuovo Cimento, C','Nuovo Cimento, C');
INSERT INTO flxKBEJOURNALS VALUES ('Nuovo Cimento, D','Nuovo Cimento, D');
INSERT INTO flxKBEJOURNALS VALUES ('Obs.','Obs.');
INSERT INTO flxKBEJOURNALS VALUES ('Opt. Commun.','Opt. Commun.');
INSERT INTO flxKBEJOURNALS VALUES ('Opt. Eng.','Opt. Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('Opt. Lasers Eng.','Opt. Lasers Eng.');
INSERT INTO flxKBEJOURNALS VALUES ('Opt. Mater.','Opt. Mater.');
INSERT INTO flxKBEJOURNALS VALUES ('Opt. Spectrosc.','Opt. Spectrosc.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. At. Nucl.','Phys. At. Nucl.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Chem. Miner.','Phys. Chem. Miner.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Educ.','Phys. Educ.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Fluids','Phys. Fluids');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Fluids, A','Phys. Fluids, A');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Fluids, B','Phys. Fluids, B');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Lett., A','Phys. Lett., A');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Lett., B','Phys. Lett., B');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Med. Biol.','Phys. Med. Biol.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Part. Nucl.','Phys. Part. Nucl.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Plasmas','Phys. Plasmas');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rep.','Phys. Rep.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev., A','Phys. Rev., A');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev., B','Phys. Rev., B');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev., C','Phys. Rev., C');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev., D','Phys. Rev., D');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev., E','Phys. Rev., E');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev., ser. 1','Phys. Rev., ser. 1');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev. Lett.','Phys. Rev. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev. Spec. Top. Accel. Beams','Phys. Rev. Spec. Top. Accel. Beams');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Rev.','Phys. Rev.');
INSERT INTO flxKBEJOURNALS VALUES ('Phys. Solid State','Phys. Solid State');
INSERT INTO flxKBEJOURNALS VALUES ('Physica, A','Physica, A');
INSERT INTO flxKBEJOURNALS VALUES ('Physica, B','Physica, B');
INSERT INTO flxKBEJOURNALS VALUES ('Physica, C','Physica, C');
INSERT INTO flxKBEJOURNALS VALUES ('Physica, D','Physica, D');
INSERT INTO flxKBEJOURNALS VALUES ('Physica, E','Physica, E');
INSERT INTO flxKBEJOURNALS VALUES ('Physiol. Meas.','Physiol. Meas.');
INSERT INTO flxKBEJOURNALS VALUES ('Planet. Space Sci.','Planet. Space Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Plasma Phys. Control. Fusion','Plasma Phys. Control. Fusion');
INSERT INTO flxKBEJOURNALS VALUES ('Plasma Phys. Rep.','Plasma Phys. Rep.');
INSERT INTO flxKBEJOURNALS VALUES ('Plasma Sources Sci. Technol.','Plasma Sources Sci. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('Polym. Bull.','Polym. Bull.');
INSERT INTO flxKBEJOURNALS VALUES ('Powder Diffraction','Powder Diffraction');
INSERT INTO flxKBEJOURNALS VALUES ('Probab. Theory Relat. Fields','Probab. Theory Relat. Fields');
INSERT INTO flxKBEJOURNALS VALUES ('Proc. Astron. Soc. Aust.','Proc. Astron. Soc. Aust.');
INSERT INTO flxKBEJOURNALS VALUES ('Proc. Nat. Acad. Sci.','Proc. Nat. Acad. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Prog. Cryst. Growth Charact. Mat.','Prog. Cryst. Growth Charact. Mat.');
INSERT INTO flxKBEJOURNALS VALUES ('Prog. Part. Nucl. Phys.','Prog. Part. Nucl. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Prog. Quantum Electron.','Prog. Quantum Electron.');
INSERT INTO flxKBEJOURNALS VALUES ('Prog. Surf. Sci.','Prog. Surf. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Program','Program');
INSERT INTO flxKBEJOURNALS VALUES ('Publ. Astron. Soc. Aust.','Publ. Astron. Soc. Aust.');
INSERT INTO flxKBEJOURNALS VALUES ('Publ. Astron. Soc. Jpn.','Publ. Astron. Soc. Jpn.');
INSERT INTO flxKBEJOURNALS VALUES ('Publ. Astron. Soc. Pac.','Publ. Astron. Soc. Pac.');
INSERT INTO flxKBEJOURNALS VALUES ('Publ. Underst. Sci.','Publ. Underst. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Pure Appl. Opt.: J. Eur. Opt. Soc. P. A','Pure Appl. Opt.: J. Eur. Opt. Soc. P. A');
INSERT INTO flxKBEJOURNALS VALUES ('Quantum Semiclass. Opt.: J. Eur. Opt. Soc. P. B','Quantum Semiclass. Opt.: J. Eur. Opt. Soc. P. B');
INSERT INTO flxKBEJOURNALS VALUES ('Radiat. Environ. Biophys.','Radiat. Environ. Biophys.');
INSERT INTO flxKBEJOURNALS VALUES ('Radiat. Meas.','Radiat. Meas.');
INSERT INTO flxKBEJOURNALS VALUES ('Radiat. Phys. Chem.','Radiat. Phys. Chem.');
INSERT INTO flxKBEJOURNALS VALUES ('Radiologe','Radiologe');
INSERT INTO flxKBEJOURNALS VALUES ('Radioprotection','Radioprotection');
INSERT INTO flxKBEJOURNALS VALUES ('Rep. Math. Phys.','Rep. Math. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Rep. Prog. Phys.','Rep. Prog. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Res. Exp. Med.','Res. Exp. Med.');
INSERT INTO flxKBEJOURNALS VALUES ('Rev. Mex. Astron. Astrofis.','Rev. Mex. Astron. Astrofis.');
INSERT INTO flxKBEJOURNALS VALUES ('Rev. Mod. Phys.','Rev. Mod. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Rev. Sci. Instrum.','Rev. Sci. Instrum.');
INSERT INTO flxKBEJOURNALS VALUES ('Sel. Math., New Ser.','Sel. Math., New Ser.');
INSERT INTO flxKBEJOURNALS VALUES ('Semicond.','Semicond.');
INSERT INTO flxKBEJOURNALS VALUES ('Semicond. Sci. Technol.','Semicond. Sci. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('Shock Waves','Shock Waves');
INSERT INTO flxKBEJOURNALS VALUES ('SIAM J. Appl. Math.','SIAM J. Appl. Math.');
INSERT INTO flxKBEJOURNALS VALUES ('SIAM J. Comput.','SIAM J. Comput.');
INSERT INTO flxKBEJOURNALS VALUES ('SIAM J. Math. Anal.','SIAM J. Math. Anal.');
INSERT INTO flxKBEJOURNALS VALUES ('SIAM J. Numer. Anal.','SIAM J. Numer. Anal.');
INSERT INTO flxKBEJOURNALS VALUES ('SIAM J. Optim.','SIAM J. Optim.');
INSERT INTO flxKBEJOURNALS VALUES ('SIAM Rev.','SIAM Rev.');
INSERT INTO flxKBEJOURNALS VALUES ('Smart Mat. Struct.','Smart Mat. Struct.');
INSERT INTO flxKBEJOURNALS VALUES ('Soft Comput.','Soft Comput.');
INSERT INTO flxKBEJOURNALS VALUES ('Softw. Concepts Tools','Softw. Concepts Tools');
INSERT INTO flxKBEJOURNALS VALUES ('Solar Phys.','Solar Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Solid State Commun.','Solid State Commun.');
INSERT INTO flxKBEJOURNALS VALUES ('Solid State Electron.','Solid State Electron.');
INSERT INTO flxKBEJOURNALS VALUES ('Solid State Ion.','Solid State Ion.');
INSERT INTO flxKBEJOURNALS VALUES ('Sov. Astron. Lett.','Sov. Astron. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Superconductor Science and Technology','Superconductor Science and Technology');
INSERT INTO flxKBEJOURNALS VALUES ('Surf. Coatings Techn.','Surf. Coatings Techn.');
INSERT INTO flxKBEJOURNALS VALUES ('Surf. Sci.','Surf. Sci.');
INSERT INTO flxKBEJOURNALS VALUES ('Surf. Sci. Rep.','Surf. Sci. Rep.');
INSERT INTO flxKBEJOURNALS VALUES ('Surf. Sci. Spectra','Surf. Sci. Spectra');
INSERT INTO flxKBEJOURNALS VALUES ('Synth. Metals','Synth. Metals');
INSERT INTO flxKBEJOURNALS VALUES ('Syst. Fam.','Syst. Fam.');
INSERT INTO flxKBEJOURNALS VALUES ('Tech. Phys.','Tech. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Tech. Phys. Lett.','Tech. Phys. Lett.');
INSERT INTO flxKBEJOURNALS VALUES ('Theor. Comput. Fluid Dyn.','Theor. Comput. Fluid Dyn.');
INSERT INTO flxKBEJOURNALS VALUES ('Theory Comput. Syst.','Theory Comput. Syst.');
INSERT INTO flxKBEJOURNALS VALUES ('Thin Solid Films','Thin Solid Films');
INSERT INTO flxKBEJOURNALS VALUES ('Tribol. Int.','Tribol. Int.');
INSERT INTO flxKBEJOURNALS VALUES ('Ultramicroscopy','Ultramicroscopy');
INSERT INTO flxKBEJOURNALS VALUES ('Vacuum','Vacuum');
INSERT INTO flxKBEJOURNALS VALUES ('VLDB J.','VLDB J.');
INSERT INTO flxKBEJOURNALS VALUES ('Virtual J. Nanoscale Sci. Technol.','Virtual J. Nanoscale Sci. Technol.');
INSERT INTO flxKBEJOURNALS VALUES ('Virtual J. Biol. Phys. Res.','Virtual J. Biol. Phys. Res.');
INSERT INTO flxKBEJOURNALS VALUES ('Vis. Comput.','Vis. Comput.');
INSERT INTO flxKBEJOURNALS VALUES ('Wave Motion','Wave Motion');
INSERT INTO flxKBEJOURNALS VALUES ('Waves Random Media','Waves Random Media');
INSERT INTO flxKBEJOURNALS VALUES ('Wear','Wear');
INSERT INTO flxKBEJOURNALS VALUES ('Z. Angew. Math. Phys.','Z. Angew. Math. Phys.');
INSERT INTO flxKBEJOURNALS VALUES ('Z. Phys., A','Z. Phys., A');
INSERT INTO flxKBEJOURNALS VALUES ('Z. Phys., B','Z. Phys., B');
INSERT INTO flxKBEJOURNALS VALUES ('Z. Phys., C','Z. Phys., C');
INSERT INTO flxKBEJOURNALS VALUES ('Zphys-e.C','Zphys-e.C');
INSERT INTO flxKBEJOURNALS VALUES ('ATLAS eNews','ATLAS eNews');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('PICTURE','unpublished');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('PREPRINT','techreport');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('ARTICLE','article');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('REPORT','techreport');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('BOOK','book');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('THESIS','phdthesis');
INSERT INTO flxKBDBCOLLID2BIBTEX VALUES ('POETRY','unpublished');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CD','909','C','D','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','520','520','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','590','590','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909C0','909','C','0','N','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','110','110','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','583','583','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','270','270','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909C1','909','C','1','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CL','909','C','L','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','700','700','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','100','100','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','506','506','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CE','909','C','E','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CI','909','C','I','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','710','710','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','030','030','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CZ','909','C','Z','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CA','909','C','A','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','111','111','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','711','711','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','524','524','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909C4','909','C','4','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CP','909','C','P','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CM','909','C','M','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','8560','856','0','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','037','037','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','8564','856','4','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','866','866','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','260','260','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','300','300','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','690C','690','C','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','020','020','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','022','022','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','654','654','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','6531','653','1','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','6532','653','2','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CK','909','C','K','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','041','041','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','852','852','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','340','340','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','600','600','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','595','595','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','500','500','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','502','502','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CC','909','C','C','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','596','596','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','591','591','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CO','909','C','O','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','594','594','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','856','856','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','598','598','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CR','909','C','R','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CH','909','C','H','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CF','909','C','F','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','088','088','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','246','246','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','770','770','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','772','772','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','780','780','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','785','785','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','787','787','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','541','541','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','0248','024','8','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','490','490','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','65017','650','1','7','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','65027','650','2','7','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909CS','909','C','S','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','044','044','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','310','310','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','909C2','909','C','2','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','655','655','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','245','245','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','250','250','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','130','130','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','246_1','246','','1','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','246_3','246','','3','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','210','210','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','85642','856','4','2','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','080','080','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','999C5','999','C','5','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','040','040','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','980','980','','','S','DATAFIELD');
INSERT INTO flxXMLMARCEXTRULES VALUES ('DEFAULT','001','001','','','S','CONTROLFIELD');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','','','');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','z','z');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','520','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','520','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','590','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','590','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','110','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','583','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C1','u','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','700','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','700','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','700','u','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','100','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','100','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','506','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','506','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','m','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CE','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','l','l');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','m','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','710','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','110','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C1','o','o');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C1','l','l');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C1','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C1','m','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','030','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CZ','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CZ','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CZ','m','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CZ','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CZ','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CZ','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909Cz','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','9','9');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','111','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','9','9');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','711','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','524','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','v','v');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','y','y');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','710','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','P','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CP','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','l','l');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','k','k');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','z','z');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','583','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CM','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','110','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CM','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8560','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8560','x','x');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','037','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8564','z','z');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8564','u','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8564','q','q');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8564','x','x');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CM','h','h');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','866','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','866','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','866','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','866','z','z');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','866','x','x');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','866','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CM','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','260','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','300','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','260','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','260','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','260','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','V','v');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','690C','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','020','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','022','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','654','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','6531','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','6532','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C','$','$');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CK','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CK','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CK','k','k');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CK','l','l');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CK','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','041','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','852','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','852','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','m','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','8564','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','340','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','600','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','595','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','500','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','502','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CP','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CC','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CC','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CC','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CC','h','h');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CC','l','l');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','596','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','591','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','o','o');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','o','o');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CO','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CP','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CO','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CP','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','594','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','594','c','c');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','594','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','856','k','k');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','u','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','598','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CR','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CR','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CR','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CR','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CR','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CR','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CP','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CF','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CF','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CH','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CF','g','g');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CF','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CF','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','088','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','246','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','770','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','772','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','780','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','785','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','787','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CA','q','q');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','246','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','770','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','772','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','780','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','785','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','787','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','541','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','541','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','541','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','0248','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CI','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CE','m','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','490','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','490','v','v');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CE','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CE','d','d');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','65017','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','65017','2','2');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','6502','$','$');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','65027','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CS','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','044','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','310','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C2','i','i');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C2','f','f');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C2','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CS','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CS','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CS','y','y');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','o','o');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','655','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','245','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','250','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','245','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','130','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','130','s','s');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','130','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','246','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','246_1','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','246_3','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','210','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CP','t','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','85642','r','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','85642','z','z');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','85642','u','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','b','b');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','270','e','e');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','v','v');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CD','x','x');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','080','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','u','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','245','n','n');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','245','p','p');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CM','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CM','l','l');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909CL','x','x');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C1','y','y');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C0','y','y');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','T','t');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','040','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','770','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','772','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','780','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','785','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','787','w','w');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','M','m');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','Y','y');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','R','r');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','U','u');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','Z','z');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','999C5','O','o');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','980','a','a');
INSERT INTO flxXMLMARCEXTRULESUBFIELDS VALUES ('DEFAULT','909C4','D','d');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('DEFAULT',100,0,'record','\" <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hb</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"DEFAULT_HTML_BRIEF\"))\r\n\" </subfield> \r\n </datafield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hd</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"DEFAULT_HTML_DETAILED\"))\r\n\" </subfield> \r\n </datafield>\r\n\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HB',100,0,'','\"<record>\r\n <controlfield tag=\\\"001\\\">\" $001 \"</controlfield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hb</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"DEFAULT_HTML_BRIEF\"))\r\n\" </subfield> \r\n </datafield>\r\n</record>\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HP',0,0,'','\"<record>\r\n <controlfield tag=\\\"001\\\">\" $001 \"</controlfield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hp</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"DEFAULT_HTML_PORTFOLIO\"))\r\n\" </subfield> \r\n </datafield>\r\n</record>\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HC',0,0,'','\"<record>\r\n <controlfield tag=\\\"001\\\">\" $001 \"</controlfield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hc</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"DEFAULT_HTML_CAPTIONS\"))\r\n\" </subfield> \r\n </datafield>\r\n</record>\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HD',100,100,'','\"<record>\r\n <controlfield tag=\\\"001\\\">\" $001 \"</controlfield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hd</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"DEFAULT_HTML_DETAILED\"))\r\n\" </subfield> \r\n </datafield>\r\n</record>\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HB',0,0,'','\"<record>\r\n <controlfield tag=\\\"001\\\">\" $001 \"</controlfield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hb</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"PICTURE_HTML_BRIEF\"))\r\n\" </subfield> \r\n </datafield>\r\n</record>\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HD',90,0,'','\"<record>\r\n <controlfield tag=\\\"001\\\">\" $001 \"</controlfield>\r\n <datafield tag=\\\"FMT\\\" ind1=\\\"\\\" ind2=\\\"\\\"> \r\n <subfield code=\\\"f\\\">hd</subfield> \r\n <subfield code=\\\"g\\\">\" \r\nxml_text(format(\"PICTURE_HTML_DETAILED\"))\r\n\" </subfield> \r\n </datafield>\r\n</record>\"');
INSERT INTO flxBEHAVIORCONDITIONSACTIONS VALUES ('HX',0,0,'','format(\"_FULL_BIBTEX\")');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('DEFAULT',100,'\"\"=\"\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HB',0,'$980.a=\"PICTURE\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HB',100,'\"\"=\"\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HP',0,'\"\"=\"\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HC',0,'\"\"=\"\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HD',100,'\"\"=\"\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HD',90,'$980.a=\"PICTURE\"');
INSERT INTO flxBEHAVIORCONDITIONS VALUES ('HX',0,'\"\"=\"\"');
INSERT INTO flxBEHAVIORS VALUES ('DEFAULT','IENRICH','Creates <b>DEFAULT</b> formats and includes them in the input XML OAI MARC record in the \"FMT\" element');
INSERT INTO flxBEHAVIORS VALUES ('HB','NORMAL','Produces HTML brief format. Useful for reformatting records existing in the database.');
INSERT INTO flxBEHAVIORS VALUES ('HP','NORMAL','PRODUCES HTML PORTFOLIO FORMAT. USEFUL FOR REFORMATTING RECORDS EXISTING IN THE DATABASE.');
INSERT INTO flxBEHAVIORS VALUES ('HC','NORMAL','PRODUCES HTML CAPTIONS FORMAT. USEFUL FOR REFORMATTING RECORDS\r\nEXISTING IN THE DATABASE.');
INSERT INTO flxBEHAVIORS VALUES ('HD','NORMAL','PRODUCES HTML DETAILED FORMAT. USEFUL FOR REFORMATTING RECORDS EXISTING IN THE DATABASE.');
INSERT INTO flxBEHAVIORS VALUES ('HX','NORMAL','PRODUCES HTML BibTeX format.');
INSERT INTO flxUDFS VALUES ('URLENCODE','return urlencode($url);','STRING',NULL);
INSERT INTO flxUDFS VALUES ('UPPER','return strtoupper($s);','STRING','<b>Purpose</b>: Returns characters of string <i>s</i> into uppercase characters\r\n<b>Example</b>: upper(\"test12\") gives as result \"TEST12\"');
INSERT INTO flxUDFS VALUES ('SUBSTR','return substr($s, $start, $end-$start+1);','STRING','<b>Purpose</b>: Returns substring between position <i>start</i> and <i>end</i> from the string <i>s</i>\r\n<b>Example</b>: substr(\"test\", 2, 3) gives as result \"st\"');
INSERT INTO flxUDFS VALUES ('ADD','if($prefix!=\"\")\r\n $value=$prefix.$value;\r\nif($postfix!=\"\")\r\n $value=$value.$postfix;\r\nreturn $value;\r\n','STRING','<b>Purpose</b>: This function adds <i>prefix</i> at the begining and <i>postfix</i> at the end, of <i>value</i>\r\n<b>Example</b>: add(\"test\",\"pre\",\"post\") gives as result \"pretestpost\"\r\n<b>Note</b>: Defined to keep compatibility with uploader\'s languaje');
INSERT INTO flxUDFS VALUES ('MINFO','return \"<a href=\\\"http://weblib.cern.ch/cgi-bin/showfull?id=$sysno\\\">More Info</a>\";','STRING','');
INSERT INTO flxUDFS VALUES ('RNETC','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('EXT','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('MARK','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('SEPARATOR','if(!$LAST_ITERATION)\r\n return $str;\r\nreturn \"\";','STRING',NULL);
INSERT INTO flxUDFS VALUES ('TIONE','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('BRBER','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('MINFA','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('INDIS','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('INHLD','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('LKR','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('NIUCO','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('HOL','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('SNLNK','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('AUFU','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('LKRFU','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('SP','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('HO','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('SREF','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('QUOT','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('MARKF','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('LATEX','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('DI','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('REP_PREFIX','if($FIRST_ITERATION) return $str; return \"\";','STRING',NULL);
INSERT INTO flxUDFS VALUES ('XML_TEXT','return htmlspecialchars($str,ENT_QUOTES); \r\n\r\n','STRING','');
INSERT INTO flxUDFS VALUES ('REP','return str_replace($search, $replacement, $str); \r\n\r\n','STRING','<b>Purpose</b>: Replaces any occurence of string <i>search</i> inside string <i>str</i> by the \r\n<i>replacement</i> one.\r\n<b>Example</b>: rep(\"test12test\", \"12\", \"-\") gives as result \"test-test\"');
INSERT INTO flxUDFS VALUES ('SAVETOFILE','$fh=fopen($filename, \"w\"); if(!$fh) return \"ERROR OPENING FILE \'$filename\'\"; fwrite($fh, $code); fclose($fh); return \"\"; ','STRING',NULL);
INSERT INTO flxUDFS VALUES ('FORMAT_EXIST','$format_name=strtoupper(trim($format_name)); \r\n$res=\"\"; \r\n$db=mysql_pconnect(\"cdsdb.cern.ch\", \"flexelink\", \"2flexible\"); \r\nmysql_selectdb(\"flexelink\"); \r\n$qry=\"select name from FORMATS where name=\'$format_name\'\"; \r\n$qh=mysql_query($qry); \r\nif(mysql_num_rows($qh)==1) \r\n $res=\"Y\"; \r\nreturn $res; ','STRING','<b>Purpose</b>: Tells if a format exists in the FlexElink formats database. Returns non-empty string when a format called <i>format_name</i> doesn\'t exist in the format db, empty string in\r\n other case\r\n<b>Note</b>: To be migrated to FlexElink EL internal fuction');
INSERT INTO flxUDFS VALUES ('TOC','return \"\";','STRING','Temporary defined for \"automatic format migration\" compatibility. Gives empty string.');
INSERT INTO flxUDFS VALUES ('DATE','return date(\"j M Y H:i:s\");','STRING','<b>Purpose</b>: Gives the current date in the following format \"day month_name year2k hh:mm:ss\"');
INSERT INTO flxUDFS VALUES ('FILTER_PAGENR','$temp=explode(\"-\", $str);\r\nreturn $temp[0];','STRING','');
INSERT INTO flxUDFS VALUES ('LOWER','return strtolower($str);','STRING','<b>Purpose</b>: Returns characters of string <i>s</i> into lowercase characters \r\n<b>Example</b>: lower(\"TEsT12\") gives as result \"test12\"');
INSERT INTO flxUDFS VALUES ('SUBSTR_END','return substr($str, $start);','STRING','<b>Purpose</b>: Returns a substring from the string <i>s</i>, from position <i>start</i> to the end of the string. \r\nNote that characters into a string are always numerated starting in 0\r\n<b>Example</b>: substr(\"test\", 2) gives as result \"st\"');
INSERT INTO flxUDFS VALUES ('LIMW_L','$temp=explode($token, $str, 2);\r\nreturn $temp[0];','STRING','<b>Purpose</b>: Returns a substring from the string <i>str</i>, containing all characters found in it\r\nbefore the first occurrence of string <i>token</i>.\r\n<b>Example</b>: substr_bef_token(\"test1@test2@test3\", \"@\") gives as result \"test1\"');
INSERT INTO flxUDFS VALUES ('LIMW_R','$temp=explode($token, $str, 2); \r\nreturn $temp[1];','STRING','<b>Purpose</b>: Returns a substring from the string <i>str</i>, containing all characters found in it\r\nafter the first acourrence of string <i>token</i>.\r\n<b>Example</b>: substr_bef_token(\"test1@test2@test3\", \"@\") gives as result \"test2@test3\"');
INSERT INTO flxUDFS VALUES ('FILE_EXISTS','$fh=@fopen($url, \"r\");\r\n$res=\"\";\r\nif($fh)\r\n $res=$url;\r\nreturn $res;','STRING','<b>Purpose</b>: Checks if the given <i>url</i> exists. If so it returns the <i>url</i>, if not it gives back an empty string.\r\n<b>Example</b>: file_exists(\"/not/exists\") gives \"\" as far as file \"/not/exists\" doesn\'t exist');
INSERT INTO flxUDFS VALUES ('CUT_FILE','$fh=@fopen($url, \"r\");\r\n$res=\"\";\r\nif($fh)\r\n{\r\n $found=false;\r\n if($start_token==\"\")\r\n {\r\n $found=true;\r\n }\r\n while(!feof($fh))\r\n {\r\n if(!$found)\r\n {\r\n $line=fgets($fh, 4096);\r\n $pos=strpos($line, $start_token);\r\n if($pos === false)\r\n continue;\r\n $res=substr($line, $pos, strlen($start_tag));\r\n $line=substr($line, $pos+strlen($start_tag));\r\n $found=true;\r\n }\r\n else\r\n {\r\n $pos=strpos($line, $end_token);\r\n if($pos === false)\r\n {\r\n $res.=$line;\r\n $line=fgets($fh, 4096);\r\n }\r\n else\r\n {\r\n $res.=substr($line, 0, $pos+strlen($end_token));\r\n break;\r\n }\r\n }\r\n }\r\n fclose($fh);\r\n}\r\n\r\nreturn $res;','STRING','<b>Purpose</b>: This function opens the file pointed by the URL <i>url</i>. If it\'s accessible, it parses it and \r\nreturns all characters between first occurence of string <i>start_token</i> and first occurrence of \r\nstring <i>end_token</i>.\r\n<b>Example</b>: cut_file(\"/local/pp.txt\", \"PEPE\", \"JOSE\") and \"/local/pp.txt\" file contains the\r\n following text \r\n\"In spanish PEPE means JOSE and PACO means FRANCISCO\", \r\nwould give as result \"PEPE means JOSE\"');
INSERT INTO flxUDFS VALUES ('STRPOS','$pos=strpos($str, $substr);\r\nif($pos === false)\r\n{\r\n return \"\";\r\n}\r\nelse\r\n{\r\n return \"$pos\";\r\n}','STRING','');
INSERT INTO flxUDFS VALUES ('GET_FROM_SETLINKURL','$url=parse_url( $url );\r\n$res=\"\";\r\nif(trim($url[query])!=\"\")\r\n{\r\n $params=explode(\"&\", $url[query]);\r\n foreach($params as $param)\r\n {\r\n $param=explode(\"=\", $param);\r\n if(trim($param[0])==$field)\r\n {\r\n $res=trim($param[1]);\r\n break;\r\n }\r\n } \r\n}\r\nreturn $res;','STRING','');
INSERT INTO flxUDFS VALUES ('FILTER_CDS_ID','$temp=explode(\"-\", $str, 2); \r\nreturn $temp[0];','STRING','');
INSERT INTO flxUDFS VALUES ('COPY','return substr($str, $start, $length);','STRING','<b>Purpose</b>: Returns a substring from string <i>str</i>, that starts in position <i>start</i>\r\n and that is <i>length</i> characters long from there\r\n<b>Example</b>: copy(\"test\", \"1\", \"2\") gives as result \"es\"');
INSERT INTO flxUDFS VALUES ('TERMINATOR','if($LAST_ITERATION)\r\n return $str;','STRING','');
INSERT INTO flxUDFS VALUES ('SUM','return $v1+$v2;','STRING','<b>Purpose</b>: Gives the result of adding <i>v1</i> to <i>v2</i> (<i>v1</i>+<i>v2</i>)\r\n<b>Example</b>: add(\"3\", \"4\") gives as result \"7\"');
INSERT INTO flxUDFS VALUES ('GT','if($v1>$v2)\r\n return \"1\";\r\nreturn \"\";','STRING','<b>Purpose</b>: \"Greater than\" function; returns \"1\" if <i>v1</i>><i>v2</i>, \"\" in other case\r\n<b>Example</b>: gt(\"3\", \"4\") gives as result \"\"');
INSERT INTO flxUDFS VALUES ('EXTRACT_EMAIL','if(ereg(\"([^ <\\t\\n]+@[^ >\\t\\n]+)\", $str, $res))\r\n{\r\n return $res[1];\r\n}\r\nelse\r\n return \"\";\r\n','STRING','<b>Purpose</b>: Returns the first valid (filtered) email address found in string <i>str</i>. \r\nIf there\'s no valid email address in it, it returns \"\"\r\n<b>Example</b>: extract_email(\"Hector Sanchez <Hector.Sanchez@cern.ch>\") gives \"Hector.Sanchez@cern.ch\".');
INSERT INTO flxUDFS VALUES ('GE','if($v1>=$v2)\r\n return \"1\";\r\nreturn \"\";','STRING','<b>Purpose</b>: \"Greater or equal than\" function; returns \"1\" if <i>v1</i>>=<i>v2</i>, \"\" in other case\r\n<b>Example</b>: ge(\"3\", \"4\") gives as result \"\"');
INSERT INTO flxUDFS VALUES ('LE','if($v1<=$v2)\r\n return \"1\";\r\nreturn \"\";','STRING','<b>Purpose</b>: \"Lower or equal than\" function; returns \"1\" if <i>v1</i><=<i>v2</i>, \"\" in other case\r\n<b>Example</b>: ge(\"3\", \"4\") gives as result \"\"');
INSERT INTO flxUDFS VALUES ('ISO_NUM','$iso=substr($str, strlen($str_iso));\r\n$temp=explode(\"-\", $iso, 2);\r\n$isonum=$temp[0]; \r\nreturn $isonum;\r\n','STRING','');
INSERT INTO flxUDFS VALUES ('ISO_PART','$iso=substr($str, strlen($str_iso)); \r\n$temp=explode(\"-\", $iso, 2); \r\n$isopart=\"\";\r\nif(count($temp)>1)\r\n{\r\n $isopart=$temp[1]; \r\n}\r\nreturn $isopart; \r\n','STRING','');
INSERT INTO flxUDFS VALUES ('ISO_NUMPART_LINK','$iso=substr($str, strlen($str_iso));\r\n$temp=explode(\"-\", $iso, 2);\r\n$isolink=$temp[0]; \r\nif(count($temp)>1)\r\n{\r\n if(strlen($temp[1])>0)\r\n {\r\n $isolink.=\"&part=\";\r\n $isolink.=str_replace(\"-\", \"&se=\", $temp[1]);\r\n }\r\n}\r\nreturn $isolink;\r\n','STRING','');
INSERT INTO flxUDFS VALUES ('STRIP_SPACES','return str_replace(\" \", \"\", $str);','STRING','');
INSERT INTO flxUDFS VALUES ('LFILL','if(strlen($char)==0) return $str;\r\nif(strlen($str)>$digits) \r\n $str=substr($str, strlen($str)-$digits);\r\nelse\r\n $str=sprintf(\"%0\".$digits.\"u\", $str);\r\nreturn $str;','STRING','<b>Purpose</b>: Returns a string consisting in the string <i>str</i> with the character <i>char</i> \r\nadded to its left the numer of times needed until the lenght <i>digits</i> is reached. If the length\r\nof <i>str</i> is bigger than <i>digits</i>, a left truncated string to length <i>digit</i> is returned.\r\n<b>Example</b>: lfill(\"12\", \"0\", \"5\") gives as result \"00012\", while lfill(\"12345\", \"0\", \"3\") gives as result \"345\", while');
INSERT INTO flxUDFS VALUES ('STR_BUFFER','return add_text($action, $str_to_add, $remove_end_before_print, $min_length_for_print);\r\n\r\nfunction add_text($action, $str_to_add, $remove_end_before_print, $min_length_for_print) {\r\n static $whole_str_buffer = \'\';\r\n\r\n if($action === \'print\') {\r\n if (strlen($whole_str_buffer) > $min_length_for_print){ \r\n $retrn_val = substr($whole_str_buffer, 0, strlen($whole_str_buffer) - $remove_end_before_print) . $str_to_add;\r\n $whole_str_buffer = \'\';\r\n \r\n return $retrn_val;\r\n }\r\n $whole_str_buffer = \'\';\r\n return \'\';\r\n }elseif($action === \'add\'){\r\n $whole_str_buffer .= $str_to_add;\r\n return \'\';\r\n }elseif($action ===\'reset\'){\r\n $whole_str_buffer = \'\';\r\n return \'\';\r\n }else{\r\n return \'\';\r\n }\r\n}','','<b>Purpose</b>:Concatenates strings into static buffer without printing it out before you say so.\r\n<b>Parameters</b>:\r\n<i>action</i>: If action is \"add\", then it adds the string to the buffer, if the action is \"print\", then it first removes the end of the string, then adds str_to_add, then prints out. If action is \"reset\", then it resets the buffer to \"\". When you do a \"print\", it also resets the buffer.\r\n<i>str_to_add</i>: The string you want to add to the already stored string. If action is \"print\" then this part will be added after the function has taken away the end of the string.\r\n<i>remove_end_before_print</i>: Only works when action is \"print\", then it removes the number of chars you have specified before adding the rest of the string, and prints out.\r\n<i>min_length_for_print</i>: If string is shorter then this when action is \"print\", then it will return \"\". This parameter is only in use when action is \"print\".\r\n<b>Example</b>:\r\nSTR_BUFFER(\"add\", \"\\\"Øyvind and \", \"0\", \"0\");\r\nSTR_BUFFER(\"print\", \"\\\"\", \"5\", \"3\");\r\noutputs: \"Øyvind\"');
INSERT INTO flxUDFS VALUES ('GET_NAME','$pos=strpos($names, \',\');\r\n\r\nif($pos === false){\r\n $name_ar = preg_split(\"/[\\s+]+/\", $names);\r\n $names = \"\";\r\n\r\n for($i = 0; $i < count($name_ar); $i++){\r\n if(strlen($name_ar[$i]) >= strlen($names)){\r\n $names = $name_ar[$i];\r\n }\r\n }\r\n return $names;\r\n}\r\n\r\n$newname = substr($names, 0, $pos);\r\n\r\nreturn str_replace(\" \", \"\", $newname);','','<b>Purpose</b>: Tryes to find the last name in a string, and returns it.\r\n<b>Example</b>: GET_NAME(\"Østlund, Øyvind B\"); returns \"Østlund\".');
INSERT INTO flxUDFS VALUES ('SPLIT_LINE','$start_index = 0;\r\n$result_string;\r\n$done = false;\r\n$firstline = true;\r\n\r\nwhile (!$done){\r\n\r\n if($start_index + $str_len >= strlen($split_str)){\r\n $done = true;\r\n $split = strlen($split_str) - $start_index;\r\n $result_string .= substr($split_str, $start_index);\r\n }else{\r\n $found = false;\r\n\r\n if($firstline == true){\r\n $split = $str_len + $indentation;\r\n $firstline = false;\r\n }else{\r\n $split = $str_len;\r\n }\r\n\r\n while ($split > 0 && $found == false){\r\n if($split_str[$start_index + $split] == \' \'){\r\n $found = true;\r\n }else{\r\n $split --;\r\n }\r\n }\r\n\r\n $result_string .= substr($split_str, $start_index, $split) . \'<br>\' . str_repeat(\' \', $indentation);\r\n $start_index += $split + 1;\r\n }\r\n}\r\n\r\n\r\nreturn $result_string;\r\n\r\n\r\n\r\n','','<b>Purpose</b>: Splits a line after a certain amount of letters. Does not split a word in two, but finds the nearest word break. \r\nNotice: Indentation is only for line 2->n, not line 1.\r\nNotice: First line will be the length of str_len + indentation.\r\nNotice: If there is HTML tags in the string, they will be counted too.\r\n<b>Example</b>: SPLIT_LINE(\"title = Nuclear matter with off-shell propagation\", \"35\", \"15\");\r\nReturns:<pre>title = Nuclear matter with\r\n off-shell propagation</pre>');
INSERT INTO flxUDFS VALUES ('GET_MONTH','if(eregi(\'jan\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'feb\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'mar\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'apr\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'may\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'jun\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'jul\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'aug\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'sep\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'oct\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'nov\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(eregi(\'dec\', $date, $res)){\r\n return ucfirst(strtolower($res[0]));\r\n}elseif(preg_match(\'/(?<=[-\\/])\\n\\n(?=[-\\/])/i\', $date, $res)){\r\n if($res[0] === \'01\' || $res[0] === \'1\'){\r\n return \'Jan\';\r\n }elseif($res[0] === \'02\' || $res[0] === \'2\'){\r\n return \'Feb\';\r\n }elseif($res[0] === \'03\' || $res[0] === \'3\'){\r\n return \'Mar\';\r\n }elseif($res[0] === \'04\' || $res[0] === \'4\'){\r\n return \'Apr\';\r\n }elseif($res[0] === \'05\' || $res[0] === \'5\'){\r\n return \'May\';\r\n }elseif($res[0] === \'06\' || $res[0] === \'6\'){\r\n return \'Jun\';\r\n }elseif($res[0] === \'07\' || $res[0] === \'7\'){\r\n return \'Jul\';\r\n }elseif($res[0] === \'08\' || $res[0] === \'8\'){\r\n return \'Aug\';\r\n }elseif($res[0] === \'09\' || $res[0] === \'9\'){\r\n return \'Sep\';\r\n }elseif($res[0] === \'10\'){\r\n return \'Oct\';\r\n }elseif($res[0] === \'11\'){\r\n return \'Nov\';\r\n }elseif($res[0] === \'12\'){\r\n return \'Dec\';\r\n }\r\n}\r\n\r\nreturn \"\";','','<b>Purpose</b>: Takes a string as input, and returns a 3 letter abrivation of the month if the string contains it.\r\n<b>Example</b>: Accepted string format is e.g. <em>17 February 2004<em>, <em>2004/02/17<em>, <em>17-Feb-2004<em>, etc. (Almost any English date format!)');
INSERT INTO flxUDFS VALUES ('GET_YEAR','if(ereg(\'[[:digit:]][[:digit:]][[:digit:]][[:digit:]]\', $date, $res)){\r\n return $res[0];\r\n}elseif(ereg(\'[[:digit:]][[:digit:]][[:digit:]][[:digit:]]\', $date, $res)){\r\n return $res[0];\r\n}','','<b>Purpose</b>: Takes a string as input, and returns a 4 digit year if the string contains it.');
INSERT INTO flxUDFPARAMS VALUES ('URLENCODE','url',0);
INSERT INTO flxUDFPARAMS VALUES ('ADD','postfix',2);
INSERT INTO flxUDFPARAMS VALUES ('SUBSTR','end',2);
INSERT INTO flxUDFPARAMS VALUES ('UPPER','s',0);
INSERT INTO flxUDFPARAMS VALUES ('SUBSTR','s',0);
INSERT INTO flxUDFPARAMS VALUES ('SUBSTR','start',1);
INSERT INTO flxUDFPARAMS VALUES ('MINFO','sysno',0);
INSERT INTO flxUDFPARAMS VALUES ('SEPARATOR','str',0);
INSERT INTO flxUDFPARAMS VALUES ('REP_PREFIX','str',0);
INSERT INTO flxUDFPARAMS VALUES ('XML_TEXT','str',0);
INSERT INTO flxUDFPARAMS VALUES ('REP','search',1);
INSERT INTO flxUDFPARAMS VALUES ('REP','str',0);
INSERT INTO flxUDFPARAMS VALUES ('SAVETOFILE','filename',0);
INSERT INTO flxUDFPARAMS VALUES ('SAVETOFILE','code',1);
INSERT INTO flxUDFPARAMS VALUES ('REP','replacement',2);
INSERT INTO flxUDFPARAMS VALUES ('FORMAT_EXIST','format_name',0);
INSERT INTO flxUDFPARAMS VALUES ('FILTER_PAGENR','str',0);
INSERT INTO flxUDFPARAMS VALUES ('LOWER','str',0);
INSERT INTO flxUDFPARAMS VALUES ('ADD','value',0);
INSERT INTO flxUDFPARAMS VALUES ('ADD','prefix',1);
INSERT INTO flxUDFPARAMS VALUES ('STRPOS','substr',1);
INSERT INTO flxUDFPARAMS VALUES ('STRPOS','str',0);
INSERT INTO flxUDFPARAMS VALUES ('CUT_FILE','end_token',2);
INSERT INTO flxUDFPARAMS VALUES ('CUT_FILE','start_token',1);
INSERT INTO flxUDFPARAMS VALUES ('CUT_FILE','url',0);
INSERT INTO flxUDFPARAMS VALUES ('FILE_EXISTS','url',0);
INSERT INTO flxUDFPARAMS VALUES ('SUBSTR_END','str',0);
INSERT INTO flxUDFPARAMS VALUES ('SUBSTR_END','start',1);
INSERT INTO flxUDFPARAMS VALUES ('LIMW_R','str',0);
INSERT INTO flxUDFPARAMS VALUES ('LIMW_L','str',0);
INSERT INTO flxUDFPARAMS VALUES ('LIMW_L','token',1);
INSERT INTO flxUDFPARAMS VALUES ('LIMW_R','token',1);
INSERT INTO flxUDFPARAMS VALUES ('GET_FROM_SETLINKURL','url',0);
INSERT INTO flxUDFPARAMS VALUES ('GET_FROM_SETLINKURL','field',1);
INSERT INTO flxUDFPARAMS VALUES ('FILTER_CDS_ID','str',0);
INSERT INTO flxUDFPARAMS VALUES ('COPY','str',0);
INSERT INTO flxUDFPARAMS VALUES ('COPY','start',1);
INSERT INTO flxUDFPARAMS VALUES ('TERMINATOR','str',0);
INSERT INTO flxUDFPARAMS VALUES ('SUM','v1',0);
INSERT INTO flxUDFPARAMS VALUES ('GT','v1',0);
INSERT INTO flxUDFPARAMS VALUES ('SUM','v2',1);
INSERT INTO flxUDFPARAMS VALUES ('EXTRACT_EMAIL','str',0);
INSERT INTO flxUDFPARAMS VALUES ('GT','v2',1);
INSERT INTO flxUDFPARAMS VALUES ('GE','v2',1);
INSERT INTO flxUDFPARAMS VALUES ('GE','v1',0);
INSERT INTO flxUDFPARAMS VALUES ('LE','v1',0);
INSERT INTO flxUDFPARAMS VALUES ('LE','v2',1);
INSERT INTO flxUDFPARAMS VALUES ('ISO_NUM','str_iso',0);
INSERT INTO flxUDFPARAMS VALUES ('ISO_NUM','str',1);
INSERT INTO flxUDFPARAMS VALUES ('ISO_PART','str_iso',0);
INSERT INTO flxUDFPARAMS VALUES ('ISO_PART','str',1);
INSERT INTO flxUDFPARAMS VALUES ('ISO_NUMPART_LINK','str_iso',0);
INSERT INTO flxUDFPARAMS VALUES ('ISO_NUMPART_LINK','str',1);
INSERT INTO flxUDFPARAMS VALUES ('STRIP_SPACES','str',0);
INSERT INTO flxUDFPARAMS VALUES ('LFILL','digits',2);
INSERT INTO flxUDFPARAMS VALUES ('LFILL','char',1);
INSERT INTO flxUDFPARAMS VALUES ('LFILL','str',0);
INSERT INTO flxUDFPARAMS VALUES ('COPY','length',2);
INSERT INTO flxUDFPARAMS VALUES ('STR_BUFFER','action',0);
INSERT INTO flxUDFPARAMS VALUES ('STR_BUFFER','str_to_add',1);
INSERT INTO flxUDFPARAMS VALUES ('STR_BUFFER','min_length_for_print',3);
INSERT INTO flxUDFPARAMS VALUES ('STR_BUFFER','remove_end_before_print',2);
INSERT INTO flxUDFPARAMS VALUES ('GET_YEAR','date',0);
INSERT INTO flxUDFPARAMS VALUES ('GET_MONTH','date',0);
INSERT INTO flxUDFPARAMS VALUES ('GET_NAME','names',0);
INSERT INTO flxUDFPARAMS VALUES ('SPLIT_LINE','indentation',2);
INSERT INTO flxUDFPARAMS VALUES ('SPLIT_LINE','split_str',0);
INSERT INTO flxUDFPARAMS VALUES ('SPLIT_LINE','str_len',1);
INSERT INTO flxUSERS VALUES (1);
INSERT INTO sbmACTION VALUES ('Submit New Record','SBI','running','1998-08-17','2001-08-08','','Submit New Record');
INSERT INTO sbmACTION VALUES ('Modify Record','MBI','modify','1998-08-17','2001-11-07','','Modify Record');
INSERT INTO sbmACTION VALUES ('Submit New File','SRV','revise','0000-00-00','2001-11-07','','Submit New File');
INSERT INTO sbmACTION VALUES ('Approve Record','APP','approve','2001-11-08','2002-06-11','','Approve Record');
INSERT INTO sbmALLFUNCDESCR VALUES ('CaseEDS','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Create_Modify_Interface',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Create_Recid',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Finish_Submission','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Get_Info','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Get_Report_Number',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Get_Sysno',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Insert_Modify_Record','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Insert_Record',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Is_Original_Submitter','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Is_Referee','This function checks whether the logged user is a referee for the current document');
INSERT INTO sbmALLFUNCDESCR VALUES ('Mail_Submitter',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Make_Modify_Record',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Make_Record','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Move_From_Pending','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Move_to_Done',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Move_to_Pending',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Print_Success','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Print_Success_APP','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Print_Success_MBI',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Print_Success_SRV',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Report_Number_Generation',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Send_Approval_Request',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Send_APP_Mail','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Send_Modify_Mail',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Send_SRV_Mail',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Test_Status','');
INSERT INTO sbmALLFUNCDESCR VALUES ('Update_Approval_DB',NULL);
INSERT INTO sbmALLFUNCDESCR VALUES ('Upload_Files','');
INSERT INTO sbmCHECKS VALUES ('AUCheck','function AUCheck(txt) {\r\n var res=1;\r\n tmp=txt.indexOf(\"\\015\");\r\n while (tmp != -1) {\r\n left=txt.substring(0,tmp);\r\n right=txt.substring(tmp+2,txt.length);\r\n txt=left + \"\\012\" + right;\r\n tmp=txt.indexOf(\"\\015\");\r\n }\r\n tmp=txt.indexOf(\"\\012\");\r\n if (tmp==-1){\r\n line=txt;\r\n txt=\'\';}\r\n else{\r\n line=txt.substring(0,tmp);\r\n txt=txt.substring(tmp+1,txt.length);}\r\n while (line != \"\"){\r\n coma=line.indexOf(\",\");\r\n left=line.substring(0,coma);\r\n right=line.substring(coma+1,line.length);\r\n coma2=right.indexOf(\",\");\r\n space=right.indexOf(\" \");\r\n if ((coma==-1)||(left==\"\")||(right==\"\")||(space!=0)||(coma2!=-1)){\r\n res=0;\r\n error_log=line;\r\n }\r\n tmp=txt.indexOf(\"\\012\");\r\n if (tmp==-1){\r\n line=txt;\r\n txt=\'\';}\r\n else{\r\n line=txt.substring(0,tmp-1);\r\n txt=txt.substring(tmp+1,txt.length);}\r\n }\r\n if (res == 0){\r\n alert(\"This author name cannot be managed \\: \\012\\012\" + error_log + \" \\012\\012It is not in the required format!\\012Put one author per line and a comma (,) between the name and the firstname initial letters. \\012The name is going first, followed by the firstname initial letters.\\012Don\'t forget the whitespace after the comma!!!\\012\\012Example \\: Put\\012\\012Le Meur, J Y \\012Baron, T \\012\\012for\\012\\012Le Meur Jean-Yves & Baron Thomas.\");\r\n return 0;\r\n } \r\n return 1; \r\n}','1998-08-18','0000-00-00','','');
INSERT INTO sbmCHECKS VALUES ('DatCheckNew','function DatCheckNew(txt) {\r\n var res=1;\r\n if (txt.length != 10){res=0;}\r\n if (txt.indexOf(\"/\") != 2){res=0;}\r\n if (txt.lastIndexOf(\"/\") != 5){res=0;}\r\n tmp=parseInt(txt.substring(0,2),10);\r\n if ((tmp > 31)||(tmp < 1)||(isNaN(tmp))){res=0;}\r\n tmp=parseInt(txt.substring(3,5),10);\r\n if ((tmp > 12)||(tmp < 1)||(isNaN(tmp))){res=0;}\r\n tmp=parseInt(txt.substring(6,10),10);\r\n if ((tmp < 1)||(isNaN(tmp))){res=0;}\r\n if (txt.length == 0){res=1;}\r\n if (res == 0){\r\n alert(\"Please enter a correct Date \\012Format: dd/mm/yyyy\");\r\n return 0;\r\n }\r\n return 1; \r\n}','0000-00-00','0000-00-00','','');
INSERT INTO sbmFORMATEXTENSION VALUES ('WORD','.doc');
INSERT INTO sbmFORMATEXTENSION VALUES ('PostScript','.ps');
INSERT INTO sbmFORMATEXTENSION VALUES ('PDF','.pdf');
INSERT INTO sbmFORMATEXTENSION VALUES ('JPEG','.jpg');
INSERT INTO sbmFORMATEXTENSION VALUES ('JPEG','.jpeg');
INSERT INTO sbmFORMATEXTENSION VALUES ('GIF','.gif');
INSERT INTO sbmFORMATEXTENSION VALUES ('PPT','.ppt');
INSERT INTO sbmFORMATEXTENSION VALUES ('HTML','.htm');
INSERT INTO sbmFORMATEXTENSION VALUES ('HTML','.html');
INSERT INTO sbmFORMATEXTENSION VALUES ('Latex','.tex');
INSERT INTO sbmFORMATEXTENSION VALUES ('Compressed PostScript','.ps.gz');
INSERT INTO sbmFORMATEXTENSION VALUES ('Tarred Tex (.tar)','.tar');
INSERT INTO sbmFORMATEXTENSION VALUES ('Text','.txt');
INSERT INTO sbmFUNDESC VALUES ('Get_Report_Number','edsrn');
INSERT INTO sbmFUNDESC VALUES ('Send_Modify_Mail','addressesMBI');
INSERT INTO sbmFUNDESC VALUES ('Send_Modify_Mail','sourceDoc');
INSERT INTO sbmFUNDESC VALUES ('Report_Number_Generation','edsrn');
INSERT INTO sbmFUNDESC VALUES ('Report_Number_Generation','autorngen');
INSERT INTO sbmFUNDESC VALUES ('Report_Number_Generation','rnin');
INSERT INTO sbmFUNDESC VALUES ('Report_Number_Generation','counterpath');
INSERT INTO sbmFUNDESC VALUES ('Report_Number_Generation','rnformat');
INSERT INTO sbmFUNDESC VALUES ('Report_Number_Generation','yeargen');
INSERT INTO sbmFUNDESC VALUES ('Mail_Submitter','authorfile');
INSERT INTO sbmFUNDESC VALUES ('Mail_Submitter','status');
INSERT INTO sbmFUNDESC VALUES ('Send_Approval_Request','authorfile');
INSERT INTO sbmFUNDESC VALUES ('Create_Modify_Interface','fieldnameMBI');
INSERT INTO sbmFUNDESC VALUES ('Send_Modify_Mail','fieldnameMBI');
INSERT INTO sbmFUNDESC VALUES ('Update_Approval_DB','categformatDAM');
INSERT INTO sbmFUNDESC VALUES ('Send_SRV_Mail','categformatDAM');
INSERT INTO sbmFUNDESC VALUES ('Send_SRV_Mail','addressesSRV');
INSERT INTO sbmFUNDESC VALUES ('Send_Approval_Request','directory');
INSERT INTO sbmFUNDESC VALUES ('Send_Approval_Request','categformatDAM');
INSERT INTO sbmFUNDESC VALUES ('Send_Approval_Request','addressesDAM');
INSERT INTO sbmFUNDESC VALUES ('Send_Approval_Request','titleFile');
INSERT INTO sbmFUNDESC VALUES ('Send_APP_Mail','edsrn');
INSERT INTO sbmFUNDESC VALUES ('Mail_Submitter','titleFile');
INSERT INTO sbmFUNDESC VALUES ('Send_Modify_Mail','emailFile');
INSERT INTO sbmFUNDESC VALUES ('Get_Info','authorFile');
INSERT INTO sbmFUNDESC VALUES ('Get_Info','emailFile');
INSERT INTO sbmFUNDESC VALUES ('Get_Info','titleFile');
INSERT INTO sbmFUNDESC VALUES ('Make_Modify_Record','modifyTemplate');
INSERT INTO sbmFUNDESC VALUES ('Send_APP_Mail','addressesAPP');
INSERT INTO sbmFUNDESC VALUES ('Send_APP_Mail','categformatAPP');
INSERT INTO sbmFUNDESC VALUES ('Send_APP_Mail','newrnin');
INSERT INTO sbmFUNDESC VALUES ('CaseEDS','casevariable');
INSERT INTO sbmFUNDESC VALUES ('CaseEDS','casevalues');
INSERT INTO sbmFUNDESC VALUES ('CaseEDS','casesteps');
INSERT INTO sbmFUNDESC VALUES ('CaseEDS','casedefault');
INSERT INTO sbmFUNDESC VALUES ('Send_SRV_Mail','noteFile');
INSERT INTO sbmFUNDESC VALUES ('Send_SRV_Mail','emailFile');
INSERT INTO sbmFUNDESC VALUES ('Mail_Submitter','emailFile');
INSERT INTO sbmFUNDESC VALUES ('Mail_Submitter','edsrn');
INSERT INTO sbmFUNDESC VALUES ('Mail_Submitter','newrnin');
INSERT INTO sbmFUNDESC VALUES ('Upload_Files','maxsize');
INSERT INTO sbmFUNDESC VALUES ('Upload_Files','minsize');
INSERT INTO sbmFUNDESC VALUES ('Upload_Files','iconsize');
INSERT INTO sbmFUNDESC VALUES ('Upload_Files','type');
INSERT INTO sbmFUNDESC VALUES ('Make_Record','sourceTemplate');
INSERT INTO sbmFUNDESC VALUES ('Make_Record','createTemplate');
INSERT INTO sbmFUNDESC VALUES ('Print_Success','edsrn');
INSERT INTO sbmFUNDESC VALUES ('Print_Success','newrnin');
INSERT INTO sbmFUNDESC VALUES ('Print_Success','status');
INSERT INTO sbmFUNDESC VALUES ('Make_Modify_Record','sourceTemplate');
INSERT INTO sbmGFILERESULT VALUES ('HTML','HTML document');
INSERT INTO sbmGFILERESULT VALUES ('WORD','data');
INSERT INTO sbmGFILERESULT VALUES ('PDF','PDF document');
INSERT INTO sbmGFILERESULT VALUES ('PostScript','PostScript document');
INSERT INTO sbmGFILERESULT VALUES ('PostScript','data ');
INSERT INTO sbmGFILERESULT VALUES ('PostScript','HP Printer Job Language data');
INSERT INTO sbmGFILERESULT VALUES ('jpg','JPEG image');
INSERT INTO sbmGFILERESULT VALUES ('Compressed PostScript','gzip compressed data');
INSERT INTO sbmGFILERESULT VALUES ('Tarred Tex (.tar)','tar archive');
INSERT INTO sbmGFILERESULT VALUES ('JPEG','JPEG image');
INSERT INTO sbmGFILERESULT VALUES ('GIF','GIF');
INSERT INTO accROLE VALUES (1,'superadmin','superuser with all rights');
INSERT INTO accROLE VALUES (2,'photoadmin','Photo collection administrator');
INSERT INTO accROLE VALUES (3,'webaccessadmin','WebAccess administrator');
INSERT INTO user_accROLE VALUES (1,1);
INSERT INTO user_accROLE VALUES (1,3);
INSERT INTO accACTION VALUES (1,'cfgwebsearch','configure WebSearch','','no');
INSERT INTO accACTION VALUES (2,'cfgbibformat','configure BibFormat','','no');
INSERT INTO accACTION VALUES (3,'runbibindex','run BibIndex','','no');
INSERT INTO accACTION VALUES (4,'runbibupload','run BibUpload','','no');
INSERT INTO accACTION VALUES (5,'runwebcoll','run webcoll','collection','yes');
INSERT INTO accACTION VALUES (6,'runbibformat','run BibFormat','format','yes');
INSERT INTO accACTION VALUES (7,'cfgwebaccess','configure WebAccess','','no');
INSERT INTO accACTION VALUES (8,'accdelegaterole','delegate subroles inside WebAccess','role','no');
INSERT INTO accACTION VALUES (9,'runbibtaskex','run BibTaskEx example', '','no');
INSERT INTO accACTION VALUES (11,'submit','use webSubmit','doctype,act','no');
INSERT INTO accACTION VALUES (12,'cfgwebsubmit','configure webSubmit','','no');
INSERT INTO accACTION VALUES (13,'referee','referee document type doctype','doctype,categ','yes');
INSERT INTO accACTION VALUES (14,'runbibrank','run BibRank','','no');
INSERT INTO accACTION VALUES (15,'cfgbibrank','configure BibRank','','no');
INSERT INTO accACTION VALUES (16,'cfgbibindex','configure BibIndex','','no');
INSERT INTO accACTION VALUES (17,'cfgbibharvest','configure BibHarvest','','no');
INSERT INTO accACTION VALUES (18,'runoaiharvest','run BibHarvest periodical harvesting','','no');
INSERT INTO accACTION VALUES (19,'cfgwebcomment','configure WebComment','','no');
INSERT INTO accACTION VALUES (20,'runoaiarchive','run OAI archive','','no');
INSERT INTO accARGUMENT VALUES (1,'collection','Pictures');
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,1, 0, 0);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,2, 0, 0);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,3, 0, 0);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,4, 0, 0);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,6,-1,-1);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,7, 0, 0);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (2,5, 1, 1);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (3,7, 0, 0);
INSERT INTO accROLE_accACTION_accARGUMENT VALUES (1,9, 0, 0);
</protect>
diff --git a/modules/miscutil/web/Makefile.am b/modules/miscutil/web/Makefile.am
index 9237ef6ea..d9cfeba1b 100644
--- a/modules/miscutil/web/Makefile.am
+++ b/modules/miscutil/web/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)
webapp_DATA = error.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/miscutil/web/error.py b/modules/miscutil/web/error.py
index 19d1ca58b..230a75a49 100644
--- a/modules/miscutil/web/error.py
+++ b/modules/miscutil/web/error.py
@@ -1,49 +1,49 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__lastupdated__ = """FIXME: last updated"""
from cdsware.webpage import page
from cdsware.errorlib import *
def send_report(req, header="NA", url="NA", time="NA", browser="NA", client="NA", error="NA", sys_error="NA", traceback="NA", referer="NA"):
"""
Confirmation page of error report sent the admin
parameters are the same as used for the error box. See webstyle_templates.tmpl_error_box
"""
send_error_report_to_admin(header, url, time, browser, client, error, sys_error, traceback)
out = '''
<span class="exampleleader">The error report has been sent</span><br>
<br>
Many thanks for helping us make CDSware better.<br>
<br>
%(back)s
''' % \
{ 'back' : referer!="NA" and "<a href=\"%s\">back</a>" % (referer,) or "Use the back button of your browser to return to the previous page"
}
return page(title="Thanks", body=out, navtrail="", description="", keywords="",
cdspageheaderadd="", cdspageboxlefttopadd="", cdspageboxleftbottomadd="", cdspageboxrighttopadd="",
cdspageboxrightbottomadd="", cdspagefooteradd="", lastupdated="", urlargs="", verbose=1, titleprologue="", titleepilogue="",
req=req)
diff --git a/modules/webaccess/Makefile.am b/modules/webaccess/Makefile.am
index ce16c5c0d..10488862b 100644
--- a/modules/webaccess/Makefile.am
+++ b/modules/webaccess/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = lib bin doc web
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/webaccess/bin/Makefile.am b/modules/webaccess/bin/Makefile.am
index 9f08c9d11..ab32f473c 100644
--- a/modules/webaccess/bin/Makefile.am
+++ b/modules/webaccess/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = authaction webaccessadmin
EXTRA_DIST = authaction.in webaccessadmin.in
CLEANFILES = *~ *.tmp authactionc
diff --git a/modules/webaccess/bin/authaction.in b/modules/webaccess/bin/authaction.in
index fef57b66d..1386ff5f1 100644
--- a/modules/webaccess/bin/authaction.in
+++ b/modules/webaccess/bin/authaction.in
@@ -1,94 +1,94 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""authaction -- CLI interface to Access Control Engine"""
__version__ = "$Id$"
try:
import sys
from cdsware.config import *
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_config import cfg_webaccess_warning_msgs
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
def usage(code, msg=''):
"""Print usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("authaction -- CLI interface to Access Control Engine\n")
sys.stderr.write("Usage: %s [options] <id_user> <name_action> [keyword1] [value1] [keyword2] [value2] ...\n" % sys.argv[0])
sys.stderr.write("Command options:\n")
sys.stderr.write(" <id_user> = ID of the user\n")
sys.stderr.write(" <name_action> = action name\n")
sys.stderr.write(" [keyword1] = optional first keyword argument\n")
sys.stderr.write(" [value1] = its value\n")
sys.stderr.write(" [keyword2] = optional second keyword argument\n")
sys.stderr.write(" [value2] = its value\n")
sys.stderr.write(" ... = et caetera\n")
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.exit(code)
def main():
"""CLI to acc_authorize_action. The function finds the needed
arguments in sys.argv.
If the number of arguments is wrong it prints help.
Return 0 on success, 9 or higher on failure. """
alen, auth = len(sys.argv), 0
# return ``not permitted'' if wrong arguments
if alen > 1 and sys.argv[1] in ["-h", "--help"]:
usage(0)
elif alen > 1 and sys.argv[1] in ["-V", "--version"]:
sys.stderr.write("%s\n" % __version__)
sys.exit(0)
if alen < 3 or alen % 2 == 0:
print "7 - %s" % cfg_webaccess_warning_msgs[7]
return "7 - %s" % cfg_webaccess_warning_msgs[7]
# try to authorize
else:
# get values
id_user = sys.argv[1]
name_action = sys.argv[2]
dict = {}
for i in range(3, alen, 2):
dict[sys.argv[i]] = sys.argv[i + 1]
# run ace-function
(auth_code, auth_message) = acc_authorize_action(id_user, name_action, **dict)
# print and return
print "%s - %s" % (auth_code, auth_message)
return "%s - %s" % (auth_code, auth_message)
if __name__ == '__main__':
main()
diff --git a/modules/webaccess/bin/webaccessadmin.in b/modules/webaccess/bin/webaccessadmin.in
index 607a19186..17c3a837e 100644
--- a/modules/webaccess/bin/webaccessadmin.in
+++ b/modules/webaccess/bin/webaccessadmin.in
@@ -1,106 +1,106 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""WebAccess Admin -- reset or add default authorization settings"""
__version__ = "$Id$"
try:
import getpass
import sys
from cdsware.config import supportemail
from cdsware.access_control_admin import acc_reset_default_settings
from cdsware.access_control_admin import acc_add_default_settings
from cdsware.dbquery import run_sql
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
def usage(code, msg=''):
"""Print usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("WebAccess Admin -- reset or add default authorization settings\n")
sys.stderr.write("Usage: %s [options] <command>\n" % sys.argv[0])
sys.stderr.write("Command options:\n")
sys.stderr.write(" <command> = reset-default-settings\n")
sys.stderr.write(" <command> = add-default-settings\n")
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.exit(code)
def main():
"""CLI to acc_authorize_action. The function finds the needed
arguments in sys.argv.
If the number of arguments is wrong it prints help.
Return 1 on success, 0 on failure. """
alen = len(sys.argv)
action = ''
# print help if wrong arguments
if alen > 1 and sys.argv[1] in ["-h", "--help"]:
usage(0)
elif alen > 1 and sys.argv[1] in ["-V", "--version"]:
print __version__
sys.exit(0)
if alen != 2 or sys.argv[1] not in ['reset-default-settings', 'add-default-settings']:
usage(1)
# getting input from user
print 'User: ',
user = raw_input()
password = getpass.getpass()
# validating input
perform = 0
# check password
if user == supportemail:
perform = run_sql("""select * from user where email = '%s' and password = '%s' """ % (supportemail, password)) and 1 or 0
if not perform:
# wrong password or user not recognized
print 'User not authorized'
return perform
# perform chosen action, add all users above as superusers
if sys.argv[1] == 'reset-default-settings':
action = 'reset'
acc_reset_default_settings([supportemail])
elif sys.argv[1] == 'add-default-settings':
action = 'added'
acc_add_default_settings([supportemail])
# notify of success
if action:
print '\nOkay, the default authorization settings have been __%s__.' % (action, )
else:
print 'Requested action failed.'
return perform
if __name__ == '__main__':
main()
diff --git a/modules/webaccess/doc/Makefile.am b/modules/webaccess/doc/Makefile.am
index 9ac6a119d..11d00dfa3 100644
--- a/modules/webaccess/doc/Makefile.am
+++ b/modules/webaccess/doc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
\ No newline at end of file
diff --git a/modules/webaccess/doc/admin/Makefile.am b/modules/webaccess/doc/admin/Makefile.am
index ac6ba5351..71dffb1ad 100644
--- a/modules/webaccess/doc/admin/Makefile.am
+++ b/modules/webaccess/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webaccess
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webaccess/doc/admin/guide.html.wml b/modules/webaccess/doc/admin/guide.html.wml
index 5f7e8a7db..a5fa713b0 100644
--- a/modules/webaccess/doc/admin/guide.html.wml
+++ b/modules/webaccess/doc/admin/guide.html.wml
@@ -1,936 +1,936 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAccess Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/>Admin Area</a> &gt; <a class=navtrail href=<WEBURL>/admin/webaccess/>WebAccess Admin</a> " \
navbar_name="admin" \
navbar_select="webaccess-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">Introduction, using roles</a></strong><br>
<strong>2. <a href="#2">WebAccess admin interface</a></strong><br>
<strong>3. <a href="#3">Example pages, illustrating snapshots</a></strong><br>
<strong>4. <a href="#4">Managing accounts / Access policy</a></strong><br>
<strong>5. <a href="#5">Managing login methods</a></strong><br>
<h2><a name="1">1. INTRODUCTION, USING ROLES</a></h2>
<pre>
WebAccess is a common RBAC, role based access control, for all of
CDSware. This means that users are connected to roles that cover
different areas of access. I.e <em>administrator of the photo
collection</em> or <em>system librarian</em>. Users can be active in
different areas and of course connected to as many roles as needed.
The roles are connected to actions. An action identifies a task you
can perform in CDSware. It can be defined to take any number of
arguments in order to more clearly describe what you are allowing
connected users to do.
For example the system librarian can be allowed to run bibwords on
the different indexes. To allow system librarians to run the
bibwords indexing on the field author we connect role <em>system
librarian</em> with action <em>runbibwords</em> using the argument
<em>index='author'</em>.
WebAccess is based on allowing users to perform actions. This means
that only allowed actions are stored in the access control engine's
database.
</pre>
<h2><a name="2">2. WEBACCESS ADMIN INTERFACE</a></h2>
<pre>
All the WebAccess Administration web pages have certain
features/design choices in common
- Divided into steps
The process of adding new authorizations/information is
stepwise. The subtitle contains information about wich step you are
on and what you are supposed to do.
- Restart from any wanted step
You can always start from an earlier step by simply clicking the
wanted button. This is not a way to undo changes! No information
about previous database is kept, so all changes are definite.
- Change or new entry must confirmed
On all the pages you will be asked to confirm the change, with
information about what kind of change you are about to perform.
- Links to other relevant admin areas on the right side
To make it easier to perform your administration tasks, we have
added a menu area on the right hand side of these pages. The menu
contain links to other relevant admin pages and change according to
the page you are on and the information you have selected.
</pre>
<h2><a name="3">3. EXAMPLE PAGES</a></h2>
<pre>
I. Role area
II. Example - connecting role and user
I. Role area</a>
Administration tasks starts in one of the administration areas. The
role area is the main area from where you can perform all your
managing tasks. The other admin areas are just other ways of
entering.
</pre>
<div class="snapshot">
<div>
<table border="0" cellspacing="0" cellpadding="0" class="navtrailbox" width="100%" summary="">
<tr>
<td class="navtrailboxbody">
<a class="navtrail" href="">Home</a> &gt; <a class="navtrail" href="">Admin Area</a> &gt; <a class="navtrail" href="">WebAccess Admin</a> &gt;
<a class="navtrail" href="">Manage WebAccess</a> &gt; Role Administration
</td>
</tr>
</table>
</div>
<div class="pagebody">
<table border="0" cellspacing="0" cellpadding="0" width="100%" summary="">
<tr valign="top">
<td class="pagebodystripemiddle" align="left">
<h1 class="headline">Role Administration</h1>
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft" colspan="2">administration with roles as access point</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: top; margin-top: 5px; width: 75%;">
<dl>
<dt>Users:</dt>
<dd>add or remove users from the access to a role and its priviliges.</dd>
<dt>Authorizations/Actions:</dt>
<dd>these terms means almost the same, but an authorization is a <br>
connection between a role and an action (possibly) containing arguments.</dd>
<dt>Roles:</dt>
<dd>see all the information attached to a role and decide if you want to<br>delete it.</dd>
</dl>
<table class="admin_wvar_nomargin" summary="">
<tr>
<th class="adminheader">id</th>
<th class="adminheader">name</th>
<th class="adminheader">description</th>
<th class="adminheader">users</th>
<th class="adminheader">authorizations / actions</th>
<th class="adminheader">role</th>
<th class="adminheader"></th>
<th class="adminheader"></th>
</tr>
<tr>
<td class="admintdright">2</td>
<td class="admintdleft">photoadmin</td>
<td class="admintdleft">administrator of the photo col...</td>
<td class="admintdleft">
<a href="">add</a> /
<a href="">remove</a>
</td>
<td class="admintdleft">
<a href="">add</a> /
<a href="">modify</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">delete</a></td>
<td class="admintdleft"><a href="">show details</a></td>
<td rowspan="4" style="vertical-align: bottom">
</td>
</tr>
<tr>
<td class="admintdright">9</td>
<td class="admintdleft">submitter</td>
<td class="admintdleft"></td>
<td class="admintdleft">
<a href="">add</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">add</a> /
<a href="">modify</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">delete</a></td>
<td class="admintdleft"><a href="">show details</a></td>
</tr>
<tr>
<td class="admintdright">1</td>
<td class="admintdleft">superadmin</td>
<td class="admintdleft">all rights</td>
<td class="admintdleft"><a href="">add</a> / <a href="">remove</a></td>
<td class="admintdleft"><a href="">add</a> /
<a href="">modify</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">delete</a></td>
<td class="admintdleft"><a href="">show details</a></td>
</tr>
<tr>
<td class="admintdright">4</td>
<td class="admintdleft">systemlibrarian</td>
<td class="admintdleft">system librarian</td>
<td class="admintdleft">
<a href="">add</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">add</a> /
<a href="">modify</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">delete</a></td>
<td class="admintdleft"><a href="">show details</a></td>
</tr>
<tr>
<td class="admintdright">3</td>
<td class="admintdleft">webaccessadmin</td>
<td class="admintdleft">access to web administrator in...</td>
<td class="admintdleft">
<a href="">add</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">add</a> /
<a href="">modify</a> /
<a href="">remove</a>
</td>
<td class="admintdleft"><a href="">delete</a></td>
<td class="admintdleft"><a href="">show details</a></td>
</tr>
</table>
</td>
<td style="vertical-align: top; margin-top: 5px; width: 25%;">
<dl>
<dt><a href="">Create new role</a></dt>
<dd>go here to add a new role.</dd>
<dt><a href="">Create new action</a></dt>
<dd>go here to add a new action.</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
</div>
<pre>
II. Example - connecting role and user</a>
One of the important tasks that can be handled via the WebAccess Admin Web Interface
is the delegation of access rights to users. This is done by connecting them to the
different roles offered.
The task is divided into 5 simple and comprehensive steps. Below follows the pages from
the different steps with comments on the ongoing procedure.
- step 1 - select a role
You must first select the role you want to connect users to. All the available roles are
listed alfabetically in a select box. Just find the wanted role and select it. Then click on
the button saying &quot;select role&quot;.
If you start from the Role Area, this step is already done, and you start directly on step 2.
</pre>
<div class="snapshot">
<table border="0" cellspacing="0" cellpadding="0" class="navtrailbox" width="100%" summary="">
<tr>
<td class="navtrailboxbody">
<a class="navtrail" href="">Home</a> &gt; <a class="navtrail" href="">Admin Area</a> &gt; <a class="navtrail" href="">WebAccess Admin</a> &gt;
<a class="navtrail" href="">Manage WebAccess</a> &gt; <a class="navtrail" href="">Role Administration</a> &gt; Connect user to role
</td>
</tr>
</table>
<div class="pagebody">
<table border="0" cellspacing="0" cellpadding="0" width="100%" summary="">
<tr valign="top">
<td class="pagebodystripemiddle" align="left">
<h1 class="headline">Connect user to role </h1>
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft" colspan="2">step 1 - select a role</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: top; margin-top: 5px; width: 75%;">
<form action="" method="POST">
<span class="adminlabel">1. select role</span>
<select name="id_role" class="admin_w200">
<option value="0">*** select role ***</option>
<option value="2">photoadmin</option>
<option value="9">submitter</option>
<option value="1">superadmin</option>
<option value="4">systemlibrarian</option>
<option value="3">webaccessadmin</option>
</select>
<input class="adminbutton" type="submit" value="select role">
</form>
</td>
<td style="vertical-align: top; margin-top: 5px; width: 25%;">
<dl>
<dt><a href="">Create new role</a></dt>
<dd>go here to add a new role.</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</td>
<td class="pagebodystriperight" width="120" align="right" valign="top">
</td>
</tr>
</table>
</div>
</div>
<pre>
- step 2 - search for users
As you can see, the subtitle of the page has now changed. The subtitle always tells you
which step you are on and what your current task is.
There can be possibly thousands of users using your online library, therefore it is important
to make it easier to identify the user you are looking for. Give part of, or the entire search
string and all users with partly matching e-mails will be listed on the next step.
You can also see that the right hand menu has changed. This area is always updated with links
to related admin areas.
</pre>
<div class="snapshot">
<table border="0" cellspacing="0" cellpadding="0" class="navtrailbox" width="100%" summary="">
<tr>
<td class="navtrailboxbody">
<a class="navtrail" href="">Home</a> &gt; <a class="navtrail" href="">Admin Area</a> &gt; <a class="navtrail" href="">WebAccess Admin</a> &gt;
<a class="navtrail" href="">Manage WebAccess</a> &gt; <a class="navtrail" href="">Role Administration</a> &gt; Connect user to role
</td>
</tr>
</table>
<div class="pagebody">
<table border="0" cellspacing="0" cellpadding="0" width="100%" summary="">
<tr valign="top">
<td class="pagebodystripemiddle" align="left">
<h1 class="headline">Connect user to role </h1>
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft" colspan="2">step 2 - search for users</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: top; margin-top: 5px; width: 75%;">
<form action="" method="POST">
<span class="adminlabel">1. select role</span>
<select name="id_role" class="admin_w200">
<option value="0">*** select role ***</option>
<option value="2">photoadmin</option>
<option value="9">submitter</option>
<option value="1" selected="selected">superadmin</option>
<option value="4">systemlibrarian</option>
<option value="3">webaccessadmin</option>
</select>
<input class="adminbutton" type="submit" value="select role">
</form>
<form action="" method="POST">
<table summary="">
<tr>
<td>
<span class="adminlabel">2. search pattern </span>
<input class="admin_wvar" type="text" name="email_user_pattern" value="">
<input type="hidden" name="id_role" value="1">
</td>
<td style="vertical-align: bottom">
<input class="adminbutton" type="submit" value="search for users">
</td>
</tr>
</table>
</form>
</td>
<td style="vertical-align: top; margin-top: 5px; width: 25%;">
<dl>
<dt><a href="">Create new role</a></dt>
<dd>go here to add a new role.</dd>
</dl>
<dl>
<dt><a href="">Remove users</a></dt>
<dd>remove users from role superadmin.</dd>
<dt><a href="">Connected users</a></dt>
<dd>show all users connected to role superadmin.</dd>
</dl>
<dl>
<dt><a href="">Add authorization</a></dt>
<dd>start adding new authorizations to role superadmin.</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</td>
<td class="pagebodystriperight" width="120" align="right" valign="top">
</td>
</tr>
</table>
</div>
</div>
<pre>
- step 3 - select a user.
The select box contains all users with partly matching e-mail adresses. Select the one
you want to connect to the role and continue.
Notice the navigation trail that tells you were on the Administrator pages you are currently
working.
</pre>
<div class="snapshot">
<table border="0" cellspacing="0" cellpadding="0" class="navtrailbox" width="100%" summary="">
<tr>
<td class="navtrailboxbody">
<a class="navtrail" href="">Home</a> &gt; <a class="navtrail" href="">Admin Area</a> &gt; <a class="navtrail" href="">WebAccess Admin</a> &gt;
<a class="navtrail" href="">Manage WebAccess</a> &gt; <a class="navtrail" href="">Role Administration</a> &gt; Connect user to role
</td>
</tr>
</table>
<div class="pagebody">
<table border="0" cellspacing="0" cellpadding="0" width="100%" summary="">
<tr valign="top">
<td class="pagebodystripemiddle" align="left">
<h1 class="headline">Connect user to role </h1>
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft" colspan="2">step 3 - select a user</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: top; margin-top: 5px; width: 75%;">
<form action="" method="POST">
<span class="adminlabel">1. select role</span>
<select name="id_role" class="admin_w200">
<option value="0">*** select role ***</option>
<option value="2">photoadmin</option>
<option value="9">submitter</option>
<option value="1" selected="selected">superadmin</option>
<option value="4">systemlibrarian</option>
<option value="3">webaccessadmin</option>
</select>
<input class="adminbutton" type="submit" value="select role">
</form>
<form action="" method="POST">
<table summary="">
<tr>
<td>
<span class="adminlabel">2. search pattern </span>
<input class="admin_wvar" type="text" name="email_user_pattern" value="k">
<input type="hidden" name="id_role" value="1">
</td>
<td style="vertical-align: bottom">
<input class="adminbutton" type="submit" value="search for users">
</td>
</tr>
</table>
</form>
<form action="" method="POST">
<span class="adminlabel">3. select user</span>
<select name="id_user" class="admin_w200">
<option value="0">*** select user ***</option>
<option value="136">franck.black@cern.ch</option>
<option value="134">kurt.cobain@cern.ch</option>
<option value="100" selected="selected">mikael.vik@cern.ch</option>
<option value="-6">tibor.simko@cern.ch (connected)</option>
</select>
<input type="hidden" name="id_role" value="1">
<input type="hidden" name="email_user_pattern" value="k">
<input class="adminbutton" type="submit" value="add this user">
</form>
</td>
<td style="vertical-align: top; margin-top: 5px; width: 25%;">
<dl>
<dt><a href="">Create new role</a></dt>
<dd>go here to add a new role.</dd>
</dl>
<dl>
<dt><a href="">Remove users</a></dt>
<dd>remove users from role superadmin.</dd>
<dt><a href="">Connected users</a></dt>
<dd>show all users connected to role superadmin.</dd>
</dl>
<dl>
<dt><a href="">Add authorization</a></dt>
<dd>start adding new authorizations to role superadmin.</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</td>
<td class="pagebodystriperight" width="120" align="right" valign="top">
</td>
</tr>
</table>
</div>
</div>
<pre>
- step 4 - confirm to add user
All WebAccess Administrator web pages display the action you are about to peform, this
means explaining what kind of addition, change or update will be done to your access control
data.
If you are happy with your decision, simply confirm it.
</pre>
<div class="snapshot">
<table border="0" cellspacing="0" cellpadding="0" class="navtrailbox" width="100%" summary="">
<tr>
<td class="navtrailboxbody">
<a class="navtrail" href="">Home</a> &gt; <a class="navtrail" href="">Admin Area</a> &gt; <a class="navtrail" href="">WebAccess Admin</a> &gt;
<a class="navtrail" href="">Manage WebAccess</a> &gt; <a class="navtrail" href="">Role Administration</a> &gt; Connect user to role
</td>
</tr>
</table>
<div class="pagebody">
<table border="0" cellspacing="0" cellpadding="0" width="100%" summary="">
<tr valign="top">
<td class="pagebodystripemiddle" align="left">
<h1 class="headline">Connect user to role </h1>
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft" colspan="2">step 4 - confirm to add user</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: top; margin-top: 5px; width: 75%;">
<form action="" method="POST">
<span class="adminlabel">1. select role</span>
<select name="id_role" class="admin_w200">
<option value="0">*** select role ***</option>
<option value="2">photoadmin</option>
<option value="9">submitter</option>
<option value="1" selected="selected">superadmin</option>
<option value="4">systemlibrarian</option>
<option value="3">webaccessadmin</option>
</select>
<input class="adminbutton" type="submit" value="select role">
</form>
<form action="" method="POST">
<table summary="">
<tr>
<td>
<span class="adminlabel">2. search pattern </span>
<input class="admin_wvar" type="text" name="email_user_pattern" value="k">
<input type="hidden" name="id_role" value="1">
</td>
<td style="vertical-align: bottom">
<input class="adminbutton" type="submit" value="search for users">
</td>
</tr>
</table>
</form>
<form action="" method="POST">
<span class="adminlabel">3. select user</span>
<select name="id_user" class="admin_w200">
<option value="0">*** select user ***</option>
<option value="136">franck.black@cern.ch</option>
<option value="134">kurt.cobain@cern.ch</option>
<option value="100" selected="selected">mikael.vik@cern.ch</option>
<option value="-6">tibor.simko@cern.ch (connected)</option>
</select>
<input type="hidden" name="id_role" value="1">
<input type="hidden" name="email_user_pattern" value="k">
<input class="adminbutton" type="submit" value="add this user">
</form>
<form action="" method="POST">
<table summary="">
<tr>
<td>add user <strong>mikael.vik@cern.ch</strong> to role <strong>superadmin</strong>?
<input type="hidden" name="confirm" value="1">
<input type="hidden" name="id_user" value="100">
<input type="hidden" name="id_role" value="1">
<input type="hidden" name="email_user_pattern" value="k">
</td>
<td style="vertical-align: bottom">
<input class="adminbutton" type="submit" value="confirm">
</td>
</tr>
</table>
</form>
</td>
<td style="vertical-align: top; margin-top: 5px; width: 25%;">
<dl>
<dt><a href="">Create new role</a></dt>
<dd>go here to add a new role.</dd>
</dl>
<dl>
<dt><a href="">Remove users</a></dt>
<dd>remove users from role superadmin.</dd>
<dt><a href="">Connected users</a></dt>
<dd>show all users connected to role superadmin.</dd>
</dl>
<dl>
<dt><a href="">Add authorization</a></dt>
<dd>start adding new authorizations to role superadmin.</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</td>
<td class="pagebodystriperight" width="120" align="right" valign="top">
</td>
</tr>
</table>
</div>
</div>
<pre>
- step 5 - confirm user added.
The user has now been added to this role. You can easily continue adding more users to this
role be restarting from step 2 or 3. You can also go directly to another area and keep working
on the same role.
</pre>
<div class="snapshot">
<table border="0" cellspacing="0" cellpadding="0" class="navtrailbox" width="100%" summary="">
<tr>
<td class="navtrailboxbody">
<a class="navtrail" href="">Home</a> &gt; <a class="navtrail" href="">Admin Area</a> &gt; <a class="navtrail" href="">WebAccess Admin</a> &gt;
<a class="navtrail" href="">Manage WebAccess</a> &gt; <a class="navtrail" href="">Role Administration</a> &gt; Connect user to role
</td>
</tr>
</table>
<div class="pagebody">
<table border="0" cellspacing="0" cellpadding="0" width="100%" summary="">
<tr valign="top">
<td class="pagebodystripemiddle" align="left">
<h1 class="headline">Connect user to role </h1>
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft" colspan="2">step 5 - confirm user added</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: top; margin-top: 5px; width: 75%;">
<form action="" method="POST">
<span class="adminlabel">1. select role</span>
<select name="id_role" class="admin_w200">
<option value="0">*** select role ***</option>
<option value="2">photoadmin</option>
<option value="9">submitter</option>
<option value="1" selected="selected">superadmin</option>
<option value="4">systemlibrarian</option>
<option value="3">webaccessadmin</option>
</select>
<input class="adminbutton" type="submit" value="select role">
</form>
<form action="" method="POST">
<table summary="">
<tr>
<td>
<span class="adminlabel">2. search pattern </span>
<input class="admin_wvar" type="text" name="email_user_pattern" value="k">
<input type="hidden" name="id_role" value="1">
</td>
<td style="vertical-align: bottom">
<input class="adminbutton" type="submit" value="search for users">
</td>
</tr>
</table>
</form>
<form action="" method="POST">
<span class="adminlabel">3. select user</span>
<select name="id_user" class="admin_w200">
<option value="0">*** select user ***</option>
<option value="136">franck.black@cern.ch</option>
<option value="134">kurt.cobain@cern.ch</option>
<option value="100" selected="selected">mikael.vik@cern.ch</option>
<option value="-6">tibor.simko@cern.ch (connected)</option>
</select>
<input type="hidden" name="id_role" value="1">
<input type="hidden" name="email_user_pattern" value="k">
<input class="adminbutton" type="submit" value="add this user">
</form>
<form action="" method="POST">
<table summary="">
<tr>
<td>add user <strong>mikael.vik@cern.ch</strong> to role <strong>superadmin</strong>?
<input type="hidden" name="confirm" value="1">
<input type="hidden" name="id_user" value="100">
<input type="hidden" name="id_role" value="1">
<input type="hidden" name="email_user_pattern" value="k">
</td>
<td style="vertical-align: bottom">
<input class="adminbutton" type="submit" value="confirm">
</td>
</tr>
</table>
</form>
<p>confirm: user <strong>mikael.vik@cern.ch</strong> added to role <strong>superadmin</strong>.</p>
</td>
<td style="vertical-align: top; margin-top: 5px; width: 25%;">
<dl>
<dt><a href="">Create new role</a></dt>
<dd>go here to add a new role.</dd>
</dl>
<dl>
<dt><a href="">Remove users</a></dt>
<dd>remove users from role superadmin.</dd>
<dt><a href="">Connected users</a></dt>
<dd>show all users connected to role superadmin.</dd>
</dl>
<dl>
<dt><a href="">Add authorization</a></dt>
<dd>start adding new authorizations to role superadmin.</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</td>
<td class="pagebodystriperight" width="120" align="right" valign="top">
</td>
</tr>
</table>
</div>
</div>
<pre>
- we are done
This example is very similar to all the other pages where you administrate WebAccess. The pages
are an easy gateway to maintaing access control rights and share a lot of features.
- divided into steps
- restart from any wanted step (not undo)
- changes must be confirmed
- link to other relevant areas
- prevent unwanted input
As an administrator with access to these pages you are free to manage the rights any way you want.
</pre>
<h2><a name="4">IV. Managing accounts and access policy</a></h2>
<pre>
Here you can administrate the accounts and the access policy for your CDSware installation.
- Access policy:
To change the access policy, the general config file (or
access_control_config.py) must be edited manually in a text
editor. The site can there be defined as opened or closed, you can
edit the access policy level for guest accounts, registered
accounts and decide when to warn the owner of the account when
something happens with it, either when it is created, deleted or
approved. The Apache server must be restarted after modifying
these settings.
The two levels for guest account, are:
0 - Allow guest accounts
1 - Do not allow guest accounts
The five levels for normal accounts, are:
0 - Allow user to create account, automatically activate new accounts
1 - Allow user to create account, administrator must activate account
2 - Only administrators can create account. User cannot edit the email address.
3 - Users cannot register or update account information (email/password)
4 - User cannot change default login method
You can configure CDSware to send an email:
1. To an admin email-address when an account is created
2. To the owner of an account when it is created
3. To the owner of an account when it is activated
4. To the owner of an account when it is deleted
Define how open the site is:
0 = normal operation of the site
1 = read-only site, all write operations temporarily closed
2 = site fully closed
CFG_ACCESS_CONTROL_LEVEL_SITE = 0
Access policy for guests:
0 = Allow guests to search,
1 = Guests cannot search (all users must login)
CFG_ACCESS_CONTROL_LEVEL_GUESTS = 0
Access policy for accounts:
0 = Users can register, automatically acticate accounts
1 = Users can register, but admin must activate the accounts
2 = Users cannot register or change email address, only admin can register accounts.
3 = Users cannot register or update email address or password, only admin can register accounts.
4 = Same as 3, but user cannot change login method.
CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS = 0
Limit email addresses available to use when register a new account (example: cern.ch):
CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN = ""
Send an email when a new account is created by an user:
CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS = 0
Send an email to the user notifying when the account is created:
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT = 0
Send an email to the user notifying when the account is activated:
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION = 0
Send an email to the user notifying when the account is deleted/rejected:
CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION = 0
- Account overview:
Here you find an overview of the number of guest accounts, registered accounts and accounts
awaiting activation, with a link to the activation page.
- Create account:
For creating new accounts, the email address must be unique. If configured to do so, an email
will be sent to the given address when an account is created.
- Edit accounts:
For activating or rejecting accounts in addition to modifying them. An activated account can be
inactivated for a short period of time, but this will not warn the account owner. To find accounts
enter a part of the email address of the account and then search. This may take some time. If there
are more than the selected number of accounts per page, you can use the next/prev links to switch
pages. The accounts to search in can also be limited to only activated or not activated accounts.
- Edit account:
When editing one account, you can change the email address, password, delete the account, or modify
the baskets or alerts belonging to one account. Which login method should be the default for this
account can also be selected. To modify baskets or alerts, you need to login as the user, and
modify the desired data as a normal user. Remember to log out as the user when you are finished
editing.
</pre>
<h2><a name="5">V. Managing login methods</a></h2>
<pre>
CDSware supports using external login systems to authenticate users.
When a user wants to login, the username and password given by the user is checked against the selected
system, if the user is authenticated by the external system, a valid email-address is returned to
CDSware and used to recognize the user within CDSware.
If a new user is trying to login without having an account, using an external login system, an account
is automatically created in CDSware to recognize and store the users settings. The password for the
local account is randomly generated.
If you want the user to be unable to change login method and account username / password, forcing use
of certain external systems, set CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS to 4 as mentioned in the last paragraph.
If a user is changing login method from an external one to the internal, he also need to either change the
password before logging out, or ask to get the password sent by email, since the password is randomly
generated for the local account when using an external login method.
If a external login system is used, you may want to protect the users username / password using HTTPS.
To add new system, two changes must be made:
- The name of the method, if it is default or not, and the classname must be added to the variable
CFG_EXTERNAL_AUTHENTICATION in access_control_config.py. Atleast one method must be marked as the
default one. The internal login method should be given with None as classname.
Example:
CFG_EXTERNAL_AUTHENTICATION = {"%s (internal)" % cdsname: (None, True), "CERN NICE (external)":
(external_auth_nice(), False)}
- A class must be added in the file external_authentication.py. This class must include the
function auth_user. This function returns a valid email-address in CDSware if the user
is authenticated, not necessarily the same entered by the user as username. If the user
is not authenticated, return None.
Example template:
class external_auth_template:
def __init__(self):
pass
def auth_user(self, username, password):
return email
return None
- end of file -
</pre>
diff --git a/modules/webaccess/doc/admin/index.html.wml b/modules/webaccess/doc/admin/index.html.wml
index 7c8eba78c..cb51702a0 100644
--- a/modules/webaccess/doc/admin/index.html.wml
+++ b/modules/webaccess/doc/admin/index.html.wml
@@ -1,50 +1,50 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAccess Admin" \
navbar_name="hacking-webaccess" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/>Admin Area</a> " \
navbar_name="admin" \
navbar_select="webaccess"
<p>
This is the gate to the admin area for WebAccess. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/webaccess/">login</a> to enter.
</p>
<dl>
<dt><a href="webaccessadmin.py">Manage WebAccess - Full Functionality</a>.</dt>
<dd>Start area for WebAccess administration. Here you have <br>
all possibility to manage, grant and revoke rights to anyone.</dd>
</dl>
<dl>
<dt><a href="webaccessadmin.py/delegate_startarea">Delegate Rights - With Restrictions</a>.</dt>
<dd>Delegate the rights to a specified number of roles. <br>
Everything you can do here is also allowed in the Main Admin Area. <br>
Contact Main Administrator for delegation rights.</dd>
</dl>
<dl>
<dt><a href="webaccessadmin.py/manageaccounts">Manage Accounts</a>.</dt>
<dd>Start area for WebAccess Account Administration. Here you can <br>
enable, disable and modify accounts.</dd>
</dl>
<dl>
<dt><a href="<WEBURL>/admin/webaccess/guide.html">Guide</a>.</dt>
<dd>How to administrate WebAccess.</dd>
</dl>
diff --git a/modules/webaccess/doc/hacking/Makefile.am b/modules/webaccess/doc/hacking/Makefile.am
index 3456f2b09..f9cc5a379 100644
--- a/modules/webaccess/doc/hacking/Makefile.am
+++ b/modules/webaccess/doc/hacking/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/webaccess
doc_DATA=index.html api.html admin-internals.html table-structure.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webaccess/doc/hacking/admin-internals.html.wml b/modules/webaccess/doc/hacking/admin-internals.html.wml
index 32449bb99..42fa031f7 100644
--- a/modules/webaccess/doc/hacking/admin-internals.html.wml
+++ b/modules/webaccess/doc/hacking/admin-internals.html.wml
@@ -1,157 +1,157 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Access Control Admin Internals" \
navbar_name="hacking-webaccess" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/webaccess/index.html>WebAccess Internals</a> " \
navbar_select="hacking-webaccess-admin-internals"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
These are the functions called by the WebAccess Web Admin Interface to administrate
the wanted authorizations. This listing is of the most important functions.
For more information look in the source code or at the signatures.
CONTENTS
1. Adding Information
2. Finding Information
3. Deleting Information
1. Adding Information
acc_addAction(name_action='', description='', optional='no', *allowedkeywords)
function to create new entry in accACTION for an action
name_action - name of the new action, must be unique
keyvalstr - string with allowed keywords
allowedkeywords - a list of allowedkeywords
keyvalstr and allowedkeywordsdict can not be in use simultanously
success -> return id_action, name_action, description and allowedkeywords
failure -> return 0
acc_addRole(name_role, description)
add a new role to accROLE in the database.
name_role - name of the role, must be unique
description - text to describe the role
acc_addUserRole(id_user=0, id_role=0, email='', name_role='')
this function adds a new entry to table user_accROLE and returns it
id_user, id_role - self explanatory
email - email of the user
name_role - name of the role, to be used instead of id.
acc_addRoleActionArguments_names(name_role='', name_action='', arglistid=-1, optional=0, verbose=0, **keyval)
this function makes it possible to pass names when creating new entries instead of ids.
get ids for all the names,
create entries in accARGUMENT that does not exist,
pass on to id based function.
name_role, name_action - self explanatory
arglistid - add entries to or create group with arglistid, default -1 create new.
optional - create entry with optional keywords, **keyval is ignored, but should be empty
verbose - used to print extra information
**keyval - dictionary of keyword=value pairs, used to find ids.
2. Finding Information
acc_findPossibleActions(id_role, id_action)
Role based function to find all action combinations for a
give role and action.
id_role - id of role in the database
id_action - id of the action in the database
returns a list with all the combinations.
first row is used for header.
3. Deleting Information
acc_deleteAction(id_action=0, name_action=0)
delete action in accACTION according to id, or secondly name.
entries in accROLE_accACTION_accARGUMENT will also be removed.
id_action - id of action to be deleted, prefered variable
name_action - this is used if id_action is not given
if the name or id is wrong, the function does nothing
acc_deleteRole(id_role=0, name_role=0)
delete role entry in table accROLE and all references from other tables.
id_role - id of role to be deleted, prefered variable
name_role - this is used if id_role is not given
acc_deleteUserRole(id_user, id_role=0, name_role=0)
function deletes entry from user_accROLE and reports the success.
id_user - user in database
id_role - role in the database, prefered parameter
name_role - can also delete role on background of role name.
acc_deleteRoleActionArguments_names(name_role='', name_action='', arglistid=1, **keyval)
utilize the function on ids by first finding all ids and redirecting the function call.
break of and return 0 if any of the ids can't be found.
name_role = name of the role
name_action - name of the action
arglistid - the argumentlistid, all keyword=value pairs must be in this same group.
**keyval - dictionary of keyword=value pairs for the arguments.
</pre>
diff --git a/modules/webaccess/doc/hacking/api.html.wml b/modules/webaccess/doc/hacking/api.html.wml
index ff80f1220..5744bd832 100644
--- a/modules/webaccess/doc/hacking/api.html.wml
+++ b/modules/webaccess/doc/hacking/api.html.wml
@@ -1,172 +1,172 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Access Control Engine API" \
navbar_name="hacking-webaccess" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/webaccess/index.html>WebAccess Internals</a> " \
navbar_select="hacking-webaccess-engine-api"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
CDSware Access Control Engine can be called from within your Python programs
via both a regular Python API and CLI.
In addition the you get an explanation of the program flow.
Contents:
1. Regular API
2. Command Line Interface
3. Program Flow
4. External login methods
1. Regular API
Description:
There is not very much information in the database at the moment.
More can be added on demand.
Information on these will be added when time allows it.
Signature:
def acc_authorize_action(id_user, name_action, dict={}, **arguments):
""" Check if user is allowed to perform action
with given list of arguments.
Return (0, message) if authentication succeeds, (error_code, error_message) if it fails.
The arguments are as follows:
id_user - id of the user to be authorized in the database
name_action - the name of the action
arguments - dictionary with keyword=value pairs created automatically
by python on the extra arguments. these depend on the
given action. """
Examples:
>>> # import the functions from module
>>> # change this to your local settings...
>>> pylibdir = '/log/cdsware-DEMODEV/lib/python/cdsware/'
>>> import sys
>>> sys.path.append('%s' % pylibdir)
>>> from access_control_engine import *
>>> # authorize user 109 for action WebSearch_search with collection="LHC"
>>> acc_authorize_action(109, 'cfgwebsearch', collection="LHC")
(0, "User authorized")
>>> # authorize user 109 for action WebSearch_search with collection="fail this"
>>> acc_authorize_action(109, 'cfgwebsearch', collection="fail this")
(8, "Error (8): Incorrect keyword given for specified action.")
>>> # authorize user 109 for action BibFormat_modify with format="htmlbrief"
>>> acc_authorize_action(109, 'cfgbibformat', format="htmlbrief")
(0, "User authorized")
2. Command Line Interface
Description:
The Command Line Interface uses the regular API of acc_authorize_action.
Signature:
authaction id_user name_action keyword1 value1 keyword2 value2 ...
""" See description from function acc_authorize_action.
id_user - id of user to be authorized
name_action - name of the action
keyword1 - first keyword like in the keyword=value pairs,
same rules for the following ones.
always one word.
value1 - value that belongs in a pair with the corresponding keyword,
same rules for the following ones.
add quotes if it is more that one word.
the keyword=value pairs are collected in a dictionary
"""
Examples:
These are the same ones as for the regular API:
$ authaction 109 cfgwebsearch collection LHC
0 - User authorized
$ authaction 109 cfgwebsearch collection 'fail this'
8 - Error (8): Incorrect keyword given for specified action.
$ authaction 109 cfgbibformat format htmlbrief
0 - User authorized
3. Program Flow
this is a quick explanation of the different tasks
performed by the authorization engine.
I. find information for the action
use admin API to find info.
II. see if user is a superadmin
query the database for connection between user and role superadmin.
-> authorize if yes
III. check if the user exists and find all of the users roles and create string with the ids
query the database and build string of ids
-> don't authorize if no roles
IV. try to authorize without arguments
action without arguments: query database
-> authorize if yes
action with optional arguments
-> authorize if yes
V. create list of keyword=value pairs to query the database
run through dictionary and create string for adding to database query
VI. find all table entries from the database
query the database for table entries
create list of the tuples and sort it
-> don't authorize if no entries
-> authorize if only 1 argument and result
VII. combine entries and try to satisfy authorization
dictionary with the arguments as keys, all values 0
run throught the list created in VI
if moving on to new authorization
check dictionary values
-> authorize if combination found
reset values to 0 if not found
set dictionary[keyword] to 1.
(countinue loop)
VIII. all the above failed
-> authorization failed
4. External login methods
If you want to call defined external loginmethods, it can be done by:
import cdsware.external_authentication
example_method = cdsware.external_authentication.example()
example_method.auth_user("testuser", "testpassword")
Example is here a class used as an example, which must contain the method
auth_user.
</pre>
diff --git a/modules/webaccess/doc/hacking/index.html.wml b/modules/webaccess/doc/hacking/index.html.wml
index b50dda978..d02732aa8 100644
--- a/modules/webaccess/doc/hacking/index.html.wml
+++ b/modules/webaccess/doc/hacking/index.html.wml
@@ -1,41 +1,41 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAccess Internals" \
navbar_name="hacking-webaccess" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a>" \
navbar_select="hacking-webaccess-index"
This page summarizes all the information suitable to dig inside
the WebAccess internals.
<blockquote>
<dl>
<dt><a href="api.html">Access Control Engine API</a> </dt>
<dd>Explains how to call access control engine from your Python programs.<br>
In addition the program flow is explained briefly.</dd>
<dt><a href="admin-internals.html">Access Control Admin Internals</a> </dt>
<dd>Explains how to administrate the authorizations stored in the database for <br>
WebAccess. Not all functions are mentioned. All mentioned functions are <br>
represented with signatures, some with additional explanations as well.</dd>
<dt><a href="table-structure.html">Access Control Table Structure</a> </dt>
<dd>Explains the structure of the WebAccess tables and how to create authorizations.</dd>
</dl>
</blockquote>
diff --git a/modules/webaccess/doc/hacking/table-structure.html.wml b/modules/webaccess/doc/hacking/table-structure.html.wml
index 4eaa06fa4..bf4fe5366 100644
--- a/modules/webaccess/doc/hacking/table-structure.html.wml
+++ b/modules/webaccess/doc/hacking/table-structure.html.wml
@@ -1,105 +1,105 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAccess Table Structure" \
navbar_name="hacking-webaccess" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=<WEBURL>/hacking/webaccess/index.html>WebAccess Internals</a> " \
navbar_select="hacking-webaccess-tabfill"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
Explanation of the WebAccess table structure and how to create authorizations.
-- accROLE --
roles are collections of authorizations within specified areas. these should
have a clear connection, for example within a module or for a special type of
person, e.g a library administator.
id - specify the id of the role
name - unique name for the role
description - describe the authorization tasks the role will cover
-- user_accROLE --
give users access to the authorizations/actions provided by the given role.
id_user - id of user in the database, usually just the supportemail and/or adminemail
id_accROLE - id of role from accROLE
-- accACTION --
the actions specify what information is needed to create an authorization.
an action can take any number of arguments, and you also have the possibility to
make these arguments optional.
id - specify the id of the action
name - unique name for the action
description - describe authorization area
allowedkeywords - the keywords for the wanted arguments
optional - enum to define wether arguments can be optional
value: ['yes', 'no']
'no' - action without arguments or not optional arguments
'yes' - only actions with arguments
-- accARGUMENT --
arguments for the authorizations. one entry might be shared by several authorizations,
so it is important to not change these but simply add new ones when a change is needed.
id - id of the argument
keyword - the one listed in an action's allowedkeywords
value - the value connected to the keyword in an keyword=value argument pair
-- accROLE_accACTION_accARGUMENT --
ternary connection to create authorizations. when an authorization has more than
one argument they need to be connected somehow. the same id for role, action and
argumentlist does this. there must be at least as many entries as allowedkeywords
for the action. with more entries all authorizations are found using a cross product.
id_accARGUMENT and argumentlistid are both set to 0 when the action have no arguments.
with optional arguments they are both set to -1.
id_accROLE - reference to argument in table accROLE
id_accACTION - reference to argument in table accACTION
id_accARGUMENT - reference to argument in table accARGUMENT
argumentlistid - glue to bind entries into authorizations.
</pre>
diff --git a/modules/webaccess/lib/Makefile.am b/modules/webaccess/lib/Makefile.am
index cd9d1c097..53773a51c 100644
--- a/modules/webaccess/lib/Makefile.am
+++ b/modules/webaccess/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = access_control_engine.py access_control_config.py access_control_admin.py webaccessadmin_lib.py external_authentication.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webaccess/lib/access_control_admin.py b/modules/webaccess/lib/access_control_admin.py
index d75ac246b..98ab702c9 100644
--- a/modules/webaccess/lib/access_control_admin.py
+++ b/modules/webaccess/lib/access_control_admin.py
@@ -1,1588 +1,1588 @@
# $Id$
## CDSware Access Control Engine in mod_python.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Access Control Admin."""
__version__ = "$Id$"
# check this: def acc_addUserRole(id_user, id_role=0, name_role=0):
## import interesting modules:
import sys
import time
from MySQLdb import ProgrammingError
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_config import *
from cdsware.config import *
from cdsware.dbquery import run_sql
# ACTIONS
def acc_addAction(name_action='', description='', optional='no', *allowedkeywords):
"""function to create new entry in accACTION for an action
name_action - name of the new action, must be unique
keyvalstr - string with allowed keywords
allowedkeywords - a list of allowedkeywords
keyvalstr and allowedkeywordsdict can not be in use simultanously
success -> return id_action, name_action, description and allowedkeywords
failure -> return 0 """
keystr = ''
# action with this name all ready exists, return 0
if run_sql("""SELECT * FROM accACTION WHERE name = '%s'""" % (name_action, )):
return 0
# create keyword string
for value in allowedkeywords:
if keystr: keystr += ','
keystr += value
if not allowedkeywords: optional = 'no'
# insert the new entry
try: res = run_sql("""INSERT INTO accACTION (name, description, allowedkeywords, optional) VALUES ('%s', '%s', '%s', '%s')""" % (name_action, description, keystr, optional))
except ProgrammingError: return 0
if res: return res, name_action, description, keystr, optional
return 0
def acc_deleteAction(id_action=0, name_action=0):
"""delete action in accACTION according to id, or secondly name.
entries in accROLE_accACTION_accARGUMENT will also be removed.
id_action - id of action to be deleted, prefered variable
name_action - this is used if id_action is not given
if the name or id is wrong, the function does nothing
"""
if id_action and name_action:
return 0
# delete the action
if run_sql("""DELETE FROM accACTION WHERE id = %s OR name = '%s'""" % (id_action, name_action)):
# delete all entries related
return 1 + run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT WHERE id_accACTION = %s """ % (id_action, ))
else:
return 0
def acc_verifyAction(name_action='', description='', allowedkeywords='', optional=''):
"""check if all the values of a given action are the same as
those in accACTION in the database. self explanatory parameters.
return id if identical, 0 if not. """
id_action = acc_getActionId(name_action=name_action)
if not id_action: return 0
res_desc = acc_getActionDescription(id_action=id_action)
res_keys = acc_getActionKeywordsString(id_action=id_action)
bool_desc = res_desc == description and 1 or 0
bool_keys = res_keys == allowedkeywords and 1 or 0
bool_opti = acc_getActionIsOptional(id_action=id_action)
return bool_desc and bool_keys and bool_opti and id_action or 0
def acc_updateAction(id_action=0, name_action='', verbose=0, **update):
"""try to change the values of given action details.
if there is no change nothing is done.
some changes require to update other parts of the database.
id_action - id of the action to change
name_action - if no id_action is given try to find it using this name
**update - dictionary containg keywords: description,
allowedkeywords and/or
optional
other keywords are ignored """
id_action = id_action or acc_getActionId(name_action=name_action)
if not id_action: return 0
try:
if update.has_key('description'):
# change the description, no other effects
if verbose: print 'desc'
run_sql("""UPDATE accACTION SET description = '%s' WHERE id = %s"""
% (update['description'], id_action))
if update.has_key('allowedkeywords'):
# change allowedkeywords
if verbose: print 'keys'
# check if changing allowedkeywords or not
if run_sql("""SELECT * FROM accACTION
WHERE id = %s AND allowedkeywords != '%s' """ % (id_action, update['allowedkeywords'])):
# change allowedkeywords
if verbose: print ' changing'
run_sql("""UPDATE accACTION SET allowedkeywords = '%s' WHERE id = %s"""
% (update['allowedkeywords'], id_action))
# delete entries, but keep optional authorizations if there still is keywords
if verbose: print ' deleting auths'
run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accACTION = %s %s """ % (id_action, update['allowedkeywords'] and 'AND id_accARGUMENT != -1' or ''))
if update.has_key('optional'):
# check if there changing optional or not
if verbose: print 'optional'
if run_sql("""SELECT * FROM accACTION
WHERE id = %s AND optional != '%s' """ % (id_action, update['optional'])):
# change optional
if verbose: print ' changing'
run_sql("""UPDATE accACTION SET optional = '%s' WHERE id = %s"""
% (update['optional'], id_action))
# setting it to no, delete authorizations with optional arguments
if update['optional'] == 'no':
if verbose: print ' deleting optional'
run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accACTION = %s AND
id_accARGUMENT = -1 AND
argumentlistid = -1 """ % (id_action, ))
except ProgrammingError:
return 0
return 1
# ROLES
def acc_addRole(name_role, description):
"""add a new role to accROLE in the database.
name_role - name of the role, must be unique
description - text to describe the role"""
if not run_sql("""SELECT * FROM accROLE WHERE name = '%s'""" % (name_role, )):
res = run_sql("""INSERT INTO accROLE (name, description) VALUES ('%s', '%s') """ % (name_role, description))
return res, name_role, description
return 0
def acc_isRole(name_action,**arguments):
""" check whether the role which allows action name_action on arguments exists
action_name - name of the action
arguments - arguments for authorization"""
# first check if an action exists with this name
query1 = """select a.id, a.allowedkeywords, a.optional
from accACTION a
where a.name = '%s'""" % (name_action)
try: id_action, aallowedkeywords, optional = run_sql(query1)[0]
except (ProgrammingError, IndexError): return 0
defkeys = aallowedkeywords.split(',')
for key in arguments.keys():
if key not in defkeys: return 0
# then check if a role giving this authorization exists
# create dictionary with default values and replace entries from input arguments
defdict = {}
for key in defkeys:
try: defdict[key] = arguments[key]
except KeyError: return 0 # all keywords must be present
# except KeyError: defdict[key] = 'x' # default value, this is not in use...
# create or-string from arguments
str_args = ''
for key in defkeys:
if str_args: str_args += ' OR '
str_args += """(arg.keyword = '%s' AND arg.value = '%s')""" % (key, defdict[key])
query4 = """SELECT DISTINCT raa.id_accROLE, raa.id_accACTION, raa.argumentlistid,
raa.id_accARGUMENT, arg.keyword, arg.value
FROM accROLE_accACTION_accARGUMENT raa, accARGUMENT arg
WHERE raa.id_accACTION = %s AND
(%s) AND
raa.id_accARGUMENT = arg.id """ % (id_action, str_args)
try: res4 = run_sql(query4)
except ProgrammingError: return 0
if not res4: return 0 # no entries at all
res5 = []
for res in res4:
res5.append(res)
res5.sort()
if len(defdict) == 1: return 1
cur_role = cur_action = cur_arglistid = 0
booldict = {}
for key in defkeys: booldict[key] = 0
# run through the results
for (role, action, arglistid, arg, keyword, val) in res5 + [(-1, -1, -1, -1, -1, -1)]:
# not the same role or argumentlist (authorization group), i.e. check if thing are satisfied
# if cur_arglistid != arglistid or cur_role != role or cur_action != action:
if (cur_arglistid, cur_role, cur_action) != (arglistid, role, action):
# test if all keywords are satisfied
for value in booldict.values():
if not value: break
else:
return 1 # USER AUTHENTICATED TO PERFORM ACTION
# assign the values for the current tuple from the query
cur_arglistid, cur_role, cur_action = arglistid, role, action
for key in booldict.keys():
booldict[key] = 0
# set keyword qualified for the action, (whatever result of the test)
booldict[keyword] = 1
# matching failed
return 0
def acc_deleteRole(id_role=0, name_role=0):
""" delete role entry in table accROLE and all references from other tables.
id_role - id of role to be deleted, prefered variable
name_role - this is used if id_role is not given """
count = 0
id_role = id_role or acc_getRoleId(name_role=name_role)
# try to delete
if run_sql("""DELETE FROM accROLE WHERE id = %s """ % (id_role, )):
# delete everything related
# authorization entries
count += 1 + run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = %s""" % (id_role, ))
# connected users
count += run_sql("""DELETE FROM user_accROLE WHERE id_accROLE = %s """ % (id_role, ))
# delegated rights over the role
rolenames = run_sql("""SELECT name FROM accROLE""")
# string of rolenames
roles_str = ''
for (name, ) in rolenames: roles_str += (roles_str and ',' or '') + '"%s"' % (name, )
# arguments with non existing rolenames
not_valid = run_sql("""SELECT ar.id FROM accARGUMENT ar WHERE keyword = 'role' AND value NOT IN (%s)""" % (roles_str, ))
if not_valid:
nv_str = ''
for (id, ) in not_valid: nv_str += (nv_str and ',' or '') + '%s' % (id, )
# delete entries
count += run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accACTION = %s AND id_accARGUMENT IN (%s) """ % (acc_getActionId(name_action=DELEGATEADDUSERROLE), nv_str))
# return number of deletes
return count
def acc_updateRole(id_role=0, name_role='', verbose=0, description=''):
"""try to change the description.
id_role - id of the role to change
name_role - use this to find id if not present
verbose - extra output
description - new description """
id_role = id_role or acc_getRoleId(name_role=name_role)
if not id_role: return 0
return run_sql("""UPDATE accROLE SET description = '%s'
WHERE id = %s AND
description != '%s' """
% (description, id_role, description))
# CONNECTIONS BETWEEN USER AND ROLE
def acc_addUserRole(id_user=0, id_role=0, email='', name_role=''):
""" this function adds a new entry to table user_accROLE and returns it
id_user, id_role - self explanatory
email - email of the user
name_role - name of the role, to be used instead of id. """
id_user = id_user or acc_getUserId(email=email)
id_role = id_role or acc_getRoleId(name_role=name_role)
# check if the id_role exists
if id_role and not acc_getRoleName(id_role=id_role): return 0
# check that the user actually exist
if not acc_getUserEmail(id_user=id_user): return 0
# control if existing entry
if run_sql("""SELECT * FROM user_accROLE WHERE id_user = %s AND id_accROLE = %s""" % (id_user, id_role)):
return id_user, id_role, 0
else:
run_sql("""INSERT INTO user_accROLE (id_user, id_accROLE) VALUES (%s, %s) """ % (id_user, id_role))
return id_user, id_role, 1
def acc_deleteUserRole(id_user, id_role=0, name_role=0):
""" function deletes entry from user_accROLE and reports the success.
id_user - user in database
id_role - role in the database, prefered parameter
name_role - can also delete role on background of role name. """
# need to find id of the role
id_role = id_role or acc_getRoleId(name_role=name_role)
# number of deleted entries will be returned (0 or 1)
return run_sql("""DELETE FROM user_accROLE WHERE id_user = %s AND id_accROLE = %s """ % (id_user, id_role))
# ARGUMENTS
def acc_addArgument(keyword='', value=''):
""" function to insert an argument into table accARGUMENT.
if it exists the old id is returned, if it does not the entry is created and the new id is returned.
keyword - inserted in keyword column
value - inserted in value column. """
# if one of the values are missing, return 0
if not keyword or not value: return 0
# try to return id of existing argument
try: return run_sql("""SELECT id from accARGUMENT where keyword = '%s' and value = '%s'""" % (keyword, value))[0][0]
# return id of newly added argument
except IndexError: return run_sql("""INSERT INTO accARGUMENT (keyword, value) values ('%s', '%s') """ % (keyword, value))
def acc_deleteArgument(id_argument):
""" functions deletes one entry in table accARGUMENT.
the success of the operation is returned.
id_argument - id of the argument to be deleted"""
# return number of deleted entries, 1 or 0
return run_sql("""DELETE FROM accARGUMENT WHERE id = %s """ % (id_argument, ))
def acc_deleteArgument_names(keyword='', value=''):
"""delete argument according to keyword and value,
send call to another function..."""
# one of the values is missing
if not keyword or not value: return 0
# find id of the entry
try: return run_sql("""SELECT id from accARGUMENT where keyword = '%s' and value = '%s'""" % (keyword, value))[0][0]
except IndexError: return 0
# AUTHORIZATIONS
# ADD WITH names and keyval list
def acc_addAuthorization(name_role='', name_action='', optional=0, **keyval):
""" function inserts entries in accROLE_accACTION_accARGUMENT if all references are valid.
this function is made specially for the webaccessadmin web interface.
always inserting only one authorization.
id_role, id_action - self explanatory, preferably used
name_role, name_action - self explanatory, used if id not given
optional - if this is set to 1, check that function can have optional
arguments and add with arglistid -1 and id_argument -1
**keyval - dictionary of keyword=value pairs, used to find ids. """
inserted = []
# check that role and action exist
id_role = run_sql("""SELECT id FROM accROLE where name = '%s'""" % (name_role, ))
action_details = run_sql("""SELECT * from accACTION where name = '%s' """ % (name_action, ))
if not id_role or not action_details: return []
# get role id and action id and details
id_role, id_action = id_role[0][0], action_details[0][0]
allowedkeywords_str = action_details[0][3]
allowedkeywords_lst = acc_getActionKeywords(id_action=id_action)
optional_action = action_details[0][4] == 'yes' and 1 or 0
optional = int(optional)
# this action does not take arguments
if not optional and not keyval:
# can not add if user is doing a mistake
if allowedkeywords_str: return []
# check if entry exists
if not run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND id_accACTION = %s AND argumentlistid = %s AND id_accARGUMENT = %s"""
% (id_role, id_action, 0, 0)):
# insert new authorization
run_sql("""INSERT INTO accROLE_accACTION_accARGUMENT values (%s, %s, %s, %s)""" % (id_role, id_action, 0, 0))
return [[id_role, id_action, 0, 0], ]
return []
# try to add authorization without the optional arguments
elif optional:
# optional not allowed for this action
if not optional_action: return []
# check if authorization already exists
if not run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND
id_accACTION = %s AND
id_accARGUMENT = -1 AND
argumentlistid = -1""" % (id_role, id_action, )):
# insert new authorization
run_sql("""INSERT INTO accROLE_accACTION_accARGUMENT (id_accROLE, id_accACTION, id_accARGUMENT, argumentlistid) VALUES (%s, %s, -1, -1) """ % (id_role, id_action))
return [[id_role, id_action, -1, -1], ]
return []
else:
# regular authorization
# get list of ids, if they don't exist, create arguments
id_arguments = []
argstr = ''
for key in keyval.keys():
if key not in allowedkeywords_lst: return []
id_argument = (acc_getArgumentId(key, keyval[key])
or
run_sql("""INSERT INTO accARGUMENT (keyword, value) values ('%s', '%s') """ % (key, keyval[key])))
id_arguments.append(id_argument)
argstr += (argstr and ',' or '') + str(id_argument)
# check if equal authorization exists
for (id_trav, ) in run_sql("""SELECT DISTINCT argumentlistid FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = '%s' AND id_accACTION = '%s' """% (id_role, id_action)):
listlength = run_sql("""SELECT COUNT(*) FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = '%s' AND id_accACTION = '%s' AND argumentlistid = '%s' AND
id_accARGUMENT IN (%s) """ % (id_role, id_action, id_trav, argstr))[0][0]
notlist = run_sql("""SELECT COUNT(*) FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = '%s' AND id_accACTION = '%s' AND argumentlistid = '%s' AND
id_accARGUMENT NOT IN (%s) """ % (id_role, id_action, id_trav, argstr))[0][0]
# this means that a duplicate already exists
if not notlist and listlength == len(id_arguments): return []
# find new arglistid, highest + 1
try: arglistid = 1 + run_sql("""SELECT MAX(argumentlistid) FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = %s AND id_accACTION = %s """
% (id_role, id_action))[0][0]
except (IndexError, TypeError): arglistid = 1
if arglistid <= 0: arglistid = 1
# insert
for id_argument in id_arguments:
run_sql("""INSERT INTO accROLE_accACTION_accARGUMENT values (%s, %s, %s, %s) """
% (id_role, id_action, id_argument, arglistid))
inserted.append([id_role, id_action, id_argument, arglistid])
return inserted
def acc_addRoleActionArguments(id_role=0, id_action=0, arglistid=-1, optional=0, verbose=0, id_arguments=[]):
""" function inserts entries in accROLE_accACTION_accARGUMENT if all references are valid.
id_role, id_action - self explanatory
arglistid - argumentlistid for the inserted entries
if -1: create new group
other values: add to this group, if it exists or not
optional - if this is set to 1, check that function can have
optional arguments and add with arglistid -1 and
id_argument -1
verbose - extra output
id_arguments - list of arguments to add to group."""
inserted = []
if verbose: print 'ids: starting'
if verbose: print 'ids: checking ids'
# check that all the ids are valid and reference something...
if not run_sql("""SELECT * FROM accROLE WHERE id = %s""" % (id_role, )):
return 0
if verbose: print 'ids: get allowed keywords'
# check action exist and get allowed keywords
try:
allowedkeys = acc_getActionKeywords(id_action=id_action)
# allowedkeys = run_sql("""SELECT * FROM accACTION WHERE id = %s""" % (id_action, ))[0][3].split(',')
except (IndexError, AttributeError):
return 0
if verbose: print 'ids: is it optional'
# action with optional arguments
if optional:
if verbose: print 'ids: yes - optional'
if not acc_getActionIsOptional(id_action=id_action):
return []
if verbose: print 'ids: run query to check if exists'
if not run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND
id_accACTION = %s AND
id_accARGUMENT = -1 AND
argumentlistid = -1""" %
(id_role, id_action, )):
if verbose: print 'ids: does not exist'
run_sql("""INSERT INTO accROLE_accACTION_accARGUMENT (id_accROLE, id_accACTION, id_accARGUMENT, argumentlistid) VALUES (%s, %s, -1, -1) """
% (id_role, id_action))
return ((id_role, id_action, -1, -1), )
if verbose: print 'ids: exists'
return []
if verbose: print 'ids: check if not arguments'
# action without arguments
if not allowedkeys:
if verbose: print 'ids: not arguments'
if not run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND id_accACTION = %s AND argumentlistid = %s AND id_accARGUMENT = %s"""
% (id_role, id_action, 0, 0)):
if verbose: print 'ids: try to insert'
result = run_sql("""INSERT INTO accROLE_accACTION_accARGUMENT values (%s, %s, %s, %s)""" % (id_role, id_action, 0, 0))
return ((id_role, id_action, 0, 0), )
else:
if verbose: print 'ids: already existed'
return 0
else:
if verbose: print 'ids: arguments exist'
argstr = ''
# check that the argument exists, and that it is a valid key
if verbose: print 'ids: checking all the arguments'
for id_argument in id_arguments:
res_arg = run_sql("""SELECT * FROM accARGUMENT WHERE id = %s""" % (id_argument, ))
if not res_arg or res_arg[0][1] not in allowedkeys:
return 0
else:
if argstr: argstr += ','
argstr += '%s' % (id_argument, )
# arglistid = -1 means that the user wants a new group
if verbose: print 'ids: find arglistid'
if arglistid < 0:
# check if such single group already exists
for (id_trav, ) in run_sql("""SELECT DISTINCT argumentlistid FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = '%s' AND id_accACTION = '%s' """
% (id_role, id_action)):
listlength = run_sql("""SELECT COUNT(*) FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = '%s' AND id_accACTION = '%s' AND argumentlistid = '%s' AND
id_accARGUMENT IN (%s) """ % (id_role, id_action, id_trav, argstr))[0][0]
notlist = run_sql("""SELECT COUNT(*) FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = '%s' AND id_accACTION = '%s' AND argumentlistid = '%s' AND
id_accARGUMENT NOT IN (%s) """ % (id_role, id_action, id_trav, argstr))[0][0]
# this means that a duplicate already exists
if not notlist and listlength == len(id_arguments): return 0
# find new arglistid
try:
arglistid = run_sql("""SELECT MAX(argumentlistid) FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = %s AND id_accACTION = %s """ %
(id_role, id_action))[0][0] + 1
except ProgrammingError: return 0
except (IndexError, TypeError): arglistid = 1
if arglistid <= 0: arglistid = 1
if verbose: print 'ids: insert all the entries'
# all references are valid, insert: one entry in raa for each argument
for id_argument in id_arguments:
if not run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = %s AND id_accACTION = %s AND id_accARGUMENT = %s AND argumentlistid = %s""" %
(id_role, id_action, id_argument, arglistid)):
run_sql("""INSERT INTO accROLE_accACTION_accARGUMENT (id_accROLE, id_accACTION, id_accARGUMENT, argumentlistid) VALUES (%s, %s, %s, %s) """
% (id_role, id_action, id_argument, arglistid))
inserted.append((id_role, id_action, id_argument, arglistid))
# [(r, ac, ar1, aid), (r, ac, ar2, aid)]
if verbose:
print 'ids: inside add function'
for r in acc_findPossibleActions(id_role=id_role, id_action=id_action):
print 'ids: ', r
return inserted
def acc_addRoleActionArguments_names(name_role='', name_action='', arglistid=-1, optional=0, verbose=0, **keyval):
""" this function makes it possible to pass names when creating new entries instead of ids.
get ids for all the names,
create entries in accARGUMENT that does not exist,
pass on to id based function.
name_role, name_action - self explanatory
arglistid - add entries to or create group with arglistid, default -1 create new.
optional - create entry with optional keywords, **keyval is ignored, but should be empty
verbose - used to print extra information
**keyval - dictionary of keyword=value pairs, used to find ids. """
if verbose: print 'names: starting'
if verbose: print 'names: checking ids'
# find id of the role, return 0 if it doesn't exist
id_role = run_sql("""SELECT id FROM accROLE where name = '%s'""" % (name_role, ))
if id_role: id_role = id_role[0][0]
else: return 0
# find id of the action, return 0 if it doesn't exist
res = run_sql("""SELECT * from accACTION where name = '%s'""" % (name_action, ))
if res: id_action = res[0][0]
else: return 0
if verbose: print 'names: checking arguments'
id_arguments = []
if not optional:
if verbose: print 'names: not optional'
# place to keep ids of arguments and list of allowed keywords
allowedkeys = acc_getActionKeywords(id_action=id_action) # res[0][3].split(',')
# find all the id_arguments and create those that does not exist
for key in keyval.keys():
# this key does not exist
if key not in allowedkeys:
return 0
id_argument = acc_getArgumentId(key, keyval[key])
id_argument = id_argument or run_sql("""INSERT INTO accARGUMENT (keyword, value) values ('%s', '%s') """ % (key, keyval[key]))
id_arguments.append(id_argument) # append the id to the list
else:
if verbose: print 'names: optional'
# use the other function
return acc_addRoleActionArguments(id_role=id_role,
id_action=id_action,
arglistid=arglistid,
optional=optional,
verbose=verbose,
id_arguments=id_arguments)
# DELETE WITH ID OR NAMES
def acc_deleteRoleActionArguments(id_role, id_action, arglistid=1, auths=[[]]):
"""delete all entries in accROLE_accACTION_accARGUMENT that satisfy the parameters.
return number of actual deletes.
this function relies on the id-lists in auths to have the same order has the possible actions...
id_role, id_action - self explanatory
arglistid - group to delete from.
if more entries than deletes, split the group before delete.
id_arguments - list of ids to delete."""
keepauths = [] # these will be kept
# find all possible actions
pas = acc_findPossibleActions_ids(id_role, id_action)
header = pas[0]
# decide which to keep or throw away
for pa in pas[1:]:
if pa[0] == arglistid and pa[1:] not in auths:
keepauths.append(pa[1:])
# delete everything
run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND
id_accACTION = %s AND
argumentlistid = %s """
% (id_role, id_action, arglistid))
# insert those to be kept
for auth in keepauths:
acc_addRoleActionArguments(id_role=id_role,
id_action=id_action,
arglistid=-1,
id_arguments=auth)
return 1
def acc_deleteRoleActionArguments_names(name_role='', name_action='', arglistid=1, **keyval):
"""utilize the function on ids by first finding all ids and redirecting the function call.
break of and return 0 if any of the ids can't be found.
name_role = name of the role
name_action - name of the action
arglistid - the argumentlistid, all keyword=value pairs must be in this same group.
**keyval - dictionary of keyword=value pairs for the arguments."""
# find ids for role and action
id_role = acc_getRoleId(name_role=name_role)
id_action = acc_getActionId(name_action=name_action)
# create string with the ids
idstr = ''
idlist = []
for key in keyval.keys():
id = acc_getArgumentId(key, keyval[key])
if not id: return 0
if idstr: idstr += ','
idstr += '%s' % id
idlist.append(id)
# control that a fitting group exists
try: count = run_sql("""SELECT COUNT(*) FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND
id_accACTION = %s AND
argumentlistid = %s AND
id_accARGUMENT IN (%s)""" % (id_role, id_action, arglistid, idstr))[0][0]
except IndexError: return 0
if count < len(keyval): return 0
# call id based function
return acc_deleteRoleActionArguments(id_role, id_action, arglistid, [idlist])
def acc_deleteRoleActionArguments_group(id_role=0, id_action=0, arglistid=0):
"""delete entire group of arguments for connection between role and action."""
if not id_role or not id_action: return []
return run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND
id_accACTION = %s AND
argumentlistid = %s """ % (id_role, id_action, arglistid))
def acc_deletePossibleActions(id_role=0, id_action=0, authids=[]):
"""delete authorizations in selected rows. utilization of the delete function.
id_role - id of role to be connected to action.
id_action - id of action to be connected to role
authids - list of row indexes to be removed. """
# find all authorizations
pas = acc_findPossibleActions(id_role=id_role, id_action=id_action)
# get the keys
keys = pas[0][1:]
# create dictionary for all the argumentlistids
ald = {}
for authid in authids:
if authid > len(pas): return authid, len(pas)
# get info from possible action
id = pas[authid][0]
values = pas[authid][1:]
# create list of authids for each authorization
auth = [acc_getArgumentId(keys[0], values[0])]
for i in range(1, len(keys)):
auth.append(acc_getArgumentId(keys[i], values[i]))
# create entries in the dictionary for each argumentlistid
try: ald[id].append(auth)
except KeyError: ald[id] = [auth]
# do the deletes
result = 1
for key in ald.keys():
result = 1 and acc_deleteRoleActionArguments(id_role=id_role,
id_action=id_action,
arglistid=key,
auths=ald[key])
return result
def acc_deleteRoleAction(id_role=0, id_action=0):
"""delete all connections between a role and an action. """
count = run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = '%s' AND id_accACTION = '%s' """ % (id_role, id_action))
return count
# GET FUNCTIONS
# ACTION RELATED
def acc_getActionId(name_action):
"""get id of action when name is given
name_action - name of the wanted action"""
try: return run_sql("""SELECT id FROM accACTION WHERE name = '%s'""" % (name_action, ))[0][0]
except IndexError: return 0
def acc_getActionName(id_action):
"""get name of action when id is given. """
try:
return run_sql("""SELECT name FROM accACTION WHERE id = %s""" % (id_action, ))[0][0]
except (ProgrammingError, IndexError):
return ''
def acc_getActionDescription(id_action):
"""get description of action when id is given. """
try:
return run_sql("""SELECT description FROM accACTION WHERE id = %s""" % (id_action, ))[0][0]
except (ProgrammingError, IndexError):
return ''
def acc_getActionKeywords(id_action=0, name_action=''):
"""get list of keywords for action when id is given.
empty list if no keywords."""
result = acc_getActionKeywordsString(id_action=id_action, name_action=name_action)
if result: return result.split(',')
else: return []
def acc_getActionKeywordsString(id_action=0, name_action=''):
"""get keywordstring when id is given. """
id_action = id_action or acc_getActionId(name_action)
try: result = run_sql("""SELECT allowedkeywords from accACTION where id = %s """ % (id_action, ))[0][0]
except IndexError: return ''
return result
def acc_getActionIsOptional(id_action=0):
"""get if the action arguments are optional or not.
return 1 if yes, 0 if no."""
result = acc_getActionOptional(id_action=id_action)
return result == 'yes' and 1 or 0
def acc_getActionOptional(id_action=0):
"""get if the action arguments are optional or not.
return result, but 0 if action does not exist. """
try: result = run_sql("""SELECT optional from accACTION where id = %s """ % (id_action, ))[0][0]
except IndexError: return 0
return result
def acc_getActionDetails(id_action=0):
"""get all the fields for an action."""
details = []
try: result = run_sql("""SELECT * FROM accACTION WHERE id = %s """ % (id_action, ))[0]
except IndexError: return details
if result:
for r in result: details.append(r)
return details
def acc_getAllActions():
"""returns all entries in accACTION."""
return run_sql("""SELECT a.id, a.name, a.description FROM accACTION a ORDER BY a.name""")
def acc_getActionRoles(id_action):
return run_sql("""SELECT DISTINCT(r.id), r.name, r.description
FROM accROLE_accACTION_accARGUMENT raa LEFT JOIN accROLE r
ON raa.id_accROLE = r.id
WHERE raa.id_accACTION = %s
ORDER BY r.name """ % (id_action, ))
# ROLE RELATED
def acc_getRoleId(name_role):
"""get id of role, name given. """
try: return run_sql("""SELECT id FROM accROLE WHERE name = %s""", (name_role, ))[0][0]
except IndexError: return 0
def acc_getRoleName(id_role):
"""get name of role, id given. """
try: return run_sql("""SELECT name FROM accROLE WHERE id = %s""", (id_role, ))[0][0]
except IndexError: return ''
def acc_getRoleDetails(id_role=0):
"""get all the fields for an action."""
details = []
try: result = run_sql("""SELECT * FROM accROLE WHERE id = %s """, (id_role, ))[0]
except IndexError: return details
if result:
for r in result: details.append(r)
return details
def acc_getAllRoles():
"""get all entries in accROLE."""
return run_sql("""SELECT r.id, r.name, r.description FROM accROLE r ORDER BY r.name""")
def acc_getRoleActions(id_role):
"""get all actions connected to a role. """
return run_sql("""SELECT DISTINCT(a.id), a.name, a.description
FROM accROLE_accACTION_accARGUMENT raa, accACTION a
WHERE raa.id_accROLE = %s and
raa.id_accACTION = a.id
ORDER BY a.name """, (id_role, ))
def acc_getRoleUsers(id_role):
"""get all users that have access to a role. """
return run_sql("""SELECT DISTINCT(u.id), u.email, u.settings
FROM user_accROLE ur, user u
WHERE ur.id_accROLE = %s AND
u.id = ur.id_user
ORDER BY u.email""", (id_role, ))
# ARGUMENT RELATED
def acc_getArgumentId(keyword, value):
"""get id of argument, keyword=value pair given.
value = 'optional value' is replaced for id_accARGUMENT = -1."""
try: return run_sql("""SELECT DISTINCT id FROM accARGUMENT WHERE keyword = %s and value = %s""", (keyword, value))[0][0]
except IndexError:
if value == 'optional value': return -1
return 0
# USER RELATED
def acc_getUserEmail(id_user=0):
"""get email of user, id given."""
try: return run_sql("""SELECT email FROM user WHERE id = %s """, (id_user, ))[0][0]
except IndexError: return ''
def acc_getUserId(email=''):
"""get id of user, email given."""
try: return run_sql("""SELECT id FROM user WHERE email = %s """, (email, ))[0][0]
except IndexError: return 0
def acc_getUserRoles(id_user=0):
"""get all roles a user is connected to."""
res = run_sql("""SELECT ur.id_accROLE
FROM user_accROLE ur
WHERE ur.id_user = %s
ORDER BY ur.id_accROLE""", (id_user, ))
return res
def acc_findUserInfoIds(id_user=0):
"""find all authorization entries for all the roles a user is connected to."""
res1 = run_sql("""SELECT ur.id_user, raa.*
FROM user_accROLE ur LEFT JOIN accROLE_accACTION_accARGUMENT raa
ON ur.id_accROLE = raa.id_accROLE
WHERE ur.id_user = %s """, (id_user, ))
res2 = []
for res in res1: res2.append(res)
res2.sort()
return res2
def acc_findUserInfoNames(id_user=0):
query = """ SELECT ur.id_user, r.name, ac.name, raa.argumentlistid, ar.keyword, ar.value
FROM accROLE_accACTION_accARGUMENT raa, user_accROLE ur, accROLE r, accACTION ac, accARGUMENT ar
WHERE ur.id_user = %s and
ur.id_accROLE = raa.id_accROLE and
raa.id_accROLE = r.id and
raa.id_accACTION = ac.id and
raa.id_accARGUMENT = ar.id """ % (id_user, )
res1 = run_sql(query)
res2 = []
for res in res1: res2.append(res)
res2.sort()
return res2
def acc_findUserRoleActions(id_user=0):
"""find name of all roles and actions connected to user, id given."""
query = """SELECT DISTINCT r.name, a.name
FROM user_accROLE ur, accROLE_accACTION_accARGUMENT raa, accACTION a, accROLE r
WHERE ur.id_user = %s and
ur.id_accROLE = raa.id_accROLE and
raa.id_accACTION = a.id and
raa.id_accROLE = r.id """ % (id_user, )
res1 = run_sql(query)
res2 = []
for res in res1: res2.append(res)
res2.sort()
return res2
# POSSIBLE ACTIONS / AUTHORIZATIONS
def acc_findPossibleActionsAll(id_role):
"""find all the possible actions for a role.
the function utilizes acc_findPossibleActions to find
all the entries from each of the actions under the given role
id_role - role to find all actions for
returns a list with headers"""
query = """SELECT DISTINCT(aar.id_accACTION)
FROM accROLE_accACTION_accARGUMENT aar
WHERE aar.id_accROLE = %s
ORDER BY aar.id_accACTION""" % (id_role, )
res = []
for (id_action, ) in run_sql(query):
hlp = acc_findPossibleActions(id_role, id_action)
if hlp:
res.append(['role', 'action'] + hlp[0])
for row in hlp[1:]:
res.append([id_role, id_action] + row)
return res
def acc_findPossibleActionsArgumentlistid(id_role, id_action, arglistid):
"""find all possible actions with the given arglistid only."""
# get all, independent of argumentlistid
res1 = acc_findPossibleActions_ids(id_role, id_action)
# create list with only those with the right arglistid
res2 = []
for row in res1[1:]:
if row[0] == arglistid: res2.append(row)
# return this list
return res2
def acc_findPossibleActionsUser(id_user, id_action):
"""user based function to find all action combination for a given
user and action. find all the roles and utilize findPossibleActions for all these.
id_user - user id, used to find roles
id_action - action id. """
res = []
for (id_role, ) in acc_getUserRoles(id_user):
hlp = acc_findPossibleActions(id_role, id_action)
if hlp and not res: res.append(['role'] + hlp[0])
for row in hlp[1:]:
res.append([id_role] + row)
return res
def acc_findPossibleActions_ids(id_role, id_action):
"""finds the ids of the possible actions.
utilization of acc_getArgumentId and acc_findPossibleActions. """
pas = acc_findPossibleActions(id_role, id_action)
if not pas: return []
keys = pas[0]
pas_ids = [pas[0:1]]
for pa in pas[1:]:
auth = [pa[0]]
for i in range(1, len(pa)):
auth.append(acc_getArgumentId(keys[i], pa[i]))
pas_ids.append(auth)
return pas_ids
def acc_findPossibleActions(id_role, id_action):
"""Role based function to find all action combinations for a
give role and action.
id_role - id of role in the database
id_action - id of the action in the database
returns a list with all the combinations.
first row is used for header."""
# query to find all entries for user and action
res1 = run_sql(""" SELECT raa.argumentlistid, ar.keyword, ar.value
FROM accROLE_accACTION_accARGUMENT raa, accARGUMENT ar
WHERE raa.id_accROLE = %s and
raa.id_accACTION = %s and
raa.id_accARGUMENT = ar.id """, (id_role, id_action))
# find needed keywords, create header
keywords = acc_getActionKeywords(id_action=id_action)
keywords.sort()
if not keywords:
# action without arguments
if run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE = %s AND id_accACTION = %s AND id_accARGUMENT = 0 AND argumentlistid = 0""", (id_role, id_action)):
return [['#', 'argument keyword'], ['0', 'action without arguments']]
# tuples into lists
res2, arglistids = [], {}
for res in res1:
res2.append([])
for r in res: res2[-1].append(r)
res2.sort()
# create multilevel dictionary
for res in res2:
a, kw, value = res # rolekey, argumentlistid, keyword, value
if kw not in keywords: continue
if not arglistids.has_key(a):
arglistids[a] = {}
# fill dictionary
if not arglistids[a].has_key(kw): arglistids[a][kw] = [value]
elif not value in arglistids[a][kw]: arglistids[a][kw] = arglistids[a][kw] + [value]
# fill list with all possible combinations
res3 = []
# rolekeys = roles2.keys(); rolekeys.sort()
for a in arglistids.keys(): # argumentlistids
# fill a list with the new entries, shortcut and copying first keyword list
next_arglistid = []
for row in arglistids[a][keywords[0]]: next_arglistid.append([a, row[:] ])
# run through the rest of the keywords
for kw in keywords[1:]:
if not arglistids[a].has_key(kw): arglistids[a][kw] = ['optional value']
new_list = arglistids[a][kw][:]
new_len = len(new_list)
# duplicate the list
temp_list = []
for row in next_arglistid:
for i in range(new_len): temp_list.append(row[:])
# append new values
for i in range(len(temp_list)):
new_item = new_list[i % new_len][:]
temp_list[i].append( new_item )
next_arglistid = temp_list[:]
res3.extend(next_arglistid)
res3.sort()
# if optional allowed, put on top
opt = run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s AND
id_accACTION = %s AND
id_accARGUMENT = -1 AND
argumentlistid = -1""" % (id_role, id_action))
if opt: res3.insert(0, [-1] + ['optional value'] * len(keywords))
# put header on top
if res3:
res3.insert(0, ['#'] + keywords)
return res3
def acc_splitArgumentGroup(id_role=0, id_action=0, arglistid=0):
"""collect the arguments, find all combinations, delete original entries
and insert the new ones with different argumentlistids for each group
id_role - id of the role
id_action - id of the action
arglistid - argumentlistid to be splittetd"""
if not id_role or not id_action or not arglistid: return []
# don't split if none or one possible actions
res = acc_findPossibleActionsArgumentlistid(id_role, id_action, arglistid)
if not res or len(res) <= 1: return 0
# delete the existing group
delete = acc_deleteRoleActionArguments_group(id_role, id_action, arglistid)
# add all authorizations with new and different argumentlistid
addlist = []
for row in res:
argids = row[1:]
addlist.append(acc_addRoleActionArguments(id_role=id_role,
id_action=id_action,
arglistid=-1,
id_arguments=argids))
# return list of added authorizations
return addlist
def acc_mergeArgumentGroups(id_role=0, id_action=0, arglistids=[]):
"""merge the authorizations from groups with different argumentlistids
into one single group.
this can both save entries in the database and create extra authorizations.
id_role - id of the role
id_action - role of the action
arglistids - list of groups to be merged together into one."""
if len(arglistids) < 2: return []
argstr = ''
for id in arglistids:
argstr += 'raa.argumentlistid = %s or ' % (id, )
argstr = '(%s)' % (argstr[:-4], )
# query to find all entries that will be merged
query = """ SELECT ar.keyword, ar.value, raa.id_accARGUMENT
FROM accROLE_accACTION_accARGUMENT raa, accARGUMENT ar
WHERE raa.id_accROLE = %s and
raa.id_accACTION = %s and
%s and
raa.id_accARGUMENT = ar.id """ % (id_role, id_action, argstr)
q_del = """DELETE FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE = %s and
id_accACTION = %s and
%s """ % (id_role, id_action, argstr.replace('raa.', ''))
res = run_sql(query)
if not res: return []
run_sql(q_del)
# list of entire entries
old = []
# list of only the ids
ids = []
for (k, v, id) in res:
if [k, v, id] not in old:
old.append([k, v, id])
ids.append(id)
# for (k, v, id) in res: if id not in ids: ids.append(id)
return acc_addRoleActionArguments(id_role=id_role,
id_action=id_action,
arglistid=-1,
id_arguments=ids)
def acc_reset_default_settings(superusers=[]):
"""reset to default by deleting everything and adding default.
superusers - list of superuser emails """
remove = acc_delete_all_settings()
add = acc_add_default_settings(superusers=superusers)
return remove, add
def acc_delete_all_settings():
"""simply remove all data affiliated with webaccess by truncating
tables accROLE, accACTION, accARGUMENT and those connected. """
run_sql("""TRUNCATE accROLE""")
run_sql("""TRUNCATE accACTION""")
run_sql("""TRUNCATE accARGUMENT""")
run_sql("""TRUNCATE user_accROLE""")
run_sql("""TRUNCATE accROLE_accACTION_accARGUMENT""")
return 1
def acc_add_default_settings(superusers=[]):
"""add the default settings if they don't exist.
superusers - list of superuser emails """
# imported from config
global supportemail
# imported from access_control_config
global def_roles
global def_users
global def_actions
global def_auths
# from superusers: allow input formats ['email1', 'email2'] and [['email1'], ['email2']] and [['email1', id], ['email2', id]]
for user in superusers:
if type(user) is str: user = [user]
def_users.append(user[0])
if supportemail not in def_users: def_users.append(supportemail)
# add data
# add roles
insroles = []
for (name, description) in def_roles:
# try to add, don't care if description is different
id = acc_addRole(name_role=name,
description=description)
if not id:
id = acc_getRoleId(name_role=name)
acc_updateRole(id_role=id, description=description)
insroles.append([id, name, description])
# add users to superadmin
insuserroles = []
for user in def_users:
insuserroles.append(acc_addUserRole(email=user,
name_role=SUPERADMINROLE))
# add actions
insactions = []
for (name, description, allkeys, optional) in def_actions:
# try to add action as new
id = acc_addAction(name, description, optional, allkeys)
# action with the name exist
if not id:
id = acc_getActionId(name_action=name)
# update the action, necessary updates to the database will also be done
acc_updateAction(id_action=id, optional=optional, allowedkeywords=allkeys)
# keep track of inserted actions
insactions.append([id, name, description, allkeys])
# add authorizations
insauths = []
for (name_role, name_action, arglistid, optional, args) in def_auths:
# add the authorization
acc_addRoleActionArguments_names(name_role=name_role,
name_action=name_action,
arglistid=arglistid,
optional=optional,
**args)
# keep track of inserted authorizations
insauths.append([name_role, name_action, arglistid, optional, args])
return insroles, insactions, insuserroles, insauths
def acc_find_delegated_roles(id_role_admin=0):
"""find all the roles the admin role has delegation rights over.
return tuple of all the roles.
id_role_admin - id of the admin role """
id_action_delegate = acc_getActionId(name_action=DELEGATEADDUSERROLE)
rolenames = run_sql("""SELECT DISTINCT(ar.value)
FROM accROLE_accACTION_accARGUMENT raa LEFT JOIN accARGUMENT ar
ON raa.id_accARGUMENT = ar.id
WHERE raa.id_accROLE = '%s' AND
raa.id_accACTION = '%s'
""" % (id_role_admin, id_action_delegate))
result = []
for (name_role, ) in rolenames:
roledetails = run_sql("""SELECT * FROM accROLE WHERE name = %s """, (name_role, ))
if roledetails: result.append(roledetails)
return result
def acc_cleanupArguments():
"""function deletes all accARGUMENTs that are not referenced by accROLE_accACTION_accARGUMENT.
returns how many arguments where deleted and a list of the deleted id_arguments"""
# find unreferenced arguments
ids1 = run_sql("""SELECT DISTINCT ar.id
FROM accARGUMENT ar LEFT JOIN accROLE_accACTION_accARGUMENT raa ON ar.id = raa.id_accARGUMENT
WHERE raa.id_accARGUMENT IS NULL """)
# it is clean
if not ids1: return 1
# create list and string of the ids
ids2 = []
idstr = ''
for (id, ) in ids1:
ids2.append(id)
if idstr: idstr += ','
idstr += '%s' % id
# delete unreferenced arguments
count = run_sql("""DELETE FROM accARGUMENT
WHERE id in (%s)""" % (idstr, ))
# return count and ids of deleted arguments
return (count, ids2)
def acc_cleanupUserRoles():
"""remove all entries in user_accROLE referencing non-existing roles.
return number of deletes and the ids.
FIXME: THIS FUNCTION HAS NOT BEEN TESTED """
# find unreferenced arguments
ids1 = run_sql("""SELECT DISTINCT ur.id_accROLE
FROM accROLE ur LEFT JOIN accROLE r ON ur.id_accROLE = r.id
WHERE r.id IS NULL""")
# it is clean
if not ids1: return 1
# create list and string of the ids
ids2 = []
idstr = ''
for (id, ) in ids1:
ids2.append(id)
if idstr: idstr += ','
idstr += '%s' % id
# delete unreferenced arguments
count = run_sql("""DELETE FROM user_accROLE
WHERE id_accROLE in (%s)""" % (idstr, ))
# return count and ids of deleted arguments
return (count, ids2)
def acc_garbage_collector(verbose=0):
"""clean the entire database for unused data"""
# keep track of all deleted entries
del_entries = []
# user_accROLEs without existing role or user
count = 0
# roles have been deleted
id_roles = run_sql("""SELECT DISTINCT r.id FROM accROLE r""")
idrolesstr = ''
for (id, ) in id_roles:
idrolesstr += (idrolesstr and ',' or '') + '%s' % id
if idrolesstr:
count += run_sql("""DELETE FROM user_accROLE WHERE id_accROLE NOT IN (%s)""" % (idrolesstr, ))
# users have been deleted
id_users = run_sql("""SELECT DISTINCT u.id FROM user u WHERE email != ''""")
idusersstr = ''
for (id, ) in id_users:
idusersstr += (idusersstr and ',' or '') + '%s' % id
if idusersstr:
count += run_sql("""DELETE FROM user_accROLE WHERE id_user NOT IN (%s) """ % (idusersstr, ))
del_entries.append([count])
# accROLE_accACTION_accARGUMENT where role is deleted
count = 0
if idrolesstr:
count += run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT WHERE id_accROLE NOT IN (%s)""" % (idrolesstr, ))
# accROLE_accACTION_accARGUMENT where action is deleted
id_actions = run_sql("""SELECT DISTINCT a.id FROM accACTION a""")
idactionsstr = ''
for (id, ) in id_actions:
idactionsstr += (idactionsstr and ',' or '') + '%s' % id # FIXME: here was a syntactic bug, so check the code!
if idactionsstr:
count += run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT WHERE id_accACTION NOT IN (%s)""" % (idactionsstr, ))
del_entries.append([count])
# delegated roles that does not exist
nameroles = run_sql("""SELECT DISTINCT r.name FROM accROLE r""")
namestr = ''
for (name, ) in nameroles:
namestr += (namestr and ',' or '') + '"%s"' % name
if namestr:
idargs = run_sql("""SELECT ar.id FROM accARGUMENT WHERE keyword = 'role' AND value NOT IN (%s) """ % (namestr, ))
idstr = ''
for (id, ) in idargs:
idstr += (idstr and ',' or '') + '%s' % id
if namestr and idstr:
count = run_sql("""DELETE FROM accROLE_accACTION_accARGUMENT WHERE id_accARGUMENT IN (%s) """ % (idstr, ))
else: count = 0
del_entries.append([0])
# delete unreferenced arguments
unused_args = run_sql("""SELECT DISTINCT ar.id
FROM accARGUMENT ar LEFT JOIN accROLE_accACTION_accARGUMENT raa ON ar.id = raa.id_accARGUMENT
WHERE raa.id_accARGUMENT IS NULL """)
args = []
idstr = ''
for (id, ) in unused_args:
args.append(id)
idstr += (idstr and ',' or '') + '%s' % id
count = run_sql("""DELETE FROM accARGUMENT
WHERE id in (%s)""" % (idstr, ))
del_entries.append([count, args])
# return statistics
return del_entries
diff --git a/modules/webaccess/lib/access_control_config.py b/modules/webaccess/lib/access_control_config.py
index 924ba0cca..fc66389c2 100644
--- a/modules/webaccess/lib/access_control_config.py
+++ b/modules/webaccess/lib/access_control_config.py
@@ -1,136 +1,136 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Access Control Config. """
__version__ = "$Id$"
## global configuration parameters:
from cdsware.config import *
## local configuration parameters:
from cdsware.external_authentication import *
# VALUES TO BE EXPORTED
# CURRENTLY USED BY THE FILES access_control_engine.py access_control_admin.py webaccessadmin_lib.py
# name of the role giving superadmin rights
SUPERADMINROLE = 'superadmin'
# name of the webaccess webadmin role
WEBACCESSADMINROLE = 'webaccessadmin'
# name of the action allowing roles to access the web administrator interface
WEBACCESSACTION = 'cfgwebaccess'
# name of the action allowing roles to delegate the rights to other roles
# ex: libraryadmin to delegate libraryworker
DELEGATEADDUSERROLE = 'accdelegaterole'
# max number of users to display in the drop down selects
MAXSELECTUSERS = 25
# max number of users to display in a page (mainly for user area)
MAXPAGEUSERS = 25
# Use external source for access control?
# Atleast one must be added
# Adviced not to change the name, since it is used to identify the account
# Format is: System name: (System class, Default True/Flase), atleast one must be default
CFG_EXTERNAL_AUTHENTICATION = {"%s (internal)" % cdsname: (None, True)}
#CFG_EXTERNAL_AUTHENTICATION = {"%s (internal)" % cdsname: (None, True), "CERN NICE (external)": (external_auth_nice(), False)}
# default data for the add_default_settings function
# roles
# name description
def_roles = ((SUPERADMINROLE, 'superuser with all rights'),
('photoadmin', 'Photo collection administrator'),
(WEBACCESSADMINROLE, 'WebAccess administrator'))
# users
# list of e-mail addresses
def_users = []
# actions
# name desc allowedkeywords optional
def_actions = (
('cfgwebsearch', 'configure WebSearch', '', 'no'),
('cfgbibformat', 'configure BibFormat', '', 'no'),
('cfgwebsubmit', 'configure WebSubmit', '', 'no'),
('runbibindex', 'run BibIndex', '', 'no'),
('runbibupload', 'run BibUpload', '', 'no'),
('runwebcoll', 'run webcoll', 'collection', 'yes'),
('runbibformat', 'run BibFormat', 'format', 'yes'),
(WEBACCESSACTION, 'configure WebAccess', '', 'no'),
(DELEGATEADDUSERROLE, 'delegate subroles inside WebAccess', 'role', 'no'),
('runbibtaskex', 'run BibTaskEx example', '', 'no'),
('referee', 'referee document type doctype/category categ', 'doctype,categ', 'yes'),
('submit', 'use webSubmit', 'doctype,act', 'yes'),
('runbibrank', 'run BibRank', '', 'no'),
('cfgbibrank', 'configure BibRank', '', 'no'),
('cfgbibharvest', 'configure BibHarvest', '', 'no'),
('runoaiharvest', 'run oaiharvest task', '', 'no'),
('cfgwebcomment', 'configure WebComment', '', 'no'),
)
# authorizations
# role action arglistid optional arguments
def_auths = (
(SUPERADMINROLE, 'cfgwebsearch', -1, 0, {}),
(SUPERADMINROLE, 'cfgbibformat', -1, 0, {}),
(SUPERADMINROLE, 'cfgwebsubmit', -1, 0, {}),
(SUPERADMINROLE, 'runbibindex', -1, 0, {}),
(SUPERADMINROLE, 'runbibupload', -1, 0, {}),
(SUPERADMINROLE, 'runbibformat', -1, 1, {}),
(SUPERADMINROLE, WEBACCESSACTION, -1, 0, {}),
('photoadmin', 'runwebcoll', -1, 0, {'collection': 'Pictures'}),
(WEBACCESSADMINROLE,WEBACCESSACTION, -1, 0, {}),
(SUPERADMINROLE, 'runtaskex', -1, 0, {}),
(SUPERADMINROLE, 'referee', -1, 1, {}),
(SUPERADMINROLE, 'submit', -1, 1, {}),
(SUPERADMINROLE, 'runbibrank', -1, 0, {}),
(SUPERADMINROLE, 'cfgbibrank', -1, 0, {}),
(SUPERADMINROLE, 'cfgbibharvest', -1, 0, {}),
(SUPERADMINROLE, 'runoaiharvest', -1, 0, {}),
(SUPERADMINROLE, 'cfgwebcomment', -1, 0, {}),
)
cfg_webaccess_msgs = {
0: 'Try to <a href="%s/youraccount.py/login?referer=%s/admin/%s">login</a> with another account.' % (weburl, weburl, "%s"),
1: '<br>If you think this is not correct, please contact: <a href="mailto:%s">%s</a>' % (supportemail, supportemail),
2: '<br>If you have any questions, please write to <a href="mailto:%s">%s</a>' % (supportemail, supportemail),
3: 'Guest users are not allowed, please <a href="%s/youraccount.py/login">login</a>.' % weburl,
4: 'The site is temporarily closed for maintenance. Please come back soon.',
5: 'Authorization failure',
6: '%s temporarily closed' % cdsname,
7: 'This functionality is temporarily closed due to server maintenance. Please use only the search engine in the meantime.',
8: 'Functionality temporarily closed'
}
cfg_webaccess_warning_msgs = {
0: 'Authorization granted',
1: 'Error(1): You are not authorized to perform this action.',
2: 'Error(2): You are not authorized to perform any action.',
3: 'Error(3): The action %s does not exist.',
4: 'Error(4): Unexpected error occurred.',
5: 'Error(5): Missing mandatory keyword argument(s) for this action.',
6: 'Error(6): Guest accounts are not authorized to perform this action.',
7: 'Error(7): Not enough arguments, user ID and action name required.',
8: 'Error(8): Incorrect keyword argument(s) for this action.',
9: """Error(9): Account '%s' is not yet activated.""",
10: """Error(10): You were not authorized by the authentication method '%s'.""",
11: """Error(11): The selected login method '%s' is not the default method for this account, please try another one.""",
12: """Error(12): Selected login method '%s' does not exist.""",
13: """Error(13): Could not register '%s' account.""",
14: """Error(14): Could not login using '%s', because this user is unknown.""",
15: """Error(15): Could not login using your '%s' account, because you have introduced a wrong password."""
}
diff --git a/modules/webaccess/lib/access_control_engine.py b/modules/webaccess/lib/access_control_engine.py
index 5c31ea351..25520d774 100644
--- a/modules/webaccess/lib/access_control_engine.py
+++ b/modules/webaccess/lib/access_control_engine.py
@@ -1,234 +1,234 @@
## $Id$
## CDSware Access Control Engine in mod_python.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Access Control Engine in mod_python."""
__version__ = "$Id$"
from MySQLdb import ProgrammingError
from cdsware.config import *
from cdsware.dbquery import run_sql
from cdsware.access_control_config import SUPERADMINROLE, cfg_webaccess_warning_msgs, cfg_webaccess_msgs, CFG_ACCESS_CONTROL_LEVEL_GUESTS, CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS#, CFG_EXTERNAL_ACCESS_CONTROL
called_from = 1 #1=web,0=cli
try:
import _apache
except ImportError, e:
called_from = 0
## access controle engine function
def acc_authorize_action(id_user, name_action, verbose=0, **arguments):
"""Check if user is allowed to perform action
with given list of arguments.
Return (0, message) if authentication succeeds, (error code, error message) if it fails.
The arguments are as follows:
id_user - id of the user in the database
name_action - the name of the action
arguments - dictionary with keyword=value pairs created automatically
by python on the extra arguments. these depend on the
given action.
"""
#TASK -1: Checking external source if user is authorized:
#if CFG_:
# em_pw = run_sql("SELECT email, password FROM user WHERE id=%s", (id_user,))
# if em_pw:
# if not CFG_EXTERNAL_ACCESS_CONTROL.loginUser(em_pw[0][0], em_pw[0][1]):
# return (10, "%s %s" % (cfg_webaccess_warning_msgs[10], (called_from and cfg_webaccess_msgs[1] or "")))
# TASK 0: find id and allowedkeywords of action
if verbose: print 'task 0 - get action info'
query1 = """select a.id, a.allowedkeywords, a.optional
from accACTION a
where a.name = '%s'""" % (name_action)
try: id_action, aallowedkeywords, optional = run_sql(query1)[0]
except (ProgrammingError, IndexError): return (3, "%s %s" % (cfg_webaccess_warning_msgs[3] % name_action, (called_from and cfg_webaccess_msgs[1] or "")))
defkeys = aallowedkeywords.split(',')
for key in arguments.keys():
if key not in defkeys: return (8, "%s %s" % (cfg_webaccess_warning_msgs[8], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or ""))) #incorrect arguments?
# -------------------------------------------
# TASK 1: check if user is a superadmin
# we know the action exists. no connection with role is necessary
# passed arguments must have allowed keywords
# no check to see if the argument exists
if verbose: print 'task 1 - is user %s' % (SUPERADMINROLE, )
if run_sql("""SELECT *
FROM accROLE r LEFT JOIN user_accROLE ur
ON r.id = ur.id_accROLE
WHERE r.name = '%s' AND
ur.id_user = '%s' """ % (SUPERADMINROLE, id_user)):
return (0, cfg_webaccess_warning_msgs[0])
# ------------------------------------------
# TASK 2: check if user exists and find all the user's roles and create or-string
if verbose: print 'task 2 - find user and userroles'
try:
query2 = """SELECT email, note from user where id=%s""" % id_user
res2 = run_sql(query2)
if not res2:
raise Exception
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1 and res2[0][1] not in [1, "1"]:
if res[0][1]:
return (9, "%s %s" % (cfg_webaccess_warning_msgs[9] % res[0][1], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or "")))
else:
raise Exception
query2 = """SELECT ur.id_accROLE FROM user_accROLE ur WHERE ur.id_user=%s ORDER BY ur.id_accROLE """ % id_user
res2 = run_sql(query2)
except Exception: return (6, "%s %s" % (cfg_webaccess_warning_msgs[6], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or "")))
if not res2: return (2, "%s %s" % (cfg_webaccess_warning_msgs[2], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or ""))) #user has no roles
# -------------------------------------------
# create role string (add default value? roles='(raa.id_accROLE='def' or ')
str_roles = ''
for (role, ) in res2:
if str_roles: str_roles += ','
str_roles += '%s' % (role, )
# TASK 3: authorizations with no arguments given
if verbose: print 'task 3 - checks with no arguments'
if not arguments:
# 3.1
if optional == 'no':
if verbose: print ' - action with zero arguments'
connection = run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE IN (%s) AND
id_accACTION = %s AND
argumentlistid = 0 AND
id_accARGUMENT = 0 """ % (str_roles, id_action))
if connection and 1:
return (0, cfg_webaccess_warning_msgs[0])
else:
return (1, "%s %s" % (cfg_webaccess_warning_msgs[1], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or "")))
# 3.2
if optional == 'yes':
if verbose: print ' - action with optional arguments'
connection = run_sql("""SELECT * FROM accROLE_accACTION_accARGUMENT
WHERE id_accROLE IN (%s) AND
id_accACTION = %s AND
id_accARGUMENT = -1 AND
argumentlistid = -1 """ % (str_roles, id_action))
if connection and 1:
return (0, cfg_webaccess_warning_msgs[0])
else:
return (1, "%s %s" % (cfg_webaccess_warning_msgs[1], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or "")))
# none of the zeroargs tests succeded
if verbose: print ' - not authorization without arguments'
return (5, "%s %s" % (cfg_webaccess_warning_msgs[5], (called_from and "%s" % (cfg_webaccess_msgs[1] or ""))))
# TASK 4: create list of keyword and values that satisfy part of the authentication and create or-string
if verbose: print 'task 4 - create keyword=value pairs'
# create dictionary with default values and replace entries from input arguments
defdict = {}
for key in defkeys:
try: defdict[key] = arguments[key]
except KeyError: return (5, "%s %s" % (cfg_webaccess_warning_msgs[5], (called_from and "%s" % (cfg_webaccess_msgs[1] or "")))) # all keywords must be present
# except KeyError: defdict[key] = 'x' # default value, this is not in use...
# create or-string from arguments
str_args = ''
for key in defkeys:
if str_args: str_args += ' OR '
str_args += """(arg.keyword = '%s' AND arg.value = '%s')""" % (key, defdict[key])
# TASK 5: find all the table entries that partially authorize the action in question
if verbose: print 'task 5 - find table entries that are part of the result'
query4 = """SELECT DISTINCT raa.id_accROLE, raa.id_accACTION, raa.argumentlistid,
raa.id_accARGUMENT, arg.keyword, arg.value
FROM accROLE_accACTION_accARGUMENT raa, accARGUMENT arg
WHERE raa.id_accACTION = %s AND
raa.id_accROLE IN (%s) AND
(%s) AND
raa.id_accARGUMENT = arg.id """ % (id_action, str_roles, str_args)
try: res4 = run_sql(query4)
except ProgrammingError: return (3, "%s %s" % (cfg_webaccess_warning_msgs[3], (called_from and "%s" % (cfg_webaccess_msgs[1] or ""))))
if not res4: return (1, "%s %s" % (cfg_webaccess_warning_msgs[1], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or ""))) # no entries at all
res5 = []
for res in res4:
res5.append(res)
res5.sort()
# USER AUTHENTICATED TO PERFORM ACTION WITH ONE ARGUMENT
if len(defdict) == 1: return (0, cfg_webaccess_warning_msgs[0])
# CHECK WITH MORE THAN 1 ARGUMENT
# TASK 6: run through the result and try to satisfy authentication
if verbose: print 'task 6 - combine results and try to satisfy'
cur_role = cur_action = cur_arglistid = 0
booldict = {}
for key in defkeys: booldict[key] = 0
# run through the results
for (role, action, arglistid, arg, keyword, val) in res5 + [(-1, -1, -1, -1, -1, -1)]:
# not the same role or argumentlist (authorization group), i.e. check if thing are satisfied
# if cur_arglistid != arglistid or cur_role != role or cur_action != action:
if (cur_arglistid, cur_role, cur_action) != (arglistid, role, action):
if verbose: print ' : checking new combination',
# test if all keywords are satisfied
for value in booldict.values():
if not value: break
else:
if verbose: print '-> found satisfying combination'
return (0, cfg_webaccess_warning_msgs[0]) # USER AUTHENTICATED TO PERFORM ACTION
if verbose: print '-> not this one'
# assign the values for the current tuple from the query
cur_arglistid, cur_role, cur_action = arglistid, role, action
for key in booldict.keys():
booldict[key] = 0
# set keyword qualified for the action, (whatever result of the test)
booldict[keyword] = 1
if verbose: print 'finished'
# authentication failed
return (4, "%s %s" % (cfg_webaccess_warning_msgs[4], (called_from and "%s %s" % (cfg_webaccess_msgs[0] % name_action[3:], cfg_webaccess_msgs[1]) or "")))
diff --git a/modules/webaccess/lib/external_authentication.py b/modules/webaccess/lib/external_authentication.py
index 1c12d6047..07d32bb07 100644
--- a/modules/webaccess/lib/external_authentication.py
+++ b/modules/webaccess/lib/external_authentication.py
@@ -1,64 +1,64 @@
## $Id$
## CDSware Access Control Config in mod_python.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import httplib
import urllib
import re
class external_auth_nice:
users = {}
name = ""
def __init__(self):
#Initialize stuff here
pass
def auth_user(self, username, password):
#login user here
params = urllib.urlencode({'Username': username, 'Password': password})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = httplib.HTTPSConnection("winservices.web.cern.ch")
conn.request("POST", "/WinServices/Authentication/CDS/default.asp", params, headers)
response = conn.getresponse()
data = response.read()
conn.close()
m = re.search('<CCID>\d+</CCID>', data)
if m:
m = m.group()
CCID = int(re.search('\d+',m).group())
if CCID > 0:
m = re.search('<EMAIL>.*?</EMAIL>', data)
if m:
email = m.group()
email = email.replace('<EMAIL>', '')
email = email.replace('</EMAIL>', '')
return email
return None
class external_auth_template:
def __init__(self):
#Initialize stuff here
pass
def auth_user(self, username, password):
#login user here
return email
return None
diff --git a/modules/webaccess/lib/webaccessadmin_lib.py b/modules/webaccess/lib/webaccessadmin_lib.py
index 3a9e8ae91..2e43f1364 100644
--- a/modules/webaccess/lib/webaccessadmin_lib.py
+++ b/modules/webaccess/lib/webaccessadmin_lib.py
@@ -1,3430 +1,3430 @@
## $Id$
## Administrator interface for WebAccess
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware WebAccess Administrator Interface."""
__lastupdated__ = """$Date$"""
## fill config variables:
import cgi
import re
import random
import MySQLdb
import string
import smtplib
from mod_python import apache
import cdsware.access_control_engine as acce
import cdsware.access_control_admin as acca
from cdsware.bibrankadminlib import adderrorbox,addadminbox,tupletotable,tupletotable_onlyselected,addcheckboxes,createhiddenform
from cdsware.access_control_config import *
from cdsware.dbquery import run_sql
from cdsware.config import *
from cdsware.webpage import page, pageheaderonly, pagefooteronly
from cdsware.webuser import getUid, get_email, page_not_authorized
from cdsware.search_engine import print_record
from cdsware.webuser import checkemail, get_user_preferences, set_user_preferences
__version__ = "$Id$"
def index(req, title='', body='', subtitle='', adminarea=2, authorized=0):
"""main function to show pages for webaccessadmin.
1. if user not logged in and administrator, show the mustlogin page
2. if used without body argument, show the startpage
3. show admin page with title, body, subtitle and navtrail.
adminarea - number codes that tell what extra info to put in the navtrail
0 - nothing extra
1 - add Delegate Rights
2 - add Manage WebAccess
maybe add:
3: role admin
4: action admin
5: user area
6: reset area
authorized - if 1, don't check if the user is allowed to be webadmin """
navtrail_previous_links = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/webaccess/">WebAccess Admin</a> """ % (weburl, weburl)
if body:
if adminarea == 1: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/delegate_startarea>Delegate Rights</a> ' % (weburl, )
if adminarea >= 2 and adminarea < 7: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py>Manage WebAccess</a> ' % (weburl, )
if adminarea == 3: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/rolearea>Role Administration</a> ' % (weburl, )
elif adminarea == 4: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/actionarea>Action Administration</a> ' % (weburl, )
elif adminarea == 5: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/userarea>User Administration</a> ' % (weburl, )
elif adminarea == 6: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/resetarea>Reset Authorizations</a> ' % (weburl, )
elif adminarea == 7: navtrail_previous_links += '&gt; <a class=navtrail href=%s/admin/webaccess/webaccessadmin.py/manageaccounts>Manage Accounts</a> ' % (weburl, )
id_user = getUid(req)
(auth_code, auth_message) = is_adminuser(req)
if not authorized and auth_code != 0: return mustloginpage(req, auth_message)
elif not body:
title = 'Manage WebAccess'
body = startpage()
elif type(body) != str: body = addadminbox(subtitle, datalist=body)
return page(title=title,
uid=id_user,
body=body,
navtrail=navtrail_previous_links,
lastupdated=__lastupdated__)
def mustloginpage(req, message):
"""show a page asking the user to login."""
navtrail_previous_links = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/webaccess/">WebAccess Admin</a> """ % (weburl, weburl)
return page_not_authorized(req=req, text=message, navtrail=navtrail_previous_links)
def is_adminuser(req):
"""check if user is a registered administrator. """
id_user = getUid(req)
return acce.acc_authorize_action(id_user, WEBACCESSACTION)
def perform_rolearea(req):
"""create the role area menu page."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
header = ['id', 'name', 'description', 'users', 'authorizations / actions', 'role', '']
roles = acca.acc_getAllRoles()
roles2 = []
for (id, name, desc) in roles:
if len(desc) > 30: desc = desc[:30] + '...'
roles2.append([id, name, desc])
for col in [(('add', 'adduserrole'),
('remove', 'deleteuserrole')),
(('add', 'addauthorization'),
('modify', 'modifyauthorizations'),
('remove', 'deleteroleaction')),
(('delete', 'deleterole'), ),
(('show details', 'showroledetails'), )]:
roles2[-1].append('<a href="%s?id_role=%s">%s</a>' % (col[0][1], id, col[0][0]))
for (str, function) in col[1:]:
roles2[-1][-1] += ' / <a href="%s?id_role=%s">%s</a>' % (function, id, str)
output = """
<dl>
<dt>Users:</dt>
<dd>add or remove users from the access to a role and its priviliges.</dd>
<dt>Authorizations/Actions:</dt>
<dd>these terms means almost the same, but an authorization is a <br>
connection between a role and an action (possibly) containing arguments.</dd>
<dt>Roles:</dt>
<dd>see all the information attached to a role and decide if you want to<br>delete it.</dd>
</dl>
"""
output += tupletotable(header=header, tuple=roles2)
extra = """
<dl>
<dt><a href="addrole">Create new role</a></dt>
<dd>go here to add a new role.</dd>
<dt><a href="addaction">Create new action</a></dt>
<dd>go here to add a new action.</dd>
</dl>
"""
return index(req=req,
title='Role Administration',
subtitle='administration with roles as access point',
body=[output, extra],
adminarea=2)
def perform_actionarea(req):
"""create the action area menu page."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
header = ['id', 'name', 'authorizations/roles', 'action', '']
actions = acca.acc_getAllActions()
actions2 = []
roles2 = []
for (id, name, dontcare) in actions:
actions2.append([id, name])
for col in [(('add', 'addauthorization'),
('modify', 'modifyauthorizations'),
('remove', 'deleteroleaction')),
(('delete', 'deleteaction'), ),
(('show details', 'showactiondetails'), )]:
actions2[-1].append('<a href="%s?id_action=%s&amp;reverse=1">%s</a>' % (col[0][1], id, col[0][0]))
for (str, function) in col[1:]:
actions2[-1][-1] += ' / <a href="%s?id_action=%s&amp;reverse=1">%s</a>' % (function, id, str)
output = """
<dl>
<dt>Authorizations/Roles:</dt>
<dd>these terms means almost the same, but an authorization is a <br>
connection between a role and an action (possibly) containing arguments.</dd>
<dt>Actions:</dt>
<dd>see all the information attached to an action and decide if you want to<br>delete it.</dd>
</dl>
"""
output += tupletotable(header=header, tuple=actions2)
extra = """
<dl>
<dt><a href="addrole">Create new role</a>
<dd>go here to add a new role.
<dt><a href="addaction">Create new action</a>
<dd>go here to add a new action.
</dl>
"""
return index(req=req,
title='Action Administration',
subtitle='administration with actions as access point',
body=[output, extra],
adminarea=2)
def perform_userarea(req, email_user_pattern=''):
"""create area to show info about users. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = 'step 1 - search for users'
output = """
<p>
search for users to display.
</p> """
# remove letters not allowed in an email
email_user_pattern = cleanstring_email(email_user_pattern)
text = ' <span class="adminlabel">1. search for user</span>\n'
text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
output += createhiddenform(action="userarea",
text=text,
button="search for users")
if email_user_pattern:
users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email LIMIT %s""" % (email_user_pattern, MAXPAGEUSERS+1))
if not users1:
output += '<p>no matching users</p>'
else:
subtitle = 'step 2 - select what to do with user'
users = []
for (id, email) in users1[:MAXPAGEUSERS]:
users.append([id, email])
for col in [(('add', 'addroleuser'),
('remove', 'deleteuserrole')),
(('show details', 'showuserdetails'), )]:
users[-1].append('<a href="%s?email_user_pattern=%s&amp;id_user=%s">%s</a>' % (col[0][1], email_user_pattern, id, col[0][0]))
for (str, function) in col[1:]:
users[-1][-1] += ' / <a href="%s?email_user_pattern=%s&amp;id_user=%s&amp;reverse=1">%s</a>' % (function, email_user_pattern, id, str)
output += '<p>found <strong>%s</strong> matching users:</p>' % (len(users1), )
output += tupletotable(header=['id', 'email', 'roles', ''], tuple=users)
if len(users1) > MAXPAGEUSERS:
output += '<p><strong>only showing the first %s users, narrow your search...</strong></p>' % (MAXPAGEUSERS, )
return index(req=req,
title='User Administration',
subtitle=subtitle,
body=[output],
adminarea=2)
def perform_resetarea(req):
"""create the reset area menu page."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
output = """
<dl>
<dt><a href="resetdefaultsettings">Reset to Default Authorizations</a>
<dd>remove all changes that has been done to the roles and <br>
add only the default authorization settings.
<dt><a href="adddefaultsettings">Add Default Authorizations</a>
<dd>keep all changes and add the default authorization settings.
</dl>
"""
return index(req=req,
title='Reset Authorizations',
subtitle='reseting to or adding default authorizations',
body=[output],
adminarea=2)
def perform_resetdefaultsettings(req, superusers=[], confirm=0):
"""delete all roles, actions and authorizations presently in the database
and add only the default roles.
only selected users will be added to superadmin, rest is blank """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
# cleaning input
if type(superusers) == str: superusers = [superusers]
# remove not valid e-mails
for email in superusers:
if not check_email(email): superusers.remove(email)
# instructions
output = """
<p>
before you reset the settings, we need some users<br>
to connect to <strong>%s</strong>.<br>
enter as many e-mail adresses you want and press <strong>reset</strong>.<br>
<strong>confirm reset settings</strong> when you have added enough e-mails.<br>
<strong>%s</strong> is added as default.
</p>""" % (SUPERADMINROLE, supportemail)
# add more superusers
output += """
<p>enter user e-mail addresses: </p>
<form action="resetdefaultsettings" method="POST">"""
for email in superusers:
output += ' <input type="hidden" name="superusers" value="%s" />' % (email, )
output += """
<span class="adminlabel">e-mail</span>
<input class="admin_wvar" type="text" name="superusers" />
<input class="adminbutton" type="submit" value="add e-mail" />
</form>"""
if superusers:
# remove emails
output += """
<form action="resetdefaultsettings" method="POST">
have you entered wrong data?
<input class="adminbutton" type="submit" value="remove all e-mails" />
</form>
"""
# superusers confirm table
start = '<form action="resetdefaultsettings" method="POST">'
extra = ' <input type="hidden" name="confirm" value="1" />'
for email in superusers:
extra += '<input type="hidden" name="superusers" value="%s" />' % (email, )
extra += ' <input class="adminbutton" type="submit" value="confirm to reset settings" />'
end = '</form>'
output += '<p><strong>reset default settings</strong> with the users below? </p>'
output += tupletotable(header=['e-mail address'],
tuple=superusers,
start=start,
extracolumn=extra,
end=end)
if confirm in [1, "1"]:
res = acca.acc_reset_default_settings(superusers)
if res:
output += '<p>successfully reset default settings</p>'
else:
output += '<p>sorry, could not reset default settings</p>'
return index(req=req,
title='Reset Default Settings',
subtitle='reset settings',
body=[output],
adminarea=6)
def perform_adddefaultsettings(req, superusers=[], confirm=0):
"""add the default settings, and keep everything else.
probably nothing will be deleted, except if there has been made changes to the defaults."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
# cleaning input
if type(superusers) == str: superusers = [superusers]
# remove not valid e-mails
for email in superusers:
if not check_email(email): superusers.remove(email)
# instructions
output = """
<p>
before you add the settings, we need some users<br>
to connect to <strong>%s</strong>.<br>
enter as many e-mail adresses you want and press <strong>add</strong>.<br>
<strong>confirm add settings</strong> when you have added enough e-mails.<br>
<strong>%s</strong> is added as default.
</p>""" % (SUPERADMINROLE, supportemail)
# add more superusers
output += """
<p>enter user e-mail addresses: </p>
<form action="adddefaultsettings" method="POST">"""
for email in superusers:
output += ' <input type="hidden" name="superusers" value="%s" />' % (email, )
output += """
<span class="adminlabel">e-mail</span>
<input class="admin_wvar" type="text" name="superusers" />
<input class="adminbutton" type="submit" value="add e-mail" />
</form>
"""
if superusers:
# remove emails
output += """
<form action="adddefaultsettings" method="POST">
have you entered wrong data?
<input class="adminbutton" type="submit" value="remove all e-mails" />
</form>
"""
# superusers confirm table
start = '<form action="adddefaultsettings" method="POST">'
extra = ' <input type="hidden" name="confirm" value="1" />'
for email in superusers:
extra += '<input type="hidden" name="superusers" value="%s" />' % (email, )
extra += ' <input class="adminbutton" type="submit" value="confirm to add settings" />'
end = '</form>'
output += '<p><strong>add default settings</strong> with the users below? </p>'
output += tupletotable(header=['e-mail address'],
tuple=superusers,
start=start,
extracolumn=extra,
end=end)
if confirm in [1, "1"]:
res = acca.acc_add_default_settings(superusers)
if res:
output += '<p>successfully added default settings</p>'
else:
output += '<p>sorry, could not add default settings</p>'
return index(req=req,
title='Add Default Settings',
subtitle='add settings',
body=[output],
adminarea=6)
def perform_manageaccounts(req, mtype='', content='', confirm=0):
"""start area for managing accounts."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = 'Overview'
fin_output = ''
fin_output += """
<table>
<tr>
<td><b>Menu</b></td>
</tr>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_showall">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_accesspolicy#1">Access policy</a></
small></td>
<td>2.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_accountoverview#2">Account overview</a></
small></td>
<td>3.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_createaccount#3">Create account</a></
small></td>
<td>4.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/manageaccounts?mtype=perform_modifyaccounts#4">Edit accounts</a></small></
td>
</tr>
</table>
""" % (weburl, weburl, weburl, weburl, weburl)
if mtype == "perform_accesspolicy" and content:
fin_output += content
elif mtype == "perform_accesspolicy" or mtype == "perform_showall":
fin_output += perform_accesspolicy(req, callback='')
fin_output += "<br>"
if mtype == "perform_accountoverview" and content:
fin_output += content
elif mtype == "perform_accountoverview" or mtype == "perform_showall":
fin_output += perform_accountoverview(req, callback='')
fin_output += "<br>"
if mtype == "perform_createaccount" and content:
fin_output += content
elif mtype == "perform_createaccount" or mtype == "perform_showall":
fin_output += perform_createaccount(req, callback='')
fin_output += "<br>"
if mtype == "perform_modifyaccounts" and content:
fin_output += content
elif mtype == "perform_modifyaccounts" or mtype == "perform_showall":
fin_output += perform_modifyaccounts(req, callback='')
fin_output += "<br>"
return index(req=req,
title='Manage Accounts',
subtitle=subtitle,
body=[fin_output],
adminarea=0,
authorized=1)
def perform_accesspolicy(req, callback='yes', confirm=0):
"""Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="1"></a>1. Access policy.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
account_policy = {}
account_policy[0] = "Users can register new accounts. New accounts automatically activated."
account_policy[1] = "Users can register new accounts. Admin users must activate the accounts."
account_policy[2] = "Only admin can register new accounts. User cannot edit email address."
account_policy[3] = "Only admin can register new accounts. User cannot edit email address or password."
account_policy[4] = "Only admin can register new accounts. User cannot edit email address,password or login method."
site_policy = {}
site_policy[0] = "Normal operation of the site."
site_policy[1] = "Read-only site, all write operations temporarily closed."
site_policy[2] = "Site fully closed."
output = "(Modifications must be done in access_control_config.py)<br>"
output += "<br><b>Current settings:</b><br>"
output += "Site status: %s<br>" % (site_policy[CFG_ACCESS_CONTROL_LEVEL_SITE])
output += "Guest accounts allowed: %s<br>" % (CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0 and "Yes" or "No")
output += "Account policy: %s<br>" % (account_policy[CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS])
output += "Allowed email addresses limited: %s<br>" % (CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN and CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN or "Not limited")
output += "Send email to admin when new account: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS == 1 and "Yes" or "No")
output += "Send email to user after creating new account: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1 and "Yes" or "No")
output += "Send email to user when account is activated: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION == 1 and "Yes" or "No")
output += "Send email to user when account is deleted/rejected: %s<br>" % (CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1 and "Yes" or "No")
output += "<br>"
output += "<b>Available 'login via' methods:</b><br>"
methods = CFG_EXTERNAL_AUTHENTICATION.keys()
methods.sort()
for system in methods:
output += """%s %s<br>""" % (system, (CFG_EXTERNAL_AUTHENTICATION[system][1] and "(Default)" or ""))
output += "<br><b>Changing the settings:</b><br>"
output += "Currently, all changes must be done using your favourite editor, and the webserver restarted for changes to take effect. For the settings to change, either look in the guide or in access_control_config.py ."
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_manageaccounts(req, "perform_accesspolicy", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_accountoverview(req, callback='yes', confirm=0):
"""Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="2"></a>2. Account overview.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
output = ""
res = run_sql("SELECT COUNT(*) FROM user WHERE email=''")
output += "Guest accounts: %s<br>" % res[0][0]
res = run_sql("SELECT COUNT(*) FROM user WHERE email!=''")
output += "Registered accounts: %s<br>" % res[0][0]
res = run_sql("SELECT COUNT(*) FROM user WHERE email!='' AND note='0' OR note IS NULL")
output += "Inactive accounts: %s " % res[0][0]
if res[0][0] > 0:
output += ' [<a href="modifyaccounts?email_user_pattern=&amp;limit_to=disabled&amp;maxpage=25&amp;page=1">Activate/Reject accounts</a>]'
res = run_sql("SELECT COUNT(*) FROM user")
output += "<br>Total nr of accounts: %s<br>" % res[0][0]
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_manageaccounts(req, "perform_accountoverview", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_createaccount(req, email='', password='', callback='yes', confirm=0):
"""Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="3"></a>3. Create account.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
output = ""
text = ' <span class="adminlabel">Email:</span>\n'
text += ' <input class="admin_wvar" type="text" name="email" value="%s" /><br>' % (email, )
text += ' <span class="adminlabel">Password:</span>\n'
text += ' <input class="admin_wvar" type="text" name="password" value="%s" /><br>' % (password, )
output += createhiddenform(action="createaccount",
text=text,
confirm=1,
button="Create")
if confirm in [1, "1"] and email and checkemail(email):
res = run_sql("SELECT * FROM user WHERE email='%s'" % MySQLdb.escape_string(email))
if not res:
res = run_sql("INSERT INTO user (email,password, note) values('%s','%s', '1')" % (MySQLdb.escape_string(email), MySQLdb.escape_string(password)))
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1:
emailsent = sendNewUserAccountWarning(email, email, password)
if password:
output += '<b><span class="info">Account created with password and activated.</span></b>'
else:
output += '<b><span class="info">Account created without password and activated.</span></b>'
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1:
if emailsent:
output += '<br><b><span class="info">An email has been sent to the owner of the account.</span></b>'
else:
output += '<br><b><span class="important">Could not send an email to the owner of the account.</span></b>'
else:
output += '<b><span class="info">An account with the same email already exists.</span></b>'
elif confirm in [1, "1"]:
output += '<b><span class="info">Please specify an valid email-address.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_manageaccounts(req, "perform_createaccount", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyaccountstatus(req, userID, email_user_pattern, limit_to, maxpage, page, callback='yes', confirm=0):
"""set a disabled account to enabled and opposite"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
res = run_sql("SELECT id, email, note, password FROM user WHERE id=%s" % userID)
output = ""
if res:
if res[0][2] in [0, "0", None]:
res2 = run_sql("UPDATE user SET note=1 WHERE id=%s" % userID)
output += """<b><span class="info">The account '%s' has been activated.</span></b>""" % res[0][1]
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_ACTIVATION == 1:
emailsent = sendAccountActivatedMessage(res[0][1], res[0][1], res[0][3])
if emailsent:
output += """<br><b><span class="info">An email has been sent to the owner of the account.</span></b>"""
else:
output += """<br><b><span class="info">Could not send an email to the owner of the account.</span></b>"""
elif res[0][2] in [1, "1"]:
res2 = run_sql("UPDATE user SET note=0 WHERE id=%s" % userID)
output += """<b><span class="info">The account '%s' has been set inactive.</span></b>""" % res[0][1]
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyaccounts(req, email_user_pattern, limit_to, maxpage, page, content=output, callback='yes')
else:
return addadminbox(subtitle, body)
def perform_editaccount(req, userID, mtype='', content='', callback='yes', confirm=-1):
"""form to modify an account. this method is calling other methods which again is calling this and sending back the output of the method.
if callback, the method will call perform_editcollection, if not, it will just return its output.
userID - id of the user
mtype - the method that called this method.
content - the output from that method."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
res = run_sql("SELECT id, email FROM user WHERE id=%s" % userID)
if not res:
if mtype == "perform_deleteaccount":
text = """<b><span class="info">The selected account has been deleted, to continue editing, go back to 'Manage Accounts'.</span></b>"""
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1:
text += """<br><b><span class="info">An email has been sent to the owner of the account.</span></b>"""
else:
text = """<b><span class="info">The selected accounts does not exist, please go back and select an account to edit.</span></b>"""
return index(req=req,
title='Edit Account',
subtitle="Edit account",
body=[text],
adminarea=7,
authorized=1)
fin_output = """
<table>
<tr>
<td><b>Menu</b></td>
</tr>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifylogindata">Modify login-data</a></small></td>
<td>2.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifybasket">Modify baskets</a></small></td>
<td>3.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifyalerts">Modify alerts</a></small></td>
<td>4.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_modifypreferences">Modify preferences</a></small></td>
</tr><tr>
<td>5.&nbsp;<small><a href="%s/admin/webaccess/webaccessadmin.py/editaccount?userID=%s&amp;mtype=perform_deleteaccount">Delete account</a></small></td>
</tr>
</table>
""" % (weburl, userID, weburl, userID, weburl, userID, weburl, userID, weburl, userID, weburl, userID)
if mtype == "perform_modifylogindata" and content:
fin_output += content
elif mtype == "perform_modifylogindata" or not mtype:
fin_output += perform_modifylogindata(req, userID, callback='')
if mtype == "perform_modifybasket" and content:
fin_output += content
elif mtype == "perform_modifybasket" or not mtype:
fin_output += perform_modifybasket(req, userID, callback='')
if mtype == "perform_modifypreferences" and content:
fin_output += content
elif mtype == "perform_modifypreferences" or not mtype:
fin_output += perform_modifypreferences(req, userID, callback='')
if mtype == "perform_modifyalerts" and content:
fin_output += content
elif mtype == "perform_modifyalerts" or not mtype:
fin_output += perform_modifyalerts(req, userID, callback='')
if mtype == "perform_deleteaccount" and content:
fin_output += content
elif mtype == "perform_deleteaccount" or not mtype:
fin_output += perform_deleteaccount(req, userID, callback='')
return index(req=req,
title='Edit Account',
subtitle="Edit account '%s'" % res[0][1],
body=[fin_output],
adminarea=7,
authorized=1)
def perform_modifybasket(req, userID, callback='yes', confirm=0):
"""modify email and password of an account"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="2"></a>2. Modify baskets.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
output = ""
if res:
text = """To modify the baskets for this account, you have to login as the user."""
output += createhiddenform(action="%s/youraccount.py/login?" % weburl,
text=text,
p_email=res[0][1],
p_pw=res[0][2],
referer="%s/yourbaskets.py/display" % weburl,
button="Login")
output += "Remember that you will be logged out as the current user."
#baskets = run_sql("SELECT basket.id, basket.name, basket.public FROM basket, user_basket WHERE id_user=%s and user_basket.id_basket=basket.id" % userID)
#output += "<table><tr>"
#for (id, name, public) in baskets:
# output += "<tr><td>%s<br>Public: %s</td></tr>" % (name, (public=="y" and "Yes" or "No"))
# basket_records = run_sql("SELECT id_record, nb_order FROM basket_record WHERE id_basket=%s" % id)
# for (id_record, nb_order) in basket_records:
# output += "<tr><td></td><td>"
# output += print_record(id_record)
# output += "</td></tr>"
#
#output += "</tr></table>"
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editaccount(req, userID, mtype='perform_modifybasket', content=addadminbox(subtitle, body), callback='yes')
else:
return addadminbox(subtitle, body)
def perform_modifylogindata(req, userID, email='', password='', callback='yes', confirm=0):
"""modify email and password of an account"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="1"></a>1. Edit login-data.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
output = ""
if res:
if not email and not password:
email = res[0][1]
password = res[0][2]
text = ' <span class="adminlabel">Account id:</span>%s<br>\n' % userID
text += ' <span class="adminlabel">Email:</span>\n'
text += ' <input class="admin_wvar" type="text" name="email" value="%s" /><br>' % (email, )
text += ' <span class="adminlabel">Password:</span>\n'
text += ' <input class="admin_wvar" type="text" name="password" value="%s" /><br>' % (password, )
output += createhiddenform(action="modifylogindata",
text=text,
userID=userID,
confirm=1,
button="Modify")
if confirm in [1, "1"] and email and checkemail(email):
res = run_sql("UPDATE user SET email='%s' WHERE id=%s" % (MySQLdb.escape_string(email), userID))
res = run_sql("UPDATE user SET password='%s' WHERE id=%s" % (MySQLdb.escape_string(password), userID))
output += '<b><span class="info">Email and/or password modified.</span></b>'
elif confirm in [1, "1"]:
output += '<b><span class="info">Please specify an valid email-address.</span></b>'
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editaccount(req, userID, mtype='perform_modifylogindata', content=addadminbox(subtitle, body), callback='yes')
else:
return addadminbox(subtitle, body)
def perform_modifyalerts(req, userID, callback='yes', confirm=0):
"""modify email and password of an account"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="3"></a>3. Modify alerts.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
output = ""
if res:
text = """To modify the alerts for this account, you have to login as the user."""
output += createhiddenform(action="%s/youraccount.py/login?" % weburl,
text=text,
p_email=res[0][1],
p_pw=res[0][2],
referer="%s/youralerts.py/display" % weburl,
button="Login")
output += "Remember that you will be logged out as the current user."
res= """ SELECT q.id, q.urlargs, a.id_basket,
a.alert_name, a.frequency, a.notification,
DATE_FORMAT(a.date_creation,'%%d %%b %%Y'),
DATE_FORMAT(a.date_lastrun,'%%d %%b %%Y')
FROM query q, user_query_basket a
WHERE a.id_user='%s' AND a.id_query=q.id
ORDER BY a.alert_name ASC """ % userID
#res = run_sql(res)
#for (qID, qurlargs, id_basket, alertname, frequency, notification, date_creation, date_lastrun) in res:
# output += "%s - %s - %s - %s - %s - %s - %s<br>" % (qID, id_basket, alertname, frequency, notification, date_creation, date_lastrun)
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editaccount(req, userID, mtype='perform_modifyalerts', content=addadminbox(subtitle, body), callback='yes')
else:
return addadminbox(subtitle, body)
def perform_modifypreferences(req, userID, login_method='', callback='yes', confirm=0):
"""modify email and password of an account"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="4"></a>4. Modify preferences.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
output = ""
if res:
user_pref = get_user_preferences(userID)
if confirm in [1, "1"]:
if login_method:
user_pref['login_method'] = login_method
set_user_preferences(userID, user_pref)
output += "Select default login method:<br>"
text = ""
methods = CFG_EXTERNAL_AUTHENTICATION.keys()
methods.sort()
for system in methods:
text += """<input type="radio" name="login_method" value="%s" %s>%s<br>""" % (system, (user_pref['login_method'] == system and "checked" or ""), system)
output += createhiddenform(action="modifypreferences",
text=text,
confirm=1,
userID=userID,
button="Select")
if confirm in [1, "1"]:
if login_method:
output += """<b><span class="info">The login method has been changed</span></b>"""
else:
output += """<b><span class="info">Nothing to update</span></b>"""
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editaccount(req, userID, mtype='perform_modifypreferences', content=addadminbox(subtitle, body), callback='yes')
else:
return addadminbox(subtitle, body)
def perform_deleteaccount(req, userID, callback='yes', confirm=0):
"""delete account"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="5"></a>5. Delete account.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
res = run_sql("SELECT id, email, password FROM user WHERE id=%s" % userID)
output = ""
if res:
if confirm in [0, "0"]:
text = '<b><span class="important">Are you sure you want to delete the account with email: "%s"?</span></b>' % res[0][1]
output += createhiddenform(action="deleteaccount",
text=text,
userID=userID,
confirm=1,
button="Delete")
elif confirm in [1, "1"]:
res2 = run_sql("DELETE FROM user WHERE id=%s" % userID)
output += '<b><span class="info">Account deleted.</span></b>'
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1:
emailsent = sendAccountDeletedMessage(res[0][1], res[0][1])
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editaccount(req, userID, mtype='perform_deleteaccount', content=addadminbox(subtitle, body), callback='yes')
else:
return addadminbox(subtitle, body)
def perform_rejectaccount(req, userID, email_user_pattern, limit_to, maxpage, page, callback='yes', confirm=0):
"""Delete account and send an email to the owner."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
res = run_sql("SELECT id, email, password, note FROM user WHERE id=%s" % userID)
output = ""
if res:
res2 = run_sql("DELETE FROM user WHERE id=%s" % userID)
output += '<b><span class="info">Account rejected and deleted.</span></b>'
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_DELETION == 1:
if not res[0][3] or res[0][3] == "0":
emailsent = sendAccountRejectedMessage(res[0][1], res[0][1])
elif res[0][3] == "1":
emailsent = sendAccountDeletedMessage(res[0][1], res[0][1])
if emailsent:
output += """<br><b><span class="info">An email has been sent to the owner of the account.</span></b>"""
else:
output += """<br><b><span class="info">Could not send an email to the owner of the account.</span></b>"""
else:
output += '<b><span class="info">The account id given does not exist.</span></b>'
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_modifyaccounts(req, email_user_pattern, limit_to, maxpage, page, content=output, callback='yes')
else:
return addadminbox(subtitle, body)
def perform_modifyaccounts(req, email_user_pattern='', limit_to=-1, maxpage=MAXPAGEUSERS, page=1, content='', callback='yes', confirm=0):
"""Modify default behaviour of a guest user or if new accounts should automatically/manually be modified."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
subtitle = """<a name="4"></a>4. Edit accounts.&nbsp&nbsp&nbsp<small>[<a title="See guide" href="%s/admin/webaccess/guide.html#4">?</a>]</small>""" % weburl
output = ""
# remove letters not allowed in an email
email_user_pattern = cleanstring_email(email_user_pattern)
try:
maxpage = int(maxpage)
except:
maxpage = MAXPAGEUSERS
try:
page = int(page)
if page < 1:
page = 1
except:
page = 1
text = ' <span class="adminlabel">Email (part of):</span>\n'
text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" /><br>' % (email_user_pattern, )
text += """<span class="adminlabel">Limit to:</span>
<select name="limit_to" class="admin_w200">
<option value="all" %s>All accounts</option>
<option value="enabled" %s>Active accounts</option>
<option value="disabled" %s>Inactive accounts</option>
</select><br>""" % ((limit_to=="all" and "selected" or ""), (limit_to=="enabled" and "selected" or ""), (limit_to=="disabled" and "selected" or ""))
text += """<span class="adminlabel">Accounts per page:</span>
<select name="maxpage" class="admin_wvar">
<option value="25" %s>25</option>
<option value="50" %s>50</option>
<option value="100" %s>100</option>
<option value="250" %s>250</option>
<option value="500" %s>500</option>
<option value="1000" %s>1000</option>
</select><br>""" % ((maxpage==25 and "selected" or ""), (maxpage==50 and "selected" or ""), (maxpage==100 and "selected" or ""), (maxpage==250 and "selected" or ""), (maxpage==500 and "selected" or ""), (maxpage==1000 and "selected" or ""))
output += createhiddenform(action="modifyaccounts",
text=text,
button="search for accounts")
if limit_to not in [-1, "-1"] and maxpage:
users1 = "SELECT id,email,note FROM user WHERE "
if limit_to == "enabled":
users1 += " email!='' AND note=1"
elif limit_to == "disabled":
users1 += " email!='' AND note=0 OR note IS NULL"
elif limit_to == "guest":
users1 += " email=''"
else:
users1 += " email!=''"
if email_user_pattern:
users1 += " AND email RLIKE '%s'" % (email_user_pattern)
users1 += " ORDER BY email LIMIT %s" % (maxpage * page + 1)
users1 = run_sql(users1)
if not users1:
output += '<b><span class="info">There are no accounts matching the email given.</span></b>'
else:
users = []
if maxpage * (page - 1) > len(users1):
page = len(users1) / maxpage + 1
for (id, email, note) in users1[maxpage * (page - 1):(maxpage * page)]:
users.append(['', id, email, (note=="1" and '<strong class="info">Active</strong>' or '<strong class="important">Inactive</strong>')])
for col in [(((note=="1" and 'Inactivate' or 'Activate'), 'modifyaccountstatus'), ((note == "0" and 'Reject' or 'Delete'), 'rejectaccount'), ),
(('Edit account', 'editaccount'), ),]:
users[-1].append('<a href="%s?userID=%s&amp;email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s&amp;rand=%s">%s</a>' % (col[0][1], id, email_user_pattern, limit_to, maxpage, page, random.randint(0,1000), col[0][0]))
for (str, function) in col[1:]:
users[-1][-1] += ' / <a href="%s?userID=%s&amp;email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s&amp;rand=%s">%s</a>' % (function, id, email_user_pattern, limit_to, maxpage, page, random.randint(0,1000), str)
last = ""
next = ""
if len(users1) > maxpage:
if page > 1:
last += '<b><span class="info"><a href="modifyaccounts?email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s">Last Page</a></span></b>' % (email_user_pattern, limit_to, maxpage, (page - 1))
if len(users1[maxpage * (page - 1):(maxpage * page)]) == maxpage:
next += '<b><span class="info"><a href="modifyaccounts?email_user_pattern=%s&amp;limit_to=%s&amp;maxpage=%s&amp;page=%s">Next page</a></span></b>' % (email_user_pattern, limit_to, maxpage, (page + 1))
output += '<b><span class="info">Showing accounts %s-%s:</span></b>' % (1 + maxpage * (page - 1), maxpage * page)
else:
output += '<b><span class="info">%s matching account(s):</span></b>' % len(users1)
output += tupletotable(header=[last, 'id', 'email', 'Status', '', '',next], tuple=users)
else:
output += '<b><span class="info">Please select which accounts to find and how many to show per page.</span></b>'
if content:
output += "<br>%s" % content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_manageaccounts(req, "perform_modifyaccounts", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_delegate_startarea(req):
"""start area for lower level delegation of rights."""
subtitle = 'select what to do'
output = ''
if is_adminuser(req)[0] == 0:
output += """
<p>
You are also allowed to be in the <a href="../webaccessadmin.py">Main Admin Area</a> which gives you<br>
the access to the full functionality of WebAccess.
</p>
"""
output += """
<dl>
<dt><a href="delegate_adduserrole">Connect users to roles</a></dt>
<dd>add users to the roles you have delegation rights to.</dd>
<dt><a href="delegate_deleteuserrole">Remove users from roles</a></dt>
<dd>remove users from the roles you have delegation rights to.</dd>
</dl>
<dl>
<dt><a href="delegate_adminsetup">Set up delegation rights</a></dt>
<dd>spesialized area to set up the delegation rights used in the areas above. <br>
you need to be a web administrator to access the area.</dd>
</dl>
"""
return index(req=req,
title='Delegate Rights',
subtitle=subtitle,
body=[output],
adminarea=0,
authorized=1)
def perform_delegate_adminsetup(req, id_role_admin=0, id_role_delegate=0, confirm=0):
"""lets the webadmins set up the delegation rights for the other roles
id_role_admin - the role to be given delegation rights
id_role_delegate - the role over which the delegation rights are given
confirm - make the connection happen """
subtitle = 'step 1 - select admin role'
admin_roles = acca.acc_getAllRoles()
output = """
<p>
This is a specialized area to handle a task that also can be handled<br>
from the &quot;add authorization&quot; interface.
</p>
<p>
By handling the delegation rights here you get the advantage of<br>
not having to select the correct action <i>(%s)</i> or<br>
remembering the names of available roles.
</p>
""" % (DELEGATEADDUSERROLE, )
output += createroleselect(id_role=id_role_admin,
step=1,
button='select admin role',
name='id_role_admin',
action='delegate_adminsetup',
roles=admin_roles)
if str(id_role_admin) != '0':
subtitle = 'step 2 - select delegate role'
name_role_admin = acca.acc_getRoleName(id_role=id_role_admin)
delegate_roles_old = acca.acc_find_delegated_roles(id_role_admin=id_role_admin)
delegate_roles = []
delegate_roles_old_names = []
for role in admin_roles:
if (role,) not in delegate_roles_old:
delegate_roles.append(role)
else:
delegate_roles_old_names.append(role[1])
if delegate_roles_old_names:
delegate_roles_old_names.sort()
names_str = ''
for name in delegate_roles_old_names:
if names_str: names_str += ', '
names_str += name
output += '<p>previously selected roles: <strong>%s</strong>.</p>' % (names_str, )
extra = """
<dl>
<dt><a href="modifyauthorizations?id_role=%s&amp;id_action=%s">Remove delegated roles</a></dt>
<dd>use the standard administration area to remove delegation rights
you no longer want to be available.</dd>
</dl>
""" % (id_role_admin, acca.acc_getActionId(name_action=DELEGATEADDUSERROLE))
else:
output += '<p>no previously selected roles.</p>'
output += createroleselect(id_role=id_role_delegate,
step=2,
button='select delegate role',
name='id_role_delegate',
action='delegate_adminsetup',
roles=delegate_roles,
id_role_admin=id_role_admin)
if str(id_role_delegate) != '0':
subtitle = 'step 3 - confirm to add delegation right'
name_role_delegate = acca.acc_getRoleName(id_role=id_role_delegate)
output += """
<p>
<span class="warning"><strong>Warning:</strong> don't hand out delegation rights that can harm the system (e.g. delegating superrole).</span>
</p> """
output += createhiddenform(action="delegate_adminsetup",
text='let role <strong>%s</strong> delegate rights over role <strong>%s</strong>?' % (name_role_admin, name_role_delegate),
id_role_admin=id_role_admin,
id_role_delegate=id_role_delegate,
confirm=1)
if int(confirm):
subtitle = 'step 4 - confirm delegation right added'
# res1 = acca.acc_addRoleActionArguments_names(name_role=name_role_admin,
# name_action=DELEGATEADDUSERROLE,
# arglistid=-1,
# optional=0,
# role=name_role_delegate)
res1 = acca.acc_addAuthorization(name_role=name_role_admin,
name_action=DELEGATEADDUSERROLE,
optional=0,
role=name_role_delegate)
if res1:
output += '<p>confirm: role <strong>%s</strong> delegates role <strong>%s</strong>.' % (name_role_admin, name_role_delegate)
else: output += '<p>sorry, delegation right could not be added,<br>it probably already exists.</p>'
# see if right hand menu is available
try: body = [output, extra]
except NameError: body = [output]
return index(req=req,
title='Delegate Rights',
subtitle=subtitle,
body=body,
adminarea=1)
def perform_delegate_adduserrole(req, id_role=0, email_user_pattern='', id_user=0, confirm=0):
"""let a lower level web admin add users to a limited set of roles.
id_role - the role to connect to a user
id_user - the user to connect to a role
confirm - make the connection happen """
# finding the allowed roles for this user
id_admin = getUid(req)
id_action = acca.acc_getActionId(name_action=DELEGATEADDUSERROLE)
actions = acca.acc_findPossibleActionsUser(id_user=id_admin, id_action=id_action)
allowed_roles = []
allowed_id_roles = []
for (id, arglistid, name_role_help) in actions[1:]:
id_role_help = acca.acc_getRoleId(name_role=name_role_help)
if id_role_help and [id_role_help, name_role_help, ''] not in allowed_roles:
allowed_roles.append([id_role_help, name_role_help, ''])
allowed_id_roles.append(str(id_role_help))
output = ''
if not allowed_roles:
subtitle = 'no delegation rights'
output += """
<p>
You do not have the delegation rights over any roles.<br>
If you think you should have such rights, contact a WebAccess Administrator.
</p>"""
extra = ''
else:
subtitle = 'step 1 - select role'
output += """
<p>
Lower level delegation of access rights to roles.<br>
An administrator with all rights have to give you these rights.
</p>"""
email_out = acca.acc_getUserEmail(id_user=id_user)
name_role = acca.acc_getRoleName(id_role=id_role)
output += createroleselect(id_role=id_role, step=1, name='id_role',
action='delegate_adduserrole', roles=allowed_roles)
if str(id_role) != '0' and str(id_role) in allowed_id_roles:
subtitle = 'step 2 - search for users'
# remove letters not allowed in an email
email_user_pattern = cleanstring_email(email_user_pattern)
text = ' <span class="adminlabel">2. search for user </span>\n'
text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
output += createhiddenform(action="delegate_adduserrole",
text=text,
button="search for users",
id_role=id_role)
# pattern is entered
if email_user_pattern:
# users with matching email-address
users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email """ % (email_user_pattern, ))
# users that are connected
users2 = run_sql("""SELECT DISTINCT u.id, u.email
FROM user u LEFT JOIN user_accROLE ur ON u.id = ur.id_user
WHERE ur.id_accROLE = '%s' AND u.email RLIKE '%s'
ORDER BY u.email """ % (id_role, email_user_pattern))
# no users that match the pattern
if not (users1 or users2):
output += '<p>no qualified users, try new search.</p>'
# too many matching users
elif len(users1) > MAXSELECTUSERS:
output += '<p><strong>%s hits</strong>, too many qualified users, specify more narrow search. (limit %s)</p>' % (len(users1), MAXSELECTUSERS)
# show matching users
else:
subtitle = 'step 3 - select a user'
users = []
extrausers = []
for (id, email) in users1:
if (id, email) not in users2: users.append([id,email,''])
for (id, email) in users2:
extrausers.append([-id, email,''])
output += createuserselect(id_user=id_user,
action="delegate_adduserrole",
step=3,
users=users,
extrausers=extrausers,
button="add this user",
id_role=id_role,
email_user_pattern=email_user_pattern)
try: id_user = int(id_user)
except ValueError: pass
# user selected already connected to role
if id_user < 0:
output += '<p>users in brackets are already attached to the role, try another one...</p>'
# a user is selected
elif email_out:
subtitle = "step 4 - confirm to add user"
output += createhiddenform(action="delegate_adduserrole",
text='add user <strong>%s</strong> to role <strong>%s</strong>?' % (email_out, name_role),
id_role=id_role,
email_user_pattern=email_user_pattern,
id_user=id_user,
confirm=1)
# it is confirmed that this user should be added
if confirm:
# add user
result = acca.acc_addUserRole(id_user=id_user, id_role=id_role)
if result and result[2]:
subtitle = 'step 5 - confirm user added'
output += '<p>confirm: user <strong>%s</strong> added to role <strong>%s</strong>.</p>' % (email_out, name_role)
else:
subtitle = 'step 5 - user could not be added'
output += '<p>sorry, but user could not be added.</p>'
extra = """
<dl>
<dt><a href="delegate_deleteuserrole?id_role=%s">Remove users from role</a></dt>
<dd>remove users from the roles you have delegating rights to.</dd>
</dl>
""" % (id_role, )
return index(req=req,
title='Connect users to roles',
subtitle=subtitle,
body=[output, extra],
adminarea=1,
authorized=1)
def perform_delegate_deleteuserrole(req, id_role=0, id_user=0, confirm=0):
"""let a lower level web admin remove users from a limited set of roles.
id_role - the role to connect to a user
id_user - the user to connect to a role
confirm - make the connection happen """
subtitle = 'in progress...'
output = '<p>in progress...</p>'
# finding the allowed roles for this user
id_admin = getUid(req)
id_action = acca.acc_getActionId(name_action=DELEGATEADDUSERROLE)
actions = acca.acc_findPossibleActionsUser(id_user=id_admin, id_action=id_action)
output = ''
if not actions:
subtitle = 'no delegation rights'
output += """
<p>
You do not have the delegation rights over any roles.<br>
If you think you should have such rights, contact a WebAccess Administrator.
</p>"""
extra = ''
else:
subtitle = 'step 1 - select role'
output += """
<p>
Lower level delegation of access rights to roles.<br>
An administrator with all rights have to give you these rights.
</p>"""
email_out = acca.acc_getUserEmail(id_user=id_user)
name_role = acca.acc_getRoleName(id_role=id_role)
# create list of allowed roles
allowed_roles = []
allowed_id_roles = []
for (id, arglistid, name_role_help) in actions[1:]:
id_role_help = acca.acc_getRoleId(name_role=name_role_help)
if id_role_help and [id_role_help, name_role_help, ''] not in allowed_roles:
allowed_roles.append([id_role_help, name_role_help, ''])
allowed_id_roles.append(str(id_role_help))
output += createroleselect(id_role=id_role, step=1,
action='delegate_deleteuserrole', roles=allowed_roles)
if str(id_role) != '0' and str(id_role) in allowed_id_roles:
subtitle = 'step 2 - select user'
users = acca.acc_getRoleUsers(id_role)
output += createuserselect(id_user=id_user,
step=2,
action='delegate_deleteuserrole',
users=users,
id_role=id_role)
if str(id_user) != '0':
subtitle = 'step 3 - confirm delete of user'
email_user = acca.acc_getUserEmail(id_user=id_user)
output += createhiddenform(action="delegate_deleteuserrole",
text='delete user %s from %s?'
% (headerstrong(user=id_user), headerstrong(role=id_role)),
id_role=id_role,
id_user=id_user,
confirm=1)
if confirm:
res = acca.acc_deleteUserRole(id_user=id_user, id_role=id_role)
if res:
subtitle = 'step 4 - confirm user deleted from role'
output += '<p>confirm: deleted user <strong>%s</strong> from role <strong>%s</strong>.</p>' % (email_user, name_role)
else:
subtitle = 'step 4 - user could not be deleted'
output += 'sorry, but user could not be deleted<br>user is probably already deleted.'
extra = """
<dl>
<dt><a href="delegate_adduserrole?id_role=%s">Connect users to role</a></dt>
<dd>add users to the roles you have delegating rights to.</dd>
</dl>
""" % (id_role, )
return index(req=req,
title='Remove users from roles',
subtitle=subtitle,
body=[output, extra],
adminarea=1,
authorized=1)
def perform_addaction(req, name_action='', arguments='', optional='no', description='put description here.', confirm=0):
"""form to add a new action with these values:
name_action - name of the new action
arguments - allowedkeywords, separated by whitespace
description - optional description of the action"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
name_action = cleanstring(name_action)
arguments = cleanstring(arguments, comma=1)
title = 'Add Action'
subtitle = 'step 1 - give values to the requested fields'
output = """
<form action="addaction" method="POST">
<span class="adminlabel">action name </span>
<input class="admin_wvar" type="text" name="name_action" value="%s" /> <br>
<span class="adminlabel">arguments </span>
<input class="admin_wvar" type="text" name="arguments" value="%s" />
<small>keywords for arguments, separate with comma, no whitespace.</small> <br>
<span class="adminlabel">optional arguments</span>
<select name="optional" class="admin_w200">
<option value="no" selected="selected">no, not allowed</option>
<option value="yes" %s>yes, allowed</option>
</select><br>
<span class="adminlabel">description </span>
<textarea class="admin_wvar" rows="6" cols="30" name="description">%s</textarea>
<input class="adminbutton" type="submit" value="add action" />
</form>
""" % (name_action, arguments, optional == 'yes' and 'selected="selected"' or '', description)
if name_action:
# description must be changed before it is submitted
if description == 'put description here.': internaldesc = ''
else: internaldesc = description
if arguments:
subtitle = 'step 2 - confirm to add action with %s arguments' % (optional == 'yes' and 'optional' or '', )
arguments = arguments.replace(' ', '')
text = 'add action with: <br>\n'
text += 'name: <strong>%s</strong><br>\n' % (name_action, )
if internaldesc:
text += 'description: <strong>%s</strong><br>\n' % (description, )
text += '%sarguments: <strong>%s</strong><br>' % (optional == 'yes' and 'optional ' or '', arguments)
text += 'optional: <strong>%s</strong>?' % (optional, )
else:
optional = 'no'
subtitle = 'step 2 - confirm to add action without arguments'
text = 'add action <strong>%s</strong> without arguments' % (name_action, )
if internaldesc: text += '<br>\nand description: <strong>%s</strong>?\n' % (description, )
else: text += '?\n'
output += createhiddenform(action="addaction",
text=text,
name_action=name_action,
arguments=arguments,
optional=optional,
description=description,
confirm=1)
if confirm not in ["0", 0]:
arguments = arguments.split(',')
result = acca.acc_addAction(name_action,
internaldesc,
optional,
*arguments)
if result:
subtitle = 'step 3 - action added'
output += '<p>action added:</p>'
output += tupletotable(header=['id', 'action name', 'description', 'allowedkeywords', 'optional'],
tuple=[result])
else:
subtitle = 'step 3 - action could not be added'
output += '<p>sorry, could not add action, <br>action with the same name probably exists.</p>'
extra = """
<dl>
<dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add authorization</a></dt>
<dd>start adding new authorizations to action %s.</dd>
</dl> """ % (acca.acc_getActionId(name_action=name_action), name_action)
try: body = [output, extra]
except NameError: body = [output]
return index(req=req,
title=title,
body=body,
subtitle=subtitle,
adminarea=4)
def perform_deleteaction(req, id_action="0", confirm=0):
"""show all roles connected, and ask for confirmation.
id_action - id of action to delete """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
title='Delete action'
subtitle='step 1 - select action to delete'
name_action = acca.acc_getActionName(id_action=id_action)
output = createactionselect(id_action=id_action,
action="deleteaction",
step=1,
actions=acca.acc_getAllActions(),
button="delete action")
if id_action != "0" and name_action:
subtitle = 'step 2 - confirm the delete'
output += actiondetails(id_action=id_action)
if acca.acc_getActionRoles(id_action=id_action):
output += createhiddenform(action="deleteroleaction",
text="""rather delete only connection between action %s
and a selected role?""" % (name_action, ),
id_action=id_action,
reverse=1,
button='go there')
output += createhiddenform(action="deleteaction",
text=' delete action <strong>%s</strong> and all connections?' % (name_action, ),
confirm=1,
id_action=id_action)
if confirm:
subtitle = 'step 3 - confirm delete of action'
res = acca.acc_deleteAction(id_action=id_action)
if res:
output += '<p>confirm: action <strong>%s</strong> deleted.<br>\n' % (name_action, )
output += '%s entries deleted all in all.</p>\n' % (res, )
else:
output += '<p>sorry, action could not be deleted.</p>\n'
elif id_action != "0":
output += '<p>the action has been deleted...</p>'
return index(req=req,
title=title,
subtitle=subtitle,
body=[output],
adminarea=4)
def perform_showactiondetails(req, id_action):
"""show the details of an action. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
output = createactionselect(id_action=id_action,
action="showactiondetails",
step=1,
actions=acca.acc_getAllActions(),
button="select action")
if id_action not in [0, '0']:
output += actiondetails(id_action=id_action)
extra = """
<dl>
<dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add new authorization</a></dt>
<dd>add an authorization.</dd>
<dt><a href="modifyauthorizations?id_action=%s&amp;reverse=1">Modify authorizations</a></dt>
<dd>modify existing authorizations.</dd>
<dt><a href="deleteroleaction?id_action=%s&amp;reverse=1">Remove role</a></dt>
<dd>remove all authorizations from action and a role.</dd>
</dl>
""" % (id_action, id_action, id_action)
body = [output, extra]
else:
output += '<p>no details to show</p>'
body = [output]
return index(req=req,
title='Show Action Details',
subtitle='show action details',
body=body,
adminarea=4)
def actiondetails(id_action=0):
"""show details of given action. """
output = ''
if id_action not in [0, '0']:
name_action = acca.acc_getActionName(id_action=id_action)
output += '<p>action details:</p>'
output += tupletotable(header=['id', 'name', 'description', 'allowedkeywords', 'optional'],
tuple=[acca.acc_getActionDetails(id_action=id_action)])
roleshlp = acca.acc_getActionRoles(id_action=id_action)
if roleshlp:
roles = []
for (id, name, dontcare) in roleshlp:
roles.append([id, name,
'<a href="simpleauthorization?id_role=%s&amp;id_action=%s">show authorization details</a>'
% (id, id_action),
'<a href="showroleusers?id_role=%s">show connected users</a>' % (id, )])
roletable = tupletotable(header=['id', 'name', '', ''], tuple=roles)
output += '<p>roles connected to %s:</p>\n' % (headerstrong(action=name_action, query=0), )
output += roletable
else:
output += '<p>no roles connected to %s.</p>\n' % (headerstrong(action=name_action, query=0), )
else:
output += '<p>no details to show</p>'
return output
def perform_addrole(req, name_role='', description='put description here.', confirm=0):
"""form to add a new role with these values:
name_role - name of the new role
description - optional description of the role """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
name_role = cleanstring(name_role)
title='Add Role'
subtitle = 'step 1 - give values to the requested fields'
output = """
<form action="addrole" method="POST">
<span class="adminlabel">role name </span>
<input class="admin_wvar" type="text" name="name_role" value="%s" /> <br>
<span class="adminlabel">description </span>
<textarea class="admin_wvar" rows="6" cols="30" name="description">%s</textarea>
<input class="adminbutton" type="submit" value="add role" />
</form>
""" % (name_role, description)
if name_role:
# description must be changed before submitting
subtitle = 'step 2 - confirm to add role'
internaldesc = ''
if description != 'put description here.':
internaldesc = description
text = """
add role with: <br>\n
name: <strong>%s</strong> <br>""" % (name_role, )
if internaldesc:
text += 'description: <strong>%s</strong>?\n' % (description, )
output += createhiddenform(action="addrole",
text=text,
name_role=name_role,
description=description,
confirm=1)
if confirm not in ["0", 0]:
result = acca.acc_addRole(name_role=name_role,
description=internaldesc)
if result:
subtitle = 'step 3 - role added'
output += '<p>role added: </p>'
output += tupletotable(header=['id', 'action name', 'description', 'allowedkeywords'],
tuple=[result])
else:
subtitle = 'step 3 - role could not be added'
output += '<p>sorry, could not add role, <br>role with the same name probably exists.</p>'
id_role = acca.acc_getRoleId(name_role=name_role)
extra = """
<dl>
<dt><a href="addauthorization?id_role=%s">Add authorization</a></dt>
<dd>start adding new authorizations to role %s.</dd>
</dl>
<dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
<dd>connect a user to role %s.</dd>
<dl>
</dl>""" % (id_role, name_role, id_role, name_role)
try: body = [output, extra]
except NameError: body = [output]
return index(req=req,
title=title,
body=body,
subtitle=subtitle,
adminarea=3)
def perform_deleterole(req, id_role="0", confirm=0):
"""select a role and show all connected information,
users - users that can access the role.
actions - actions with possible authorizations."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
title = 'Delete role'
subtitle = 'step 1 - select role to delete'
name_role = acca.acc_getRoleName(id_role=id_role)
output = createroleselect(id_role=id_role,
action="deleterole",
step=1,
roles=acca.acc_getAllRoles(),
button="delete role")
if id_role != "0" and name_role:
subtitle = 'step 2 - confirm delete of role'
output += roledetails(id_role=id_role)
output += createhiddenform(action="deleterole",
text='delete role <strong>%s</strong> and all connections?' % (name_role, ),
id_role=id_role,
confirm=1)
if confirm:
res = acca.acc_deleteRole(id_role=id_role)
subtitle = 'step 3 - confirm role deleted'
if res:
output += "<p>confirm: role <strong>%s</strong> deleted.<br>" % (name_role, )
output += "<strong>%s</strong> entries were removed.</p>" % (res, )
else:
output += "<p>sorry, the role could not be deleted.</p>"
elif id_role != "0":
output += '<p>the role has been deleted...</p>'
return index(req=req,
title=title,
subtitle=subtitle,
body=[output],
adminarea=3)
def perform_showroledetails(req, id_role):
"""show the details of a role."""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
output = createroleselect(id_role=id_role,
action="showroledetails",
step=1,
roles=acca.acc_getAllRoles(),
button="select role")
if id_role not in [0, '0']:
name_role = acca.acc_getRoleName(id_role=id_role)
output += roledetails(id_role=id_role)
extra = """
<dl>
<dt><a href="addauthorization?id_role=%s">Add new authorization</a></dt>
<dd>add an authorization.</dd>
<dt><a href="modifyauthorizations?id_role=%s">Modify authorizations</a></dt>
<dd>modify existing authorizations.</dd>
</dl>
<dl>
<dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
<dd>connect a user to role %s.</dd>
<dt><a href="deleteuserrole?id_role=%s">Remove user</a></dt>
<dd>remove a user from role %s.</dd>
</dl>
""" % (id_role, id_role, id_role, name_role, id_role, name_role)
body = [output, extra]
else:
output += '<p>no details to show</p>'
body = [output]
return index(req=req,
title='Show Role Details',
subtitle='show role details',
body=body,
adminarea=3)
def roledetails(id_role=0):
"""create the string to show details about a role. """
name_role = acca.acc_getRoleName(id_role=id_role)
usershlp = acca.acc_getRoleUsers(id_role)
users = []
for (id, email, dontcare) in usershlp:
users.append([id, email, '<a href="showuserdetails?id_user=%s">show user details</a>' % (id, )])
usertable = tupletotable(header=['id', 'email'], tuple=users)
actionshlp = acca.acc_getRoleActions(id_role)
actions = []
for (id, name, dontcare) in actionshlp:
actions.append([id, name,
'<a href="showactiondetails?id_role=%s&amp;id_action=%s">show action details</a>' % (id_role, id),
'<a href="simpleauthorization?id_role=%s&amp;id_action=%s">show authorization details</a>' % (id_role, id)])
actiontable = tupletotable(header=['id', 'name', '', ''], tuple=actions)
# show role details
details = '<p>role details:</p>'
details += tupletotable(header=['id', 'name', 'description'],
tuple=[acca.acc_getRoleDetails(id_role=id_role)])
# show connected users
details += '<p>users connected to %s:</p>' % (headerstrong(role=name_role, query=0), )
if users:
details += usertable
else:
details += '<p>no users connected.</p>'
# show connected authorizations
details += '<p>authorizations for %s:</p>' % (headerstrong(role=name_role, query=0), )
if actions:
details += actiontable
else:
details += '<p>no authorizations connected</p>'
return details
def perform_adduserrole(req, id_role='0', email_user_pattern='', id_user='0', confirm=0):
"""create connection between user and role.
id_role - id of the role to add user to
email_user_pattern - search for users using this pattern
id_user - id of user to add to the role. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
email_out = acca.acc_getUserEmail(id_user=id_user)
name_role = acca.acc_getRoleName(id_role=id_role)
title = 'Connect user to role '
subtitle = 'step 1 - select a role'
output = createroleselect(id_role=id_role,
action="adduserrole",
step=1,
roles=acca.acc_getAllRoles())
# role is selected
if id_role != "0":
title += name_role
subtitle = 'step 2 - search for users'
# remove letters not allowed in an email
email_user_pattern = cleanstring_email(email_user_pattern)
text = ' <span class="adminlabel">2. search for user </span>\n'
text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
output += createhiddenform(action="adduserrole",
text=text,
button="search for users",
id_role=id_role)
# pattern is entered
if email_user_pattern:
# users with matching email-address
users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email """ % (email_user_pattern, ))
# users that are connected
users2 = run_sql("""SELECT DISTINCT u.id, u.email
FROM user u LEFT JOIN user_accROLE ur ON u.id = ur.id_user
WHERE ur.id_accROLE = '%s' AND u.email RLIKE '%s'
ORDER BY u.email """ % (id_role, email_user_pattern))
# no users that match the pattern
if not (users1 or users2):
output += '<p>no qualified users, try new search.</p>'
elif len(users1) > MAXSELECTUSERS:
output += '<p><strong>%s hits</strong>, too many qualified users, specify more narrow search. (limit %s)</p>' % (len(users1), MAXSELECTUSERS)
# show matching users
else:
subtitle = 'step 3 - select a user'
users = []
extrausers = []
for (id, email) in users1:
if (id, email) not in users2: users.append([id,email,''])
for (id, email) in users2:
extrausers.append([-id, email,''])
output += createuserselect(id_user=id_user,
action="adduserrole",
step=3,
users=users,
extrausers=extrausers,
button="add this user",
id_role=id_role,
email_user_pattern=email_user_pattern)
try: id_user = int(id_user)
except ValueError: pass
# user selected already connected to role
if id_user < 0:
output += '<p>users in brackets are already attached to the role, try another one...</p>'
# a user is selected
elif email_out:
subtitle = "step 4 - confirm to add user"
output += createhiddenform(action="adduserrole",
text='add user <strong>%s</strong> to role <strong>%s</strong>?' % (email_out, name_role),
id_role=id_role,
email_user_pattern=email_user_pattern,
id_user=id_user,
confirm=1)
# it is confirmed that this user should be added
if confirm:
# add user
result = acca.acc_addUserRole(id_user=id_user, id_role=id_role)
if result and result[2]:
subtitle = 'step 5 - confirm user added'
output += '<p>confirm: user <strong>%s</strong> added to role <strong>%s</strong>.</p>' % (email_out, name_role)
else:
subtitle = 'step 5 - user could not be added'
output += '<p>sorry, but user could not be added.</p>'
extra = """
<dl>
<dt><a href="addrole">Create new role</a></dt>
<dd>go here to add a new role.</dd>
</dl>
"""
if str(id_role) != "0":
extra += """
<dl>
<dt><a href="deleteuserrole?id_role=%s">Remove users</a></dt>
<dd>remove users from role %s.</dd>
<dt><a href="showroleusers?id_role=%s">Connected users</a></dt>
<dd>show all users connected to role %s.</dd>
</dl>
<dl>
<dt><a href="addauthorization?id_role=%s">Add authorization</a></dt>
<dd>start adding new authorizations to role %s.</dd>
</dl>
""" % (id_role, name_role, id_role, name_role, id_role, name_role)
return index(req=req,
title=title,
subtitle=subtitle,
body=[output, extra],
adminarea=3)
def perform_addroleuser(req, email_user_pattern='', id_user='0', id_role='0', confirm=0):
"""delete connection between role and user.
id_role - id of role to disconnect
id_user - id of user to disconnect. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
email_out = acca.acc_getUserEmail(id_user=id_user)
name_role = acca.acc_getRoleName(id_role=id_role)
# used to sort roles, and also to determine right side links
con_roles = []
not_roles = []
title = 'Connect user to roles'
subtitle = 'step 1 - search for users'
# clean email search string
email_user_pattern = cleanstring_email(email_user_pattern)
text = ' <span class="adminlabel">1. search for user </span>\n'
text += ' <input class="admin_wvar" type="text" name="email_user_pattern" value="%s" />\n' % (email_user_pattern, )
output = createhiddenform(action='addroleuser',
text=text,
button='search for users',
id_role=id_role)
if email_user_pattern:
subtitle = 'step 2 - select user'
users1 = run_sql("""SELECT id, email FROM user WHERE email RLIKE '%s' ORDER BY email """ % (email_user_pattern, ))
users = []
for (id, email) in users1: users.append([id, email, ''])
# no users
if not users:
output += '<p>no qualified users, try new search.</p>'
# too many users
elif len(users) > MAXSELECTUSERS:
output += '<p><strong>%s hits</strong>, too many qualified users, specify more narrow search. (limit %s)</p>' % (len(users), MAXSELECTUSERS)
# ok number of users
else:
output += createuserselect(id_user=id_user,
action='addroleuser',
step=2,
users=users,
button='select user',
email_user_pattern=email_user_pattern)
if int(id_user):
subtitle = 'step 3 - select role'
# roles the user is connected to
role_ids = acca.acc_getUserRoles(id_user=id_user)
# all the roles, lists are sorted on the background of these...
all_roles = acca.acc_getAllRoles()
# sort the roles in connected and not connected roles
for (id, name, description) in all_roles:
if (id, ) in role_ids: con_roles.append([-id, name, description])
else: not_roles.append([id, name, description])
# create roleselect
output += createroleselect(id_role=id_role,
action='addroleuser',
step=3,
roles=not_roles,
extraroles=con_roles,
extrastamp='(connected)',
button='add this role',
email_user_pattern=email_user_pattern,
id_user=id_user)
if int(id_role) < 0:
name_role = acca.acc_getRoleName(id_role=-int(id_role))
output += '<p>role %s already connected to the user, try another one...<p>' % (name_role, )
elif int(id_role):
subtitle = 'step 4 - confirm to add role to user'
output += createhiddenform(action='addroleuser',
text='add role <strong>%s</strong> to user <strong>%s</strong>?' % (name_role, email_out),
email_user_pattern=email_user_pattern,
id_user=id_user,
id_role=id_role,
confirm=1)
if confirm:
# add role
result = acca.acc_addUserRole(id_user=id_user, id_role=id_role)
if result and result[2]:
subtitle = 'step 5 - confirm role added'
output += '<p>confirm: role <strong>%s</strong> added to user <strong>%s</strong>.</p>' % (name_role, email_out)
else:
subtitle = 'step 5 - role could not be added'
output += '<p>sorry, but role could not be added</p>'
extra = """
<dl>
<dt><a href="addrole">Create new role</a></dt>
<dd>go here to add a new role.</dd>
"""
if int(id_user) and con_roles:
extra += """
</dl>
<dl>
<dt><a href="deleteuserrole?id_user=%s&amp;reverse=1">Remove roles</a></dt>
<dd>disconnect roles from user %s.</dd>
</dl>
""" % (id_user, email_out)
if int(id_role):
if int(id_role) < 0: id_role = -int(id_role)
extra += """
<dl>
<dt><a href="deleteuserrole?id_role=%s">Remove users</a></dt>
<dd>disconnect users from role %s.<dd>
</dl>
""" % (id_role, name_role)
return index(req=req,
title=title,
subtitle=subtitle,
body=[output, extra],
adminarea=5)
def perform_deleteuserrole(req, id_role='0', id_user='0', reverse=0, confirm=0):
"""delete connection between role and user.
id_role - id of role to disconnect
id_user - id of user to disconnect. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
title = 'Remove user from role'
email_user = acca.acc_getUserEmail(id_user=id_user)
name_role = acca.acc_getRoleName(id_role=id_role)
output = ''
if reverse in [0, '0']:
adminarea = 3
subtitle = 'step 1 - select the role'
output += createroleselect(id_role=id_role,
action="deleteuserrole",
step=1,
roles=acca.acc_getAllRoles())
if id_role != "0":
subtitle = 'step 2 - select the user'
output += createuserselect(id_user=id_user,
action="deleteuserrole",
step=2,
users=acca.acc_getRoleUsers(id_role=id_role),
id_role=id_role)
else:
adminarea = 5
# show only if user is connected to a role, get users connected to roles
users = run_sql("""SELECT DISTINCT(u.id), u.email, u.note
FROM user u LEFT JOIN user_accROLE ur
ON u.id = ur.id_user
WHERE ur.id_accROLE != 'NULL' AND u.email != ''
ORDER BY u.email """)
has_roles = 1
# check if the user is connected to any roles
for (id, email, note) in users:
if str(id) == str(id_user): break
# user not connected to a role
else:
subtitle = 'step 1 - user not connected'
output += '<p>no need to remove roles from user <strong>%s</strong>,<br>user is not connected to any roles.</p>' % (email_user, )
has_roles, id_user = 0, '0' # stop the rest of the output below...
# user connected to roles
if has_roles:
output += createuserselect(id_user=id_user,
action="deleteuserrole",
step=1,
users=users,
reverse=reverse)
if id_user != "0":
subtitle = 'step 2 - select the role'
role_ids = acca.acc_getUserRoles(id_user=id_user)
all_roles = acca.acc_getAllRoles()
roles = []
for (id, name, desc) in all_roles:
if (id, ) in role_ids: roles.append([id, name, desc])
output += createroleselect(id_role=id_role,
action="deleteuserrole",
step=2,
roles=roles,
id_user=id_user,
reverse=reverse)
if id_role != '0' and id_user != '0':
subtitle = 'step 3 - confirm delete of user'
output += createhiddenform(action="deleteuserrole",
text='delete user %s from %s?' % (headerstrong(user=id_user), headerstrong(role=id_role)),
id_role=id_role,
id_user=id_user,
reverse=reverse,
confirm=1)
if confirm:
res = acca.acc_deleteUserRole(id_user=id_user, id_role=id_role)
if res:
subtitle = 'step 4 - confirm delete of user'
output += '<p>confirm: deleted user <strong>%s</strong> from role <strong>%s</strong>.</p>' % (email_user, name_role)
else:
subtitle = 'step 4 - user could not be deleted'
output += 'sorry, but user could not be deleted<br>user is probably already deleted.'
extra = ''
if str(id_role) != "0":
extra += """
<dl>
<dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
<dd>add users to role %s.</dd>
""" % (id_role, name_role)
if int(reverse):
extra += """
<dt><a href="deleteuserrole?id_role=%s">Remove user</a></dt>
<dd>remove users from role %s.</dd> """ % (id_role, name_role)
extra += '</dl>'
if str(id_user) != "0":
extra += """
<dl>
<dt><a href="addroleuser?email_user_pattern=%s&amp;id_user=%s">Connect role</a></dt>
<dd>add roles to user %s.</dd>
""" % (email_user, id_user, email_user)
if not int(reverse):
extra += """
<dt><a href="deleteuserrole?id_user=%s&amp;email_user_pattern=%s&amp;reverse=1">Remove role</a></dt>
<dd>remove roles from user %s.</dd> """ % (id_user, email_user, email_user)
extra += '</dl>'
if extra: body = [output, extra]
else: body = [output]
return index(req=req,
title=title,
subtitle=subtitle,
body=body,
adminarea=adminarea)
def perform_showuserdetails(req, id_user=0):
"""show the details of a user. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
if id_user not in [0, '0']:
output = userdetails(id_user=id_user)
email_user = acca.acc_getUserEmail(id_user=id_user)
extra = """
<dl>
<dt><a href="addroleuser?id_user=%s&amp;email_user_pattern=%s">Connect role</a></dt>
<dd>connect a role to user %s.</dd>
<dt><a href="deleteuserrole?id_user=%s&amp;reverse=1">Remove role</a></dt>
<dd>remove a role from user %s.</dd>
</dl>
""" % (id_user, email_user, email_user, id_user, email_user)
body = [output, extra]
else:
body = ['<p>no details to show</p>']
return index(req=req,
title='Show User Details',
subtitle='show user details',
body=body,
adminarea=5)
def userdetails(id_user=0):
"""create the string to show details about a user. """
# find necessary details
email_user = acca.acc_getUserEmail(id_user=id_user)
userroles = acca.acc_getUserRoles(id_user=id_user)
conn_roles = []
# find connected roles
for (id, name, desc) in acca.acc_getAllRoles():
if (id, ) in userroles:
conn_roles.append([id, name, desc])
conn_roles[-1].append('<a href="showroledetails?id_role=%s">show details</a>' % (id, ))
if conn_roles:
# print details
details = '<p>roles connected to user <strong>%s</strong></p>' % (email_user, )
details += tupletotable(header=['id', 'name', 'description', ''], tuple=conn_roles)
else:
details = '<p>no roles connected to user <strong>%s</strong>.</p>' % (email_user, )
return details
def perform_addauthorization(req, id_role="0", id_action="0", optional=0, reverse="0", confirm=0, **keywords):
""" form to add new connection between user and role:
id_role - role to connect
id_action - action to connect
reverse - role or action first? """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
# values that might get used
name_role = acca.acc_getRoleName(id_role=id_role) or id_role
name_action = acca.acc_getActionName(id_action=id_action) or id_action
optional = optional == 'on' and 1 or int(optional)
extra = """
<dl>
<dt><a href="addrole">Create new role</a></dt>
<dd>go here to add a new role.</dd>
<dt><a href="addaction">Create new action</a></dt>
<dd>go here to add a new action.</dd>
</dl>
"""
# create the page according to which step the user is on
# role -> action -> arguments
if reverse in ["0", 0]:
adminarea = 3
subtitle = 'step 1 - select role'
output = createroleselect(id_role=id_role,
action="addauthorization",
step=1,
roles=acca.acc_getAllRoles(),
reverse=reverse)
if str(id_role) != "0":
subtitle = 'step 2 - select action'
rolacts = acca.acc_getRoleActions(id_role)
allhelp = acca.acc_getAllActions()
allacts = []
for r in allhelp:
if r not in rolacts: allacts.append(r)
output += createactionselect(id_action=id_action,
action="addauthorization",
step=2,
actions=rolacts,
extraactions=allacts,
id_role=id_role,
reverse=reverse)
# action -> role -> arguments
else:
adminarea = 4
subtitle = 'step 1 - select action'
output = createactionselect(id_action=id_action,
action="addauthorization",
step=1,
actions=acca.acc_getAllActions(),
reverse=reverse)
if str(id_action) != "0":
subtitle = 'step 2 - select role'
actroles = acca.acc_getActionRoles(id_action)
allhelp = acca.acc_getAllRoles()
allroles = []
for r in allhelp:
if r not in actroles: allroles.append(r)
output += createroleselect(id_role=id_role,
action="addauthorization",
step=2,
roles=actroles,
extraroles=allroles,
id_action=id_action,
reverse=reverse)
# ready for step 3 no matter which direction we took to get here
if id_action != "0" and id_role != "0":
# links to adding authorizations in the other direction
if str(reverse) == "0":
extra += """
<dl>
<dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add authorization</a></dt>
<dd>add authorizations to action %s.</dd>
</dl> """ % (id_action, name_action)
else:
extra += """
<dl>
<dt><a href="addauthorization?id_role=%s">Add authorization</a></dt>
<dd>add authorizations to role %s.</dd>
</dl> """ % (id_role, name_role)
subtitle = 'step 3 - enter values for the keywords\n'
output += """
<form action="addauthorization" method="POST">
<input type="hidden" name="id_role" value="%s">
<input type="hidden" name="id_action" value="%s">
<input type="hidden" name="reverse" value="%s">
""" % (id_role, id_action, reverse)
# the actions argument keywords
res_keys = acca.acc_getActionKeywords(id_action=id_action)
# res used to display existing authorizations
# res used to determine if showing "create connection without arguments"
res_auths = acca.acc_findPossibleActions(id_role, id_action)
if not res_keys:
# action without arguments
if not res_auths:
output += """
<input type="hidden" name="confirm" value="1">
create connection between %s?
<input class="adminbutton" type="submit" value="confirm">
</form>
""" % (headerstrong(role=name_role, action=name_action, query=0), )
else:
output += '<p><strong>connection without arguments is already created.</strong></p>'
else:
# action with arguments
optionalargs = acca.acc_getActionIsOptional(id_action=id_action)
output += '<span class="adminlabel">3. authorized arguments</span><br>'
if optionalargs:
# optional arguments
output += """
<p>
<input type="radio" name="optional" value="1" %s />
connect %s to %s for any arguments <br>
<input type="radio" name="optional" value="0" %s />
connect %s to %s for only these argument cases:
</p>
""" % (optional and 'checked="checked"' or '', name_role, name_action, not optional and 'checked="checked"' or '', name_role, name_action)
# list the arguments
allkeys = 1
for key in res_keys:
output += '<span class="adminlabel" style="margin-left: 30px;">%s </span>\n <input class="admin_wvar" type="text" name="%s"' % (key, key)
try:
val = keywords[key] = cleanstring_argumentvalue(keywords[key])
if val: output += 'value="%s" ' % (val, )
else: allkeys = 0
except KeyError: allkeys = 0
output += ' /> <br>\n'
output = output[:-5] + ' <input class="adminbutton" type="submit" value="create authorization -->" />\n'
output += '</form>\n'
# ask for confirmation
if str(allkeys) != "0" or optional:
keys = keywords.keys()
keys.reverse()
subtitle = 'step 4 - confirm add of authorization\n'
text = """
create connection between <br>
%s <br>
""" % (headerstrong(role=name_role, action=name_action, query=0), )
if optional:
text += 'withouth arguments'
keywords = {}
else:
for key in keys:
text += '<strong>%s</strong>: %s \n' % (key, keywords[key])
output += createhiddenform(action="addauthorization",
text=text,
id_role=id_role,
id_action=id_action,
reverse=reverse,
confirm=1,
optional=optional,
**keywords)
# show existing authorizations, found authorizations further up in the code...
# res_auths = acca.acc_findPossibleActions(id_role, id_action)
output += '<p>existing authorizations:</p>'
if res_auths:
output += tupletotable(header=res_auths[0], tuple=res_auths[1:])
# shortcut to modifying authorizations
extra += """
<dl>
<dt><a href="modifyauthorizations?id_role=%s&amp;id_action=%s&amp;reverse=%s">Modify authorizations</a></dt>
<dd>modify the existing authorizations.</dd>
</dl> """ % (id_role, id_action, reverse)
else: output += '<p>no details to show</p>'
# user confirmed to add entries
if confirm:
subtitle = 'step 5 - confirm authorization added'
res1 = acca.acc_addAuthorization(name_role=name_role,
name_action=name_action,
optional=optional,
**keywords)
if res1:
res2 = acca.acc_findPossibleActions(id_role, id_action)
arg = res1[0][3] # the arglistid
new = [res2[0]]
for row in res2[1:]:
if int(row[0]) == int(arg): new.append(row)
newauths = tupletotable(header=new[0], tuple=new[1:])
newentries = tupletotable(header=['role id', 'action id', 'argument id', '#'], tuple=res1)
st = 'style="vertical-align: top"'
output += """
<p>new authorization and entries:</p>
<table><tr>
<td class="admintd" %s>%s</td>
<td class="admintd" %s>%s</td>
</tr></table> """ % (st, newauths, st, newentries)
else: output += '<p>sorry, authorization could not be added,<br>it probably already exists</p>'
# trying to put extra link on the right side
try: body = [output, extra]
except NameError: body = [output]
return index(req=req,
title = 'Create entry for new authorization',
subtitle=subtitle,
body=body,
adminarea=adminarea)
def perform_deleteroleaction(req, id_role="0", id_action="0", reverse=0, confirm=0):
"""delete all connections between a role and an action.
id_role - id of the role
id_action - id of the action
reverse - 0: ask for role first
1: ask for action first"""
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
title = 'Remove action from role '
if reverse in ["0", 0]:
# select role -> action
adminarea = 3
subtitle = 'step 1 - select a role'
output = createroleselect(id_role=id_role,
action="deleteroleaction",
step=1,
roles=acca.acc_getAllRoles(),
reverse=reverse)
if id_role != "0":
rolacts = acca.acc_getRoleActions(id_role=id_role)
subtitle = 'step 2 - select the action'
output += createactionselect(id_action=id_action,
action="deleteroleaction",
step=2,
actions=rolacts,
reverse=reverse,
id_role=id_role,
button="remove connection and all authorizations")
else:
# select action -> role
adminarea = 4
subtitle = 'step 1 - select an action'
output = createactionselect(id_action=id_action,
action="deleteroleaction",
step=1,
actions=acca.acc_getAllActions(),
reverse=reverse)
if id_action != "0":
actroles = acca.acc_getActionRoles(id_action=id_action)
subtitle = 'step 2 - select the role'
output += createroleselect(id_role=id_role,
action="deleteroleaction",
step=2,
roles=actroles,
button="remove connection and all authorizations",
id_action=id_action,
reverse=reverse)
if id_action != "0" and id_role != "0":
subtitle = 'step 3 - confirm to remove authorizations'
# ask for confirmation
res = acca.acc_findPossibleActions(id_role, id_action)
if res:
output += '<p>authorizations that will be deleted:</p>'
output += tupletotable(header=res[0], tuple=res[1:])
output += createhiddenform(action="deleteroleaction",
text='remove %s from %s' % (headerstrong(action=id_action), headerstrong(role=id_role)),
confirm=1,
id_role=id_role,
id_action=id_action,
reverse=reverse)
else:
output += 'no authorizations'
# confirmation is given
if confirm:
subtitle = 'step 4 - confirm authorizations removed '
res = acca.acc_deleteRoleAction(id_role=id_role, id_action=id_action)
if res:
output += '<p>confirm: removed %s from %s<br>' % (headerstrong(action=id_action), headerstrong(role=id_role))
output += '<strong>%s</strong> entries were removed.</p>' % (res, )
else:
output += '<p>sorry, no entries could be removed.</p>'
return index(req=req,
title=title,
subtitle=subtitle,
body=[output],
adminarea=adminarea)
def perform_modifyauthorizations(req, id_role="0", id_action="0", reverse=0, confirm=0, errortext='', sel='', authids=[]):
"""given ids of a role and an action, show all possible action combinations
with checkboxes and allow user to access other functions.
id_role - id of the role
id_action - id of the action
reverse - 0: ask for role first
1: ask for action first
sel - which button and modification that is selected
errortext - text to print when no connection exist between role and action
authids - ids of checked checkboxes """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
name_role = acca.acc_getRoleName(id_role)
name_action = acca.acc_getActionName(id_action)
output = ''
try: id_role, id_action, reverse = int(id_role), int(id_action), int(reverse)
except ValueError: pass
extra = """
<dl>
<dt><a href="addrole">Create new role</a></dt>
<dd>go here to add a new role.</dd>
<dt><a href="addaction">Create new action</a></dt>
<dd>go here to add a new action.</dd>
</dl>
"""
if id_role or id_action:
extra += '\n<dl>\n'
if id_role and id_action:
extra += """
<dt><a href="addauthorization?id_role=%s&amp;id_action=%s&amp;reverse=%s">Add authorizations</a></dt>
<dd>add an authorization to the existing ones.</dd> """ % (id_role, id_action, reverse)
if id_role:
extra += """
<dt><a href="addauthorization?id_role=%s">Add authorizations</a></dt>
<dd>add to role %s.</dd> """ % (id_role, name_role)
if id_action:
extra += """
<dt><a href="addauthorization?id_action=%s&amp;reverse=1">Add authorizations</a></dt>
<dd>add to action %s.</dd> """ % (id_action, name_action)
extra += '\n</dl>\n'
if not reverse:
# role -> action
adminarea = 3
subtitle = 'step 1 - select the role'
output += createroleselect(id_role=str(id_role),
action="modifyauthorizations",
step=1,
roles=acca.acc_getAllRoles(),
reverse=reverse)
if id_role:
rolacts = acca.acc_getRoleActions(id_role=id_role)
subtitle = 'step 2 - select the action'
output += createactionselect(id_action=str(id_action),
action="modifyauthorizations",
step=2,
actions=rolacts,
id_role=id_role,
reverse=reverse)
else:
adminarea = 4
# action -> role
subtitle = 'step 1 - select the action'
output += createactionselect(id_action=str(id_action),
action="modifyauthorizations",
step=1,
actions=acca.acc_getAllActions(),
reverse=reverse)
if id_action:
actroles = acca.acc_getActionRoles(id_action=id_action)
subtitle = 'step 2 - select the role'
output += createroleselect(id_role=str(id_role),
action="modifyauthorizations",
step=2,
roles=actroles,
id_action=id_action,
reverse=reverse)
if errortext: output += '<p>%s</p>' % (errortext, )
if id_role and id_action:
# adding to main area
if type(authids) is not list: authids = [authids]
subtitle = 'step 3 - select groups and modification'
# get info
res = acca.acc_findPossibleActions(id_role, id_action)
# clean the authids
hiddenids = []
if sel in ['delete selected']:
hiddenids = authids[:]
elif sel in ['split groups', 'merge groups']:
for authid in authids:
arghlp = res[int(authid)][0]
if authid not in hiddenids and arghlp not in [-1, '-1', 0, '0']: hiddenids.append(authid)
authids = hiddenids[:]
if confirm:
# do selected modification and output with new authorizations
if sel == 'split groups':
res = splitgroups(id_role, id_action, authids)
elif sel == 'merge groups':
res = mergegroups(id_role, id_action, authids)
elif sel == 'delete selected':
res = deleteselected(id_role, id_action, authids)
authids = []
res = acca.acc_findPossibleActions(id_role, id_action)
output += 'authorizations after <strong>%s</strong>.<br>\n' % (sel, )
elif sel and authids:
output += 'confirm choice of authorizations and modification.<br>\n'
else:
output += 'select authorizations and perform modification.<br>\n'
if not res:
errortext='all connections deleted, try different '
if reverse in ["0", 0]:
return perform_modifyauthorizations(req=req, id_role=id_role, errortext=errortext + 'action.')
else:
return perform_modifyauthorizations(req=req, id_action=id_action, reverse=reverse, errortext=errortext + 'role.')
# display
output += modifyauthorizationsmenu(id_role, id_action, header=res[0], tuple=res[1:], checked=authids, reverse=reverse)
if sel and authids:
subtitle = 'step 4 - confirm to perform modification'
# form with hidden authids
output += '<form action="%s" method="POST">\n' % ('modifyauthorizations', )
for hiddenid in hiddenids:
output += '<input type="hidden" name="authids" value="%s" />\n' % (hiddenid, )
# choose what to do
if sel == 'split groups':
output += '<p>split groups containing:</p>'
elif sel == 'merge groups':
output += '<p>merge groups containing:</p>'
elif sel == 'delete selected':
output += '<p>delete selected entries:</p>'
extracolumn = '<input type="checkbox" name="confirm" value="1" />\n'
extracolumn += '<input class="adminbutton" type="submit" value="confirm" />\n'
# show the entries here...
output += tupletotable_onlyselected(header=res[0],
tuple=res[1:],
selected=hiddenids,
extracolumn=extracolumn)
output += '<input type="hidden" name="id_role" value="%s" />\n' % (id_role, )
output += '<input type="hidden" name="id_action" value="%s" />\n' % (id_action, )
output += '<input type="hidden" name="sel" value="%s" />\n' % (sel, )
output += '<input type="hidden" name="reverse" value="%s" />\n' % (reverse, )
output += '</form>'
# tried to perform modification without something selected
elif sel and not authids and not confirm:
output += '<p>no valid groups selected</p>'
# trying to put extra link on the right side
try: body = [output, extra]
except NameError: body = [output]
# Display the page
return index(req=req,
title='Modify Authorizations',
subtitle=subtitle,
body=body,
adminarea=adminarea)
def modifyauthorizationsmenu(id_role, id_action, tuple=[], header=[], checked=[], reverse=0):
"""create table with header and checkboxes, used for multiple choice.
makes use of tupletotable to add the actual table
id_role - selected role, hidden value in the form
id_action - selected action, hidden value in the form
tuple - all rows to be put in the table (with checkboxes)
header - column headers, empty strings added at start and end
checked - ids of rows to be checked """
if not tuple:
return 'no authorisations...'
argnum = len(acca.acc_getActionKeywords(id_action=id_action))
tuple2 = []
for t in tuple: tuple2.append(t[:])
tuple2 = addcheckboxes(datalist=tuple2, name='authids', startindex=1, checked=checked)
hidden = '<input type="hidden" name="id_role" value="%s" /> \n' % (id_role, )
hidden += '<input type="hidden" name="id_action" value="%s" /> \n' % (id_action, )
hidden += '<input type="hidden" name="reverse" value="%s" /> \n' % (reverse, )
button = '<input type="submit" class="adminbutton" value="delete selected" name="sel" />\n'
if argnum > 1:
button += '<input type="submit" class="adminbutton" value="split groups" name="sel" />\n'
button += '<input type="submit" class="adminbutton" value="merge groups" name="sel" />\n'
hdrstr = ''
for h in [''] + header + ['']: hdrstr += ' <th class="adminheader">%s</th>\n' % (h, )
if hdrstr: hdrstr = ' <tr>\n%s\n </tr>\n' % (hdrstr, )
output = '<form action="modifyauthorizations" method="POST">\n'
output += '<table class="admin_wvar_nomargin"> \n'
output += hdrstr
output += '<tr><td>%s</td></tr>\n' % (hidden, )
align = ['admintdleft'] * len(tuple2[0])
try: align[1] = 'admintdright'
except IndexError: pass
output += '<tr>'
for i in range(len(tuple2[0])): output += '<td class="%s">%s</td>\n' % (align[i], tuple2[0][i])
output += '<td rowspan="%s" style="vertical-align: bottom">\n%s\n</td>\n' % (len(tuple2), button)
output += '</tr>\n'
for row in tuple2[1:]:
output += ' <tr>\n'
for i in range(len(row)): output += '<td class="%s">%s</td>\n' % (align[i], row[i])
output += ' </tr>\n'
output += '</table>\n</form>\n'
return output
def splitgroups(id_role=0, id_action=0, authids=[]):
"""get all the old ones, gather up the arglistids find a list of
arglistidgroups to be split, unique get all actions in groups outside
of the old ones, (old arglistid is allowed).
show them like in showselect. """
if not id_role or not id_action or not authids:
return 0
# find all the actions
datalist = acca.acc_findPossibleActions(id_role, id_action)
if type(authids) is str: authids = [authids]
for i in range(len(authids)): authids[i] = int(authids[i])
# argumentlistids of groups to be split
splitgrps = []
for authid in authids:
hlp = datalist[authid][0]
if hlp not in splitgrps and authid in range(1,len(datalist)):
splitgrps.append(hlp)
# split groups and return success or failure
result = 1
for splitgroup in splitgrps:
result = 1 and acca.acc_splitArgumentGroup(id_role, id_action, splitgroup)
return result
def mergegroups(id_role=0, id_action=0, authids=[]):
"""get all the old ones, gather up the argauthids find a list
of arglistidgroups to be split, unique get all actions in groups
outside of the old ones, (old arglistid is allowed).
show them like in showselect."""
if not id_role or not id_action or not authids:
return 0
datalist = acca.acc_findPossibleActions(id_role, id_action)
if type(authids) is str: authids = [authids]
for i in range(len(authids)): authids[i] = int(authids[i])
# argumentlistids of groups to be merged
mergegroups = []
for authid in authids:
hlp = datalist[authid][0]
if hlp not in mergegroups and authid in range(1, len(datalist)):
mergegroups.append(hlp)
# merge groups and return success or failure
if acca.acc_mergeArgumentGroups(id_role, id_action, mergegroups):
return 1
else:
return 0
def deleteselected(id_role=0, id_action=0, authids=[]):
"""delete checked authorizations/possible actions, ids in authids.
id_role - role to delete from
id_action - action to delete from
authids - listids for which possible actions to delete."""
if not id_role or not id_action or not authids:
return 0
if type(authids) in [str, int]: authids = [authids]
for i in range(len(authids)): authids[i] = int(authids[i])
result = acca.acc_deletePossibleActions(id_role=id_role,
id_action=id_action,
authids=authids)
return result
def headeritalic(**ids):
"""transform keyword=value pairs to string with value in italics.
**ids - a dictionary of pairs to create string from """
output = ''
value = ''
table = ''
for key in ids.keys():
if key in ['User', 'user']:
value, table = 'email', 'user'
elif key in ['Role', 'role']:
value, table = 'name', 'accROLE'
elif key in ['Action', 'action']:
value, table = 'name', 'accACTION'
else:
if output: output += ' and '
output += ' %s <i>%s</i>' % (key, ids[key])
continue
res = run_sql("""SELECT %s FROM %s WHERE id = %s""" % (value, table, ids[key]))
if res:
if output: output += ' and '
output += ' %s <i>%s</i>' % (key, res[0][0])
return output
def headerstrong(query=1, **ids):
"""transform keyword=value pairs to string with value in strong text.
**ids - a dictionary of pairs to create string from
query - 1 -> try to find names to ids of role, user and action.
0 -> do not try to find names, use the value passed on """
output = ''
value = ''
table = ''
for key in ids.keys():
if key in ['User', 'user']:
value, table = 'email', 'user'
elif key in ['Role', 'role']:
value, table = 'name', 'accROLE'
elif key in ['Action', 'action']:
value, table = 'name', 'accACTION'
else:
if output: output += ' and '
output += ' %s <strong>%s</strong>' % (key, ids[key])
continue
if query:
res = run_sql("""SELECT %s FROM %s WHERE id = %s""" % (value, table, ids[key]))
if res:
if output: output += ' and '
output += ' %s <strong>%s</strong>' % (key, res[0][0])
else:
if output: output += ' and '
output += ' %s <strong>%s</strong>' % (key, ids[key])
return output
def startpage():
"""create the menu for the startpage"""
body = """
<table class="admin_wvar" width="100%" summary="">
<thead>
<tr>
<th class="adminheaderleft">selection for WebAccess Admin</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<dl>
<dt><a href="webaccessadmin.py/rolearea">Role Area</a>
<dd>main area to configure administration rights and authorization rules.
<dt><a href="webaccessadmin.py/actionarea">Action Area</a>
<dd>configure administration rights with the actions as starting point.
<dt><a href="webaccessadmin.py/userarea">User Area</a>
<dd>configure administration rights with the users as starting point.
<dt><a href="webaccessadmin.py/resetarea">Reset Area</a>
<dd>reset roles, actions and authorizations.
</dl>
</td>
</tr>
</tbody>
</table>"""
return body
def rankarea():
return "Rankmethod area"
def perform_simpleauthorization(req, id_role=0, id_action=0):
"""show a page with simple overview of authorizations between a
connected role and action. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
res = acca.acc_findPossibleActions(id_role, id_action)
if res:
extra = createhiddenform(action='modifyauthorizations',
button='modify authorizations',
id_role=id_role,
id_action=id_action)
output = '<p>authorizations for %s:</p>' % (headerstrong(action=id_action, role=id_role), )
output += tupletotable(header=res[0], tuple=res[1:], extracolumn=extra)
else:
output = 'no details to show'
return index(req=req,
title='Simple authorization details',
subtitle='simple authorization details',
body=[output],
adminarea=3)
def perform_showroleusers(req, id_role=0):
"""show a page with simple overview of a role and connected users. """
(auth_code, auth_message) = is_adminuser(req)
if auth_code != 0: return mustloginpage(req, auth_message)
res = acca.acc_getRoleUsers(id_role=id_role)
name_role = acca.acc_getRoleName(id_role=id_role)
if res:
users = []
for (id, name, dontcare) in res: users.append([id, name, '<a href="showuserdetails?id_user=%s">show user details</a>'
% (id, )])
output = '<p>users connected to %s:</p>' % (headerstrong(role=id_role), )
output += tupletotable(header=['id', 'name', ''], tuple=users)
else:
output = 'no users connected to role <strong>%s</strong>' % (name_role, )
extra = """
<dl>
<dt><a href="adduserrole?id_role=%s">Connect user</a></dt>
<dd>connect users to the role.</dd>
</dl>
""" % (id_role, )
return index(req=req,
title='Users connected to role %s' % (name_role, ),
subtitle='simple details',
body=[output, extra],
adminarea=3)
def createselect(id_input="0", label="", step=0, name="",
action="", list=[], extralist=[], extrastamp='',
button="", **hidden):
"""create form with select and hidden values
id - the one to choose as selected if exists
label - label shown to the left of the select
name - the name of the select on which to reference it
list - primary list to select from
extralist - list of options to be put in paranthesis
extrastamp - stamp extralist entries with this if not ''
usually paranthesis around the entry
button - the value/text to be put on the button
**hidden - name=value pairs to be put as hidden in the form. """
step = step and '%s. ' % step or ''
output = '<form action="%s" method="POST">\n' % (action, )
output += ' <span class="adminlabel">%s</span>\n' % (step + label, )
output += ' <select name="%s" class="admin_w200">\n' % (name, )
if not list and not extralist:
output += ' <option value="0">*** no %ss to select from ***</option>\n' % (label.split()[-1], )
else:
output += ' <option value="0">*** %s ***</option>\n' % (label, )
for (id, email, dontcare) in list:
if str(id) == id_input: output += ' <option value="%s" selected="selected">%s</option>\n' % (id, email)
else: output += ' <option value="%s">%s</option>\n' % (id, email)
for (id, email, dontcare) in extralist:
if str(id) == id_input:
if not extrastamp: output += ' <option value="%s" selected="selected">(%s)</option>\n' % (id, email)
else: output += ' <option value="%s">%s %s</option>\n' % (id, email, extrastamp)
elif not extrastamp: output += ' <option value="%s">(%s)</option>\n' % (id, email)
else: output += ' <option value="%s">%s %s</option>\n' % (id, email, extrastamp)
output += ' </select>\n'
for key in hidden.keys():
output += ' <input type="hidden" name="%s" value="%s" />\n' % (key, hidden[key])
output += ' <input class="adminbutton" type="submit" value="%s" />\n' % (button, )
output += '</form>\n'
return output
def createactionselect(id_action="0", label="select action", step=0, name="id_action",
action="", actions=[], extraactions=[], extrastamp='',
button="select action", **hidden):
"""create a select for roles in a form. see createselect."""
return createselect(id_input=id_action, label=label, step=step, name=name,
action=action, list=actions, extralist=extraactions, extrastamp=extrastamp,
button=button, **hidden)
def createroleselect(id_role="0", label="select role", step=0, name="id_role",
action="", roles=[], extraroles=[], extrastamp='',
button="select role", **hidden):
"""create a select for roles in a form. see createselect."""
return createselect(id_input=id_role, label=label, step=step, name=name,
action=action, list=roles, extralist=extraroles, extrastamp=extrastamp,
button=button, **hidden)
def createuserselect(id_user="0", label="select user", step=0, name="id_user",
action="", users=[], extrausers=[], extrastamp='(connected)',
button="select user", **hidden):
"""create a select for users in a form.see createselect."""
return createselect(id_input=id_user, label=label, step=step, name=name,
action=action, list=users, extralist=extrausers, extrastamp=extrastamp,
button=button, **hidden)
def cleanstring(str='', comma=0):
"""clean all the strings before submitting to access control admin.
remove characters not letter, number or underscore, also remove leading
underscores and numbers. return cleaned string.
str - string to be cleaned
comma - 1 -> allow the comma to divide multiple arguments
0 -> wash commas as well """
# remove not allowed characters
str = re.sub(r'[^a-zA-Z0-9_,]', '', str)
# split string on commas
items = str.split(',')
str = ''
for item in items:
if not item: continue
if comma and str: str += ','
# create valid variable names
str += re.sub(r'^([0-9_])*', '', item)
return str
def cleanstring_argumentvalue(str=''):
"""clean the value of an argument before submitting it.
allowed characters: a-z A-Z 0-9 _ and space
str - string to be cleaned """
# remove not allowed characters
str = re.sub(r'[^a-zA-Z0-9_ .]', '', str)
# trim leading and ending spaces
str = re.sub(r'^ *| *$', '', str)
return str
def cleanstring_email(str=''):
"""clean the string and return a valid email address.
str - string to be cleaned """
# remove not allowed characters
str = re.sub(r'[^a-zA-Z0-9_.@-]', '', str)
return str
def check_email(str=''):
"""control that submitted emails are correct.
this little check is not very good, but better than nothing. """
r = re.compile(r'(.)+\@(.)+\.(.)+')
return r.match(str) and 1 or 0
def sendAccountActivatedMessage(AccountEmail, sendTo, password, ln=cdslang):
"""Send an email to the address given by sendTo about the new activated account."""
fromaddr = "From: %s" % supportemail
toaddrs = "To: %s" % sendTo
to = toaddrs + "\n"
sub = "Subject: Your account on '%s' has been activated\n\n" % cdsname
body = "Your account earlier created on '%s' has been activated:\n\n" % cdsname
body += " Username/Email: %s\n" % AccountEmail
body += " Password: %s\n" % ("*" * len(password))
body += "\n---------------------------------"
body += "\n%s" % cdsname
body += "\nContact: %s" % supportemail
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
return 0
server.quit()
return 1
def sendNewUserAccountWarning(newAccountEmail, sendTo, password, ln=cdslang):
"""Send an email to the address given by sendTo about the new account newAccountEmail."""
fromaddr = "From: %s" % supportemail
toaddrs = "To: %s" % sendTo
to = toaddrs + "\n"
sub = "Subject: Account created on '%s'\n\n" % cdsname
body = "An account has been created for you on '%s':\n\n" % cdsname
body += " Username/Email: %s\n" % newAccountEmail
body += " Password: %s\n" % ("*" * len(password))
body += "\n---------------------------------"
body += "\n%s" % cdsname
body += "\nContact: %s" % supportemail
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
return 0
server.quit()
return 1
def sendAccountRejectedMessage(newAccountEmail, sendTo, ln=cdslang):
"""Send an email to the address given by sendTo about the new account newAccountEmail."""
fromaddr = "From: %s" % supportemail
toaddrs = "To: %s" % sendTo
to = toaddrs + "\n"
sub = "Subject: Account rejected on '%s'\n\n" % cdsname
body = "Your request for an account has been rejected on '%s':\n\n" % cdsname
body += " Username/Email: %s\n" % newAccountEmail
body += "\n---------------------------------"
body += "\n%s" % cdsname
body += "\nContact: %s" % supportemail
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
return 0
server.quit()
return 1
def sendAccountDeletedMessage(newAccountEmail, sendTo, ln=cdslang):
"""Send an email to the address given by sendTo about the new account newAccountEmail."""
fromaddr = "From: %s" % supportemail
toaddrs = "To: %s" % sendTo
to = toaddrs + "\n"
sub = "Subject: Account deleted on '%s'\n\n" % cdsname
body = "Your account on '%s' has been deleted:\n\n" % cdsname
body += " Username/Email: %s\n" % newAccountEmail
body += "\n---------------------------------"
body += "\n%s" % cdsname
body += "\nContact: %s" % supportemail
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
return 0
server.quit()
return 1
diff --git a/modules/webaccess/web/Makefile.am b/modules/webaccess/web/Makefile.am
index b1171321a..52c701cf6 100644
--- a/modules/webaccess/web/Makefile.am
+++ b/modules/webaccess/web/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
\ No newline at end of file
diff --git a/modules/webaccess/web/admin/Makefile.am b/modules/webaccess/web/admin/Makefile.am
index d36ce190f..eaade85ad 100644
--- a/modules/webaccess/web/admin/Makefile.am
+++ b/modules/webaccess/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/webaccess
webapp_DATA = webaccessadmin.py
EXTRA_DIST = webaccessadmin.py
CLEANFILES = *~ *.tmp
diff --git a/modules/webaccess/web/admin/webaccessadmin.py b/modules/webaccess/web/admin/webaccessadmin.py
index e9f51463d..8f53c11c1 100644
--- a/modules/webaccess/web/admin/webaccessadmin.py
+++ b/modules/webaccess/web/admin/webaccessadmin.py
@@ -1,344 +1,344 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware WebAccess Administrator Interface."""
__lastupdated__ = """$Date$"""
import sys
import cdsware.webaccessadmin_lib as wal
# reload(wal)
# from cdsware.webaccessadmin_lib import index
__version__ = "$Id$"
index = wal.index
def rolearea(req):
"""create the role area menu page."""
return wal.perform_rolearea(req=req)
def actionarea(req):
"""create the role area menu page."""
return wal.perform_actionarea(req=req)
def userarea(req, email_user_pattern=''):
"""create the user area menu page. """
return wal.perform_userarea(req=req,
email_user_pattern=email_user_pattern)
def resetarea(req):
"""create the role area menu page."""
return wal.perform_resetarea(req=req)
def resetdefaultsettings(req, superusers=[], confirm=0):
"""create the reset default settings page. """
return wal.perform_resetdefaultsettings(req=req,
superusers=superusers,
confirm=confirm)
def adddefaultsettings(req, superusers=[], confirm=0):
"""create the add default settings page. """
return wal.perform_adddefaultsettings(req=req,
superusers=superusers,
confirm=confirm)
def manageaccounts(req, mtype='', content='', confirm=0):
"""enable, disable and edit accounts"""
return wal.perform_manageaccounts(req=req, mtype=mtype, content=content, confirm=confirm)
def modifyaccountstatus(req, userID, email_user_pattern='', limit_to=-1, maxpage=25, page=1, callback='yes', confirm=0):
"""enable or disable account"""
return wal.perform_modifyaccountstatus(req=req, userID=userID, email_user_pattern=email_user_pattern, limit_to=limit_to, maxpage=maxpage, page=page, callback=callback, confirm=confirm)
def modifypreferences(req, userID, login_method='', callback='yes', confirm=0):
"""modify the preferences of an account"""
return wal.perform_modifypreferences(req=req, userID=userID, login_method=login_method, callback=callback, confirm=confirm)
def modifylogindata(req, userID, email='', password='', callback='yes', confirm=0):
"""modify the email/password of an account"""
return wal.perform_modifylogindata(req=req, userID=userID, email=email, password=password, callback=callback, confirm=confirm)
def rejectaccount(req, userID, email_user_pattern='', limit_to=-1, maxpage=25, page=1, callback='yes', confirm=0):
"""Set account inactive, delete it and send email to the owner."""
return wal.perform_rejectaccount(req=req, userID=userID, email_user_pattern=email_user_pattern, limit_to=limit_to, maxpage=maxpage, page=page, callback=callback, confirm=confirm)
def deleteaccount(req, userID, callback='yes', confirm=0):
"""delete account"""
return wal.perform_deleteaccount(req=req, userID=userID, callback=callback, confirm=confirm)
def createaccount(req, email='', password='', callback='yes', confirm=0):
"""create account"""
return wal.perform_createaccount(req=req, email=email, password=password, callback=callback, confirm=confirm)
def editaccount(req, userID, mtype='', content='', callback='yes', confirm=0):
"""edit account. """
return wal.perform_editaccount(req=req, userID=userID, mtype=mtype, content=content, callback=callback, confirm=confirm)
def modifyaccounts(req, email_user_pattern='', limit_to=-1, maxpage=25, page=1, callback='yes', confirm=0):
"""Modify accounts. """
return wal.perform_modifyaccounts(req=req, email_user_pattern=email_user_pattern, limit_to=limit_to, maxpage=maxpage, page=page, callback=callback,confirm=confirm)
def delegate_startarea(req):
"""add info here"""
return wal.perform_delegate_startarea(req=req)
def delegate_adminsetup(req, id_role_admin=0, id_role_delegate=0, confirm=0):
"""add info here"""
return wal.perform_delegate_adminsetup(req=req,
id_role_admin=id_role_admin,
id_role_delegate=id_role_delegate,
confirm=confirm)
def delegate_adduserrole(req, id_role=0, email_user_pattern='', id_user=0, confirm=0):
"""add info here"""
return wal.perform_delegate_adduserrole(req=req,
id_role=id_role,
email_user_pattern=email_user_pattern,
id_user=id_user,
confirm=confirm)
def delegate_deleteuserrole(req, id_role=0, id_user=0, confirm=0):
"""add info here"""
return wal.perform_delegate_deleteuserrole(req=req,
id_role=id_role,
id_user=id_user,
confirm=confirm)
def addaction(req, name_action='', arguments='', optional='no', description='put description here.', confirm=0):
"""form to add a new action with these values:
name_action - name of the new action
arguments - allowedkeywords, separated by whitespace
description - optional description of the action"""
return wal.perform_addaction(req=req,
name_action=name_action,
arguments=arguments,
optional=optional,
description=description,
confirm=confirm)
def deleteaction(req, id_action="0", confirm=0):
"""show all roles connected, and ask for confirmation."""
return wal.perform_deleteaction(req=req,
id_action=id_action,
confirm=confirm)
def addrole(req, name_role='', description='put description here.', confirm=0):
"""form to add a new role with these values:
name_role - name of the new role
description - optional description of the role """
return wal.perform_addrole(req=req,
name_role=name_role,
description=description,
confirm=confirm)
def deleterole(req, id_role="0", confirm=0):
"""select a role and show all connected information,
users - users that can access the role.
actions - actions with possible authorizations."""
return wal.perform_deleterole(req=req,
id_role=id_role,
confirm=confirm)
def showroledetails(req, id_role='0'):
"""show the details of a role."""
return wal.perform_showroledetails(req=req,
id_role=id_role)
def showactiondetails(req, id_action="0"):
"""show the details of an action. """
return wal.perform_showactiondetails(req=req,
id_action=id_action)
def showuserdetails(req, id_user="0"):
"""show the details of an action. """
return wal.perform_showuserdetails(req=req,
id_user=id_user)
def adduserrole(req, id_role='0', email_user_pattern='', id_user='0', confirm=0):
"""create connection between user and role.
id_role - id of the role to add user to
email_user_pattern - search for users using this pattern
id_user - id of user to add to the role. """
return wal.perform_adduserrole(req=req,
id_role=id_role,
email_user_pattern=email_user_pattern,
id_user=id_user,
confirm=confirm)
def addroleuser(req, email_user_pattern='', id_user='0', id_role='0', confirm=0):
"""create connection between user and role.
email_user_pattern - search for users using this pattern
id_user - id of user to add to the role.
id_role - id of the role to add user to. """
return wal.perform_addroleuser(req=req,
email_user_pattern=email_user_pattern,
id_user=id_user,
id_role=id_role,
confirm=confirm)
def deleteuserrole(req, id_role='0', id_user='0', reverse=0, confirm=0):
"""delete connection between role and user.
id_role - id of role to disconnect
id_user - id of user to disconnect. """
return wal.perform_deleteuserrole(req=req,
id_role=id_role,
id_user=id_user,
reverse=reverse,
confirm=confirm)
def addauthorization(req, id_role="0", id_action="0", reverse="0", confirm=0, **keywords):
""" form to add new connection between user and role:
id_role - role to connect
id_action - action to connect
reverse - role or action first? """
return wal.perform_addauthorization(req=req,
id_role=id_role,
id_action=id_action,
reverse=reverse,
confirm=confirm,
**keywords)
def deleteroleaction(req, id_role="0", id_action="0", reverse=0, confirm=0):
"""delete all connections between a role and an action.
id_role - id of the role
id_action - id of the action
reverse - 0: ask for role first
1: ask for action first"""
return wal.perform_deleteroleaction(req=req,
id_role=id_role,
id_action=id_action,
reverse=reverse,
confirm=confirm)
def modifyauthorizations(req, id_role="0", id_action="0", reverse=0, confirm=0, sel='', errortext='', authids=[]):
"""given ids of a role and an action, show all possible action combinations
with checkboxes and allow user to access other functions.
id_role - id of the role
id_action - id of the action
reverse - 0: ask for role first
1: ask for action first
sel - which button and modification that is selected
errortext - text to print when no connection exist between role and action
authids - ids of checked checkboxes """
return wal.perform_modifyauthorizations(req=req,
id_role=id_role,
id_action=id_action,
reverse=reverse,
confirm=confirm,
sel=sel,
authids=authids)
def simpleauthorization(req, id_role=0, id_action=0):
"""show a page with simple overview of authorizations between a
connected role and action. """
return wal.perform_simpleauthorization(req=req,
id_role=id_role,
id_action=id_action)
def showroleusers(req, id_role=0):
"""show a page with simple overview of a role and connected users. """
return wal.perform_showroleusers(req=req,
id_role=id_role)
diff --git a/modules/webalert/Makefile.am b/modules/webalert/Makefile.am
index f182b89da..dd77afe9d 100644
--- a/modules/webalert/Makefile.am
+++ b/modules/webalert/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc lib web
CLEANFILES = *~
diff --git a/modules/webalert/bin/Makefile.am b/modules/webalert/bin/Makefile.am
index c5bc11263..0fcb3535d 100644
--- a/modules/webalert/bin/Makefile.am
+++ b/modules/webalert/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = alertengine
EXTRA_DIST = alertengine.in
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webalert/bin/alertengine.in b/modules/webalert/bin/alertengine.in
index b4bef0229..5f9d569a6 100644
--- a/modules/webalert/bin/alertengine.in
+++ b/modules/webalert/bin/alertengine.in
@@ -1,82 +1,82 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Alert engine command line interface"""
__version__ = "$Id$"
try:
import sys
import getopt
from cdsware.config import version, supportemail
from cdsware.alert_engine import run_alerts
from time import time
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
import datetime
def usage():
print """Usage: alertengine [OPTION]
Run the alert engine.
-h, --help display this help and exit
-V, --version output version information and exit
-d --date="YEAR-MONTH-DAY" run the alertengine as if we were the
specified day, for test purposes (today)
Report bugs to <%s>""" % supportemail
def main():
date = datetime.date.today()
try:
opts, args = getopt.getopt(sys.argv[1:], "hVd:",
["help", "version", "date="])
except getopt.GetoptError:
usage()
sys.exit(2)
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit()
if o in ("-V", "--version"):
print __version__
sys.exit(0)
if o in ("-d", "--date"):
year, month, day = map(int, a.split('-'))
date = datetime.date(year, month, day)
run_alerts(date)
if __name__ == "__main__":
t0 = time()
main()
t1 = time()
print 'Alert engine finished in %.2f seconds' % (t1 - t0)
diff --git a/modules/webalert/doc/Makefile.am b/modules/webalert/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/webalert/doc/Makefile.am
+++ b/modules/webalert/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/webalert/doc/admin/Makefile.am b/modules/webalert/doc/admin/Makefile.am
index ae19c002d..fdf83cfee 100644
--- a/modules/webalert/doc/admin/Makefile.am
+++ b/modules/webalert/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webalert
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webalert/doc/admin/guide.html.wml b/modules/webalert/doc/admin/guide.html.wml
index 6c28d8ce9..70d908701 100644
--- a/modules/webalert/doc/admin/guide.html.wml
+++ b/modules/webalert/doc/admin/guide.html.wml
@@ -1,79 +1,79 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAlert Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/webalert/>WebAlert Admin</a>" \
navbar_name="admin" \
navbar_select="webalert-admin-guide"
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
WARNING: THIS ADMIN GUIDE IS NOT FULLY COMPLETED
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
This Admin Guide is not yet completed. Moreover, some
admin-level functionality for this module exists only in the form of
manual recipes. We are in the process of developing both the
guide as well as the web admin interface. If you are interested
in seeing some specific things implemented with high priority,
please contact us at <SUPPORTEMAIL>. Thanks for your interest!
</td>
</tr>
</tbody>
</table>
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Overview</h2>
<p><CDSNAME> users may set up an automatic notification email alerts
that would send them documents corresponding to the user profile by
email either daily, weekly, or monthly. It is the job of the WebAlert
module to permit this functionality.
<h2>Configuring Alert Queries</h2>
<p>Users may set up alert queries for example from their <a
href="<WEBURL>/youralerts.py/display">search history</a> pages.
<p>Administrators may edit existing users' alerts by modifying the
<code>user_query_basket</code> table. (There is no web interface yet
for this task.)
<h2>Running Alert Engine</h2>
<p>The alert engine has to be run each day in order to send users
email notifications for the alerts they have set up:
<blockquote>
<pre>
$ alertengine
</pre>
</blockquote>
<strong>HINT:</strong> You may want to set up an external cron job
to call <code>alertengine</code> each day.
diff --git a/modules/webalert/doc/admin/index.html.wml b/modules/webalert/doc/admin/index.html.wml
index d25828b6d..73851ada6 100644
--- a/modules/webalert/doc/admin/index.html.wml
+++ b/modules/webalert/doc/admin/index.html.wml
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebAlert Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="webalert"
<p>
This is the gate to the admin area for WebAlert. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/webalert/">login</a> to enter.
</p>
<dl>
<dt><a href="guide.html">WebAlert Admin Guide</a></dt>
<dd>Everything you want to know about WebAlert administration</dd>
</dl>
diff --git a/modules/webalert/lib/Makefile.am b/modules/webalert/lib/Makefile.am
index ddb097658..38a7db1f4 100644
--- a/modules/webalert/lib/Makefile.am
+++ b/modules/webalert/lib/Makefile.am
@@ -1,27 +1,27 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = webalert.py alert_engine.py htmlparser.py textwrap.py \
webalert_templates.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webalert/lib/alert_engine.py b/modules/webalert/lib/alert_engine.py
index 08df7d37f..65b2f0372 100644
--- a/modules/webalert/lib/alert_engine.py
+++ b/modules/webalert/lib/alert_engine.py
@@ -1,408 +1,408 @@
## $Id$
## Alert engine implementation.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Alert engine implementation."""
## rest of the Python code goes below
__version__ = "$Id$"
from cgi import parse_qs
from sre import search, sub
from time import localtime, strftime, mktime, sleep
from string import split
import smtplib
import datetime
from email.Header import Header
from email.Message import Message
from email.MIMEText import MIMEText
from cdsware.config import *
from cdsware.search_engine import perform_request_search
from cdsware.dbquery import run_sql
from cdsware.htmlparser import *
import cdsware.template
webalert_templates = cdsware.template.load('webalert')
DEVELOPERADDR = [supportemail]
# Debug levels:
# 0 = production, nothing on the console, email sent
# 1 = messages on the console, email sent
# 2 = messages on the console, but no email sent
# 3 = many messages on the console, no email sent
# 4 = many messages on the console, email sent to DEVELOPERADDR
DEBUGLEVEL = 0
def update_date_lastrun(alert):
return run_sql('update user_query_basket set date_lastrun=%s where id_user=%s and id_query=%s and id_basket=%s;', (strftime("%Y-%m-%d"), alert[0], alert[1], alert[2],))
def get_alert_queries(frequency):
return run_sql('select distinct id, urlargs from query q, user_query_basket uqb where q.id=uqb.id_query and uqb.frequency=%s and uqb.date_lastrun <= now();', (frequency,))
def get_alert_queries_for_user(uid):
return run_sql('select distinct id, urlargs, uqb.frequency from query q, user_query_basket uqb where q.id=uqb.id_query and uqb.id_user=%s and uqb.date_lastrun <= now();', (uid,))
def get_alerts(query, frequency):
r = run_sql('select id_user, id_query, id_basket, frequency, date_lastrun, alert_name, notification from user_query_basket where id_query=%s and frequency=%s;', (query['id_query'], frequency,))
return {'alerts': r, 'records': query['records'], 'argstr': query['argstr'], 'date_from': query['date_from'], 'date_until': query['date_until']}
# def add_record_to_basket(record_id, basket_id):
# if DEBUGLEVEL > 0:
# print "-> adding record %s into basket %s" % (record_id, basket_id)
# try:
# return run_sql('insert into basket_record (id_basket, id_record) values(%s, %s);', (basket_id, record_id,))
# except:
# return 0
# def add_records_to_basket(record_ids, basket_id):
# # TBD: generate the list and all all records in one step (see below)
# for i in record_ids:
# add_record_to_basket(i, basket_id)
# Optimized version:
def add_records_to_basket(record_ids, basket_id):
nrec = len(record_ids)
if nrec > 0:
vals = '(%s,%s)' % (basket_id, record_ids[0])
if nrec > 1:
for i in record_ids[1:]:
vals += ',(%s, %s)' % (basket_id, i)
if DEBUGLEVEL > 0:
print "-> adding %s records into basket %s: %s" % (nrec, basket_id, vals)
try:
if DEBUGLEVEL < 4:
return run_sql('insert into basket_record (id_basket, id_record) values %s;' % vals) # Cannot use the run_sql(<query>, (<arg>,)) form for some reason
else:
print ' NOT ADDED, DEBUG LEVEL == 4'
return 0
except:
return 0
else:
return 0
def get_email(uid):
r = run_sql('select email from user where id=%s', (uid,))
return r[0][0]
def get_query(alert_id):
r = run_sql('select urlargs from query where id=%s', (alert_id,))
return r[0][0]
def send_email(fromaddr, toaddr, body, attempt=0):
if attempt > 2:
log('error sending email to %s: SMTP error; gave up after 3 attempts' % toaddr)
return
try:
server = smtplib.SMTP('localhost')
if DEBUGLEVEL > 2:
server.set_debuglevel(1)
else:
server.set_debuglevel(0)
server.sendmail(fromaddr, toaddr, body)
server.quit()
except:
if (DEBUGLEVEL > 1):
print 'Error connecting to SMTP server, attempt %s retrying in 5 minutes. Exception raised: %s' % (attempt, sys.exc_info()[0])
sleep(300)
send_email(fromaddr, toaddr, body, attempt+1)
return
def forge_email(fromaddr, toaddr, subject, content):
msg = MIMEText(content, _charset='utf-8')
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = Header(subject, 'utf-8')
return msg.as_string()
def email_notify(alert, records, argstr):
if len(records) == 0:
return
msg = ""
if DEBUGLEVEL > 0:
msg = "*** THIS MESSAGE WAS SENT IN DEBUG MODE ***\n\n"
url = weburl + "/search.py?" + argstr
# Extract the pattern and catalogue list from the formatted query
query = parse_qs(argstr)
pattern = query.get('p', [''])[0]
catalogues = query.get('c', [])
frequency = alert[3]
msg += webalert_templates.tmpl_alert_email_body(
alert[5], url, records, pattern, catalogues, frequency)
email = get_email(alert[0])
msg = MIMEText(msg, _charset='utf-8')
msg['To'] = email
# Let the template fill in missing fields
webalert_templates.tmpl_alert_email_headers(alert[5], msg)
sender = msg['From']
body = msg.as_string()
if DEBUGLEVEL > 0:
print "********************************************************************************"
print body
print "********************************************************************************"
if DEBUGLEVEL < 2:
send_email(sender, email, body)
if DEBUGLEVEL == 4:
for a in DEVELOPERADDR:
send_email(sender, a, body)
def get_argument(args, argname):
if args.has_key(argname):
return args[argname]
else:
return []
def _date_to_tuple(date):
return [str(part) for part in (date.year, date.month, date.day)]
def get_record_ids(argstr, date_from, date_until):
args = parse_qs(argstr)
p = get_argument(args, 'p')
c = get_argument(args, 'c')
cc = get_argument(args, 'cc')
as = get_argument(args, 'as')
f = get_argument(args, 'f')
rg = get_argument(args, 'rg')
so = get_argument(args, 'so')
sp = get_argument(args, 'sp')
ot = get_argument(args, 'ot')
as = get_argument(args, 'as')
p1 = get_argument(args, 'p1')
f1 = get_argument(args, 'f1')
m1 = get_argument(args, 'm1')
op1 = get_argument(args, 'op1')
p2 = get_argument(args, 'p2')
f2 = get_argument(args, 'f2')
m2 = get_argument(args, 'm2')
op2 = get_argument(args, 'op2')
p3 = get_argument(args, 'p3')
f3 = get_argument(args, 'f3')
m3 = get_argument(args, 'm3')
sc = get_argument(args, 'sc')
# search = get_argument(args, 'search')
d1y, d1m, d1d = _date_to_tuple(date_from)
d2y, d2m, d2d = _date_to_tuple(date_until)
return perform_request_search(of='id', p=p, c=c, cc=cc, f=f, so=so, sp=sp, ot=ot,
as=as, p1=p1, f1=f1, m1=m1, op1=op1, p2=p2, f2=f2,
m2=m2, op2=op2, p3=p3, f3=f3, m3=m3, sc=sc, d1y=d1y,
d1m=d1m, d1d=d1d, d2y=d2y, d2m=d2m, d2d=d2d)
def get_argument_as_string(argstr, argname):
args = parse_qs(argstr)
a = get_argument(args, argname)
r = ''
if len(a):
r = a[0]
for i in a[1:len(a)]:
r += ", %s" % i
return r
def get_pattern(argstr):
return get_argument_as_string(argstr, 'p')
def get_catalogue(argstr):
return get_argument_as_string(argstr, 'c')
def get_catalogue_num(argstr):
args = parse_qs(argstr)
a = get_argument(args, 'c')
return len(a)
def run_query(query, frequency, date_until):
"""Return a dictionary containing the information of the performed query.
The information contains the id of the query, the arguments as a
string, and the list of found records."""
if frequency == 'day':
date_from = date_until - datetime.timedelta(days=1)
elif frequency == 'week':
date_from = date_until - datetime.timedelta(weeks=1)
else:
# Months are not an explicit notion of timedelta (it's the
# most ambiguous too). So we explicitely take the same day of
# the previous month.
d, m, y = (date_until.day, date_until.month, date_until.year)
m = m - 1
if m == 0:
m = 12
y = y - 1
date_from = datetime.date(year=y, month=m, day=d)
recs = get_record_ids(query[1], date_from, date_until)
n = len(recs)
if n:
log('query %08s produced %08s records' % (query[0], len(recs)))
if DEBUGLEVEL > 2:
print "[%s] run query: %s with dates: from=%s, until=%s\n found rec ids: %s" % (
strftime("%c"), query, date_from, date_until, recs)
return {'id_query': query[0], 'argstr': query[1],
'records': recs, 'date_from': date_from, 'date_until': date_until}
def process_alert_queries(frequency, date):
"""Run the alerts according to the frequency.
Retrieves the queries for which an alert exists, performs it, and
processes the corresponding alerts."""
alert_queries = get_alert_queries(frequency)
for aq in alert_queries:
q = run_query(aq, frequency, date)
alerts = get_alerts(q, frequency)
process_alerts(alerts)
def replace_argument(argstr, argname, argval):
"""Replace the given date argument value with the new one.
If the argument is missing, it is added."""
if search('%s=\d+' % argname, argstr):
r = sub('%s=\d+' % argname, '%s=%s' % (argname, argval), argstr)
else:
r = argstr + '&%s=%s' % (argname, argval)
return r
def update_arguments(argstr, date_from, date_until):
"""Replace date arguments in argstr with the ones specified by date_from and date_until.
Absent arguments are added."""
d1y, d1m, d1d = _date_to_tuple(date_from)
d2y, d2m, d2d = _date_to_tuple(date_until)
r = replace_argument(argstr, 'd1y', d1y)
r = replace_argument(r, 'd1m', d1m)
r = replace_argument(r, 'd1d', d1d)
r = replace_argument(r, 'd2y', d2y)
r = replace_argument(r, 'd2m', d2m)
r = replace_argument(r, 'd2d', d2d)
return r
def log(msg):
try:
log = open(logdir + '/alertengine.log', 'a')
log.write(strftime('%Y%m%d%H%M%S#'))
log.write(msg + '\n')
log.close()
except:
pass
def process_alerts(alerts):
# TBD: do not generate the email each time, forge it once and then
# send it to all appropriate people
for a in alerts['alerts']:
if alert_use_basket_p(a):
add_records_to_basket(alerts['records'], a[2])
if alert_use_notification_p(a):
argstr = update_arguments(alerts['argstr'], alerts['date_from'], alerts['date_until'])
email_notify(a, alerts['records'], argstr)
update_date_lastrun(a)
def alert_use_basket_p(alert):
return alert[2] != 0
def alert_use_notification_p(alert):
return alert[6] == 'y'
def run_alerts(date):
"""Run the alerts.
First decide which alerts to run according to the current local
time, and runs them."""
if date.day == 1:
process_alert_queries('month', date)
if date.isoweekday() == 1: # first day of the week
process_alert_queries('week', date)
process_alert_queries('day', date)
def process_alert_queries_for_user(uid, date):
"""Process the alerts for the given user id.
All alerts are with reference date set as the current local time."""
alert_queries = get_alert_queries_for_user(uid)
print alert_queries
for aq in alert_queries:
frequency = aq[2]
q = run_query(aq, frequency, date)
alerts = get_alerts(q, frequency)
process_alerts(alerts)
if __name__ == '__main__':
process_alert_queries_for_user(2571422) # erik
process_alert_queries_for_user(109) # tibor
# process_alert_queries_for_user(11040) # jean-yves
diff --git a/modules/webalert/lib/htmlparser.py b/modules/webalert/lib/htmlparser.py
index 03440a5d2..8d10b8ba1 100644
--- a/modules/webalert/lib/htmlparser.py
+++ b/modules/webalert/lib/htmlparser.py
@@ -1,122 +1,122 @@
## $Id$
## HTML parser for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""HTML parser for records."""
## rest of the Python code goes below
__version__ = "$Id$"
from HTMLParser import HTMLParser
from string import split
from cdsware.config import *
from cdsware.search_engine import print_record
from cdsware import textwrap
WRAPWIDTH = 72
def wrap(text):
lines = textwrap.wrap(text, WRAPWIDTH)
r = ''
for l in lines:
r += l + '\n'
return r
def wrap_records(text):
lines = split(text, '\n')
result = ''
for l in lines:
newlines = textwrap.wrap(l, WRAPWIDTH)
for ll in newlines:
result += ll + '\n'
return result
class RecordHTMLParser(HTMLParser):
"""A parser for the HTML returned by cdsware.search_engine.print_record.
The parser provides methods to transform the HTML returned by
cdsware.search_engine.print_record into plain text, with some
minor formatting.
"""
def __init__(self):
HTMLParser.__init__(self)
self.result = ''
def handle_starttag(self, tag, attrs):
if tag == 'strong':
# self.result += '*'
pass
elif tag == 'a':
self.printURL = 0
self.unclosedBracket = 0
for f in attrs:
if f[1] == 'note':
self.result += 'Fulltext : <'
self.unclosedBracket = 1
if f[1] == 'moreinfo':
self.result += 'Detailed record : '
self.printURL = 1
if (self.printURL == 1) and (f[0] == 'href'):
self.result += '<' + f[1] + '>'
elif tag == 'br':
self.result += '\n'
def handle_endtag(self, tag):
if tag == 'strong':
# self.result += '\n'
pass
elif tag == 'a':
if self.unclosedBracket == 1:
self.result += '>'
self.unclosedBracket = 0
def handle_data(self, data):
if data == 'Detailed record':
pass
else:
self.result += data
def handle_comment(self, data):
pass
def get_as_text(record_id):
"""Return the plain text from RecordHTMLParser of the record."""
rec = print_record(record_id)
htparser = RecordHTMLParser()
try:
htparser.feed(rec)
return htparser.result
except:
#htparser.close()
return wrap(htparser.result + 'Detailed record: <http://cdsweb.cern.ch/search.py?recid=%s>.' % record_id)
if __name__ == "__main__":
rec = print_record(619028)
print rec
print "***"
print get_as_text(619028)
diff --git a/modules/webalert/lib/webalert.py b/modules/webalert/lib/webalert.py
index 73adac991..a19bf7352 100644
--- a/modules/webalert/lib/webalert.py
+++ b/modules/webalert/lib/webalert.py
@@ -1,373 +1,373 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""PERSONAL FEATURES - YOUR ALERTS"""
import cgi
import time
from cdsware.config import weburl, cdslang
from cdsware.dbquery import run_sql
from cdsware.webuser import isGuestUser
from cdsware.webaccount import warning_guest_user
from cdsware.webbasket import create_personal_baskets_selection_box
from cdsware.messages import gettext_set_language
from cdsware.dateutils import convert_datestruct_to_datetext, convert_datetext_to_dategui
import cdsware.template
webalert_templates = cdsware.template.load('webalert')
### IMPLEMENTATION
class AlertError(Exception):
pass
def check_alert_name(alert_name, uid, ln=cdslang):
"""check this user does not have another alert with this name."""
sql = """select id_query
from user_query_basket
where id_user=%s and alert_name='%s'"""%(uid, alert_name.strip())
res = run_sql( sql )
# load the right message language
_ = gettext_set_language(ln)
if len( run_sql( sql ) ) > 0:
raise AlertError( _("You already have an alert which name is <b>%(name)s</b>") % {'name' : alert_name} )
def get_textual_query_info_from_urlargs(urlargs, ln=cdslang):
"""Return nicely formatted search pattern and catalogue from urlargs of the search query.
Suitable for 'your searches' display."""
out = ""
args = cgi.parse_qs(urlargs)
return webalert_templates.tmpl_textual_query_info_from_urlargs(
ln = ln,
args = args,
)
return out
def perform_display(permanent, uid, ln=cdslang):
"""display the searches performed by the current user
input: default permanent="n"; permanent="y" display permanent queries(most popular)
output: list of searches in formatted html
"""
# load the right message language
_ = gettext_set_language(ln)
# first detect number of queries:
nb_queries_total = 0
nb_queries_distinct = 0
id_queries_distinct = []
query = "SELECT COUNT(*),COUNT(DISTINCT(id_query)) FROM user_query WHERE id_user=%s"
res = run_sql(query, (uid,), 1)
try:
nb_queries_total = res[0][0]
nb_queries_distinct = res[0][1]
except:
pass
# query for queries:
if permanent == "n":
SQL_query = "SELECT DISTINCT(q.id),q.urlargs "\
"FROM query q, user_query uq "\
"WHERE uq.id_user='%s' "\
"AND uq.id_query=q.id "\
"ORDER BY q.id DESC" % uid
else:
# permanent="y"
SQL_query = "SELECT q.id,q.urlargs "\
"FROM query q "\
"WHERE q.type='p'"
query_result = run_sql(SQL_query)
queries = []
if len(query_result) > 0:
for row in query_result :
if permanent == "n":
res = run_sql("SELECT DATE_FORMAT(MAX(date),'%%Y-%%m-%%d %%H:%%i:%%s') FROM user_query WHERE id_user=%s and id_query=%s",
(uid, row[0]))
try:
lastrun = res[0][0]
except:
lastrun = _("unknown")
else:
lastrun = ""
queries.append({
'id' : row[0],
'args' : row[1],
'textargs' : get_textual_query_info_from_urlargs(row[1], ln=ln),
'lastrun' : lastrun,
})
return webalert_templates.tmpl_display_alerts(
ln = ln,
permanent = permanent,
nb_queries_total = nb_queries_total,
nb_queries_distinct = nb_queries_distinct,
queries = queries,
guest = isGuestUser(uid),
guesttxt = warning_guest_user(type="alerts", ln=ln),
weburl = weburl
)
def perform_input_alert(action, id_query, alert_name, frequency, notification, id_basket,uid, old_id_basket=None, ln = cdslang):
"""get the alert settings
input: action="add" for a new alert (blank form), action="modify" for an update
(get old values)
id_query id the identifier of the search to be alerted
for the "modify" action specify old alert_name, frequency of checking,
e-mail notification and basket id.
output: alert settings input form"""
# display query information
res = run_sql("SELECT urlargs FROM query WHERE id=%s", (id_query,))
try:
urlargs = res[0][0]
except:
urlargs = "UNKNOWN"
baskets = create_personal_baskets_selection_box(uid=uid,
html_select_box_name='idb',
selected_bsk_id=old_id_basket,
ln=cdslang)
return webalert_templates.tmpl_input_alert(
ln = ln,
query = get_textual_query_info_from_urlargs(urlargs, ln = ln),
action = action,
frequency = frequency,
notification = notification,
alert_name = alert_name,
baskets = baskets,
old_id_basket = old_id_basket,
id_basket = id_basket,
id_query = id_query,
)
def check_alert_is_unique(id_basket, id_query, uid, ln=cdslang ):
"""check the user does not have another alert for the specified query and basket"""
_ = gettext_set_language(ln)
sql = """select id_query
from user_query_basket
where id_user = %s and id_query = %s
and id_basket= %s"""%(uid, id_query, id_basket)
res = run_sql(sql)
if len(res):
raise AlertError(_("You already have an alert defined for the specified query and basket"))
def perform_add_alert(alert_name, frequency, notification,
id_basket, id_query, uid, ln = cdslang):
"""add an alert to the database
input: the name of the new alert;
alert frequency: 'month', 'week' or 'day';
setting for e-mail notification: 'y' for yes, 'n' for no;
basket identifier: 'no' for no basket;
new basket name for this alert;
identifier of the query to be alerted
output: confirmation message + the list of alerts Web page"""
alert_name = alert_name.strip()
# load the right message language
_ = gettext_set_language(ln)
#check the alert name is not empty
if alert_name.strip() == "":
raise AlertError(_("The alert name cannot be <b>empty</b>."))
#check if the alert can be created
check_alert_name(alert_name, uid, ln)
check_alert_is_unique(id_basket, id_query, uid, ln)
# add a row to the alerts table: user_query_basket
query = """INSERT INTO user_query_basket (id_user, id_query, id_basket,
frequency, date_creation, date_lastrun,
alert_name, notification)
VALUES ('%s','%s','%s','%s','%s','','%s','%s')"""
query %= (uid, id_query, id_basket,
frequency, convert_datestruct_to_datetext(time.localtime()),
alert_name, notification)
run_sql(query)
out = _("The alert %s has been added to your profile.")
out %= '<b>' + alert_name + '</b>'
out += perform_list_alerts(uid, ln=ln)
return out
def perform_list_alerts (uid, ln=cdslang):
"""perform_list_alerts display the list of alerts for the connected user"""
# set variables
out = ""
# query the database
query = """ SELECT q.id, q.urlargs,
a.id_basket, b.name,
a.alert_name, a.frequency,a.notification,
DATE_FORMAT(a.date_creation,'%%Y-%%m-%%d %%H:%%i:%%s'),
DATE_FORMAT(a.date_lastrun,'%%Y-%%m-%%d %%H:%%i:%%s')
FROM user_query_basket a LEFT JOIN query q ON a.id_query=q.id
LEFT JOIN bskBASKET b ON a.id_basket=b.id
WHERE a.id_user='%s'
ORDER BY a.alert_name ASC """ % uid
res = run_sql(query)
alerts = []
for (qry_id, qry_args,
bsk_id, bsk_name,
alrt_name, alrt_frequency, alrt_notification, alrt_creation, alrt_last_run) in res:
alerts.append({
'queryid' : qry_id,
'queryargs' : qry_args,
'textargs' : get_textual_query_info_from_urlargs(qry_args, ln=ln),
'userid' : uid,
'basketid' : bsk_id,
'basketname' : bsk_name,
'alertname' : alrt_name,
'frequency' : alrt_frequency,
'notification' : alrt_notification,
'created' : convert_datetext_to_dategui(alrt_creation),
'lastrun' : convert_datetext_to_dategui(alrt_last_run)
})
# link to the "add new alert" form
out = webalert_templates.tmpl_list_alerts(ln=ln, weburl=weburl, alerts=alerts,
guest=isGuestUser(uid),
guesttxt=warning_guest_user(type="alerts", ln=ln))
return out
def perform_remove_alert(alert_name, id_user, id_query, id_basket, uid, ln=cdslang):
"""perform_remove_alert: remove an alert from the database
input: identifier of the user;
identifier of the query;
identifier of the basket
output: confirmation message + the list of alerts Web page"""
# set variables
out = ""
# remove a row from the alerts table: user_query_basket
query = """DELETE FROM user_query_basket
WHERE id_user='%s' AND id_query='%s' AND id_basket='%s'"""
query %= (id_user, id_query, id_basket)
run_sql(query)
out += "The alert <b>%s</b> has been removed from your profile.<br /><br />\n" % alert_name
out += perform_list_alerts(uid)
return out
def perform_update_alert(alert_name, frequency, notification, id_basket, id_query, old_id_basket,uid, ln = cdslang):
"""update alert settings into the database
input: the name of the new alert;
alert frequency: 'month', 'week' or 'day';
setting for e-mail notification: 'y' for yes, 'n' for no;
new basket identifier: 'no' for no basket;
new basket name for this alert;
identifier of the query to be alerted
old identifier of the basket associated to the alert
output: confirmation message + the list of alerts Web page"""
#set variables
out = ""
# load the right message language
_ = gettext_set_language(ln)
#check the alert name is not empty
if alert_name.strip() == "":
raise AlertError(_("The alert name cannot be <b>empty</b>."))
#check if the alert can be created
sql = """select alert_name
from user_query_basket
where id_user=%s
and id_basket=%s
and id_query=%s"""%( uid, old_id_basket, id_query )
old_alert_name = run_sql( sql )[0][0]
if old_alert_name.strip()!="" and old_alert_name != alert_name:
check_alert_name( alert_name, uid, ln)
if id_basket != old_id_basket:
check_alert_is_unique( id_basket, id_query, uid, ln)
# update a row into the alerts table: user_query_basket
query = """UPDATE user_query_basket
SET alert_name='%s',frequency='%s',notification='%s',
date_creation='%s',date_lastrun='',id_basket='%s'
WHERE id_user='%s' AND id_query='%s' AND id_basket='%s'"""
query %= (alert_name, frequency, notification,
convert_datestruct_to_datetext(time.localtime()),
id_basket, uid, id_query, old_id_basket)
run_sql(query)
out += _("The alert %s has been successfully updated.") % "<b>" + alert_name + "</b>"
out += "<br /><br />\n" + perform_list_alerts(uid)
return out
def is_selected(var, fld):
"Checks if the two are equal, and if yes, returns ' selected'. Useful for select boxes."
if var == fld:
return " selected"
else:
return ""
def account_list_alerts(uid, ln=cdslang):
"""account_list_alerts: list alert for the account page
input: the user id
language
output: the list of alerts Web page"""
query = """ SELECT q.id, q.urlargs, a.id_user, a.id_query,
a.id_basket, a.alert_name, a.frequency,
a.notification,
DATE_FORMAT(a.date_creation,'%%d %%b %%Y'),
DATE_FORMAT(a.date_lastrun,'%%d %%b %%Y'),
a.id_basket
FROM query q, user_query_basket a
WHERE a.id_user='%s' AND a.id_query=q.id
ORDER BY a.alert_name ASC """ % uid
res = run_sql(query)
alerts = []
if len(res):
for row in res:
alerts.append({
'id' : row[0],
'name' : row[5]
})
return webalert_templates.tmpl_account_list_alerts(ln=ln, alerts=alerts)
def account_list_searches(uid, ln=cdslang):
""" account_list_searches: list the searches of the user
input: the user id
output: resume of the searches"""
out =""
# first detect number of queries:
nb_queries_total = 0
nb_queries_distinct = 0
id_queries_distinct = []
res = run_sql("SELECT COUNT(*),COUNT(DISTINCT(id_query)) FROM user_query WHERE id_user=%s", (uid,), 1)
try:
nb_queries_total = res[0][0]
nb_queries_distinct = res[0][1]
except:
pass
# load the right message language
_ = gettext_set_language(ln)
out += _("You have made %(number)s queries. A %(detailed_list)s is available with a posibility to (a) view search results and (b) subscribe for automatic email alerting service for these queries") % {
'detailed_list' : """<a href="../youralerts.py/display">""" + _("detailed list") + """</a>""",
'number' : nb_queries_total,
}
return out
diff --git a/modules/webalert/lib/webalert_templates.py b/modules/webalert/lib/webalert_templates.py
index ab92d48c5..53ff7ad08 100644
--- a/modules/webalert/lib/webalert_templates.py
+++ b/modules/webalert/lib/webalert_templates.py
@@ -1,544 +1,544 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import urllib
import time
import cgi
import gettext
import string
import locale
import re
import operator
from cdsware.config import *
from cdsware.messages import gettext_set_language
from cdsware.htmlparser import get_as_text, wrap
class Template:
def tmpl_errorMsg(self, ln, error_msg, rest = ""):
"""
Adds an error message to the output
Parameters:
- 'ln' *string* - The language to display the interface in
- 'error_msg' *string* - The error message
- 'rest' *string* - The rest of the page
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<div class="quicknote">%(error)s</div><br>%(rest)s""" % {
'error' : error_msg,
'rest' : rest
}
return out
def tmpl_textual_query_info_from_urlargs(self, ln, args):
"""
Displays a human inteligible textual representation of a query
Parameters:
- 'ln' *string* - The language to display the interface in
- 'args' *array* - The URL arguments array (parsed)
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if args.has_key('p'):
out += "<strong>" + _("Pattern") + ":</strong> " + string.join(args['p'], "; ") + "<br>"
if args.has_key('f'):
out += "<strong>" + _("Field") + ":</strong> " + string.join(args['f'], "; ") + "<br>"
if args.has_key('p1'):
out += "<strong>" + _("Pattern 1") + ":</strong> " + string.join(args['p1'], "; ") + "<br>"
if args.has_key('f1'):
out += "<strong>" + _("Field 1") + ":</strong> " + string.join(args['f1'], "; ") + "<br>"
if args.has_key('p2'):
out += "<strong>" + _("Pattern 2") + ":</strong> " + string.join(args['p2'], "; ") + "<br>"
if args.has_key('f2'):
out += "<strong>" + _("Field 2") + ":</strong> " + string.join(args['f2'], "; ") + "<br>"
if args.has_key('p3'):
out += "<strong>" + _("Pattern 3") + ":</strong> " + string.join(args['p3'], "; ") + "<br>"
if args.has_key('f3'):
out += "<strong>" + _("Field 3") + ":</strong> " + string.join(args['f3'], "; ") + "<br>"
if args.has_key('c'):
out += "<strong>" + _("Collections") + ":</strong> " + string.join(args['c'], "; ") + "<br>"
elif args.has_key('cc'):
out += "<strong>" + _("Collection") + ":</strong> " + string.join(args['cc'], "; ") + "<br>"
return out
def tmpl_account_list_alerts(self, ln, alerts):
"""
Displays all the alerts in the main "Your account" page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'alerts' *array* - The existing alerts IDs ('id' + 'name' pairs)
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<FORM name="displayalert" action="../youralerts.py/list" method="post">
%(you_own)s
<SELECT name="id_alert">
<OPTION value="0">- %(alert_name)s -</OPTION>""" % {
'you_own' : _("You own following alerts:"),
'alert_name' : _("alert name"),
}
for alert in alerts :
out += """<OPTION value="%(id)s">%(name)s</OPTION>""" % alert
out += """</SELECT>
&nbsp;<CODE class="blocknote">
<INPUT class="formbutton" type="submit" name="action" value="%(show)s"></CODE>
</FORM>""" % {
'show' : _("SHOW"),
}
return out
def tmpl_input_alert(self, ln, query, alert_name, action, frequency, notification, baskets, old_id_basket, id_basket, id_query):
"""
Displays an alert adding form.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'query' *string* - The HTML code of the textual representation of the query (as returned ultimately by tmpl_textual_query_info_from_urlargs...)
- 'alert_name' *string* - The alert name
- 'action' *string* - The action to complete ('update' or 'add')
- 'frequency' *string* - The frequency of alert running ('day', 'week', 'month')
- 'notification' *string* - If notification should be sent by email ('y', 'n')
- 'baskets' *array* - The existing baskets ('id' + 'name' pairs)
- 'old_id_basket' *string* - The id of the previous basket of this alert
- 'id_basket' *string* - The id of the basket of this alert
- 'id_query' *string* - The id of the query associated to this alert
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
out += """<TABLE border="0" cellspacing="0" cellpadding="2" width="650">
<TR><TD colspan="3">%(notify_cond)s </TD></TR>
<TR>
<TD>&nbsp;&nbsp;</TD>
<TD align="left" valign="top" width="10"><B>%(query_text)s:</B></TD>
<TD align="left" valign="top" width="500">%(query)s</TD></TR>
</TABLE>""" % {
'notify_cond' : _("This alert will notify you each time/only if a new item satisfy the following query"),
'query_text' : _("QUERY"),
'query' : query,
}
out += """<FORM name="setalert" action="../youralerts.py/%(action)s" method="get">
<TABLE style="background-color:F1F1F1; border:thin groove grey" cellspacing="0" cellpadding="0"><TR><TD>
<TABLE border="0" cellpadding="0" cellspacing ="10">
<TR>
<TD align="right" valign="top"><B>%(alert_name)s</B></TD>
<TD><INPUT type="text" name="name" size="20" maxlength="50" value="%(alert)s"></TD>
</TR>
<TR><TD align="right"><B>%(freq)s</B></TD>
<TD><SELECT name="freq">
<OPTION value="month" %(freq_month)s>%(monthly)s</OPTION>
<OPTION value="week" %(freq_week)s>%(weekly)s</OPTION>
<OPTION value="day" %(freq_day)s>%(daily)s</OPTION></SELECT>
</TD>
</TR>
<TR>
<TD align="right"><B>%(send_email)s</B></TD>
<TD><SELECT name="notif">
<OPTION value="y" %(notif_yes)s>%(yes)s</OPTION>
<OPTION value="n"%(notif_no)s>%(no)s</OPTION></SELECT>
<SMALL class="quicknote"> (%(specify)s)</SMALL>&nbsp;
</TD>
</TR>
<TR>
<TD align="right" valign="top"><B>%(store_basket)s</B></TD>
<TD>%(baskets)s
""" % {
'action': action,
'alert_name' : _("Alert identification name:"),
'alert' : alert_name,
'freq' : _("Search-checking frequency:"),
'freq_month' : (frequency == 'month' and "selected" or ""),
'freq_week' : (frequency == 'week' and "selected" or ""),
'freq_day' : (frequency == 'day' and "selected" or ""),
'monthly' : _("monthly"),
'weekly' : _("weekly"),
'daily' : _("daily"),
'send_email' : _("Send notification e-mail?"),
'notif_yes' : (notification == 'y' and "selected" or ""),
'notif_no' : (notification == 'n' and "selected" or ""),
'yes' : _("yes"),
'no' : _("no"),
'specify' : _("if <B>no</B> you must specify a basket"),
'store_basket' : _("Store results in basket?"),
'baskets': baskets
}
out += """ </TD>
</TR>
<TR>
<TD colspan="2" align="center"><BR>
<INPUT type="hidden" name="idq" value="%(idq)s">
<CODE class="blocknote"><INPUT class="formbutton" type="submit" name="action" value="&nbsp;%(set_alert)s&nbsp;"></CODE>&nbsp;
<CODE class="blocknote"><INPUT class="formbutton" type="reset" value="%(clear_data)s"></CODE>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
""" % {
'idq' : id_query,
'set_alert' : _("SET ALERT"),
'clear_data' : _("CLEAR DATA"),
}
if action == "update":
out += """<INPUT type="hidden" name="old_idb" value="%s">""" % old_id_basket
out += "</FORM>"
return out
def tmpl_list_alerts(self, ln, weburl, alerts, guest, guesttxt):
"""
Displays the list of alerts
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The url of cdsware
- 'alerts' *array* - The existing alerts:
- 'queryid' *string* - The id of the associated query
- 'queryargs' *string* - The query string
- 'textargs' *string* - The textual description of the query string
- 'userid' *string* - The user id
- 'basketid' *string* - The basket id
- 'basketname' *string* - The basket name
- 'alertname' *string* - The alert name
- 'frequency' *string* - The frequency of alert running ('day', 'week', 'month')
- 'notification' *string* - If notification should be sent by email ('y', 'n')
- 'created' *string* - The date of alert creation
- 'lastrun' *string* - The last running date
- 'guest' *bool* - If the user is a guest user
- 'guesttxt' *string* - The HTML content of the warning box for guest users (produced by webaccount.tmpl_warning_guest_user)
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<P>%(set_new_alert)s</P>""" % {
'set_new_alert' : _("Set a new alert from %(your_searches)s, the %(popular_searches)s or the input form.") % {
'your_searches' : """<A href="display">%s</A>""" % _("your searches"),
'popular_searches' : """<A href="display?p='y'">%s</A>""" % _("most popular searches"),
}
}
if len(alerts):
out += """<TABLE border="1" cellspacing="0" cellpadding="3" width="100%%">
<TR class="pageboxlefttop" align="center">
<TD><B>%(no)s</B></TD>
<TD><B>%(name)s</B></TD>
<TD><B>%(search_freq)s</B></TD>
<TD><B>%(notification)s</B></TD>
<TD><B>%(result_basket)s</B></TD>
<TD><B>%(date_run)s</B></TD>
<TD><B>%(date_created)s</B></TD>
<TD><B>%(query)s</B></TD>
<TD><B>%(action)s</B></TD></TR>""" % {
'no' : _("No"),
'name' : _("Name"),
'search_freq' : _("Search checking frequency"),
'notification' : _("Notification by e-mail"),
'result_basket' : _("Result in basket"),
'date_run' : _("Date last run"),
'date_created' : _("Creation date"),
'query' : _("Query"),
'action' : _("Action"),
}
i = 0
for alert in alerts:
i += 1
if alert['frequency'] == "day":
frequency = _("daily"),
else:
if alert['frequency'] == "week":
frequency = _("weekly")
else:
frequency = _("monthly")
if alert['notification'] == "y":
notification = _("yes")
else:
notification = _("no")
out += """<TR>
<TD><I>#%(index)d</I></TD>
<TD><B><NOBR>%(alertname)s<NOBR></B></TD>
<TD>%(frequency)s</TD>
<TD align="center">%(notification)s</TD>
<TD><NOBR>%(basketname)s<NOBR></TD>
<TD><NOBR>%(lastrun)s<NOBR></TD>
<TD><NOBR>%(created)s<NOBR></TD>
<TD>%(textargs)s</TD>
<TD><A href="./remove?name=%(alertname)s&idu=%(userid)d&idq=%(queryid)d&idb=%(basketid)d">%(remove)s</A><BR>
<A href="./modify?idq=%(queryid)d&name=%(alertname)s&freq=%(freq)s&notif=%(notif)s&idb=%(basketid)d&old_idb=%(basketid)d">%(modify)s</A><BR>
<A href="%(weburl)s/search.py?%(queryargs)s">%(search)s</A>
</TD>
</TR>""" % {
'index' : i,
'alertname' : alert['alertname'],
'frequency' : frequency,
'notification' : notification,
'basketname' : alert['basketname'],
'lastrun' : alert['lastrun'],
'created' : alert['created'],
'textargs' : alert['textargs'],
'userid' : alert['userid'],
'queryid' : alert['queryid'],
'basketid' : alert['basketid'],
'freq' : alert['frequency'],
'notif' : alert['notification'],
'remove' : _("Remove"),
'modify' : _("Modify"),
'weburl' : weburl,
'search' : _("Execute search"),
'queryargs' : alert['queryargs']
}
out += '</TABLE>'
out += """<P>%(defined)s</P>""" % {
'defined' : _("You have defined <B>%(number)s</B> alerts.") % { 'number' : len(alerts)}
}
if guest:
out += guesttxt
return out
def tmpl_display_alerts(self, ln, weburl, permanent, nb_queries_total, nb_queries_distinct, queries, guest, guesttxt):
"""
Displays the list of alerts
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The url of cdsware
- 'permanent' *string* - If displaying most popular searches ('y') or only personal searches ('n')
- 'nb_queries_total' *string* - The number of personal queries in the last period
- 'nb_queries_distinct' *string* - The number of distinct queries in the last period
- 'queries' *array* - The existing queries:
- 'id' *string* - The id of the associated query
- 'args' *string* - The query string
- 'textargs' *string* - The textual description of the query string
- 'lastrun' *string* - The last running date (only for personal queries)
- 'guest' *bool* - If the user is a guest user
- 'guesttxt' *string* - The HTML content of the warning box for guest users (produced by webaccount.tmpl_warning_guest_user)
"""
# load the right message language
_ = gettext_set_language(ln)
if len(queries) == 0:
return _("You have not executed any search yet. %(click_here)s for search.") % {
'click_here' : """<a href="%(weburl)s/search.py">%(click)s</a>""" % {
'weburl' : weburl,
'click' : _("Click here"),
}
}
out = ''
# display message: number of items in the list
if permanent=="n":
out += """<P>""" + _("You have performed <B>%(number)d</B> searches (<strong>%(different)d</strong> different questions) during the last 30 days or so.""") % {
'number' : nb_queries_total,
'different' : nb_queries_distinct
} + """</P>"""
else:
# permanent="y"
out += """<P>Here are listed the <B>%s</B> most popular searches.</P>""" % len(query_result)
# display the list of searches
out += """<TABLE border="1" cellspacing="0" cellpadding="3" width="100%%">
<TR class="pageboxlefttop"><TD><B>%(no)s</B></TD><TD><B>%(question)s</B></TD>
<TD><B>%(action)s</B></TD>""" % {
'no' : _("#"),
'question' : _("Question"),
'action' : _("Action")
}
if permanent=="n":
out += """<TD><B>%s</B></TD>""" % _("Last Run")
out += """</TR>\n"""
i = 0
for query in queries :
i += 1
# id, pattern, base, search url and search set alert, date
out += """<TR>
<TD><I>#%(index)d</I></TD>
<TD>%(textargs)s</TD>
<TD><A href="%(weburl)s/search.py?%(args)s">%(execute_query)s</A><BR><A href="./input?idq=%(id)d">%(set_alert)s</A></TD>""" % {
'index' : i,
'textargs' : query['textargs'],
'weburl' : weburl,
'args' : query['args'],
'id' : query['id'],
'execute_query' : _("Execute search"),
'set_alert' : _("Set new alert")
}
if permanent=="n":
out += """<TD>%(lastrun)s</TD>""" % query
out += """</TR>\n"""
out += """</TABLE><BR>\n"""
if guest :
out += guesttxt
return out
def tmpl_alert_email_headers(self, name, headers):
headers['Subject'] = 'Alert %s run on %s' % (
name, time.strftime("%Y-%m-%d"))
headers['From'] = 'CDS Alert Engine <%s>' % alertengineemail
def tmpl_alert_email_body(self, name, url, records, pattern,
catalogues, frequency):
MAXIDS = 5
l = len(catalogues)
if l == 0:
collections = ''
elif l == 1:
collections = "collection: %s\n" % catalogues[0]
else:
collections = "collections: %s\n" % wrap(', '.join(catalogues))
if pattern:
pattern = 'pattern: %s\n' % pattern
frequency = {'day': 'daily',
'month': 'monthly',
'year': 'yearly'}[frequency]
l = len(records)
if l == 1:
total = '1 record'
else:
total = '%d records' % l
body = """\
Hello,
Below are the results of the email alert that you set up with the CERN
Document Server. This is an automatic message, please don't reply to
its address. For any question, use <%(supportemail)s> instead.
alert name: %(name)s
%(pattern)s%(collections)sfrequency: %(frequency)s
run time: %(runtime)s
found: %(total)s
url: <%(url)s>
""" % {'supportemail': supportemail,
'name': name,
'pattern': pattern,
'collections': collections,
'frequency': frequency,
'runtime': time.strftime("%a %Y-%m-%d %H:%M:%S"),
'total': total,
'url': url}
for index, recid in enumerate(records[:MAXIDS]):
body += self.tmpl_alert_email_record(index, recid)
if len(records) > MAXIDS:
body += '''
Only the first %s records were displayed. Please consult the search
URL given at the top of this email to see all the results.
''' % MAXIDS
body += '''
--
CERN Document Server Alert Service <%s>
Unsubscribe? See <%s>
Need human intervention? Contact <%s>
''' % (weburl, weburl + '/youralerts.py/list', supportemail)
return body
def tmpl_alert_email_record(self, index, recid):
""" Format a single record."""
return wrap('\n\n%s) %s' % (index+1, get_as_text(recid))) + '\n'
diff --git a/modules/webalert/web/Makefile.am b/modules/webalert/web/Makefile.am
index 94608d44e..deae1ad6c 100644
--- a/modules/webalert/web/Makefile.am
+++ b/modules/webalert/web/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)
webapp_DATA = youralerts.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/webalert/web/youralerts.py b/modules/webalert/web/youralerts.py
index 85f25f0c1..a8f6430a4 100644
--- a/modules/webalert/web/youralerts.py
+++ b/modules/webalert/web/youralerts.py
@@ -1,226 +1,226 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""PERSONAL FEATURES - YOUR ALERTS"""
__lastupdated__ = """<: print `date +"%d %b %Y %H:%M:%S %Z"`; :>"""
import sys
import time
import zlib
import urllib
import time
from mod_python import apache
from cdsware.config import weburl, cdslang, cdsname
from cdsware.webpage import page
from cdsware import webalert
from cdsware.webuser import getUid, page_not_authorized
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
from cdsware.messages import gettext_set_language
import cdsware.template
webalert_templates = cdsware.template.load('webalert')
def relative_redirect( req, relative_url, **args ):
tmp = []
for param in args.keys():
#ToDo: url encoding of the params
tmp.append( "%s=%s"%( param, args[param] ) )
req.err_headers_out.add("Location", "%s/%s?%s" % (weburl, relative_url, "&".join( tmp ) ))
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
### CALLABLE INTERFACE
def display(req, p="n", ln = cdslang):
uid = getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/display")
return page(title=_("Display searches"),
body=webalert.perform_display(p,uid, ln = ln),
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Display searches",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def input(req, idq, name="", freq="week", notif="y", idb=0, error_msg="", ln = cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/input")
# load the right message language
_ = gettext_set_language(ln)
html = webalert.perform_input_alert("add", idq, name, freq, notif, idb,uid, ln = ln)
if error_msg != "":
html = webalert_templates.tmpl_errorMsg(
ln = ln,
error_msg = error_msg,
rest = html,
)
return page(title=_("Set a new alert"),
body=html,
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Set a new alert",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def modify(req, idq, old_idb, name="", freq="week", notif="y", idb=0, error_msg="", ln = cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/modify")
# load the right message language
_ = gettext_set_language(ln)
html = webalert.perform_input_alert("update", idq, name, freq, notif, idb, uid, old_idb, ln = ln)
if error_msg != "":
html = webalert_templates.tmpl_errorMsg(
ln = ln,
error_msg = error_msg,
rest = html,
)
return page(title=_("Modify alert settings"),
body=html,
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Modify alert settings",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def list(req, ln = cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/list")
# load the right message language
_ = gettext_set_language(ln)
return page(title=_("Display alerts"),
body=webalert.perform_list_alerts(uid, ln = ln),
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Display alerts",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def add(req, name, freq, notif, idb, idq, ln = cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/add")
# load the right message language
_ = gettext_set_language(ln)
try:
html=webalert.perform_add_alert(name, freq, notif, idb, idq, uid, ln = ln)
except webalert.AlertError, e:
return input(req, idq, name, freq, notif, idb, e, ln = ln)
return page(title=_("Display alerts"),
body=html,
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Display alerts",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def update(req, name, freq, notif, idb, idq, old_idb, ln = cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/update")
# load the right message language
_ = gettext_set_language(ln)
try:
html=webalert.perform_update_alert(name, freq, notif, idb, idq, old_idb,uid, ln = ln)
except webalert.AlertError, e:
return modify(req, idq, old_idb, name, freq, notif, idb, e, ln = ln)
return page(title=_("Display alerts"),
body=html,
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Display alerts",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def remove(req, name, idu, idq, idb, ln = cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../youralerts.py/remove")
# load the right message language
_ = gettext_set_language(ln)
return page(title=_("Display alerts"),
body=webalert.perform_remove_alert(name, idu, idq, idb, uid, ln = ln),
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
description="CDS Personalize, Display alerts",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def errorMsg(title, req, c=cdsname, ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/modules/webbasket/Makefile.am b/modules/webbasket/Makefile.am
index b43ff7cf9..db9e61cf2 100644
--- a/modules/webbasket/Makefile.am
+++ b/modules/webbasket/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = doc lib web
CLEANFILES = *~
diff --git a/modules/webbasket/doc/Makefile.am b/modules/webbasket/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/webbasket/doc/Makefile.am
+++ b/modules/webbasket/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/webbasket/doc/admin/Makefile.am b/modules/webbasket/doc/admin/Makefile.am
index 2a0953102..ffdf9ed54 100644
--- a/modules/webbasket/doc/admin/Makefile.am
+++ b/modules/webbasket/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webbasket
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webbasket/doc/admin/guide.html.wml b/modules/webbasket/doc/admin/guide.html.wml
index ebff021e3..f18bd4215 100644
--- a/modules/webbasket/doc/admin/guide.html.wml
+++ b/modules/webbasket/doc/admin/guide.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebBasket Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/webbasket/>WebBasket Admin</a>" \
navbar_name="admin" \
navbar_select="webbasket-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<p>Not implemented yet. If you want to manipulate user baskets, see
tables <code>user_basket, basket, basket_record</code>.
diff --git a/modules/webbasket/doc/admin/index.html.wml b/modules/webbasket/doc/admin/index.html.wml
index 558734afa..1605691be 100644
--- a/modules/webbasket/doc/admin/index.html.wml
+++ b/modules/webbasket/doc/admin/index.html.wml
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebBasket Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="webbasket"
<p>
This is the gate to the admin area for WebBasket. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/webbasket/">login</a> to enter.
</p>
<dl>
<dt><a href="guide.html">WebBasket Admin Guide</a></dt>
<dd>Everything you want to know about WebBasket administration</dd>
</dl>
diff --git a/modules/webbasket/lib/Makefile.am b/modules/webbasket/lib/Makefile.am
index c2c7a7841..d06871423 100644
--- a/modules/webbasket/lib/Makefile.am
+++ b/modules/webbasket/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = webbasket.py webbasket_templates.py webbasket_dblayer.py webbasket_config.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webbasket/lib/webbasket.py b/modules/webbasket/lib/webbasket.py
index aef7733bf..5c02e18bf 100644
--- a/modules/webbasket/lib/webbasket.py
+++ b/modules/webbasket/lib/webbasket.py
@@ -1,865 +1,865 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Web Baskets features."""
from zlib import decompress
from cdsware.config import cdslang, weburl
from cdsware.messages import gettext_set_language, wash_language
from cdsware.dateutils import convert_datetext_to_dategui, \
convert_datetext_to_datestruct,\
convert_datestruct_to_dategui
from cdsware.urlutils import wash_url_argument
from cdsware.search_engine import print_record
from cdsware.webbasket_dblayer import *
from cdsware.webbasket_config import cfg_webbasket_share_levels, \
cfg_webbasket_share_levels_ordered, \
cfg_webbasket_categories, \
cfg_webbasket_actions, \
cfg_webbasket_warning_messages, \
cfg_webbasket_error_messages
try:
import cdsware.template
webbasket_templates = cdsware.template.load('webbasket')
except ImportError:
pass
def perform_request_display(uid,
category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0,
selected_group_id=0,
ln=cdslang):
"""Display all the baskets of given category, topic or group.
@param uid: user id
@param category: selected category (see webbasket_config.py)
@param selected_topic: # of selected topic to display baskets
@param selected_group_id: id of group to display baskets
@param ln: language"""
warnings = []
errors = []
baskets_html = []
_ = gettext_set_language(ln)
selected_topic = wash_url_argument(selected_topic, 'int')
selected_group_id = wash_url_argument(selected_group_id, 'int')
nb_groups = count_groups_user_member_of(uid)
nb_external_baskets = count_external_baskets(uid)
selectionbox = ''
infobox = ''
if category == cfg_webbasket_categories['EXTERNAL']:
baskets = get_external_baskets_infos(uid)
if len(baskets):
map(list, baskets)
else:
category = cfg_webbasket_categories['PRIVATE']
if category == cfg_webbasket_categories['GROUP']:
groups = get_group_infos(uid)
if len(groups):
if selected_group_id == 0 and len(groups):
selected_group_id = groups[0][0]
selectionbox = webbasket_templates.tmpl_group_selection(groups,
selected_group_id,
ln)
baskets = get_group_baskets_infos(selected_group_id)
def adapt_group_rights(item):
"""Suppress unused element in tuple."""
out = list(item)
if out[-1] == uid:
out[-2] = cfg_webbasket_share_levels['MANAGE']
return out[:-1]
baskets = map(adapt_group_rights, baskets)
else:
category = cfg_webbasket_categories['PRIVATE']
if category == cfg_webbasket_categories['PRIVATE']:
topics_list = get_personal_topics(uid)
if not selected_topic and len(topics_list):
selected_topic = 0
selectionbox = webbasket_templates.tmpl_topic_selection(topics_list,
selected_topic,
ln)
if len(topics_list) > 0:
baskets = get_personal_baskets_infos(uid, topics_list[selected_topic][0])
else:
baskets = []
def add_manage_rights(item):
""" Convert a tuple to a list and add rights"""
out = list(item)
out.append(cfg_webbasket_share_levels['MANAGE'])
return out
baskets = map(add_manage_rights, baskets)
bskids = []
for basket in baskets:
bskids.append(basket[0])
levels = dict(is_shared_to(bskids))
create_link = ''
if category == cfg_webbasket_categories['PRIVATE']:
create_link = webbasket_templates.tmpl_create_basket_link(selected_topic, ln)
infobox = webbasket_templates.tmpl_baskets_infobox(map(lambda x: (x[0], x[1], x[2]),
baskets),
create_link,
ln)
for (bskid, name, date_modification,
nb_views, nb_items, last_added, share_level) in baskets:
(bsk_html, bsk_e, bsk_w) = __display_basket(bskid,
name,
date_modification,
nb_views,
nb_items,
last_added,
share_level,
levels[bskid],
category,
selected_topic,
selected_group_id,
ln)
baskets_html.append(bsk_html)
errors.extend(bsk_e)
warnings.extend(bsk_w)
body = webbasket_templates.tmpl_display(selectionbox,
infobox,
baskets_html,
category,
nb_groups,
nb_external_baskets,
ln)
return (body, errors, warnings)
def __display_basket(bskid, name, date_modification, nb_views,
nb_items, last_added,
share_level, group_sharing_level,
category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group_id=0,
ln=cdslang):
"""Private function. Display a basket giving its category and topic or group.
@param category: selected category (see webbasket_config.py)
@param selected_topic: # of selected topic to display baskets
@param selected_group_id: id of group to display baskets
@param ln: language"""
_ = gettext_set_language(ln)
errors = []
warnings = []
nb_bsk_cmts = 0
last_cmt = _("N/A")
records = []
cmt_dates = []
date_modification = convert_datetext_to_dategui(date_modification, ln)
items = get_basket_content(bskid, 'hb')
for (recid, nb_cmt, last_cmt, ext_val, int_val, score) in items:
cmt_dates.append(convert_datetext_to_datestruct(last_cmt))
last_cmt = convert_datetext_to_dategui(last_cmt, ln)
val = ''
nb_bsk_cmts += nb_cmt
if recid < 0:
if ext_val:
val = decompress(ext_val)
else:
if int_val:
val = decompress(int_val)
records.append((recid, nb_cmt, last_cmt, val, score))
if len(cmt_dates) > 0:
last_cmt = convert_datestruct_to_dategui(max(cmt_dates), ln)
body = webbasket_templates.tmpl_basket(bskid,
name,
date_modification,
nb_views,
nb_items, last_added,
(__check_sufficient_rights(share_level, cfg_webbasket_share_levels['READITM']),
__check_sufficient_rights(share_level, cfg_webbasket_share_levels['MANAGE']),
__check_sufficient_rights(share_level, cfg_webbasket_share_levels['MANAGE']),
__check_sufficient_rights(share_level, cfg_webbasket_share_levels['READCMT']),
__check_sufficient_rights(share_level, cfg_webbasket_share_levels['ADDITM']),
__check_sufficient_rights(share_level, cfg_webbasket_share_levels['DELITM'])),
nb_bsk_cmts, last_cmt,
group_sharing_level,
category, selected_topic, selected_group_id,
records,
ln)
return (body, errors, warnings)
def perform_request_display_item(uid, bskid, recid, format='hd',
category=cfg_webbasket_categories['PRIVATE'],
topic=0, group_id=0,
infos=[],
ln=cdslang):
"""Display an item of a basket of given category, topic or group.
@param uid: user id
@param bskid: basket_id
@param recid: record id
@param format: format of the record (hb, hd, etc.)
@param category: selected category (see webbasket_config.py)
@param selected_topic: # of selected topic to display baskets
@param selected_group_id: id of group to display baskets
@param ln: language"""
bskid = wash_url_argument(bskid, 'int')
recid = wash_url_argument(recid, 'int')
category = wash_url_argument(category, 'str')
topic = wash_url_argument(topic, 'int')
group_id = wash_url_argument(group_id, 'int')
infos = wash_url_argument(infos, 'list')
ln = wash_language(ln)
body = ''
errors = []
warnings = []
rights = get_max_user_rights_on_basket(uid, bskid)
if not(__check_sufficient_rights(rights, cfg_webbasket_share_levels['READITM'])):
errors.append('ERR_WEBBASKET_NO_RIGHTS')
return (body, errors, warnings)
if category == cfg_webbasket_categories['PRIVATE']:
topics_list = get_personal_topics(uid)
if not topic and len(topics_list):
topic = 0
topicsbox = webbasket_templates.tmpl_topic_selection(topics_list, topic, ln)
elif category == cfg_webbasket_categories['GROUP']:
groups = get_group_infos(uid)
if group_id == 0 and len(groups):
group_id = groups[0][0]
topicsbox = webbasket_templates.tmpl_group_selection(groups, group_id, ln)
else:
topicsbox = ''
record = get_basket_record(bskid, recid, format)
comments = get_comments(bskid, recid)
group_sharing_level = None
levels = is_shared_to(bskid)
if len(levels):
group_sharing_level = levels[0][1]
basket = get_basket_general_infos(bskid)
if not(len(basket)):
errors.append('ERR_WEBBASKET_DB_ERROR')
return (body, errors, warnings)
basket = basket[0]
item_html = webbasket_templates.tmpl_item(basket,
recid, record, comments,
group_sharing_level,
(__check_sufficient_rights(rights, cfg_webbasket_share_levels['READCMT']),
__check_sufficient_rights(rights, cfg_webbasket_share_levels['ADDCMT']),
__check_sufficient_rights(rights, cfg_webbasket_share_levels['DELCMT'])),
selected_category=category, selected_topic=topic, selected_group_id=group_id,
ln=ln)
body = webbasket_templates.tmpl_display(topicsbox=topicsbox, baskets=[item_html],
selected_category=category,
nb_groups=count_groups_user_member_of(uid),
nb_external_baskets=count_external_baskets(uid),
ln=ln)
return (body, errors, warnings)
def perform_request_write_comment(uid, bskid, recid, cmtid=0,
category=cfg_webbasket_categories['PRIVATE'],
topic=0, group_id=0,
ln=cdslang):
"""Display a comment writing form"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
recid = wash_url_argument(recid, 'int')
cmtid = wash_url_argument(cmtid, 'int')
category = wash_url_argument(category, 'str')
topic = wash_url_argument(topic, 'int')
group_id = wash_url_argument(group_id, 'int')
ln = wash_language(ln)
body = ''
warnings = []
errors = []
cmt_body = ''
if not __check_user_can_comment(uid, bskid):
errors.append(('ERR_WEBBASKET_CANNOT_COMMENT'))
return (body, errors, warnings)
if cmtid:
# this is a reply to another comment
comment = get_comment(cmtid)
if comment:
cmt_body = webbasket_templates.tmpl_quote_comment(comment[2], # title
uid,
comment[0], # nickname
comment[4], # date
comment[3],
ln)
else:
warning = (cfg_webbasket_warning_messages['ERR_WEBBASKET_cmtid_INVALID'], cmtid)
warnings.append(warning)
record = get_basket_record(bskid, recid, 'hb')
body = webbasket_templates.tmpl_write_comment(bskid=bskid,
recid=recid,
cmt_body=cmt_body,
record = record,
selected_category=category,
selected_topic=topic,
selected_group_id=group_id,
warnings=warnings)
if category == cfg_webbasket_categories['PRIVATE']:
topics_list = get_personal_topics(uid)
if not topic and len(topics_list):
topic = 0
topicsbox = webbasket_templates.tmpl_topic_selection(topics_list, topic, ln)
elif category == cfg_webbasket_categories['GROUP']:
groups = get_group_infos(uid)
if group_id == 0 and len(groups):
group_id = groups[0][0]
topicsbox = webbasket_templates.tmpl_group_selection(groups, group_id, ln)
else:
topicsbox = ''
body = webbasket_templates.tmpl_display(topicsbox, '', [ body ], category, ln)
return (body, errors, warnings)
def perform_request_save_comment(uid, bskid, recid, title='', text='', ln=cdslang):
""" Save a given comment if able to.
@param uid: user id (int)
@param bskid: basket id (int)
@param recid: record id (int)
@param title: title of comment (string)
@param text: comment's body (string)
@param ln: language (string)
@return (errors, infos) where errors: list of errors while saving
infos: list of informations to display"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
recid = wash_url_argument(recid, 'int')
text = wash_url_argument(text, 'str')
ln = wash_language(ln)
_ = gettext_set_language(ln)
errors = []
infos = []
if not __check_user_can_comment(uid, bskid):
errors.append(('ERR_WEBBASKET_CANNOT_COMMENT'))
return (errors, infos)
if not(save_comment(uid, bskid, recid, title, text)):
errors.append(('ERR_WEBBASKET_DB_ERROR'))
else:
infos.append(_('Your comment has been successfully posted'))
return (errors, infos)
def perform_request_delete_comment(uid, bskid, recid, cmtid):
"""Delete comment cmtid on record recid for basket bskid."""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
recid = wash_url_argument(recid, 'int')
cmtid = wash_url_argument(cmtid, 'int')
errors = []
if __check_user_can_perform_action(uid, bskid, cfg_webbasket_share_levels['DELCMT']):
delete_comment(bskid, recid, cmtid)
else:
errors.append('ERR_WEBBASKET_NO_RIGHTS')
return errors
def perform_request_add(uid, recid=[], bskid=[], referer='',
new_basket_name='', new_topic_name='', create_in_topic='',
ln=cdslang):
"""Add records to baskets
@param uid: user id
@param recid: list of records to add
@param bskid: list of baskets to add records to. if not provided, will return a
page where user can select baskets
@param referer: URL of the referring page
@param ln: language
@return (body, errors, warnings) tuple
"""
uid = wash_url_argument(uid, 'int')
recid = wash_url_argument(recid, 'list')
bskid = wash_url_argument(bskid, 'list')
referer = wash_url_argument(referer, 'str')
new_basket_name = wash_url_argument(new_basket_name, 'str')
new_topic_name = wash_url_argument(new_topic_name, 'str')
create_in_topic = wash_url_argument(create_in_topic, 'str')
ln = wash_language(ln)
body = ''
errors = []
warnings = []
if not(len(recid)):
warnings.append('WRN_WEBBASKET_NO_RECORD')
body += webbasket_templates.tmpl_warnings(warnings, ln)
if referer and not(referer.find(weburl) == -1):
body += webbasket_templates.tmpl_back_link(referer, ln)
return (body, errors, warnings)
if new_basket_name != '':
topic = new_topic_name
if create_in_topic not in ('','0'):
topic = create_in_topic
if topic:
id_bsk = create_basket(uid, new_basket_name, topic)
bskid.append(id_bsk)
if len(bskid):
# save
nb_modified_baskets = add_to_basket(uid, recid, bskid)
body = webbasket_templates.tmpl_added_to_basket(nb_modified_baskets, ln)
body += webbasket_templates.tmpl_back_link(referer, ln)
else:
# Display basket_selection
personal_baskets = get_all_personal_baskets_names(uid)
group_baskets = get_all_group_baskets_names(uid)
external_baskets = get_all_external_baskets_names(uid)
body = webbasket_templates.tmpl_add(recids=recid,
personal_baskets=personal_baskets,
group_baskets=group_baskets,
external_baskets=external_baskets,
topics=get_personal_topics(uid), #topics
referer=referer,
ln=ln)
body += webbasket_templates.tmpl_back_link(referer, ln)
return (body, errors, warnings)
def perform_request_delete(uid, bskid, confirmed=0,
category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group_id=0,
ln=cdslang):
"""Delete a given basket.
@param uid: user id (user has to be owner of this basket)
@param bskid: basket id
@param confirmed: if 0 will return a confirmation page; if 1 will delete it.
@param category: category currently displayed
@param selected_topic: topic currently displayed
@param selected_group id: if category is group, id of the group currently displayed
@param ln: language
"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
confirmed = wash_url_argument(confirmed, 'int')
category = wash_url_argument(category, 'str')
selected_topic = wash_url_argument(selected_topic, 'int')
selected_group_id = wash_url_argument(selected_group_id, 'int')
ln = wash_language(ln)
body = ''
errors = []
warnings = []
if not(check_user_owns_baskets(uid, [bskid])):
errors.append(('ERR_WEBBASKET_NO_RIGHTS',))
return (body, errors, warnings)
if confirmed:
success = delete_basket(bskid)
if not success:
errors.append(('ERR_WEBBASKET_DB_ERROR',))
else:
body = webbasket_templates.tmpl_confirm_delete(bskid,
count_subscribers(uid, bskid),
category,
selected_topic, selected_group_id,
ln)
return (body, errors, warnings)
def delete_record(uid, bskid, recid):
"""Delete a given record in a given basket.
@param uid: user id (user has to have sufficient rights on basket
@param bskid: basket id
@param recid: record id
"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
recid = wash_url_argument(recid, 'int')
if __check_user_can_perform_action(uid, bskid, cfg_webbasket_share_levels['DELITM']):
delete_item(bskid, recid)
def perform_request_move(uid, bskids,
selected_topic=-1, new_topic_name='',
ln=cdslang):
"""Move given baskets into new topic.
@param uid: user id (user has to be owner of baskets he wants to move)
@param bskids: list of basket ids
@param selected_topic: topic currently displayed
@param new_topic_name: name for topic in which to put the baskets
@param ln: language
"""
uid = wash_url_argument(uid, 'int')
bskids = wash_url_argument(bskids, 'list')
selected_topic = wash_url_argument(selected_topic, 'int')
new_topic_name = wash_url_argument(new_topic_name, 'str')
ln = wash_language(ln)
body = ''
errors = []
warnings = []
if new_topic_name:
if check_user_owns_baskets(uid, bskids):
move_baskets_to_topic(uid, bskids, new_topic_name)
# do not move the next line above,because of side effects!
topics = get_personal_topics(uid)
try:
topics = zip(topics, range(len(topics)))
topic = [elt[1] for elt in topics if elt[0][0] == new_topic_name][0]
except:
errors.append(('ERR_WEBBASKET_DB_ERROR'))
topic = 0
else:
topic = 0
errors.append(('ERR_WEBBASKET_NOT_OWNER'))
return (topic, errors)
elif selected_topic != -1:
if check_user_owns_baskets(uid, bskids):
topics = get_personal_topics(uid)
try:
new_topic_name = topics[selected_topic][0]
move_baskets_to_topic(uid, bskids, topics[selected_topic][0])
topics = get_personal_topics(uid)
topics = zip(topics, range(len(topics)))
topic = [elt[1] for elt in topics if elt[0][0] == new_topic_name][0]
except:
errors.append(('ERR_WEBBASKET_DB_ERROR'))
topic = 0
else:
topic = 0
errors.append(('ERR_WEBBASKET_NOT_OWNER'))
return (topic, errors)
else:
topics = get_personal_topics(uid)
body = webbasket_templates.tmpl_move(bskids, topics, ln)
return (body, errors, warnings)
def move_record(uid, bskid, recid, direction):
"""Move a record up or down in a basket (change score).
@param uid: user id (user has to have manage rights over this basket)
@param bskid: basket id
@param recid: record we want to move
@param direction: cfg_webbasket_actions['UP'] or cfg_webbasket_actions['DOWN'] (default)
"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
recid = wash_url_argument(recid, 'int')
direction = wash_url_argument(direction, 'str')
if __check_user_can_perform_action(uid, bskid, cfg_webbasket_share_levels['MANAGE']):
move_item(bskid, recid, direction)
def perform_request_manage_rights(uid, bskid, topic=0,
groups={}, external='', ln=cdslang):
"""Interface for management of rights. If groups or external is provided, will save new
rights into database, else will provide interface.
@param uid: user id (user has to have sufficient rights on this basket
@param bskid: basket id to change rights on
@param topic: topic currently used
@param groups: dictionary of {usergroup id: new rights}
@param external: rights for everybody (can be 'NO')
@param ln: language
"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
topic = wash_url_argument(topic, 'int')
if not(type(groups) is dict):
groups = {}
external = wash_url_argument(external, 'str')
ln = wash_language(ln)
body = ''
errors = []
warnings = []
rights = get_max_user_rights_on_basket(uid, bskid)
if rights != cfg_webbasket_share_levels['MANAGE']:
errors.append(('ERR_WEBBASKET_NO_RIGHTS',))
return (body, errors, warnings)
if not(groups) and not(external):
bsk_name = get_basket_name(bskid)
groups_rights = get_groups_subscribing_to_basket(bskid)
external_rights = ''
if groups_rights and groups_rights[0][0] == 0:
external_rights = groups_rights[0][2]
groups_rights = groups_rights[1:]
body = webbasket_templates.tmpl_manage_rights(bskid, bsk_name,
groups_rights, external_rights,
topic, ln)
else:
groups['0'] = external
update_rights(bskid, groups)
return (body, errors, warnings)
def perform_request_add_group(uid, bskid, topic=0, group_id=0, ln=cdslang):
"""If group id is specified, share basket bskid to this group;
else return a page for selection of a group.
@param uid: user id (selection only of groups user is member of)
@param bskid: basket id
@param topic: topic currently displayed
@param ln: language
"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
group_id = wash_url_argument(group_id, 'int')
topic = wash_url_argument(topic, 'int')
ln = wash_language(ln)
if group_id:
share_basket_with_group(bskid, group_id, cfg_webbasket_share_levels['READITM'])
else:
groups = get_groups_user_member_of(uid)
body = webbasket_templates.tmpl_add_group(bskid, topic, groups, ln)
return body
def perform_request_create_basket(uid,
new_basket_name='',
new_topic_name='', create_in_topic=-1, topic_number=-1,
ln=cdslang):
"""if new_basket_name and topic infos are given create a basket and return topic number,
else return (body, errors, warnings) tuple of basket creation form.
@param uid: user id (int)
@param new_basket_name: name of the basket to create (str)
@param new_topic_name: name of new topic to create new basket in (str)
@param create_in_topic: identification number of topic to create new basket in (int)
@param topic_number: number of topic to preselect on the creation form.
@pram ln: language
"""
uid = wash_url_argument(uid, 'int')
new_basket_name = wash_url_argument(new_basket_name, 'str')
new_topic_name = wash_url_argument(new_topic_name, 'str')
create_in_topic = wash_url_argument(create_in_topic, 'int')
topic_number = wash_url_argument(topic_number, 'int')
ln = wash_language(ln)
if new_basket_name and (new_topic_name or create_in_topic != -1):
if new_topic_name:
topic = new_topic_name
else:
topics = get_personal_topics(uid)
try:
topic = topics[create_in_topic][0]
except IndexError:
return 0
create_basket(uid, new_basket_name, topic)
topics_list = map(lambda x: x[0], get_personal_topics(uid))
try:
return topics_list.index(topic)
except ValueError:
return 0
else:
topics = get_personal_topics(uid)
if topic_number > -1 and topic_number < len(topics):
create_in_topic = topics[topic_number]
body = webbasket_templates.tmpl_create_basket(new_basket_name,
new_topic_name, create_in_topic,
topics,
ln)
return (body, [], [])
def perform_request_display_public(bskid=0, of='hb', ln=cdslang):
"""return html representation of a public basket """
bskid = wash_url_argument(bskid, 'int')
of = wash_url_argument(of, 'str')
ln = wash_language(ln)
_ = gettext_set_language(ln)
body = ''
errors = []
warnings = []
basket = get_public_basket_infos(bskid)
if of[0]=='x':
items = []
if len(basket) == 7:
content = get_basket_content(bskid)
for item in content:
items.append(print_record(item[0], of))
return webbasket_templates.tmpl_xml_basket(items)
if len(basket) == 7:
items = get_basket_content(bskid)
last_cmt = _("N/A")
records = []
cmt_dates = []
for (recid, nb_cmt, last_cmt, ext_val, int_val, score) in items:
cmt_dates.append(convert_datetext_to_datestruct(last_cmt))
last_cmt = convert_datetext_to_dategui(last_cmt, ln)
val = ''
if recid < 0:
if ext_val:
val = decompress(ext_val)
else:
if int_val:
val = decompress(int_val)
records.append((recid, nb_cmt, last_cmt, val, score))
body = webbasket_templates.tmpl_display_public(basket, records, ln)
else:
errors.append('ERR_WEBBASKET_RESTRICTED_ACCESS')
return (body, errors, warnings)
def perform_request_subscribe(uid, bskid):
"""subscribe to external basket bskid"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
errors = []
if is_public(bskid):
subscribe(uid, bskid)
else:
errors.append('ERR_WEBBASKET_RESTRICTED_ACCESS')
return errors
def perform_request_unsubscribe(uid, bskid):
"""unsubscribe to external basket bskid"""
uid = wash_url_argument(uid, 'int')
bskid = wash_url_argument(bskid, 'int')
unsubscribe(uid, bskid)
def __check_user_can_comment(uid, bskid):
""" Private function. check if a user can comment """
min_right = cfg_webbasket_share_levels['ADDCMT']
rights = get_max_user_rights_on_basket(uid, bskid)
if rights:
if cfg_webbasket_share_levels_ordered.index(rights) >= cfg_webbasket_share_levels_ordered.index(min_right):
return 1
return 0
def __check_user_can_perform_action(uid, bskid, rights):
""" Private function, check if a user has sufficient rights"""
min_right = rights
rights = get_max_user_rights_on_basket(uid, bskid)
if rights:
if cfg_webbasket_share_levels_ordered.index(rights) >= cfg_webbasket_share_levels_ordered.index(min_right):
return 1
return 0
def __check_sufficient_rights(rights_user_has, rights_needed):
"""Private function, check if the rights are sufficient."""
try:
out = cfg_webbasket_share_levels_ordered.index(rights_user_has) >= cfg_webbasket_share_levels_ordered.index(rights_needed)
except ValueError:
out = 0
return out
def create_guest_warning_box(ln=cdslang):
"""return a warning message about logging into system"""
ln = wash_language(ln)
return webbasket_templates.tmpl_create_guest_warning_box(ln)
def create_personal_baskets_selection_box(uid,
html_select_box_name='baskets',
selected_bskid=None,
ln=cdslang):
"""Return HTML box for basket selection. Only for personal baskets.
@param uid: user id
@param html_select_box_name: name used in html form
@param selected_bskid: basket currently selected
@param ln: language
"""
baskets = get_all_personal_baskets_names(uid)
return webbasket_templates.tmpl_personal_baskets_selection_box(baskets,
html_select_box_name,
selected_bskid,
ln)
def create_basket_navtrail(uid,
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
bskid=0, ln=cdslang):
"""display navtrail for basket navigation.
@param uid: user id (int)
@param category: selected category (see cfg_webbasket_categories)
@param topic: selected topic # if personal baskets
@param group: selected group id for displaying (int)
@param bskid: basket id (int)
@param ln: language"""
uid = wash_url_argument(uid, 'int')
category = wash_url_argument(category, 'str')
topic = wash_url_argument(topic, 'int')
group = wash_url_argument(group, 'int')
bskid = wash_url_argument(bskid, 'int')
ln = wash_language(ln)
_ = gettext_set_language(ln)
out = ''
if category == cfg_webbasket_categories['PRIVATE']:
out += ' &gt; <a class="navtrail" href="%s/yourbaskets.py/display?%s">%s</a>'
out %= (weburl, 'category=' + category + '&amp;ln=' + ln, _("Personal baskets"))
topics = get_personal_topics(uid)
if 0 <= topic < len(topics):
out += ' &gt; '
out += '<a class="navtrail" href="%s/yourbaskets.py/display?%s">%s</a>'
out %= (weburl,
'category=' + category + '&amp;topic=' + str(topic) + '&amp;ln=' + ln,
topics[topic][0])
if bskid:
basket = get_public_basket_infos(bskid)
if basket:
out += ' &gt; '
out += '<a class="navtrail" href="%s/yourbaskets.py/display?%s">%s</a>'
out %= (weburl,
'category=' + category + '&amp;topic=' + str(topic) + \
'&amp;ln=' + ln + '#bsk' + str(bskid),
basket[1])
elif category == cfg_webbasket_categories['GROUP']:
out += ' &gt; <a class="navtrail" href="%s/yourbaskets.py/display?%s">%s</a>'
out %= (weburl, 'category=' + category + '&amp;ln=' + ln, _("Group baskets"))
groups = get_group_infos(uid)
if group:
groups = filter(lambda x: x[0]==group, groups)
if len(groups):
out += ' &gt; '
out += '<a class="navtrail" href="%s/yourbaskets.py/display?%s">%s</a>'
out %= (weburl,
'category=' + category + '&amp;group=' + str(group) + '&amp;ln=' + ln,
groups[0][1])
if bskid:
basket = get_public_basket_infos(bskid)
if basket:
out += ' &gt; '
out += '<a class="navtrail" href="%s/yourbaskets.py/display?%s"">%s</a>'
out %= (weburl,
'category=' + category + '&amp;group=' + str(group) + \
'&amp;ln=' + ln + '#bsk' + str(bskid),
basket[1])
elif category == cfg_webbasket_categories['EXTERNAL']:
out += ' &gt; <a class="navtrail" href="%s/yourbaskets.py/display?%s">%s</a>'
out %= (weburl, 'category=' + category + '&amp;ln=' + ln, _("Other's baskets"))
if bskid:
basket = get_public_basket_infos(bskid)
if basket:
out += ' &gt; '
out += '<a class="navtrail" href="%s/yourbaskets.py/display?%s"">%s</a>'
out %= (weburl,
'category=' + category + '&amp;ln=' + ln + '#bsk' + str(bskid),
basket[1])
return out
def account_list_baskets(uid, ln=cdslang):
"""Display baskets informations on account page"""
ln = wash_language(ln)
uid = wash_url_argument(uid, 'int')
_ = gettext_set_language(ln)
(personal, group, external) = count_baskets(uid)
link = '<a href="%s">%s</a>'
base_url = weburl + '/yourbaskets.py/display?category=%s&amp;ln=' + ln
personal_text = _("%i personal baskets") % personal
if personal:
url = base_url % cfg_webbasket_categories['PRIVATE']
personal_text = link % (url, personal_text)
group_text = _("%i group baskets") % group
if group:
url = base_url % cfg_webbasket_categories['GROUP']
group_text = link % (url, group_text)
external_text = _("%i other's baskets") % external
if external:
url = base_url % cfg_webbasket_categories['EXTERNAL']
external_text = link % (url, external_text)
out = _("You have %s and are subscribed to %s and %s.") % (personal_text,
group_text,
external_text)
return out
diff --git a/modules/webbasket/lib/webbasket_config.py b/modules/webbasket/lib/webbasket_config.py
index f2a498320..37b92a742 100644
--- a/modules/webbasket/lib/webbasket_config.py
+++ b/modules/webbasket/lib/webbasket_config.py
@@ -1,59 +1,59 @@
# -*- coding: utf-8 -*-
## $Id$
##
## Every db-related function of module webmessage
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
cfg_webbasket_share_levels = {'READITM': 'RI',
'READCMT': 'RC',
'ADDCMT': 'AC',
'ADDITM': 'AI',
'DELCMT': 'DC',
'DELITM': 'DI',
'MANAGE': 'MA'
}
cfg_webbasket_share_levels_ordered = [cfg_webbasket_share_levels['READITM'],
cfg_webbasket_share_levels['READCMT'],
cfg_webbasket_share_levels['ADDCMT'],
cfg_webbasket_share_levels['ADDITM'],
cfg_webbasket_share_levels['DELCMT'],
cfg_webbasket_share_levels['DELITM'],
cfg_webbasket_share_levels['MANAGE']]
cfg_webbasket_categories = {'PRIVATE': 'P',
'GROUP': 'G',
'EXTERNAL': 'E'}
cfg_webbasket_actions = {'DELETE': 'delete',
'UP': 'moveup',
'DOWN': 'movedown',
'COPY': 'copy'}
cfg_webbasket_warning_messages = {
'ERR_WEBBASKET_CMTID_INVALID': '_("%i is an invalid comment ID")',
'WRN_WEBBASKET_NO_RECORD': '_("No records to add")'
}
cfg_webbasket_error_messages = {
'ERR_WEBBASKET_CANNOT_COMMENT': '_("Sorry, you can\'t post in this baket")',
'ERR_WEBBASKET_DB_ERROR': '_("Sorry there was an error with the database")',
'ERR_WEBBASKET_NO_RIGHTS': '_("Sorry, you don\'t have sufficient rights on this basket")',
'ERR_WEBBASKET_UNDEFINED_ACTION': '_("Sorry, no such action exists")',
'ERR_WEBBASKET_NOT_OWNER': '_("You are not owner of this basket")',
'ERR_WEBBASKET_RESTRICTED_ACCESS': '_("This basket is not publicly accessible")'
}
diff --git a/modules/webbasket/lib/webbasket_dblayer.py b/modules/webbasket/lib/webbasket_dblayer.py
index 08012ad97..78e56e21a 100644
--- a/modules/webbasket/lib/webbasket_dblayer.py
+++ b/modules/webbasket/lib/webbasket_dblayer.py
@@ -1,909 +1,909 @@
# -*- coding: utf-8 -*-
## $Id$
##
## Every db-related function of module webmessage
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Database related functions for webbasket module """
from MySQLdb import escape_string
from zlib import decompress
from time import localtime
from cdsware.dbquery import run_sql
from cdsware.webbasket_config import cfg_webbasket_share_levels, \
cfg_webbasket_actions, \
cfg_webbasket_share_levels_ordered
from cdsware.dateutils import convert_datestruct_to_datetext
########################### Table of contents ################################
#
# NB. functions preceeded by a star use usergroup table
#
# 1. General functions
# - count_baskets
# - check_user_owns_basket
# - get_max_user_rights_on_basket
#
# 2. Personal baskets
# - get_personal_baskets_infos
# - get_all_personal_baskets_names
# - get_basket_name
# - get_personal_topics
# - rename_topic
# - move_baskets_to_topic
# - delete_basket
# - create_basket
#
# 3. Actions on baskets
# - get_basket_record
# - share_basket_with_group
# - update_rights
# - move_item
# - delete_item
# - add_to_basket
# - get_basket_content
#
# 4. Group baskets
# - get_group_basket_infos
# - (*) get_all_group_baskets_names
# - is_shared_to
#
# 5. External baskets (baskets user has subscribed to)
# - get_external_baskets_infos
# - count_external_baskets
# - get_all_external_baskets_names
#
# 6. Public baskets (interface to subscribe to baskets)
# - get_public_basket_infos
# - get_basket_general_infos
# - subscribe
# - unsubscribe
# - count_subscribers
# - (*) get_groups_subscribing_to_basket
#
# 7. Commenting
# - get_comments
# - get_comment
# - save_comment
# - delete_comment
#
# 8. Usergroup functions
# - (*) get_group_infos
# - count_groups_user_member_of
# - (*) get_groups_user_member_of
#
# 9. Useful functions
# - __wash_count
# - __decompress_last
#
########################## General functions ##################################
def count_baskets(uid):
"""Return (nb personal baskets, nb group baskets, nb external
baskets) tuple for given user"""
query1 = "SELECT COUNT(id) FROM bskBASKET WHERE id_owner=%i"
res1 = run_sql(query1 % int(uid))
personal = __wash_count(res1)
query2 = """SELECT count(ugbsk.id_bskbasket)
FROM usergroup_bskBASKET ugbsk LEFT JOIN user_usergroup uug
ON ugbsk.id_usergroup=uug.id_usergroup
WHERE uug.id_user=%i
GROUP BY ugbsk.id_usergroup"""
res2 = run_sql(query2 % int(uid))
if len(res2):
groups = reduce(lambda x, y: x + y, map(lambda x: x[0], res2))
else:
groups = 0
external = count_external_baskets(uid)
return (personal, groups, external)
def check_user_owns_baskets(uid, bskids):
""" Return 1 if user is owner of every basket in list bskids"""
if not(type(bskids) is list or type(bskids is tuple)):
bskids = [bskids]
query = """SELECT id_owner FROM bskBASKET WHERE %s GROUP BY id_owner"""
sep = ' OR '
query %= sep.join(map(lambda x: 'id=%i'% int(x), bskids))
res = run_sql(query)
if len(res)==1 and int(res[0][0])==uid:
return 1
else:
return 0
def get_max_user_rights_on_basket(uid, bskid):
"""Return the max rights a user has on this basket"""
query_owner = "SELECT count(id_owner) FROM bskBASKET WHERE id_owner=%i and id=%i"
params_owner = (int(uid), int(bskid))
res = run_sql(query_owner % params_owner)
if res and res[0][0]:
# if this user is owner of this baskets he can do anything he wants.
return cfg_webbasket_share_levels['MANAGE']
# not owner => group member ?
query_group_baskets = """
SELECT share_level
FROM user_usergroup AS ug LEFT JOIN usergroup_bskBASKET AS ub
ON ug.id_usergroup=ub.id_usergroup
WHERE ug.id_user=%i AND ub.id_bskBASKET=%i AND NOT(ub.share_level='NO')
"""
max_rights_index = None
params_group_baskets = (uid, bskid)
res = run_sql(query_group_baskets % params_group_baskets)
if res:
group_rights = res[0][0]
try:
max_rights_index = cfg_webbasket_share_levels_ordered.index(group_rights)
except ValueError:
return None
# public basket ?
query_public_baskets = """
SELECT share_level
FROM usergroup_bskBASKET
WHERE id_usergroup=0 AND id_bskBASKET=%i
"""
res = run_sql(query_public_baskets % bskid)
if res:
public_rights = res[0][0]
try:
index = cfg_webbasket_share_levels_ordered.index(public_rights)
if index > max_rights_index:
return cfg_webbasket_share_levels_ordered[index]
else:
return cfg_webbasket_share_levels_ordered[max_rights_index]
except ValueError:
return None
########################### Personal baskets ##################################
def get_personal_baskets_infos(uid, topic):
"""
Get useful infos (see below) for every personal basket of a given user in a given topic
share level is assumed to be MA (MAnage) for a personal basket!
@param uid: user id (int)
@param topic: topic of the basket
@return a tuple of (id,
name,
share_level,
date_modification
nb_views) tuples
"""
query = """
SELECT bsk.id,
bsk.name,
DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
bsk.nb_views,
count(rec.id_bibrec_or_bskEXTREC),
DATE_FORMAT(max(rec.date_added), '%%Y-%%m-%%d %%H:%%i:%%s')
FROM bskBASKET bsk JOIN user_bskBASKET ubsk
ON (bsk.id=ubsk.id_bskBASKET AND
ubsk.id_user=%i AND
bsk.id_owner=%i)
LEFT JOIN bskREC rec
ON (bsk.id=rec.id_bskBASKET)
WHERE ubsk.topic='%s'
GROUP BY bsk.id
"""
uid = int(uid)
topic = escape_string(topic)
res = run_sql(query%(uid, uid, topic))
if res:
return res
return ()
def get_all_personal_baskets_names(uid):
""" for a given user, returns every basket he is owner of
returns list of tuples: (bskid, bsk_name, topic)
"""
query = """
SELECT bsk.id,
bsk.name,
ubsk.topic
FROM user_bskBASKET ubsk JOIN bskBASKET bsk
ON ubsk.id_bskBASKET=bsk.id
AND ubsk.id_user=bsk.id_owner
WHERE bsk.id_owner=%i
ORDER BY ubsk.topic
"""
params = (uid)
return run_sql(query % params)
def get_basket_name(bskid):
"""return the name of a given basket"""
query = 'SELECT name FROM bskBASKET where id=%i'
res = run_sql(query % int(bskid))
if res:
return res[0][0]
else:
return ''
def get_personal_topics(uid):
"""
Get the list of every topic user has defined,
and the number of baskets in each topic
@param uid: user id (int)
@return a tuple of topics
"""
query = """SELECT topic, count(b.id)
FROM user_bskBASKET ub JOIN bskBASKET b
ON ub.id_bskBASKET=b.id AND
b.id_owner=ub.id_user
WHERE ub.id_user=%i
GROUP BY topic
ORDER BY topic"""
uid = int(uid)
res = run_sql(query% uid)
return res
def rename_topic(uid, old_topic, new_topic):
"""Rename topic to new_topic """
query = "UPDATE user_bskBASKET SET topic='%s' WHERE id_user=%i AND topic='%s'"
params = (escape_string(new_topic), int(uid), escape_string(old_topic))
res = run_sql(query % params)
return res
def move_baskets_to_topic(uid, bskids, new_topic):
"""Move given baskets to another topic"""
if not(type(bskids) is list or type(bskids is tuple)):
bskids = [bskids]
query = "UPDATE user_bskBASKET SET topic='%s' WHERE id_user=%i AND (%s)"
sep = ' OR '
where_clause = sep.join(map(lambda x: 'id_bskBASKET=%i' % int(x), bskids))
query %= (escape_string(new_topic), int(uid), where_clause)
res = run_sql(query)
return res
def delete_basket(bskid):
"""Delete given basket. """
bskid = int(bskid)
query1 = "DELETE FROM bskBASKET WHERE id=%i"
res = run_sql(query1 % bskid)
query2 = "DELETE FROM bskREC WHERE id_bskBASKET=%i"
run_sql(query2 % bskid)
query3 = "DELETE FROM bskRECORDCOMMENT WHERE id_bskBASKET=%i"
run_sql(query3 % bskid)
query4 = "DELETE FROM user_bskBASKET WHERE id_bskBASKET=%i"
run_sql(query4 % bskid)
query5 = "DELETE FROM usergroup_bskBASKET WHERE id_bskBASKET=%i"
run_sql(query5 % bskid)
query6 = "DELETE FROM user_query_basket WHERE id_basket=%i"
run_sql(query6 % bskid)
#delete group, external and alerts
return int(res)
def create_basket(uid, basket_name, topic):
"""Create new basket for given user in given topic"""
now = convert_datestruct_to_datetext(localtime())
query1 = """INSERT INTO bskBASKET (id_owner, name, date_modification)
VALUES (%i, '%s', '%s')"""
params1 = (uid, escape_string(basket_name), now)
res = run_sql(query1 % params1)
id_bsk = int(res)
query2 = """INSERT INTO user_bskBASKET (id_user, id_bskBASKET, topic)
VALUES (%i, %i, '%s')"""
params2 = (uid, id_bsk, escape_string(topic))
run_sql(query2 % params2)
return id_bsk
########################## Actions on baskets #################################
def get_basket_record(bskid, recid, format='hb'):
"""get record recid in basket bskid
"""
if recid < 0:
rec_table = 'bskEXTREC'
format_table = 'bskEXTFMT'
id_field = 'id_bskEXTREC'
sign = '-'
else:
rec_table = 'bibrec'
format_table = 'bibfmt'
id_field = 'id_bibrec'
sign = ''
query = """
SELECT DATE_FORMAT(record.creation_date, '%%Y-%%m-%%d %%H:%%i:%%s'),
DATE_FORMAT(record.modification_date, '%%Y-%%m-%%d %%H:%%i:%%s'),
DATE_FORMAT(bskREC.date_added, '%%Y-%%m-%%d %%H:%%i:%%s'),
user.nickname,
count(cmt.id_bibrec_or_bskEXTREC),
DATE_FORMAT(max(cmt.date_creation), '%%Y-%%m-%%d %%H:%%i:%%s'),
fmt.value
FROM bskREC LEFT JOIN user
ON bskREC.id_user_who_added_item=user.id
LEFT JOIN bskRECORDCOMMENT cmt
ON bskREC.id_bibrec_or_bskEXTREC=cmt.id_bibrec_or_bskEXTREC
LEFT JOIN %(rec_table)s record
ON (%(sign)sbskREC.id_bibrec_or_bskEXTREC=record.id)
LEFT JOIN %(format_table)s fmt
ON (record.id=fmt.%(id_field)s)
WHERE bskREC.id_bskBASKET=%(bskid)i AND
bskREC.id_bibrec_or_bskEXTREC=%(recid)s AND
fmt.format='%(format)s'
GROUP BY bskREC.id_bibrec_or_bskEXTREC
"""
params = {'rec_table': rec_table,
'format_table': format_table,
'sign': sign,
'bskid': int(bskid),
'recid': int(recid),
'format': escape_string(format),
'id_field': id_field}
res = run_sql(query%params)
if res:
return __decompress_last(res[0])
return ()
def share_basket_with_group(bskid, group_id,
share_level=cfg_webbasket_share_levels['READITM']):
""" Share basket bskid with group group_id with given share_level
@param share_level: see cfg_webbasket_share_levels in webbasket_config
"""
now = convert_datestruct_to_datetext(localtime())
query = """REPLACE INTO usergroup_bskBASKET
(id_usergroup, id_bskBASKET, date_shared, share_level)
VALUES (%i,%i,'%s','%s')"""
run_sql(query % (int(group_id), int(bskid), now, escape_string(str(share_level))))
def update_rights(bskid, group_rights):
"""update rights (permissions) for groups.
@param bskid: basket id
@param group_rights: dictionary of {group id: new rights}
"""
now = convert_datestruct_to_datetext(localtime())
query1 = """REPLACE INTO usergroup_bskBASKET
(id_usergroup, id_bskBASKET, date_shared, share_level)
VALUES %s"""
values = []
for (group_id, share_level) in group_rights.items():
values.append("(%i,%i,'%s','%s')" % (int(group_id), int(bskid), now, str(share_level)))
sep = ','
values = sep.join(values)
run_sql(query1 % values)
query2 = """DELETE FROM usergroup_bskBASKET WHERE share_level='NO'"""
run_sql(query2)
def move_item(bskid, recid, direction):
"""Change score of an item in a basket"""
query1 = """SELECT id_bibrec_or_bskEXTREC,
score
FROM bskREC
WHERE id_bskBASKET=%i
ORDER BY score, date_added"""
items = run_sql(query1 % bskid)
(recids, scores) = zip(*items)
(recids, scores) = (list(recids), list(scores))
if len(recids) and recid in recids:
current_index = recids.index(recid)
if direction == cfg_webbasket_actions['UP']:
switch_index = 0
if current_index != 0:
switch_index = current_index -1
else:
switch_index = len(recids) - 1
if current_index != len(recids)-1:
switch_index = current_index + 1
query2 = """UPDATE bskREC
SET score=%i
WHERE id_bskBASKET=%i AND id_bibrec_or_bskEXTREC=%i"""
res1 = run_sql(query2 % (scores[switch_index], bskid, recids[current_index]))
res2 = run_sql(query2 % (scores[current_index], bskid, recids[switch_index]))
if res1 and res2:
now = convert_datestruct_to_datetext(localtime())
query3 = "UPDATE bskBASKET SET date_modification='%s' WHERE id=%i"
params3 = (now, bskid)
run_sql(query3 % params3)
def delete_item(bskid, recid):
"""Remove item recid from basket bskid"""
query1 = "DELETE from bskREC WHERE id_bskBASKET=%i AND id_bibrec_or_bskEXTREC=%i"
params1 = (int(bskid), int(recid))
res = run_sql(query1 % params1)
if res:
now = convert_datestruct_to_datetext(localtime())
query2 = "UPDATE bskBASKET SET date_modification='%s' WHERE id=%i"
params2 = (now, bskid)
run_sql(query2 % params2)
return res
def add_to_basket(uid, recids=[], bskids=[]):
"""Add items recids to every basket in bskids list."""
if len(recids) and len(bskids):
query1 = """SELECT id_bskBASKET,
max(score)
FROM bskREC
WHERE %s
GROUP BY id_bskBASKET"""
sep_or = ' OR '
query1 %= sep_or.join(map(lambda x: 'id_bskBASKET=' + str(x), bskids))
bsks = dict.fromkeys(bskids, 0)
bsks.update(dict(run_sql(query1)))
query2 = """INSERT IGNORE
INTO bskREC
(id_bibrec_or_bskEXTREC,
id_bskBASKET,
id_user_who_added_item,
date_added,
score)
VALUES """
now = convert_datestruct_to_datetext(localtime())
records = []
for (bskid, max_score) in bsks.items():
i = 1
for recid in recids:
record = "(%i, %i, %i, '%s', %i)"
record %= (int(recid), int(bskid), int(uid), now, int(max_score) + i)
records.append(record)
i += 1
sep_comma = ','
run_sql(query2 + sep_comma.join(records))
query3 = """UPDATE bskBASKET
SET date_modification='%s'
WHERE """ % now
query3 += sep_or.join(map(lambda x: 'id=' + str(x), bskids))
run_sql(query3)
return len(bskids)
return 0
def get_basket_content(bskid, format='hb'):
"""Get all records for a given basket."""
query = """
SELECT rec.id_bibrec_or_bskEXTREC,
count(cmt.id_bibrec_or_bskEXTREC),
DATE_FORMAT(max(cmt.date_creation), '%%Y-%%m-%%d %%H:%%i:%%s'),
extern.value as ext_val,
intern.value as int_val,
rec.score
FROM bskREC rec LEFT JOIN bskRECORDCOMMENT cmt
ON (rec.id_bibrec_or_bskEXTREC=cmt.id_bibrec_or_bskEXTREC AND
rec.id_bskBASKET=cmt.id_bskBASKET)
LEFT JOIN bskEXTFMT extern
ON (-rec.id_bibrec_or_bskEXTREC=extern.id_bskEXTREC AND
extern.format='%(format)s')
LEFT JOIN bibfmt intern
ON (rec.id_bibrec_or_bskEXTREC=intern.id_bibrec AND
intern.format='%(format)s')
WHERE rec.id_bskBASKET=%(id)i
GROUP BY rec.id_bibrec_or_bskEXTREC
ORDER BY rec.score
"""
params = {'format': escape_string(format),
'id': int(bskid)}
res = run_sql(query% params)
if res:
query2 = "UPDATE bskBASKET SET nb_views=nb_views+1 WHERE id=%i"
run_sql(query2 % int(bskid))
return res
return ()
############################ Group baskets ####################################
def get_group_baskets_infos(gid):
"""
get useful infos (see below) for every basket of a group
@param gid: group id (int)
@return a tuple of (id,
name,
topic,
rigths,
date_shared,
date_modification,
nb_views) tuples
"""
if gid == 0:
return ()
query = """
SELECT bsk.id,
bsk.name,
DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
bsk.nb_views,
count(rec.id_bibrec_or_bskEXTREC),
DATE_FORMAT(max(rec.date_added), '%%Y-%%m-%%d %%H:%%i:%%s'),
ub.share_level,
bsk.id_owner
FROM bskBASKET bsk JOIN usergroup_bskBASKET ub
ON bsk.id=ub.id_bskBASKET
LEFT JOIN bskREC rec
ON bsk.id=rec.id_bskBASKET
WHERE ub.id_usergroup=%i AND NOT(ub.share_level='NO')
GROUP BY bsk.id
"""
gid = int(gid)
res = run_sql(query%gid)
if res:
return res
return ()
def get_all_group_baskets_names(uid,
min_rights=cfg_webbasket_share_levels['ADDCMT']):
""" for a given user returns every group baskets in which he can <min_rights>
return a list of tuples: (bskid, bsk_name, group_name)
"""
uid = int(uid)
try:
min_rights_num = cfg_webbasket_share_levels_ordered.index(min_rights)
except ValueError:
return ()
groups = get_groups_user_member_of(uid)
if groups:
where_clause = '('
for (group_id, group_name) in groups[:-1]:
where_clause += 'ugbsk.id_usergroup=%i OR ' % int(group_id)
where_clause += 'ugbsk.id_usergroup=%i)' % int(groups[-1][0])
where_clause += ' AND ('
for right in cfg_webbasket_share_levels_ordered[min_rights_num:-1]:
where_clause += "ugbsk.share_level = '%s' OR " % right
where_clause += "ugbsk.share_level = '%s')" % cfg_webbasket_share_levels_ordered[-1]
query = """
SELECT bsk.id,
bsk.name,
ug.name
FROM usergroup ug JOIN usergroup_bskBASKET ugbsk
ON ug.id=ugbsk.id_usergroup
JOIN bskBASKET bsk
ON bsk.id=ugbsk.id_bskBASKET
WHERE %s AND NOT(ugbsk.share_level='NO')
ORDER BY ug.name"""
return run_sql(query % where_clause)
return ()
def is_shared_to(bskids):
"""For each bskid in bskids get id of group.
"""
if not((type(bskids) == list) or (type(bskids) == tuple)):
bskids = [bskids]
query = """SELECT b.id,
min(u.id_usergroup)
FROM
bskBASKET b LEFT JOIN usergroup_bskBASKET u
ON (b.id=u.id_bskBASKET) """
if len(bskids) != 0:
query += " WHERE "
for bskid in bskids[:-1]:
query += "b.id=%i OR "% int(bskid)
query += "b.id=%i "% int(bskids[-1])
query += "GROUP BY b.id"
res = run_sql(query)
if res:
return res
return ()
########################## External baskets ###################################
def get_external_baskets_infos(uid):
"""Get general informations about every external basket user uid has subscribed to."""
query = """
SELECT bsk.id,
bsk.name,
DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
bsk.nb_views,
count(rec.id_bibrec_or_bskEXTREC),
DATE_FORMAT(max(rec.date_added), '%%Y-%%m-%%d %%H:%%i:%%s'),
ugbsk.share_level
FROM bskBASKET bsk JOIN user_bskBASKET ubsk
ON (bsk.id=ubsk.id_bskBASKET AND ubsk.id_user=%i)
LEFT JOIN bskREC rec
ON (bsk.id=rec.id_bskBASKET)
LEFT JOIN usergroup_bskBASKET ugbsk
ON (ugbsk.id_bskBASKET=bsk.id AND ugbsk.id_usergroup=0)
WHERE bsk.id_owner!=%i
GROUP BY bsk.id
"""
uid = int(uid)
params = (uid, uid)
res = run_sql(query%params)
if res:
return res
return ()
def count_external_baskets(uid):
"""return number of external baskets user has subscribed to"""
query = """
SELECT count(ubsk.id_bskBASKET)
FROM user_bskBASKET ubsk LEFT JOIN bskBASKET bsk
ON (bsk.id=ubsk.id_bskBASKET AND ubsk.id_user=%i)
WHERE bsk.id_owner!=%i
"""
return __wash_count(run_sql(query % (int(uid), int(uid))))
def get_all_external_baskets_names(uid,
min_rights=cfg_webbasket_share_levels['ADDCMT']):
""" for a given user returns every basket which he has subscribed to and in which
he can <min_rights>
return a list of tuples: (bskid, bsk_name)
"""
uid = int(uid)
try:
min_rights_num = cfg_webbasket_share_levels_ordered.index(min_rights)
except ValueError:
return ()
where_clause = ' AND ('
for right in cfg_webbasket_share_levels_ordered[min_rights_num:-1]:
where_clause += "ugbsk.share_level = '%s' OR " % right
where_clause += "ugbsk.share_level = '%s')" % cfg_webbasket_share_levels_ordered[-1]
query = """
SELECT bsk.id,
bsk.name
FROM bskBASKET bsk JOIN usergroup_bskBASKET ugbsk
ON bsk.id=ugbsk.id_bskBASKET
JOIN user_bskBASKET ubsk
ON ubsk.id_bskBASKET=bsk.id
WHERE ugbsk.id_usergroup=0 AND
ubsk.id_user=%i AND
NOT(bsk.id_owner=%i) AND
NOT(ugbsk.share_level='NO')
%s
"""
params = (uid, uid, where_clause)
return run_sql(query % params)
############################ Public access ####################################
def get_public_basket_infos(bskid):
"""return (id, name, date modification, nb of views, id of owner, nickname of owner, rights for public access)
for a given basket"""
basket = ()
query1 = """SELECT bsk.id,
bsk.name,
DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
bsk.nb_views,
bsk.id_owner,
user.nickname
FROM bskBASKET bsk LEFT JOIN user
ON bsk.id_owner=user.id
WHERE bsk.id=%i"""
res1 = run_sql(query1 % int(bskid))
if len(res1):
basket = list(res1[0])
query2 = """SELECT share_level
FROM usergroup_bskBASKET
WHERE id_usergroup=0 and id_bskBASKET=%i"""
res2 = run_sql(query2 % int(bskid))
if res2:
basket.append(res2[0][0])
else:
basket.append(None)
return basket
def get_basket_general_infos(bskid):
"""return information about a basket, suited for public access.
@return a (id, name, date of modification, nb of views, nb of records, id of owner) tuple
"""
query = """SELECT bsk.id,
bsk.name,
DATE_FORMAT(bsk.date_modification, '%%Y-%%m-%%d %%H:%%i:%%s'),
bsk.nb_views,
count(rec.id_bibrec_or_bskEXTREC),
bsk.id_owner
FROM bskBASKET bsk LEFT JOIN bskREC rec
ON bsk.id=rec.id_bskBASKET
WHERE bsk.id=%i
GROUP BY bsk.id"""
res = run_sql(query % int(bskid))
if res:
query2 = "UPDATE bskBASKET SET nb_views=nb_views+1 WHERE id=%i"
run_sql(query2 % int(bskid))
return res
return ()
def is_public(bskid):
"""return 1 if basket is public, 0 else."""
query = "SELECT count(id_usergroup) FROM usergroup_bskBASKET WHERE id_bskBASKET=%i AND id_usergroup=0"
return __wash_count(run_sql(query % int(bskid)))
def subscribe(uid, bskid):
"""user uid subscribes to basket bskid"""
query1 = "SELECT count(id_user) FROM user_bskBASKET WHERE id_user=%i AND id_bskBASKET=%i"
if not(__wash_count(run_sql(query1 % (int(uid), int(bskid))))):
query2 = "INSERT INTO user_bskBASKET (id_user, id_bskBASKET) VALUES (%i,%i)"
run_sql(query2 % (int(uid), int(bskid)))
def unsubscribe(uid, bskid):
"""unsubscribe to basket"""
query = "DELETE FROM user_bskBASKET WHERE id_user=%i AND id_bskBASKET=%i"
run_sql(query % (int(uid), int(bskid)))
def count_subscribers(uid, bskid):
""" Return a (number of users, number of groups, number of alerts) tuple """
query_groups = """SELECT count(id_usergroup)
FROM usergroup_bskBASKET
WHERE id_bskBASKET=%i and NOT(share_level='NO')
GROUP BY id_bskBASKET"""
nb_groups = __wash_count(run_sql(query_groups % bskid))
query_users = """SELECT count(id_user)
FROM user_bskBASKET
WHERE id_bskBASKET=%i AND id_user!=%i
GROUP BY id_bskBASKET"""
nb_users = __wash_count(run_sql(query_users % (bskid, uid)))
query_alerts = """SELECT count(id_query)
FROM user_query_basket
WHERE id_basket=%i
GROUP BY id_basket"""
nb_alerts = __wash_count(run_sql(query_alerts % bskid))
return (nb_users, nb_groups, nb_alerts)
def get_groups_subscribing_to_basket(bskid):
""" get list of (group id, group name, rights) tuples for a given basket
Please note that group 0 is used to mean everybody.
"""
query = """SELECT ugb.id_usergroup,
ug.name,
ugb.share_level
FROM usergroup_bskBASKET ugb LEFT JOIN usergroup ug
ON ugb.id_usergroup=ug.id
WHERE ugb.id_bskBASKET=%i
ORDER BY ugb.id_usergroup"""
return run_sql(query % int(bskid))
############################ Comments ########################################
def get_comments(bskid, recid):
"""Return all comments for record recid in basket bskid."""
out = ()
query = """
SELECT user.id,
user.nickname,
bskcmt.title,
bskcmt.body,
DATE_FORMAT(bskcmt.date_creation, '%%Y-%%m-%%d %%H:%%i:%%s'),
bskcmt.priority,
bskcmt.id
FROM bskRECORDCOMMENT bskcmt LEFT JOIN user
ON (bskcmt.id_user=user.id)
WHERE bskcmt.id_bskBASKET=%i AND
bskcmt.id_bibrec_or_bskEXTREC=%i
ORDER BY bskcmt.date_creation
"""
bskid = int(bskid)
recid = int(recid)
res = run_sql(query % (bskid, recid))
if res:
return res
return out
def get_comment(cmtid):
"""Return comment cmtid as a (author's nickname, author's uid, title, body, date of creation, priority) tuple"""
out = ()
query = """
SELECT user.nickname,
user.id,
bskcmt.title,
bskcmt.body,
DATE_FORMAT(bskcmt.date_creation, '%%Y-%%m-%%d %%H:%%i:%%s'),
bskcmt.priority
FROM bskRECORDCOMMENT bskcmt LEFT JOIN user
ON (bskcmt.id_user=user.id)
WHERE bskcmt.id=%i
"""
cmtid = int(cmtid)
res = run_sql(query % cmtid)
if res:
return res[0]
return out
def save_comment(uid, bskid, recid, title, body):
"""Save a given comment in table bskRECORDCOMMENT"""
date = convert_datestruct_to_datetext(localtime())
query = """
INSERT INTO bskRECORDCOMMENT
(id_user,
id_bskBASKET,
id_bibrec_or_bskEXTREC,
title,
body,
date_creation)
VALUES (%i, %i
, %i, '%s', '%s', '%s')"""
params = (uid, bskid, recid, escape_string(title), escape_string(body), date)
res = run_sql(query % params)
if res:
return int(res)
return 0
def delete_comment(bskid, recid, cmtid):
"""Delete a comment on an item of a basket"""
query = """DELETE FROM bskRECORDCOMMENT WHERE id_bskBASKET=%i AND id_bibrec_or_bskEXTREC=%i AND id=%i"""
run_sql(query % (int(bskid), int(recid), int(cmtid)))
########################## Usergroup functions ################################
def get_group_infos(uid):
"""Get for each group a user is member of its uid, name and number of baskets."""
query = """SELECT g.id,
g.name,
count(ugb.id_bskBASKET)
FROM usergroup g LEFT JOIN user_usergroup ug,
usergroup_bskBASKET ugb
ON (g.id=ug.id_usergroup
AND
g.id=ugb.id_usergroup)
WHERE ug.id_user=%i AND NOT(ugb.share_level='NO')
GROUP BY g.id
ORDER BY g.name"""
uid = int(uid)
res = run_sql(query% uid)
return res
def count_groups_user_member_of(uid):
"""Return number of groups user has joined."""
query = 'SELECT count(id_usergroup) FROM user_usergroup WHERE id_user=%i'
return __wash_count(run_sql(query % int(uid)))
def get_groups_user_member_of(uid):
"""
Get uids and names of groups user is member of.
@param uid: user id (int)
@return a tuple of (group_id, group_name) tuples
"""
query = """
SELECT g.id,
g.name
FROM usergroup g JOIN user_usergroup ug
ON (g.id=ug.id_usergroup)
WHERE ug.id_user=%i
ORDER BY g.name
"""
params = int(uid)
res = run_sql(query%params)
if res:
return res
return ()
########################## helpful functions ##################################
def __wash_count(res):
"""If query is like SELECT count(x) FROM y, return a washed version"""
if res:
return int(res[0][0])
else:
return 0
def __decompress_last(item):
"""private function, used to shorten code"""
item = list(item)
item[-1] = decompress(item[-1])
return item
diff --git a/modules/webbasket/lib/webbasket_templates.py b/modules/webbasket/lib/webbasket_templates.py
index 2307ecd8d..9771a4014 100644
--- a/modules/webbasket/lib/webbasket_templates.py
+++ b/modules/webbasket/lib/webbasket_templates.py
@@ -1,1368 +1,1368 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.messages import gettext_set_language
from cdsware.webbasket_config import cfg_webbasket_categories, \
cfg_webbasket_share_levels
from cdsware.webmessage_mailutils import email_quoted_txt2html, email_quote_txt
from cdsware.config import weburl, cdslang
from cdsware.textutils import indent_text
from cdsware.webuser import get_user_info
from cdsware.dateutils import convert_datetext_to_dategui
class Template:
######################## General interface ###############################
def tmpl_display(self,
topicsbox='',
baskets_infobox='',
baskets=[],
selected_category=cfg_webbasket_categories['PRIVATE'],
nb_groups=0,
nb_external_baskets=0,
ln=cdslang):
"""Generic display. takes formatted baskets, infobox and topicsbox,
add tabs and returns complete interface"""
_ = gettext_set_language(ln)
if type(baskets) not in (list, tuple):
baskets = [baskets]
tabs = self.__create_tabs(selected_category, nb_groups, nb_external_baskets, ln)
out = """
<div id="bskcontainer">
<div id="bsktabs">%s
</div>
<div id="bskcontent">""" % indent_text(tabs, 2)
if topicsbox:
out += indent_text(topicsbox, 6)
out += """
<div id="bskbaskets">"""
if baskets_infobox:
out += """
<div id="bskinfos">%s
</div>""" % indent_text(baskets_infobox, 5)
for basket in baskets:
out += indent_text(basket, 4)
out += """
</div>
</div>
</div>"""
return out
def __create_tabs(self,
selected_category=cfg_webbasket_categories['PRIVATE'],
nb_groups=0,
nb_external_baskets=0,
ln=cdslang):
"""private function, display tabs (private baskets, group baskets, other's basket)."""
_ = gettext_set_language(ln)
selected = ' id="bsktab_selected"'
private = cfg_webbasket_categories['PRIVATE']
group = cfg_webbasket_categories['GROUP']
external = cfg_webbasket_categories['EXTERNAL']
tab = """
<div class="bsktab"%(selected)s>
<img src="%(url)s/img/%(img)s" alt="%(label)s" />
<a href="%(url)s/yourbaskets.py/display?category=%(cat)s&amp;ln=%(ln)s">%(label)s</a>
</div>"""
out = tab % {'selected': selected_category == private and selected or '',
'url': weburl,
'img': 'webbasket_us.png',
'label': _("Personal baskets"),
'cat': private,
'ln': ln}
if nb_groups:
out += tab % {'selected': selected_category == group and selected or '',
'url': weburl,
'img': 'webbasket_ugs.png',
'label': _("Group baskets"),
'cat': group,
'ln': ln}
if nb_external_baskets:
out += tab % {'selected': selected_category == external and selected or '',
'url': weburl,
'img': 'webbasket_ws.png',
'label': _("Others' baskets"),
'cat': external,
'ln': ln}
return out
def tmpl_topic_selection(self,
topics_list=[],
selected_topic=0,
ln=cdslang):
"""Display the topics selection area which appears on the top of external baskets category.
@param topics_list: list of (topic name, number of baskets) tuples
@param selected_topic: # of selected topic in topics_list"""
category = cfg_webbasket_categories['PRIVATE']
if len(topics_list):
selected_topic = selected_topic <= len(topics_list) and selected_topic or 0
i = 0
out = ''
for (topic, number_of_baskets) in topics_list:
out += '<span class="bsktopic">'
topic_label = topic + ' (' + str(number_of_baskets) + ')'
if i != selected_topic:
topic_link = '%s/yourbaskets.py/display?category=%s&amp;topic=%i&amp;ln=%s'
topic_link %= (weburl, category, i, ln)
out += '<a href="%s">' % topic_link
out += topic_label + '</a>'
else:
out += topic_label
out += '</span> '
i += 1
out = """
<table id="bsktopics">
<tr>
<td>%s
</td>
</tr>
</table>""" % out
else:
out = self.tmpl_create_basket(ln=cdslang)
return out
def tmpl_group_selection(self,
groups_list=[],
selected_group_id=0,
ln=cdslang):
"""Display the group selection area which appears on the top of group baskets category.
@param groups_list: list of (group id, group name, number of baskets) tuples
@param selected_group id: id of group selected"""
out = ''
category = cfg_webbasket_categories['GROUP']
if len(groups_list):
for (group_id, group_name, number_of_baskets) in groups_list:
out += '<span class="bsktopic">'
group_label = group_name + ' (' + str(number_of_baskets) + ')'
if group_id != selected_group_id:
group_link = '%s/yourbaskets.py/display?category=%s&amp;group=%i&amp;ln=%s'
group_link %= (weburl, category, group_id, ln)
out += '<a href="%s">' % group_link
out += group_label + '</a>'
else:
out += group_label
out += '</span>'
out = """
<table id="bsktopics">
<tr>
<td>%s
</td>
</tr>
</table>""" % out
return out
def tmpl_baskets_infobox(self, basket_infos=[], create_link='', ln=cdslang):
"""
displays infos about baskets.
@param basket_infos: list of (bskid, bsk_name, bsk_last_update) tuples
@param create_link: link for the creation of basket (will appear next to descriptions)
@param ln: language
@return html as string
"""
_ = gettext_set_language(ln)
label = _("There are %i baskets") % len(basket_infos)
basket_list = ''
if len(basket_infos):
basket_list += '<ul>\n'
for (bskid, name, last_update) in basket_infos:
last_update = convert_datetext_to_dategui(last_update)
basket_list += '<li><a href="#bsk%i">%s</a> - ' % (bskid, name)
basket_list += _("updated on") + ' ' + last_update + '</li>\n'
basket_list += '</ul>'
if len(basket_infos) < 2:
label = ''
basket_list = ''
out = """
<table style="width: 100%%; vertical-align: top">
<tr>
<td style="vertical-align: top">%s</td>
<td>%s</td>
<td style="vertical-align: top">%s</td>
</tr>
</table>""" % (label, basket_list, create_link)
return out
def tmpl_display_public(self,
(bskid, bsk_name,
bsk_date_modification,bsk_nb_views,
bskid_owner, bsk_owner_nickname, bsk_share_level),
bsk_items=[],
ln=cdslang):
"""
Display public basketwith link to subscribe to it.
@param bsk_share_level is not currently used.
"""
_ = gettext_set_language(ln)
items_html = ''
if not(len(bsk_items)):
items_html = """
<tr>
<td colspan="3" style="text-align:center; height:100px">
%s
</td>
</tr>""" % _("Basket is empty")
for item in bsk_items:
items_html += self.__tmpl_basket_item(bskid=bskid, item=item, ln=ln)
if bsk_owner_nickname:
display = bsk_owner_nickname
else:
(bskid_owner, bsk_owner_nickname, display) = get_user_info(int(bskid_owner))
messaging_link = self.__create_messaging_link(bsk_owner_nickname, display, ln)
general_label = _("This basket belongs to %s. You can freely subscribe to it by using the link below.") % messaging_link
out = """
%(general_label)s
<table class="bskbasket">
<thead class="bskbasketheader">
<tr>
<td>
<img src="%(weburl)s/img/webbasket_world.png" alt="%(image_label)s"/>
</td>
<td class="bsktitle">
<b>%(name)s</b></a>
%(nb_items)i %(records_label)s - %(last_update_label)s: %(last_update)s
</td>
<td class="bskcmtcol">
<a href="%(weburl)s/yourbaskets.py/subscribe?bskid=%(bskid)i&amp;ln=%(ln)s">%(subscribe_label)s</a>
</td>
</tr>
</thead>
<tbody>
%(items)s
</tbody>
</table>""" % {'general_label': general_label,
'weburl': weburl,
'image_label': _("Public basket"),
'name': bsk_name,
'nb_items': len(bsk_items),
'records_label': _("records"),
'last_update_label': _("last update"),
'last_update': convert_datetext_to_dategui(bsk_date_modification),
'bskid': bskid,
'ln': ln,
'subscribe_label': _("Subscribe to this basket"),
'items': items_html}
return out
############################ Baskets ###################################
def tmpl_basket(self, bskid,
name,
date_modification,
nb_views,
nb_items, last_added,
(user_can_view_content, user_can_manage_rights, user_can_delete_basket,
user_can_view_comments, user_can_add_item, user_can_delete_item),
nb_comments, last_comment,
group_sharing_level,
selected_category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group=0,
items=[],
ln=cdslang):
"""
display a basket.
@param access_rights: rights user has on this basket (see cfg_webbasket_share_levels)
@param group_sharing_level: Indicate to which level a basket is shared
(None for nobody, 0 for everybody, any other natural for group)
@param items: list of (record id, nb of comments, last comment (date), body to display, score (int)) tuples
"""
_ = gettext_set_language(ln)
items_html = ''
actions = '<table class="bskbasketheaderactions"><tr>'
if group_sharing_level == None:
group_img_name = 'webbasket_user.png'
group_alt = _("Non shared basket")
elif group_sharing_level == 0:
group_img_name = 'webbasket_world.png'
group_alt = _("Shared basket")
else:
group_img_name = 'webbasket_usergroup.png'
group_alt = _("Group shared basket")
manage_link = ''
logo = "<img src=\"%s/img/%s\" alt=\"%s\" />" % (weburl, group_img_name, group_alt)
if user_can_manage_rights:
url = weburl + '/yourbaskets.py/manage_rights?bskid=%i&amp;topic=%i&amp;ln=%s'
url %= (bskid, selected_topic, ln)
logo = '<a href="%s">%s</a>' % (url, logo + '<br />' + _("Manage rights"))
actions += "<td>" + logo + "</td>"
if user_can_delete_basket:
url = "%s/yourbaskets.py/delete?bskid=%i&amp;"
url += "category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s"
url = url % (weburl,
bskid,
selected_category,
selected_topic,
selected_group,
ln)
img = "%s/img/webbasket_delete.png" % weburl
action = "<a href=\"%s\"><img src=\"%s\" alt=\"%s\" /></a>"
actions += "<td>" + action % (url, img, _("Delete basket")) + "</td>"
if selected_category == cfg_webbasket_categories['PRIVATE']:
img = "%s/img/webbasket_move.png" % weburl
url = "%s/yourbaskets.py/move?bskids=%i&amp;"
url += "category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s"
url = url % (weburl,
bskid,
selected_category,
selected_topic,
selected_group,
ln)
actions += "<td>" + action % (url, img, _("Move basket to another topic"))+ "</td>"
actions += "</tr></table>"
if user_can_view_content:
if not(len(items)):
items_html = """
<tr>
<td colspan="3" style="text-align:center; height:100px">
%s
</td>
</tr>""" % _("Basket is empty")
for item in items:
copy = 1
up = down = delete = 0
if user_can_add_item:
up = down = 1
if item == items[0]:
up = 0
if item == items[-1]:
down = 0
if user_can_delete_item:
delete = 1
items_html += self.__tmpl_basket_item(bskid=bskid,
item=item,
uparrow=up,
downarrow=down,
copy_item=copy,
delete_item=delete,
view_comments=user_can_view_comments,
selected_category=selected_category,
selected_topic=selected_topic,
selected_group=selected_group,
ln=ln)
else:
items_html = """
<tr>
<td colspan="3" style="text-align:center; height:100px">
%s
</td>
</tr>""" % _("You don't have sufficient rights to view this basket's content")
content = ''
if selected_category == cfg_webbasket_categories['EXTERNAL']:
url = "%s/yourbaskets.py/unsubscribe?bskid=%i&amp;ln=%s" % (weburl, bskid, ln)
action = "<a href=\"%s\">%s</a>"
action %= (url, _("Unsubscribe to this basket"))
content += action
footer = self.tmpl_basket_footer(bskid,
selected_category,
selected_topic,
selected_group,
group_sharing_level,
content,
ln)
comments_field = ''
if nb_comments:
comments_field = """
%i %s<br/>
%s %s""" % (nb_comments, _("comments"), _("last comment:"), last_comment)
out = """
<table class="bskbasket">
<thead class="bskbasketheader">
<tr>
<td>%(actions)s</td>
<td class="bsktitle">
<a name="bsk%(bskid)i"><b>%(name)s</b></a><br />
%(nb_items)i %(records_label)s - %(last_update_label)s: %(last_update)s
</td>
<td class="bskcmtcol">
%(comments_field)s
</td>
</tr>
</thead>
<tbody>
%(items)s
%(footer)s
</tbody>
</table>"""
out %= {'actions': actions,
'name': name,
'bskid': bskid,
'nb_items': nb_items,
'records_label': _('records'),
'last_update_label': _("last update"),
'last_update': date_modification,
'comments_field': user_can_view_comments and indent_text(comments_field, 4) or '',
'items': items_html,
'footer': footer}
return out
def __tmpl_basket_item(self,
bskid,
item,
uparrow=0, downarrow=0, copy_item=0, delete_item=0, view_comments=0,
selected_category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group=0,
ln=cdslang):
"""
display a row in a basket (row is item description and actions).
@param bskid: basket id (int)
@param item: (record id, nb of comments, last comment (date), body to display, score (int)) tuple
@param uparrow, downarrow, copy_item, delete_item, view_comments: actions. set to 1 to display these actions.
"""
_ = gettext_set_language(ln)
(recid, nb_cmt, last_cmt, val, score) = item
actions = ''
if uparrow:
url = "%s/yourbaskets.py/modify?action=moveup&amp;bskid=%i&amp;recid=%i"
url += "&amp;category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s"
url = url % (weburl,
bskid,
recid,
selected_category,
selected_topic,
selected_group,
ln)
img = "%s/img/webbasket_up.png" % weburl
actions += "<a href=\"%s\"><img src=\"%s\" alt=\"%s\" /></a>"
actions = actions % (url,
img,
_("Bring item up"))
if downarrow:
url = "%s/yourbaskets.py/modify?action=movedown&amp;bskid=%i&amp;recid=%i"
url += "&amp;category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s"
url = url % (weburl,
bskid,
recid,
selected_category,
selected_topic,
selected_group,
ln)
img = "%s/img/webbasket_down.png" % weburl
actions += "<a href=\"%s\"><img src=\"%s\" alt=\"%s\" /></a>"
actions = actions % (url,
img,
_("Bring item down"))
if copy_item:
url = "%s/yourbaskets.py/modify?action=copy&amp;bskid=%i&amp;recid=%i"
url += "&amp;category=%s&amp;topic=%i&amp;group_id=%i&amp;ln=%s"
url = url % (weburl,
bskid,
recid,
selected_category,
selected_topic,
selected_group,
ln)
img = "%s/img/webbasket_move.png" % weburl
actions += "<a href=\"%s\"><img src=\"%s\" alt=\"%s\" /></a>"
actions = actions % (url,
img,
_("Copy item"))
if delete_item:
url = "%s/yourbaskets.py/modify?action=delete&amp;bskid=%i&amp;recid=%i"
url += "&amp;category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s"
url = url % (weburl,
bskid,
recid,
selected_category,
selected_topic,
selected_group,
ln)
img = "%s/img/webbasket_delete.png" % weburl
actions += "<a href=\"%s\"><img src=\"%s\" alt=\"%s\" /></a>"
actions = actions % (url,
img,
_("Remove item"))
if recid < 0:
actions += "<img src=\"%s/img/webbasket_extern.png\" alt=\"%s\" />"
actions = actions % (weburl, _("Extern record"))
else:
pass
#actions += "<img src=\"%s/img/webbasket_intern.png\" alt=\"%s\" />"
#actions = actions % (weburl, _("Intern record"))
out = """
<tr>
<td class="bskactions">%(actions)s</td>
<td class="bskcontentcol" colspan="2">
%(content)s
<hr />"""
if view_comments:
if nb_cmt > 0:
out += """
%(nb_cmts)i %(cmts_label)s; %(last_cmt_label)s: %(last_cmt)s<br />
"""
out += """
<a href="%(weburl)s/yourbaskets.py/display_item?bskid=%(bskid)s&amp;recid=%(recid)i&amp;category=%(category)s&amp;group=%(group)i&amp;topic=%(topic)i&amp;ln=%(ln)s">%(detailed_label)s</a>
"""
out += """
</td>
</tr>"""
out = out % {'actions': actions,
'content': val,
'nb_cmts': nb_cmt,
'last_cmt': last_cmt,
'weburl': weburl,
'bskid': bskid,
'recid': recid,
'cmts_label': _("comments"),
'last_cmt_label': _("last"),
'detailed_label': _("Details and comments"),
'category': selected_category,
'topic': selected_topic,
'group': selected_group,
'ln': ln}
return out
def tmpl_basket_footer(self,
bskid,
selected_category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0,
selected_group=0,
group_sharing_level=None,
content='',
ln=cdslang):
"""display footer of a basket."""
_ = gettext_set_language(ln)
public_infos = ''
if group_sharing_level == 0:
public_url = weburl + '/yourbaskets.py/display_public?bskid=' + str(bskid)
public_link = '<a href="%s">%s</a>' % (public_url, public_url)
public_infos = _("This basket is publicly accessible at this adress: %s.") % public_link
if content:
content += '<br />'
if not(content) and not(public_infos):
content += '<br />'
out = """
<tr>
<td colspan="3" class="bskbasketfooter">
<!-- Commented. Ready for next release
<form name="bsk_sort_%(bskid)i" action="%(weburl)s/yourbaskets.py/display" method="GET">
<input type="hidden" name="bsk_to_sort" value="%(bskid)i" />
<input type="hidden" name="category" value="%(category)s" />
<input type="hidden" name="topic" value="%(topic)i" />
<input type="hidden" name="group" value="%(group_id)i" />
<input type="hidden" name="ln" value="%(ln)s" />
%(sort_label)s:
<input type="submit" name="sort_by_title" value="%(title_label)s" class="nonsubmitbutton" />
<input type="submit" name="sort_by_date" value="%(date_label)s" class="nonsubmitbutton" />
</form>-->
%(content)s
%(public_infos)s
</td>
</tr>
"""
out %= {'weburl': weburl,
'bskid': int(bskid),
'category': selected_category,
'topic': int(selected_topic),
'group_id': int(selected_group),
'ln': ln,
'sort_label': _("Sort by"),
'title_label': _("Title"),
'date_label': _("Date"),
'content': content,
'public_infos': public_infos
}
return out
######################### Display of items and commenting ###################################
def tmpl_item(self,
(bskid, bsk_name, bsk_date_modification, bsk_nb_views, bsk_nb_records, bsk_id_owner),
recid, record, comments,
sharing_level, (user_can_view_comments, user_can_add_comment, user_can_delete_comment),
selected_category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group_id=0, ln=cdslang):
"""display a specific item inside a basket. first parameter is this a big tuple which defines a basket."""
_ = gettext_set_language(ln)
total_comments = len(comments)
action = weburl + '/yourbaskets.py/write_comment?bskid=%i&amp;recid=%i'
action += '&amp;category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s'
action %= (bskid, recid, selected_category, selected_topic, selected_group_id, ln)
back_url = weburl + '/yourbaskets.py/display?category=%s&amp;topic=%i&amp;group=%i'
back_url %= (selected_category, selected_topic, selected_group_id)
def list_to_str(elt1, elt2):
"""return elt1 <br /> elt2"""
return elt1 + "<br />\n" + elt2
if comments and user_can_view_comments:
comments = [self.__tmpl_display_comment(bskid, recid, comment,
(user_can_add_comment, user_can_delete_comment),
selected_category, selected_topic, selected_group_id,
ln)
for comment in comments]
comments = reduce(list_to_str, comments)
else:
comments = ''
if record:
record_text = record[-1]
body = """
%(record)s
<hr /><br />"""
if user_can_view_comments:
body += """
<h2>%(comments_label)s</h2>
%(total_label)s<br />"""
if user_can_add_comment:
body += """
<form name="write_comment" method="POST" action="%(action)s">
<input type="submit" value="%(button_label)s" style="margin: 10px;" class="formbutton" />
</form>"""
if user_can_view_comments:
body += """
<br />
%(comments)s"""
body %= {'record': record_text,
'comments_label': _("Comments"),
'total_label': _("There is a total of %i comments") % total_comments,
'action': action,
'button_label': _("Write a comment"),
'comments': comments}
if sharing_level == None:
img = '<img src="%s/img/webbasket_user.png" alt="%s" />' % (weburl, _("Non shared basket"))
elif sharing_level == 0:
img = '<img src="%s/img/webbasket_world.png" alt="%s" />' % (weburl, _("Shared basket"))
else:
img = '<img src="%s/img/webbasket_usergroup.png" alt="%s" />' % (weburl, _("Group shared basket"))
content = ''
if selected_category == cfg_webbasket_categories['EXTERNAL']:
url = "%s/yourbaskets.py/unsubscribe?bskid=%i&amp;ln=%s" % (weburl, bskid, ln)
action = "<a href=\"%s\">%s</a>"
action %= (url, _("Unsubscribe to this basket"))
content += action
footer = self.tmpl_basket_footer(bskid,
selected_category,
selected_topic,
selected_group_id,
sharing_level,
content,
ln)
out = """
<table class="bskbasket">
<thead class="bskbasketheader">
<tr>
<td>%(img)s</td>
<td class="bsktitle" style="height: 65px">
<b><a href="%(weburl)s/yourbaskets.py/display?bskid=%(bskid)s&amp;category=%(category)s&amp;topic=%(topic)i&amp;group=%(group)i&amp;ln=%(ln)s">%(name)s</a></b><br />
%(nb_items)i %(records_label)s - %(last_update_label)s: %(last_update)s
</td>
<td class="bskcmtcol"></td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3" style="padding: 5px;">
%(body)s
</td>
</tr>
%(footer)s
</tbody>
</table>""" % {'img': img,
'weburl': weburl,
'bskid': bskid,
'category': selected_category,
'topic': selected_topic,
'group': selected_group_id,
'ln': ln,
'name': bsk_name,
'nb_items': bsk_nb_records,
'records_label': _("records"),
'last_update_label': _("last update"),
'last_update': bsk_date_modification,
'body': body,
'footer': footer}
out += """
<a href="%s">%s</a>""" % (back_url, _("Back to baskets"))
return out
def __tmpl_display_comment(self, bskid, recid,
(cmt_uid, cmt_nickname, cmt_title, cmt_body, cmt_date, cmt_priority, cmtid),
(user_can_add_comment, user_can_delete_comment),
selected_category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group_id=0, ln=cdslang):
"""Display a given comment.
@param rights: defines which links (reply, delete, ...) will be displayed. see config file for rights.
"""
_ = gettext_set_language(ln)
out = """
<div class="bskcomment">
<b>%(title)s</b>, %(label_author)s <a href="%(url)s/yourmessages.py/write?msg_to=%(user)s">%(user_display)s</a> %(label_date)s <i>%(date)s</i><br/><br/>
%(body)s
<br />"""
if user_can_add_comment:
out += """
<a href="%(url)s/yourbaskets.py/write_comment?bskid=%(bskid)i&amp;recid=%(recid)i&amp;cmtid=%(cmtid)i&amp;category=%(category)s&amp;topic=%(topic)i&amp;group=%(group_id)i&amp;ln=%(ln)s">%(reply_label)s</a>"""
if user_can_delete_comment:
out += """
| <a href="%(url)s/yourbaskets.py/delete_comment?bskid=%(bskid)i&amp;recid=%(recid)i&amp;cmtid=%(cmtid)i&amp;category=%(category)s&amp;topic=%(topic)i&amp;group=%(group_id)i&amp;ln=%(ln)s">%(delete_label)s</a>"""
out += """
</div>"""
out %= {'title': cmt_title,
'url': weburl,
'label_author': _("by"),
'label_date': _("on"),
'user': cmt_nickname or cmt_uid,
'user_display': cmt_nickname or get_user_info(cmt_uid)[2],
'date': convert_datetext_to_dategui(cmt_date),
'body': email_quoted_txt2html(cmt_body),
'bskid': bskid,
'recid': recid,
'cmtid': cmtid,
'category': selected_category,
'topic': selected_topic,
'group_id': selected_group_id,
'ln': ln,
'reply_label': _("Reply"),
'delete_label': _("Delete comment")}
return out
def tmpl_quote_comment(self, title, uid, nickname, date, body, ln=cdslang):
"""Return a comment in a quoted form (i.e. with '>' signs before each line)
@param title: title of comment to quote
@param uid: user id of user who posted comment to quote
@param nickname: nickname of user who posted comment to quote
@param date: date of post of comment to quote
@param body: body of comment to quote
@param ln: language"""
_ = gettext_set_language(ln)
if not(nickname):
nickname = get_user_info(uid)[2]
out = title + ', ' + _("by") + ' ' + nickname + ' ' + _("on") + ' ' + date + '\n' + body
return email_quote_txt(out)
def tmpl_write_comment(self, bskid, recid,
record,
cmt_body='',
selected_category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group_id=0,
ln=cdslang,
warnings=[]):
"""Display interface to write a comment.
@param bskid: basket id (int)
@param recid: record id (int)
@param record: text of the record (str)
@param selected_category: cfg_webbasket_categories
@param selected_topic: # of topic
@param selected_group_id: in case of category: group, id of selected group
@param ln: language
@param warnings: list of warnings"""
_ = gettext_set_language(ln)
action = '%s/yourbaskets.py/save_comment?bskid=%i&amp;recid=%i'
action += '&amp;category=%s&amp;topic=%i&amp;group=%i&amp;ln=%s'
action %= (weburl, bskid, recid,
selected_category, selected_topic, selected_group_id, ln)
if warnings:
warnings_box = self.tmpl_warnings(warnings, ln)
else:
warnings_box = ''
out = """
<div style="width:100%%">%(warnings)s
%(record)s
<hr />
<h2>%(write_label)s</h2>
<form name="write_comment" method="POST" action="%(action)s">
<p class="bsklabel">%(title_label)s:</p>
<input type="text" name="title" size="80" />
<p class="bsklabel">%(comment_label)s:</p>
<textarea name="text" rows="20" cols="80">%(cmt_body)s</textarea><br />
<input type="submit" class="formbutton" value="%(button_label)s" />
</form>
</div>""" % {'warnings': warnings_box,
'record': record and record[-1] or '',
'write_label': _("Add Comment"),
'title_label': _("Title"),
'comment_label': _("Comment"),
'action': action,
'cmt_body': cmt_body,
'button_label': _("Add Comment")
}
return out
############################ Basket creation ###################################
def tmpl_create_basket_link(self, selected_topic=0, ln=cdslang):
""" Create link to basket creation """
_ = gettext_set_language(ln)
url = weburl + '/yourbaskets.py/create_basket?topic_number=%i&amp;ln=%s'
url %= (selected_topic, ln)
image = '<img src="%s/img/webbasket_create_small.png" style="vertical-align: middle; margin-right: 5px" />' % weburl
out = """
<div class="bsk_create_link">
<a href="%s">%s%s</a>
</div>""" % (url, image, _("Create new basket"))
return out
def __tmpl_basket_box(self, img='', title='&nbsp;', subtitle='&nbsp;', body=''):
""" private function, display a basket/topic selection box """
out = """
<table class="bskbasket">
<thead class="bskbasketheader">
<tr>
<td class="bskactions">
<img src="%(logo)s" alt="%(label)s" />
</td>
<td class="bsktitle">
<b>%(label)s</b><br />
%(count)s
</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2">
<table>%(basket_list)s
</table>
</td>
</tr>
</tbody>
</table>"""
out %= {'logo': img,
'label': title, 'count': subtitle,
'basket_list': indent_text(body, 5)}
return out
def tmpl_create_box(self, new_basket_name='', new_topic_name='',
topics=[], selected_topic=None,
ln=cdslang):
"""Display a HTML box for creation of a new basket
@param new_basket_name: prefilled value (string)
@param new_topic_name: prefilled value (string)
@param topic: list of topics (list of strings)
@param selected_topic: preselected value for topic selection
@param ln: language"""
_ = gettext_set_language(ln)
topics_html = ''
topics = map(lambda x: x[0], topics)
if selected_topic:
try:
selected_topic = topics.index(selected_topic[0])
except:
selected_topic = None
if len(topics):
topics = zip(range(len(topics)), topics)
topics.insert(0, (-1, _("Select topic")))
topics_html = self.__create_select_menu('create_in_topic', topics, selected_topic)
create_html = """
<tr>
<td>%s</td>
<td>
<input type="text" name="new_basket_name" value="%s"/>
</td>
</tr>
<tr>
<td colspan="2">%s %s: <input type="text" name="new_topic_name" value="%s"/>
</tr>""" % (_("New basket's name"), new_basket_name,
topics_html,
topics_html!='' and _("or create a new one") or _("Create a new topic"),
new_topic_name)
return self.__tmpl_basket_box(img=weburl + '/img/webbasket_create.png',
title=_("Create a new basket"),
body=create_html)
def tmpl_create_basket(self, new_basket_name='',
new_topic_name='', create_in_topic=None, topics_list=[],
ln=cdslang):
"""Template for basket creation"""
_ = gettext_set_language(ln)
out = """
<form name="create_basket" action="%(action)s" method="POST">
<input type="hidden" name="ln" value="%(ln)s" />
<div style="padding:10px;">
%(create_box)s
<input type="submit" value="%(label)s" class="formbutton"/>
</div>
</form>""" % {'action': weburl + '/yourbaskets.py/create_basket',
'ln': ln,
'create_box': indent_text(self.tmpl_create_box(new_basket_name=new_basket_name,
new_topic_name=new_topic_name,
topics=topics_list,
selected_topic=create_in_topic,
ln=ln),
2),
'label': _("Create new basket")}
return out
############################ functions on baskets ###################################
def tmpl_add(self, recids,
personal_baskets,
group_baskets,
external_baskets,
topics,
referer, ln=cdslang):
""" returns HTML for the basket selection form """
_ = gettext_set_language(ln)
action = weburl + '/yourbaskets.py/add?ln=' + ln
personal = ''
group = ''
external = ''
if personal_baskets:
topic_names = {}
map(topic_names.setdefault, [row[2] for row in personal_baskets])
topic_names = topic_names.keys()
topic_names.sort()
personal_html = ''
for topic_name in topic_names:
baskets = map(lambda x: (x[0], x[1]),
filter(lambda x: x[2]==topic_name,
personal_baskets))
baskets.insert(0, (0, _("Select basket")))
personal_html += """<tr>
<td>%s</td>
<td>%s</td>
</tr>"""
personal_html %= (topic_name,
indent_text(self.__create_select_menu('topic ' + topic_name,
baskets),
2))
personal = self.__tmpl_basket_box(weburl + '/img/webbasket_user.png',
_("Add to a personal basket"),
_("%i baskets") % len(personal_baskets),
personal_html)
if group_baskets:
group_names = {}
map(group_names.setdefault, [row[2] for row in group_baskets])
group_names = group_names.keys()
group_names.sort()
groups_html = ''
for group_name in group_names:
baskets = map(lambda x: (x[0], x[1]),
filter(lambda x: x[2]==group_name,
group_baskets))
baskets.insert(0, (0, _("Select basket")))
groups_html += """<tr>
<td>%s</td>
<td>%s</td>
</tr>"""
groups_html %= (group_name,
indent_text(self.__create_select_menu('group ' + group_name,
baskets),
2))
group = self.__tmpl_basket_box(weburl + '/img/webbasket_usergroup.png',
_("Add to a group shared basket"),
_("%i baskets") % len(group_baskets),
groups_html)
if external_baskets:
external_html = """
<tr>
<td>
<select name="external_baskets">
<option value="0">%s</option>""" % _("Select basket")
for basket in external_baskets:
value = int(basket[0])
label = basket[1]
external_html += indent_text('<option value="%i">%s</option>'% (value, label), 3)
external_html += """
</select>
</td>
</tr>"""
external = self.__tmpl_basket_box(weburl + '/img/webbasket_world.png',
_("Add to a public basket"),
_("%i baskets") % len(external_baskets),
external_html)
create = self.tmpl_create_box(topics=topics, ln=ln)
recids_field = reduce(lambda x, y: str(x) + ',' + str(y), recids)
fields = filter(lambda x: x != '', [personal, group, external, create])
while (len(fields) != 4):
fields.append('')
out = """
<form name="add_to_basket" action="%(action)s" method="POST">
<p>%(label)s:</p>
<input type="hidden" name="referer" value="%(referer)s" />
<input type="hidden" name="recid" value="%(recids)s" />
<table style="width:100%%;">
<tr>
<td style="width:50%%;vertical-align:top;">%(field1)s</td>
<td style="width: 50%%;vertical-align:top;">%(field2)s</td>
</tr>
<tr>
<td style="vertical-align:top;">%(field3)s</td>
<td style="vertical-align:top;">%(field4)s</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" class="formbutton" value="%(submit_label)s" />
</td>
</tr>
</table>
</form>""" % {'action': action,
'referer': referer,
'recids': recids_field,
'label': _("Adding %i records to these baskets") % len(recids),
'field1': fields[0],
'field2': fields[1],
'field3': fields[2],
'field4': fields[3],
'submit_label': _("Add to baskets")}
return out
def tmpl_added_to_basket(self, nb_baskets_modified=0, ln=cdslang):
"""Display message for addition of records to baskets"""
_ = gettext_set_language(ln)
if nb_baskets_modified:
out = _("The selected records have been successfully added to %i baskets")
out %= nb_baskets_modified
else:
out = _("No records were added to the selected baskets.")
return '<p>' + out + '</p>'
def tmpl_confirm_delete(self, bskid,
(nb_users, nb_groups, nb_alerts),
category=cfg_webbasket_categories['PRIVATE'],
selected_topic=0, selected_group_id=0,
ln=cdslang):
"""
display a confirm message
@param bskid: basket id
@param category: private, group or external baskets are selected
@param selected_topic: if private baskets, topic nb
@param selected_group_id: if group: group to display baskets of
@param ln: language
@return html output
"""
_ = gettext_set_language(ln)
message = _("Are your sure you want to delete this basket?")
if nb_users:
message += '<p>' + _("%i users have subscribed to this basket")% nb_users + '</p>'
if nb_groups:
message += '<p>' + _("%i usergroups have subscribed to this basket")% nb_groups + '</p>'
if nb_alerts:
message += '<p>' + _("You have set %i alerts on this basket")% nb_alerts + '</p>'
out = """
<table class="confirmoperation">
<tr>
<td colspan="2" class="confirmmessage">
%(message)s
</td>
</tr>
<tr>
<td>
<form name="validate" action="%(url_ok)s" method="post">
<input type="hidden" name="confirmed" value="1" />
<input type="hidden" name="category" value="%(category)s" />
<input type="hidden" name="group" value="%(group)i" />
<input type="hidden" name="topic" value="%(topic)i" />
<input type="hidden" name="ln" value="%(ln)s" />
<input type="hidden" name="bskid" value="%(bskid)i" />
<input type="submit" value="%(yes_label)s" class="formbutton" />
</form>
</td>
<td>
<form name="cancel" action="%(url_cancel)s" method="get">
<input type="hidden" name="category" value="%(category)s" />
<input type="hidden" name="group" value="%(group)i" />
<input type="hidden" name="topic" value="%(topic)i" />
<input type="hidden" name="ln" value="%(ln)s" />
<input type="submit" value="%(no_label)s" class="formbutton" />
</form>
</td>
</tr>
</table>"""% {'message': message,
'bskid': bskid,
'url_ok': 'delete',
'url_cancel': 'display',
'category': category,
'topic': selected_topic,
'group': selected_group_id,
'ln':ln,
'yes_label': _("Yes"),
'no_label': _("Cancel")}
return indent_text(out, 2)
def tmpl_move(self, bskids, topics, ln=cdslang):
"""Display a topic selection / creation for moving of give baskets.
@param bskids: list of basket ids
@param topics: list of tuples (see webbasket_db_layer: get_personal_topics
@param ln: language
"""
_ = gettext_set_language(ln)
topics_selection = zip(range(len(topics)), map(lambda x: x[0], topics))
topics_selection.insert(0, (-1, _("Select topic")))
topics_body = """
<tr>
<td>%s</td>
</tr>""" % indent_text(self.__create_select_menu('selected_topic', topics_selection), 2)
if len(topics):
topics_box = self.__tmpl_basket_box(img=weburl + '/img/webbasket_user.png',
title=_("Select a topic"),
body=topics_body)
else:
topics_box = ''
create_body = """
<tr>
<td>%s</td>
<td>
<input type="text" name="new_topic_name" />
</td>
</tr>""" % _("New topic's name")
create_box = self.__tmpl_basket_box(img=weburl + '/img/webbasket_create.png',
title=_("Create a new topic"),
body=create_body)
action = weburl + '/yourbaskets.py/move'
bskids_field = reduce(lambda x, y: str(x) + ',' + str(y), bskids)
out = """
<form name="move_basket" action="%(action)s" method="POST">
<p>%(label)s:</p>
<input type="hidden" name="ln" value="%(ln)s" />
<input type="hidden" name="bskids" value="%(bskids)s" />
<table style="width:100%%;">
<tr>
<td style="width:50%%;vertical-align:top;">%(topics)s</td>
<td style="width:50%%;vertical-align:top;">%(create)s</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" class="formbutton" value="%(submit_label)s" />
</td>
</tr>
</table>
</form>""" % {'action': action,
'ln': ln,
'bskids': bskids_field,
'label': _("Moving %i baskets to this topic") % len(bskids),
'topics': topics_box,
'create': create_box,
'submit_label': _("Move to topic")}
return out
def tmpl_manage_rights(self, bskid, bsk_name, groups_rights, external_rights,
selected_topic, ln=cdslang):
"""Display interface for rights management over the given basket
@param group_rights: list of (group id, name, rights) tuples
@param external_rights: rights as defined in cfg_webbasket_share_levels
"""
_ = gettext_set_language(ln)
groups_body = ''
for (group_id, name, rights) in groups_rights:
groups_body += """
<tr>
<td>%s</td>
<td>%s</td>
</tr>""" % (name, self.__create_rights_selection_menu(str(group_id), rights, ln))
groups_body += """
<tr>
<td colspan="2">
<input type="submit" name="add_group" class="nonsubmitbutton" value="%s"/>
</td>
</tr>""" % _("Add group")
groups_box = self.__tmpl_basket_box(img=weburl + '/img/webbasket_usergroup.png',
title=_("Manage groups rights"),
body=groups_body)
external_body = """
<tr>
<td>%s</td>
</tr>""" % self.__create_rights_selection_menu('external', external_rights, ln)
external_box = self.__tmpl_basket_box(img=weburl + '/img/webbasket_world.png',
title=_("Manage global sharing rights"),
body=external_body)
out = """
<form name="manage_rights" action="%(action)s" method="POST">
<p>%(label)s</p>
<input type="hidden" name="ln" value="%(ln)s" />
<input type="hidden" name="bskid" value="%(bskid)i" />
<input type="hidden" name="topic" value ="%(topic)i" />
<table style="width:100%%;">
<tr>
<td style="width:50%%;vertical-align:top;">%(groups)s</td>
<td style="width:50%%;vertical-align:top;">%(external)s</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" class="formbutton" name="submit" value="%(submit_label)s" />
</td>
</tr>
</table>
</form>""" % {'label': _('Modifying sharing rights for basket "%s"') % bsk_name,
'action': weburl + '/yourbaskets.py/manage_rights',
'ln': ln,
'topic': selected_topic,
'bskid': bskid,
'groups': indent_text(groups_box, 4),
'external': indent_text(external_box, 4),
'submit_label': _("Change rights")}
return out
def __create_rights_selection_menu(self, name, current_rights, ln=cdslang):
"""Private function. create a drop down menu for selection of rights
@param current_rights: rights as defined in cfg_webbasket_share_levels
@param ln: language
"""
_ = gettext_set_language(ln)
elements = [('NO', _("No rights")),
(cfg_webbasket_share_levels['READITM'],
_("View records")),
(cfg_webbasket_share_levels['READCMT'],
'... ' + _("and") + ' ' + _("view comments")),
(cfg_webbasket_share_levels['ADDCMT'],
'... ' + _("and") + ' ' + _("add comments")),
(cfg_webbasket_share_levels['ADDITM'],
'... ' + _("and") + ' ' + _("add records")),
(cfg_webbasket_share_levels['DELCMT'],
'... ' + _("and") + ' ' + _("delete comments")),
(cfg_webbasket_share_levels['DELITM'],
'... ' + _("and") + ' ' + _("remove records")),
(cfg_webbasket_share_levels['MANAGE'],
'... ' + _("and") + ' ' + _("manage sharing rights"))
]
return self.__create_select_menu(name, elements, current_rights)
def tmpl_add_group(self, bskid, selected_topic, groups=[], ln=cdslang):
"""
return form for selection of groups.
@param bskid: basket id (int)
@param selected_topic: topic currently displayed (int)
@param groups: list of tuples (group id, group name)
@param ln: language
"""
_ = gettext_set_language(ln)
if len(groups):
groups_body = """
<tr>
<td>%s</td>
</tr>""" % self.__create_select_menu('new_group', groups, selected_key=None)
else:
groups_body = """
<tr>
<td>%s</td>
</tr>""" % _("You're not member of a group")
groups_box = self.__tmpl_basket_box(img=weburl + '/img/webbasket_usergroup.png',
title=_("Add group"),
body=groups_body)
out = """
<form name="add_group" action="%(action)s" method="POST">
<p>%(label)s</p>
<input type="hidden" name="ln" value="%(ln)s" />
<input type="hidden" name="bskid" value="%(bskid)i" />
<input type="hidden" name="topic" value ="%(topic)i" />
<table style="width:100%%;">
<tr>
<td style="width:50%%;vertical-align:top;">%(groups)s</td>
<td style="width:50%%;vertical-align:top;"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" class="formbutton" name="cancel" value="%(cancel_label)s" />
<input type="submit" class="formbutton" name="add_group" value="%(submit_label)s" />
</td>
</tr>
</table>
</form>""" % {'label': _('Sharing basket to a new group'),
'action': weburl + '/yourbaskets.py/manage_rights',
'ln': ln,
'topic': selected_topic,
'bskid': bskid,
'groups': indent_text(groups_box, 4),
'cancel_label': _("Cancel"),
'submit_label': _("Add group")}
return out
def tmpl_personal_baskets_selection_box(self,
baskets=[],
select_box_name='baskets',
selected_bskid=None,
ln=cdslang):
"""return an HTML popupmenu
@param baskets: list of (bskid, bsk_name, bsk_topic) tuples
@param select_box_name: name that will be used for the control
@param selected_bskid: id of the selcte basket, use None for no selection
@param ln: language"""
_ = gettext_set_language(ln)
elements = [(0, '- ' + _("no basket") + ' -')]
for (bskid, bsk_name, bsk_topic) in baskets:
elements.append((bskid, bsk_topic + ' > ' + bsk_name))
return self.__create_select_menu(select_box_name, elements, selected_bskid)
def tmpl_create_guest_warning_box(self, ln=cdslang):
"""return html warning box for non registered users"""
_ = gettext_set_language(ln)
message = _("You are logged in as a guest user, so your baskets will disappear at the end of the current session. If you wish you can %slogin or register here%s.")
message %= ('<a href="%s/youraccount.py/login?ln=%s">'% (weburl, ln), '</a>')
out = """
<table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">%s</th>
</tr>
</thead>
</table>"""
return out % message
############################ Utilities ###################################
def __create_select_menu(self, name, elements, selected_key=None):
""" private function, returns a popup menu
@param name: name of HTML control
@param elements: list of (key, value)
"""
out = '<select name="%s">' % name
for (key, label) in elements:
selected = ''
if key == selected_key:
selected = ' selected="selected"'
out += indent_text('<option value="%s"%s>%s</option>'% (key, selected, label), 1)
out += '</select>'
return out
def tmpl_warnings(self, warnings=[], ln=cdslang):
""" returns HTML for warnings """
from cdsware.errorlib import get_msgs_for_code_list
out = ''
if type(warnings) is not list:
warnings = [warnings]
if len(warnings):
warnings_parsed = get_msgs_for_code_list(warnings, 'warning', ln)
for (warning_code, warning_text) in warnings_parsed:
out += '<div class="important" style="padding: 10px;">%s</div>' % warning_text
return out
def tmpl_back_link(self, link, ln):
""" returns HTML for a link whose label should be
'Back to search results'
"""
_ = gettext_set_language(ln)
label = _("(Back to search results)")
out = '<a href="%s">%s</a>' % (link, label)
return out
def __create_messaging_link(self, to, display_name, ln=cdslang):
"""prints a link to the messaging system"""
link = "%s/yourmessages.py/write?msg_to=%s&amp;ln=%s" % (weburl, to, ln)
if to:
return '<a href="%s" class="maillink">%s</a>' % (link, display_name)
else:
return display_name
def tmpl_xml_basket(self, items=[]):
items_xml = ''
for item in items:
items_xml += ' ' + item + '\n'
return """<?xml version="1.0" encoding="UTF-8"?>
<collection>
%s
</collection>
""" % items_xml
\ No newline at end of file
diff --git a/modules/webbasket/web/Makefile.am b/modules/webbasket/web/Makefile.am
index d779eeca3..362fea4ac 100644
--- a/modules/webbasket/web/Makefile.am
+++ b/modules/webbasket/web/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)
webapp_DATA = yourbaskets.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/webbasket/web/yourbaskets.py b/modules/webbasket/web/yourbaskets.py
index c0f0eea25..409a6297c 100644
--- a/modules/webbasket/web/yourbaskets.py
+++ b/modules/webbasket/web/yourbaskets.py
@@ -1,536 +1,536 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Web Baskets features."""
__lastupdated__ = """$Date$"""
from mod_python import apache
from cdsware.config import weburl, webdir, cdslang
from cdsware.messages import gettext_set_language, wash_language
from cdsware.webpage import page
from cdsware.webuser import getUid, page_not_authorized, isGuestUser
from cdsware.messages import wash_language
from cdsware.webbasket import *
from cdsware.webbasket_config import cfg_webbasket_categories
from cdsware.urlutils import get_referer, redirect_to_url
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
imagesurl = "%s/img" % webdir
## rest of the Python code goes below
### CALLABLE INTERFACE
def index(req):
redirect_to_url(req, '%s/yourbaskets.py/display?%s' % (weburl, req.args))
def display(req,
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
bsk_to_sort=0, sort_by_title="", sort_by_date="",
ln=cdslang):
"""Display basket"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/display")
(body, errors, warnings) = perform_request_display(uid, category,
topic,
group,
ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=category, topic=topic, group=group,
ln=ln)
return page(title = _("Display baskets"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def display_item(req,
bskid=0, recid=0, format='hb',
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
ln=cdslang):
""" Display basket item """
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/display_item")
(body, errors, warnings) = perform_request_display_item(uid=uid,
bskid=bskid,
recid=recid,
format=format,
category=category,
topic=topic,
group_id=group,
ln=ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=category, topic=topic, group=group,
bskid=bskid, ln=ln)
return page(title = _("Details and comments"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def write_comment(req,
bskid=0, recid=0, cmtid=0,
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
ln=cdslang):
"""Write a comment (just interface for writing)"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/write_comment")
(body, errors, warnings) = perform_request_write_comment(uid=uid,
bskid=bskid,
recid=recid,
cmtid=cmtid,
category=category,
topic=topic,
group_id=group,
ln=ln)
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=category, topic=topic, group=group,
bskid=bskid, ln=ln)
return page(title = _("Write a comment"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def save_comment(req, bskid=0, recid=0, title='', text='',
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
ln=cdslang):
"""Save comment on record in basket"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/save_comment")
(errors_saving, infos) = perform_request_save_comment(uid=uid,
bskid=bskid,
recid=recid,
title=title,
text=text,
ln=ln)
(body, errors_displaying, warnings) = perform_request_display_item(uid=uid,
bskid=bskid,
recid=recid,
format='hb',
category=category,
topic=topic,
group_id=group,
infos=infos,
ln=ln)
errors = errors_saving.extend(errors_displaying)
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=category, topic=topic, group=group,
bskid=bskid, ln=ln)
return page(title = _("Details and comments"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def delete_comment(req, bskid=0, recid=0, cmtid=0,
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
ln=cdslang):
"""Delete a comment
@param bskid: id of basket (int)
@param recid: id of record (int)
@param cmtid: id of comment (int)
@param category: category (see webbasket_config) (str)
@param topic: nb of topic currently displayed (int)
@param group: id of group baskets currently displayed (int)
@param ln: language"""
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/delete_comment")
ln = wash_language(ln)
_ = gettext_set_language(ln)
recid = wash_url_argument(recid, 'int')
bskid = wash_url_argument(bskid, 'int')
category = wash_url_argument(category, 'str')
topic = wash_url_argument(topic, 'int')
group = wash_url_argument(group, 'int')
url = weburl + '/yourbaskets.py/display_item?recid=%i&bskid=%i' % (recid, bskid)
url += '&category=%s&topic=%i&group=%i&ln=%s' % (category, topic, group, ln)
errors = perform_request_delete_comment(uid, bskid, recid, cmtid)
if not(len(errors)):
redirect_to_url(req, url)
else:
return page(uid = uid,
language = ln,
errors = errors,
req = req)
def add(req, recid=[], referer='',
new_basket_name='', new_topic_name='', create_in_topic='',
ln=cdslang, **args):
"""Add records to baskets.
@param recid: list of records
@param bskid: list of baskets. If not set or empty, this function will display a form
for the selection of baskets.
@param referer: url of the referer
@param ln: language
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
if not(type(recid) is list):
if recid.find(',') != -1:
recid = wash_url_argument(recid, 'str')
recid = recid.split(',')
bskid={}
for basket_id in args.values():
basket_id = wash_url_argument(basket_id, 'int')
if int(basket_id):
bskid[int(basket_id)] = 1
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/add")
if not referer:
referer = get_referer(req)
(body, errors, warnings) = perform_request_add(uid=uid,
recid=recid,
bskid=bskid.keys(),
referer=referer,
new_basket_name=new_basket_name,
new_topic_name=new_topic_name,
create_in_topic=create_in_topic,
ln=ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
if not(len(warnings)) :
title = _("Your Baskets")
else:
title = _("Add records to baskets")
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
return page(title = title,
body = body,
navtrail = navtrail,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def delete(req, bskid=-1, confirmed=0,
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0,
ln=cdslang):
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
confirmed = wash_url_argument(confirmed, 'int')
category = wash_url_argument(category, 'str')
topic = wash_url_argument(topic, 'int')
group = wash_url_argument(group, 'int')
bskid = wash_url_argument(bskid, 'int')
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/delete")
(body, errors, warnings)=perform_request_delete(uid=uid,
bskid=bskid,
confirmed=confirmed,
category=category,
selected_topic=topic,
selected_group_id=group,
ln=ln)
if confirmed:
url = weburl + '/yourbaskets.py?category=%s&topic=%i&group=%i&ln=%s' % (category,
topic,
group,
ln)
redirect_to_url(req, url)
else:
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=category, topic=topic, group=group,
bskid=bskid, ln=ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
return page(title = _("Delete a basket"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def modify(req, action='', bskid=-1, recid=0,
category=cfg_webbasket_categories['PRIVATE'], topic=0, group=0, ln=cdslang):
ln = wash_language(ln)
category = wash_url_argument(category, 'str')
topic = wash_url_argument(topic, 'int')
group = wash_url_argument(group, 'int')
_ = gettext_set_language(ln)
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/modify")
action = wash_url_argument(action, 'str')
url = weburl + '/yourbaskets.py/display?category=%s&topic=%i&group=%i&ln=%s' % (category,
topic,
group,
ln)
if action == cfg_webbasket_actions['DELETE']:
delete_record(uid, bskid, recid)
redirect_to_url(req, url)
elif action == cfg_webbasket_actions['UP']:
move_record(uid, bskid, recid, action)
redirect_to_url(req, url)
elif action == cfg_webbasket_actions['DOWN']:
move_record(uid, bskid, recid, action)
redirect_to_url(req, url)
elif action == cfg_webbasket_actions['COPY']:
title = _("Copy record to basket")
referer = get_referer(req)
(body, errors, warnings) = perform_request_add(uid=uid,
recid=[recid],
referer=referer,
ln=ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
else:
title = ''
body = ''
warnings = ''
errors = [('ERR_WEBBASKET_UNDEFINED_ACTION',)]
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=category, topic=topic, group=group,
bskid=bskid, ln=ln)
return page(title = title,
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def move(req, bskids='', selected_topic=-1, new_topic_name='', ln=cdslang):
"""Move one or more baskets to a given topic"""
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/move")
ln = wash_language(ln)
_ = gettext_set_language(ln)
bskids = wash_url_argument(bskids, 'str')
selected_topic = wash_url_argument(selected_topic, 'int')
if bskids:
bskids = bskids.split(',')
if selected_topic != -1 or new_topic_name:
# a new topic has been chosen
(topic, errors) = perform_request_move(uid, bskids,
selected_topic, new_topic_name,
ln)
url = weburl + '/yourbaskets.py/display?category=%s&topic=%i&ln=%s'
url %= (cfg_webbasket_categories['PRIVATE'], topic, ln)
redirect_to_url(req, url)
else:
#user must select a topic to move basket to
(body, errors, warnings) = perform_request_move(uid=uid, bskids=bskids, ln=ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=cfg_webbasket_categories['PRIVATE'],
topic=-1, group=0,
ln=ln)
return page(title = _("Move basket to another topic"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def manage_rights(req, bskid=0,
topic='',
external='',
add_group='', submit='',
new_group='',
ln=cdslang,
**groups):
""" manage rights for a basket. **groups should be of the form group_id=new_rights """
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/manage_rights")
ln = wash_language(ln)
topic = wash_url_argument(topic, 'int')
_ = gettext_set_language(ln)
if not(add_group):
(body, errors, warnings) = perform_request_manage_rights(uid, bskid, topic,
groups, external, ln)
if add_group and not(new_group):
body = perform_request_add_group(uid=uid, bskid=bskid, topic=topic, ln=ln)
errors = []
warnings = []
elif add_group and new_group:
perform_request_add_group(uid, bskid, topic, new_group, ln)
(body, errors, warnings) = perform_request_manage_rights(uid, bskid, topic,
groups, external, ln)
elif submit and not(len(errors)):
url = weburl + '/yourbaskets.py/display?category=%s&topic=%i&ln=%s'
url %= (cfg_webbasket_categories['PRIVATE'], topic, ln)
redirect_to_url(req, url)
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
navtrail_end = create_basket_navtrail(uid=uid,
category=cfg_webbasket_categories['PRIVATE'],
topic=topic,
group=0,
bskid=bskid, ln=ln)
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
return page(title = _("Manage rights"),
body = body,
navtrail = navtrail + navtrail_end,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def create_basket(req, new_basket_name='',
new_topic_name='', create_in_topic=-1, topic_number=-1,
ln=cdslang):
"""Create basket interface"""
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourbaskets.py/manage_rights")
ln = wash_language(ln)
_ = gettext_set_language(ln)
create_in_topic = wash_url_argument(create_in_topic, 'int')
if new_basket_name and (new_topic_name or create_in_topic != -1):
topic = perform_request_create_basket(uid=uid, new_basket_name=new_basket_name,
new_topic_name=new_topic_name,
create_in_topic=create_in_topic)
url = weburl + '/yourbaskets.py/display?category=%s&topic=%i&ln=%s'
url %= (cfg_webbasket_categories['PRIVATE'], int(topic), ln)
redirect_to_url(req, url)
else:
(body, errors, warnings) = perform_request_create_basket(uid=uid,
new_basket_name=new_basket_name,
new_topic_name=new_topic_name,
create_in_topic=create_in_topic,
topic_number=topic_number,
ln=ln)
navtrail = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
navtrail %= (weburl, _("Your Account"))
if isGuestUser(uid):
body = create_guest_warning_box(ln) + body
return page(title = _("Create basket"),
body = body,
navtrail = navtrail,
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def display_public(req,bskid=0, of='hb', ln=cdslang):
"""Display public basket. If of is x** then output will be XML"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
return page_not_authorized(req, "../yourbaskets.py/display_public")
of = wash_url_argument(of, 'str')
if len(of) and of[0]=='x':
req.content_type = "text/xml"
req.send_http_header()
return perform_request_display_public(bskid=bskid, of=of, ln=ln)
(body, errors, warnings) = perform_request_display_public(bskid=bskid, ln=ln)
return page(title = _("Public basket"),
body = body,
navtrail = '',
uid = uid,
lastupdated = __lastupdated__,
language = ln,
errors = errors,
warnings = warnings,
req = req)
def unsubscribe(req, bskid=0, ln=cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
return page_not_authorized(req, "../yourbaskets.py/unsubscribe")
perform_request_unsubscribe(uid, bskid)
url = weburl + '/yourbaskets.py/display?category=%s&ln=%s'
url %= (cfg_webbasket_categories['EXTERNAL'], ln)
redirect_to_url(req, url)
def subscribe(req, bskid=0, ln=cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
return page_not_authorized(req, "../yourbaskets.py/subscribe")
errors = perform_request_subscribe(uid, bskid)
if len(errors):
return page(errors=errors, uid=uid, language=ln, req=req)
url = weburl + '/yourbaskets.py/display?category=%s&ln=%s'
url %= (cfg_webbasket_categories['EXTERNAL'], ln)
redirect_to_url(req, url)
\ No newline at end of file
diff --git a/modules/webcomment/Makefile.am b/modules/webcomment/Makefile.am
index 18a27e626..318941606 100644
--- a/modules/webcomment/Makefile.am
+++ b/modules/webcomment/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = lib doc web
CLEANFILES = *~
diff --git a/modules/webcomment/doc/Makefile.am b/modules/webcomment/doc/Makefile.am
index 98f8cd936..dcf956ced 100644
--- a/modules/webcomment/doc/Makefile.am
+++ b/modules/webcomment/doc/Makefile.am
@@ -1,21 +1,21 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
diff --git a/modules/webcomment/doc/admin/Makefile.am b/modules/webcomment/doc/admin/Makefile.am
index 2b7f63da4..3f13d6e4a 100644
--- a/modules/webcomment/doc/admin/Makefile.am
+++ b/modules/webcomment/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webcomment
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webcomment/doc/admin/guide.html.wml b/modules/webcomment/doc/admin/guide.html.wml
index a1db8cba3..b4f7089e5 100644
--- a/modules/webcomment/doc/admin/guide.html.wml
+++ b/modules/webcomment/doc/admin/guide.html.wml
@@ -1,27 +1,27 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebComment Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/webcomment/>WebComment Admin</a>" \
navbar_name="admin" \
navbar_select="webcomment-admin-guide"
FIXME
diff --git a/modules/webcomment/doc/admin/index.html.wml b/modules/webcomment/doc/admin/index.html.wml
index 8b23b8280..079e36449 100644
--- a/modules/webcomment/doc/admin/index.html.wml
+++ b/modules/webcomment/doc/admin/index.html.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebComment Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="webcomment"
<p>
This is the gate to the admin area for WebComment. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/webcomment/">login</a> to enter.
</p>
<dl>
<dt><a href="webcommentadmin.py">WebComment Admin Interface</a></dt>
<dd>Start area for WebComment administration.</dd>
</dl>
<dl>
<dt><a href="guide.html">WebComment Admin Guide</a></dt>
<dd>Everything you want to know about WebComment administration</dd>
</dl>
diff --git a/modules/webcomment/doc/hacking/Makefile.am b/modules/webcomment/doc/hacking/Makefile.am
index 5ac343f5b..62c31f5ee 100644
--- a/modules/webcomment/doc/hacking/Makefile.am
+++ b/modules/webcomment/doc/hacking/Makefile.am
@@ -1,21 +1,21 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/webcomment
diff --git a/modules/webcomment/lib/Makefile.am b/modules/webcomment/lib/Makefile.am
index 97ab2552f..b1e792559 100644
--- a/modules/webcomment/lib/Makefile.am
+++ b/modules/webcomment/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = webcomment_config.py webcomment.py webcomment_tests.py webcomment_templates.py webcommentadminlib.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webcomment/lib/webcomment.py b/modules/webcomment/lib/webcomment.py
index ca9ec611b..5f7b1ae05 100644
--- a/modules/webcomment/lib/webcomment.py
+++ b/modules/webcomment/lib/webcomment.py
@@ -1,1021 +1,1021 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Comments and reviews for records """
__lastupdated__ = """$Date$"""
# non CDSware imports:
import time
import math
# CDSware imports:
from cdsware.dbquery import run_sql
from cdsware.config import cdslang, \
alertengineemail,\
adminemail,\
weburl,\
cfg_webcomment_allow_reviews,\
cfg_webcomment_allow_comments,\
cfg_webcomment_admin_notification_level,\
cfg_webcomment_nb_reviews_in_detailed_view,\
cfg_webcomment_nb_reports_before_send_email_to_admin,\
cfg_webcomment_nb_comments_in_detailed_view,\
cfg_webcomment_timelimit_processing_comments_in_seconds,\
cfg_webcomment_timelimit_processing_reviews_in_seconds
from cdsware.webmessage_mailutils import email_quote_txt
from cdsware.webuser import get_user_info
from cdsware.dateutils import convert_datetext_to_dategui, \
datetext_default, \
convert_datestruct_to_datetext
from cdsware.messages import wash_language, gettext_set_language
from cdsware.urlutils import wash_url_argument
from cdsware.webuser import isGuestUser
from cdsware.webcomment_config import cfg_webcomment_action_code
try:
import cdsware.template
webcomment_templates = cdsware.template.load('webcomment')
except:
pass
def perform_request_display_comments_or_remarks(recID, ln=cdslang, display_order='od', display_since='all', nb_per_page=100, page=1, voted=-1, reported=-1, reviews=0):
"""
Returns all the comments (reviews) of a specific internal record or external basket record.
@param recID: record id where (internal record IDs > 0) or (external basket record IDs < -100)
@param display_order: hh = highest helpful score, review only
lh = lowest helpful score, review only
hs = highest star score, review only
ls = lowest star score, review only
od = oldest date
nd = newest date
@param display_since: all= no filtering by date
nd = n days ago
nw = n weeks ago
nm = n months ago
ny = n years ago
where n is a single digit integer between 0 and 9
@param nb_per_page: number of results per page
@param page: results page
@param voted: boolean, active if user voted for a review, see perform_request_vote function
@param reported: boolean, active if user reported a certain comment/review, perform_request_report function
@param reviews: boolean, enabled if reviews, disabled for comments
@return html body.
"""
errors = []
warnings = []
# wash arguments
recID = wash_url_argument(recID, 'int')
ln = wash_language(ln)
display_order = wash_url_argument(display_order, 'str')
display_since = wash_url_argument(display_since, 'str')
nb_per_page = wash_url_argument(nb_per_page, 'int')
page = wash_url_argument(page, 'int')
voted = wash_url_argument(voted, 'int')
reported = wash_url_argument(reported, 'int')
reviews = wash_url_argument(reviews, 'int')
# vital argument check
(valid, error_body) = check_recID_is_in_range(recID, warnings, ln)
if not(valid):
return (error_body, errors, warnings)
# Query the database and filter results
res = query_retrieve_comments_or_remarks(recID, display_order, display_since, reviews)
nb_res = len(res)
# checking non vital arguemnts - will be set to default if wrong
#if page <= 0 or page.lower() != 'all':
if page < 0:
page = 1
warnings.append(('WRN_WEBCOMMENT_INVALID_PAGE_NB',))
if nb_per_page < 0:
nb_per_page = 100
warnings.append(('WRN_WEBCOMMENT_INVALID_NB_RESULTS_PER_PAGE',))
if cfg_webcomment_allow_reviews and reviews:
if display_order not in ['od', 'nd', 'hh', 'lh', 'hs', 'ls']:
display_order = 'hh'
warnings.append(('WRN_WEBCOMMENT_INVALID_REVIEW_DISPLAY_ORDER',))
else:
if display_order not in ['od', 'nd']:
display_order = 'od'
warnings.append(('WRN_WEBCOMMENT_INVALID_DISPLAY_ORDER',))
# filter results according to page and number of reults per page
if nb_per_page > 0:
if nb_res > 0:
last_page = int(math.ceil(nb_res / float(nb_per_page)))
else:
last_page = 1
if page > last_page:
page = 1
warnings.append(("WRN_WEBCOMMENT_INVALID_PAGE_NB",))
if nb_res > nb_per_page: # if more than one page of results
if page < last_page:
res = res[(page-1)*(nb_per_page) : (page*nb_per_page)]
else:
res = res[(page-1)*(nb_per_page) : ]
else: # one page of results
pass
else:
last_page = 1
# Send to template
avg_score = 0.0
if not cfg_webcomment_allow_comments and not cfg_webcomment_allow_reviews: # comments not allowed by admin
errors.append(('ERR_WEBCOMMENT_COMMENTS_NOT_ALLOWED',))
if reported > 0:
warnings.append(('WRN_WEBCOMMENT_FEEDBACK_RECORDED',))
elif reported == 0:
warnings.append(('WRN_WEBCOMMENT_ALREADY_REPORTED',))
if cfg_webcomment_allow_reviews and reviews:
avg_score = calculate_avg_score(res)
if voted > 0:
warnings.append(('WRN_WEBCOMMENT_FEEDBACK_RECORDED',))
elif voted == 0:
warnings.append(('WRN_WEBCOMMENT_ALREADY_VOTED',))
body = webcomment_templates.tmpl_get_comments(recID,
ln,
nb_per_page, page, last_page,
display_order, display_since,
cfg_webcomment_allow_reviews,
res, nb_res, avg_score,
warnings,
border=0,
reviews=reviews)
return (body, errors, warnings)
def perform_request_vote(cmt_id, client_ip_address, value, uid=-1):
"""
Vote positively or negatively for a comment/review
@param cmt_id: review id
@param value: +1 for voting positively
-1 for voting negatively
@return integer 1 if successful, integer 0 if not
"""
cmt_id = wash_url_argument(cmt_id, 'int')
client_ip_address = wash_url_argument(client_ip_address, 'str')
value = wash_url_argument(value, 'int')
uid = wash_url_argument(uid, 'int')
if cmt_id > 0 and value in [-1, 1] and check_user_can_vote(cmt_id, client_ip_address, uid):
action_date = convert_datestruct_to_datetext(time.localtime())
action_code = cfg_webcomment_action_code['VOTE']
query = """INSERT INTO cmtACTIONHISTORY
VALUES (%i, NULL ,%i, inet_aton('%s'), '%s', '%s')"""
query %= (cmt_id, uid, client_ip_address, action_date, action_code)
run_sql(query)
return query_record_useful_review(cmt_id, value)
else:
return 0
def check_user_can_comment(recID, client_ip_address, uid=-1):
""" Check if a user hasn't already commented within the last seconds
time limit: cfg_webcomment_timelimit_processing_comments_in_seconds
@param recID: record id
@param client_ip_address: IP => use: str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
@param uid: user id, as given by cdsware.webuser.getUid(req)
"""
recID = wash_url_argument(recID, 'int')
client_ip_address = wash_url_argument(client_ip_address, 'str')
uid = wash_url_argument(uid, 'int')
max_action_time = time.time() - cfg_webcomment_timelimit_processing_comments_in_seconds
max_action_time = convert_datestruct_to_datetext(time.localtime(max_action_time))
action_code = cfg_webcomment_action_code['ADD_COMMENT']
query = """SELECT id_bibrec
FROM cmtACTIONHISTORY
WHERE id_bibrec=%i AND
action_code='%s' AND
action_time>'%s'
""" % (recID, action_code, max_action_time)
if uid < 0:
query += " AND client_host=inet_aton('%s')" % client_ip_address
else:
query += " AND id_user=%i" % uid
res = run_sql(query)
return len(res) == 0
def check_user_can_review(recID, client_ip_address, uid=-1):
""" Check if a user hasn't already reviewed within the last seconds
time limit: cfg_webcomment_timelimit_processing_reviewss_in_seconds
@param cmt_id: comment id
@param client_ip_address: IP => use: str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
@param uid: user id, as given by cdsware.webuser.getUid(req)
"""
recID = wash_url_argument(recID, 'int')
client_ip_address = wash_url_argument(client_ip_address, 'str')
uid = wash_url_argument(uid, 'int')
max_action_time = time.time() - cfg_webcomment_timelimit_processing_reviews_in_seconds
max_action_time = convert_datestruct_to_datetext(time.localtime(max_action_time))
action_code = cfg_webcomment_action_code['ADD_REVIEW']
query = """SELECT id_bibrec
FROM cmtACTIONHISTORY
WHERE id_bibrec=%i AND
action_code='%s' AND
action_time>'%s'
""" % (recID, action_code, max_action_time)
if uid < 0:
query += " AND client_host=inet_aton('%s')" % client_ip_address
else:
query += " AND id_user=%i" % uid
res = run_sql(query)
return len(res) == 0
def check_user_can_vote(cmt_id, client_ip_address, uid=-1):
""" Checks if a user hasn't already voted
@param cmt_id: comment id
@param client_ip_address: IP => use: str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
@param uid: user id, as given by cdsware.webuser.getUid(req)
"""
cmt_id = wash_url_argument(cmt_id, 'int')
client_ip_address = wash_url_argument(client_ip_address, 'str')
uid = wash_url_argument(uid, 'int')
query = """SELECT id_cmtRECORDCOMMENT
FROM cmtACTIONHISTORY
WHERE id_cmtRECORDCOMMENT=%i""" % cmt_id
if uid < 0:
query += " AND client_host=inet_aton('%s')" % client_ip_address
else:
query += " AND id_user=%i" % uid
res = run_sql(query)
return (len(res) == 0)
def perform_request_report(cmt_id, client_ip_address, uid=-1):
"""
Report a comment/review for inappropriate content.
Will send an email to the administrator if number of reports is a multiple of config.py/cfg_comment_nb_reports_before_send_email_to_admin
@param cmt_id: comment id
@return integer 1 if successful, integer 0 if not
"""
cmt_id = wash_url_argument(cmt_id, 'int')
if cmt_id <= 0:
return 0
(query_res, nb_abuse_reports) = query_record_report_this(cmt_id)
if query_res == 0:
return 0
if not(check_user_can_report(cmt_id, client_ip_address, uid)):
return 0
action_date = convert_datestruct_to_datetext(time.localtime())
action_code = cfg_webcomment_action_code['REPORT_ABUSE']
query = """INSERT INTO cmtACTIONHISTORY
VALUES (%i, NULL, %i, inet_aton('%s'), '%s', '%s')"""
query %= (cmt_id, uid, client_ip_address, action_date, action_code)
run_sql(query)
if nb_abuse_reports % cfg_webcomment_nb_reports_before_send_email_to_admin == 0:
(cmt_id2,
id_bibrec,
id_user,
cmt_body,
cmt_date,
cmt_star,
cmt_vote, cmt_nb_votes_total,
cmt_title,
cmt_reported) = query_get_comment(cmt_id)
(user_nb_abuse_reports,
user_votes,
user_nb_votes_total) = query_get_user_reports_and_votes(int(id_user))
(nickname, user_email, last_login) = query_get_user_contact_info(id_user)
from_addr = 'CDS Alert Engine <%s>' % alertengineemail
to_addr = adminemail
subject = "An error report has been sent from a user"
body = '''
The following comment has been reported a total of %(cmt_reported)s times.
Author: nickname = %(nickname)s
email = %(user_email)s
user_id = %(uid)s
This user has:
total number of reports = %(user_nb_abuse_reports)s
%(votes)s
Comment: comment_id = %(cmt_id)s
record_id = %(id_bibrec)s
date written = %(cmt_date)s
nb reports = %(cmt_reported)s
%(review_stuff)s
body =
---start body---
%(cmt_body)s
---end body---
Please go to the Comments Admin Panel %(comment_admin_link)s to delete this message if necessary. A warning will be sent to the user in question.''' % \
{ 'cfg-report_max' : cfg_webcomment_nb_reports_before_send_email_to_admin,
'nickname' : nickname,
'user_email' : user_email,
'uid' : id_user,
'user_nb_abuse_reports' : user_nb_abuse_reports,
'user_votes' : user_votes,
'votes' : cfg_webcomment_allow_reviews and \
"total number of positive votes\t= %s\n\t\t\t\ttotal number of negative votes\t= %s" % \
(user_votes, (user_nb_votes_total - user_votes)) or "\n",
'cmt_id' : cmt_id,
'id_bibrec' : id_bibrec,
'cmt_date' : cmt_date,
'cmt_reported' : cmt_reported,
'review_stuff' : cfg_webcomment_allow_reviews and \
"star score\t\t= %s\n\t\t\treview title\t\t= %s" % (cmt_star, cmt_title) or "",
'cmt_body' : cmt_body,
'comment_admin_link' : "http://%s/admin/webcomment/" % weburl,
'user_admin_link' : "user_admin_link" #! FIXME
}
#FIXME to be added to email when websession module is over:
#If you wish to ban the user, you can do so via the User Admin Panel %(user_admin_link)s.
from cdsware.alert_engine import send_email, forge_email
body = forge_email(from_addr, to_addr, subject, body)
send_email(from_addr, to_addr, body)
return 1
def check_user_can_report(cmt_id, client_ip_address, uid=-1):
""" Checks if a user hasn't already reported a comment
@param cmt_id: comment id
@param client_ip_address: IP => use: str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
@param uid: user id, as given by cdsware.webuser.getUid(req)
"""
cmt_id = wash_url_argument(cmt_id, 'int')
client_ip_address = wash_url_argument(client_ip_address, 'str')
uid = wash_url_argument(uid, 'int')
query = """SELECT id_cmtRECORDCOMMENT
FROM cmtACTIONHISTORY
WHERE id_cmtRECORDCOMMENT=%i""" % cmt_id
if uid < 0:
query += " AND client_host=inet_aton('%s')" % client_ip_address
else:
query += " AND id_user=%i" % uid
res = run_sql(query)
return (len(res) == 0)
def query_get_user_contact_info(uid):
"""
Get the user contact information
@return tuple (nickname, email, last_login), if none found return ()
Note: for the moment, if no nickname, will return email address up to the '@'
"""
query1 = """SELECT email,
nickname,
DATE_FORMAT(last_login, '%%Y-%%m-%%d %%H:%%i:%%s')
FROM user WHERE id=%s"""
params1 = (uid,)
res1 = run_sql(query1, params1)
if res1:
return res1[0]
else:
return ()
def query_get_user_reports_and_votes(uid):
"""
Retrieve total number of reports and votes of a particular user
@param uid: user id
@return tuple (total_nb_reports, total_nb_votes_yes, total_nb_votes_total)
if none found return ()
"""
query1 = """SELECT nb_votes_yes,
nb_votes_total,
nb_abuse_reports
FROM cmtRECORDCOMMENT
WHERE id_user=%s"""
params1 = (uid,)
res1 = run_sql(query1, params1)
if len(res1) == 0:
return ()
nb_votes_yes = nb_votes_total = nb_abuse_reports = 0
for cmt_tuple in res1:
nb_votes_yes += int(cmt_tuple[0])
nb_votes_total += int(cmt_tuple[1])
nb_abuse_reports += int(cmt_tuple[2])
return (nb_abuse_reports, nb_votes_yes, nb_votes_total)
def query_get_comment(comID):
"""
Get all fields of a comment
@param comID: comment id
@return tuple (comID, id_bibrec, id_user, body, date_creation, star_score, nb_votes_yes, nb_votes_total, title, nb_abuse_reports)
if none found return ()
"""
query1 = """SELECT id,
id_bibrec,
id_user,
body,
DATE_FORMAT(date_creation, '%%Y-%%m-%%d %%H:%%i:%%s'),
star_score,
nb_votes_yes,
nb_votes_total,
title,
nb_abuse_reports
FROM cmtRECORDCOMMENT
WHERE id=%s"""
params1 = (comID,)
res1 = run_sql(query1, params1)
if len(res1)>0:
return res1[0]
else:
return ()
def query_record_report_this(comID):
"""
Increment the number of reports for a comment
@param comID: comment id
@return tuple (success, new_total_nb_reports_for_this_comment) where
success is integer 1 if success, integer 0 if not
if none found, return ()
"""
#retrieve nb_abuse_reports
query1 = "SELECT nb_abuse_reports FROM cmtRECORDCOMMENT WHERE id=%s"
params1 = (comID,)
res1 = run_sql(query1, params1)
if len(res1)==0:
return ()
#increment and update
nb_abuse_reports = int(res1[0][0]) + 1
query2 = "UPDATE cmtRECORDCOMMENT SET nb_abuse_reports=%s WHERE id=%s"
params2 = (nb_abuse_reports, comID)
res2 = run_sql(query2, params2)
return (int(res2), nb_abuse_reports)
def query_record_useful_review(comID, value):
"""
private funciton
Adjust the number of useful votes and number of total votes for a comment.
@param comID: comment id
@param value: +1 or -1
@return integer 1 if successful, integer 0 if not
"""
# retrieve nb_useful votes
query1 = "SELECT nb_votes_total, nb_votes_yes FROM cmtRECORDCOMMENT WHERE id=%s"
params1 = (comID,)
res1 = run_sql(query1, params1)
if len(res1)==0:
return 0
# modify and insert new nb_useful votes
nb_votes_yes = int(res1[0][1])
if value >= 1:
nb_votes_yes = int(res1[0][1]) + 1
nb_votes_total = int(res1[0][0]) + 1
query2 = "UPDATE cmtRECORDCOMMENT SET nb_votes_total=%s, nb_votes_yes=%s WHERE id=%s"
params2 = (nb_votes_total, nb_votes_yes, comID)
res2 = run_sql(query2, params2)
return int(res2)
def query_retrieve_comments_or_remarks (recID, display_order='od', display_since='0000-00-00 00:00:00', ranking=0):
"""
Private function
Retrieve tuple of comments or remarks from the database
@param recID: record id
@param display_order: hh = highest helpful score
lh = lowest helpful score
hs = highest star score
ls = lowest star score
od = oldest date
nd = newest date
@param display_since: datetime, e.g. 0000-00-00 00:00:00
@param ranking: boolean, enabled if reviews, disabled for comments
@return tuple of comment where comment is
tuple (nickname, date_creation, body, id) if ranking disabled or
tuple (nickname, date_creation, body, nb_votes_yes, nb_votes_total, star_score, title, id)
Note: for the moment, if no nickname, will return email address up to '@'
"""
display_since = calculate_start_date(display_since)
order_dict = { 'hh' : "cmt.nb_votes_yes/(cmt.nb_votes_total+1) DESC, cmt.date_creation DESC ",
'lh' : "cmt.nb_votes_yes/(cmt.nb_votes_total+1) ASC, cmt.date_creation ASC ",
'ls' : "cmt.star_score ASC, cmt.date_creation DESC ",
'hs' : "cmt.star_score DESC, cmt.date_creation DESC ",
'od' : "cmt.date_creation ASC ",
'nd' : "cmt.date_creation DESC "
}
# Ranking only done for comments and when allowed
if ranking and recID > 0:
try:
display_order = order_dict[display_order]
except:
display_order = order_dict['od']
else:
# in case of recID > 0 => external record => no ranking!
ranking = 0
try:
if display_order[-1] == 'd':
display_order = order_dict[display_order]
else:
display_order = order_dict['od']
except:
display_order = order_dict['od']
query = """SELECT user.nickname,
cmt.id_user,
DATE_FORMAT(cmt.date_creation, '%%Y-%%m-%%d %%H:%%i:%%s'),
cmt.body,
%(ranking)s cmt.id
FROM %(table)s cmt LEFT JOIN user ON
user.id=cmt.id_user
WHERE %(id_bibrec)s=%(recID)i
%(ranking_only)s
%(display_since)s
ORDER BY %(display_order)s"""
params = { 'ranking' : ranking and ' cmt.nb_votes_yes, cmt.nb_votes_total, cmt.star_score, cmt.title, ' or '',
'ranking_only' : ranking and ' AND cmt.star_score>0 ' or ' AND cmt.star_score=0 ',
'id_bibrec' : recID > 0 and 'cmt.id_bibrec' or 'cmt.id_bibrec_or_bskEXTREC',
'table' : recID > 0 and 'cmtRECORDCOMMENT' or 'bskRECORDCOMMENT',
'recID' : recID,
'display_since' : display_since=='0000-00-00 00:00:00' and ' ' or 'AND cmt.date_creation>=\'%s\' ' % display_since,
'display_order' : display_order
}
res = run_sql(query % params)
if res:
return res
return ()
def query_add_comment_or_remark(reviews=0, recID=0, uid=-1, msg="", note="", score=0, priority=0, client_ip_address=''):
"""
Private function
Insert a comment/review or remarkinto the database
@param recID: record id
@param uid: user id
@param msg: comment body
@param note: comment title
@param score: review star score
@param priority: remark priority #!FIXME
@return integer >0 representing id if successful, integer 0 if not
"""
current_date = calculate_start_date('0d')
#change utf-8 message into general unicode
msg = msg.decode('utf-8')
note = note.decode('utf-8')
#change general unicode back to utf-8
msg = msg.encode('utf-8')
note = note.encode('utf-8')
query = """INSERT INTO cmtRECORDCOMMENT (id_bibrec,
id_user,
body,
date_creation,
star_score,
nb_votes_total,
title)
VALUES (%s, %s, %s, %s, %s, %s, %s)"""
params = (recID, uid, msg, current_date, score, 0, note)
res = run_sql(query, params)
if res:
action_code = cfg_webcomment_action_code[reviews and 'ADD_REVIEW' or 'ADD_COMMENT']
action_time = convert_datestruct_to_datetext(time.localtime())
query2 = """INSERT INTO cmtACTIONHISTORY
values ('', %i, %i, inet_aton('%s'), '%s', '%s')"""
params2 = (recID, uid, client_ip_address, action_time, action_code)
run_sql(query2%params2)
return int(res)
def calculate_start_date(display_since):
"""
Private function
Returns the datetime of display_since argument in MYSQL datetime format
calculated according to the local time.
@param display_since = all= no filtering
nd = n days ago
nw = n weeks ago
nm = n months ago
ny = n years ago
where n is a single digit number
@return string of wanted datetime.
If 'all' given as argument, will return datetext_default
datetext_default is defined in miscutils/lib/dateutils and
equals 0000-00-00 00:00:00 => MySQL format
If bad arguement given, will return datetext_default
"""
# time type and seconds coefficients
time_types = {'d':0, 'w':0, 'm':0, 'y':0}
## verify argument
# argument wrong size
if (display_since==(None or 'all')) or (len(display_since) > 2):
return datetext_default
try:
nb = int(display_since[0])
except:
return datetext_default
if str(display_since[1]) in time_types:
time_type = str(display_since[1])
else:
return datetext_default
## calculate date
# initialize the coef
if time_type == 'w':
time_types[time_type] = 7
else:
time_types[time_type] = 1
start_time = time.localtime()
start_time = (start_time[0] - nb*time_types['y'],
start_time[1] - nb*time_types['m'],
start_time[2] - nb*time_types['d'] - nb*time_types['w'],
start_time[3],
start_time[4],
start_time[5],
start_time[6],
start_time[7],
start_time[8])
return convert_datestruct_to_datetext(start_time)
def get_first_comments_or_remarks(recID=-1,
ln=cdslang,
nb_comments='all',
nb_reviews='all',
voted=-1,
reported=-1):
"""
Gets nb number comments/reviews or remarks.
In the case of comments, will get both comments and reviews
Comments and remarks sorted by most recent date, reviews sorted by highest helpful score
@param recID: record id
@param ln: language
@param nb: number of comment/reviews or remarks to get
@param voted: 1 if user has voted for a remark
@param reported: 1 if user has reported a comment or review
@return if comment, tuple (comments, reviews) both being html of first nb comments/reviews
if remark, tuple (remakrs, None)
"""
warnings = []
errors = []
voted = wash_url_argument(voted, 'int')
reported = wash_url_argument(reported, 'int')
## check recID argument
if type(recID) is not int:
return ()
if recID >= 1: #comment or review. NB: suppressed reference to basket (handled in webbasket)
if cfg_webcomment_allow_reviews:
res_reviews = query_retrieve_comments_or_remarks(recID=recID, display_order="hh", ranking=1)
nb_res_reviews = len(res_reviews)
## check nb argument
if type(nb_reviews) is int and nb_reviews < len(res_reviews):
first_res_reviews = res_reviews[:nb_reviews]
else:
if nb_res_reviews > cfg_webcomment_nb_reviews_in_detailed_view:
first_res_reviews = res_reviews[:cfg_webcomment_nb_reports_before_send_email_to_admin]
else:
first_res_reviews = res_reviews
if cfg_webcomment_allow_comments:
res_comments = query_retrieve_comments_or_remarks(recID=recID, display_order="od", ranking=0)
nb_res_comments = len(res_comments)
## check nb argument
if type(nb_comments) is int and nb_comments < len(res_comments):
first_res_comments = res_comments[:nb_comments]
else:
if nb_res_comments > cfg_webcomment_nb_comments_in_detailed_view:
first_res_comments = res_comments[:cfg_webcomment_nb_comments_in_detailed_view]
else:
first_res_comments = res_comments
else: #error
errors.append(('ERR_WEBCOMMENT_RECID_INVALID', recID)) #!FIXME dont return error anywhere since search page
# comment
if recID >= 1:
comments = reviews = ""
if reported > 0:
warnings.append(('WRN_WEBCOMMENT_FEEDBACK_RECORDED_GREEN_TEXT',))
elif reported == 0:
warnings.append(('WRN_WEBCOMMENT_FEEDBACK_NOT_RECORDED_RED_TEXT',))
if cfg_webcomment_allow_comments: # normal comments
comments = webcomment_templates.tmpl_get_first_comments_without_ranking(recID, ln, first_res_comments, nb_res_comments, warnings)
if cfg_webcomment_allow_reviews: # ranked comments
#calculate average score
avg_score = calculate_avg_score(res_reviews)
if voted > 0:
warnings.append(('WRN_WEBCOMMENT_FEEDBACK_RECORDED_GREEN_TEXT',))
elif voted == 0:
warnings.append(('WRN_WEBCOMMENT_FEEDBACK_NOT_RECORDED_RED_TEXT',))
reviews = webcomment_templates.tmpl_get_first_comments_with_ranking(recID, ln, first_res_reviews, nb_res_reviews, avg_score, warnings)
return (comments, reviews)
# remark
else:
return(webcomment_templates.tmpl_get_first_remarks(first_res_comments, ln, nb_res_comments), None)
def calculate_avg_score(res):
"""
private function
Calculate the avg score of reviews present in res
@param res: tuple of tuple returned from query_retrieve_comments_or_remarks
@return a float of the average score rounded to the closest 0.5
"""
c_nickname = 0
c_date_creation = 1
c_body = 2
c_nb_votes_yes = 3
c_nb_votes_total = 4
c_star_score = 5
c_title = 6
c_id = 7
avg_score = 0.0
nb_reviews = 0
for comment in res:
if comment[c_star_score] > 0:
avg_score += comment[c_star_score]
nb_reviews += 1
if nb_reviews == 0:
return 0.0
avg_score = avg_score / nb_reviews
avg_score_unit = avg_score - math.floor(avg_score)
if avg_score_unit < 0.25:
avg_score = math.floor(avg_score)
elif avg_score_unit > 0.75:
avg_score = math.floor(avg_score) + 1
else:
avg_score = math.floor(avg_score) + 0.5
if avg_score > 5:
avg_score = 5.0
return avg_score
def perform_request_add_comment_or_remark(recID=0,
uid=-1,
action='DISPLAY',
ln=cdslang,
msg=None,
score=None,
note=None,
priority=None,
reviews=0,
comID=-1,
client_ip_address=None):
"""
Add a comment/review or remark
@param recID: record id
@param uid: user id
@param action: 'DISPLAY' to display add form
'SUBMIT' to submit comment once form is filled
'REPLY' to reply to an existing comment
@param ln: language
@param msg: the body of the comment/review or remark
@param score: star score of the review
@param note: title of the review
@param priority: priority of remark
@param reviews: boolean, if enabled will add a review, if disabled will add a comment
@param comID: if replying, this is the comment id of the commetn are replying to
@return html add form if action is display or reply
html successful added form if action is submit
"""
warnings = []
errors = []
actions = ['DISPLAY', 'REPLY', 'SUBMIT']
## wash arguments
recID = wash_url_argument(recID, 'int')
uid = wash_url_argument(uid, 'int')
msg = wash_url_argument(msg, 'str')
score = wash_url_argument(score, 'int')
note = wash_url_argument(note, 'str')
priority = wash_url_argument(priority, 'int')
reviews = wash_url_argument(reviews, 'int')
comID = wash_url_argument(comID, 'int')
ln = wash_language(ln)
_ = gettext_set_language(ln)
## check arguments
check_recID_is_in_range(recID, warnings, ln)
if uid <= 0:
errors.append(('ERR_WEBCOMMENT_UID_INVALID', uid))
return ('', errors, warnings)
user_contact_info = query_get_user_contact_info(uid)
nickname = ''
if user_contact_info:
if user_contact_info[1]:
nickname = user_contact_info[1]
# show the form
if action == 'DISPLAY':
if reviews and cfg_webcomment_allow_reviews:
return (webcomment_templates.tmpl_add_comment_form_with_ranking(recID, uid, nickname, ln, msg, score, note, warnings), errors, warnings)
elif not reviews and cfg_webcomment_allow_comments:
return (webcomment_templates.tmpl_add_comment_form(recID, uid, nickname, ln, msg, warnings), errors, warnings)
else:
errors.append(('ERR_WEBCOMMENT_COMMENTS_NOT_ALLOWED',))
elif action == 'REPLY':
if reviews and cfg_webcomment_allow_reviews:
errors.append(('ERR_WEBCOMMENT_REPLY_REVIEW',))
return (webcomment_templates.tmpl_add_comment_form_with_ranking(recID, uid, nickname, ln, msg, score, note, warnings), errors, warnings)
elif not reviews and cfg_webcomment_allow_comments:
if comID > 0:
comment = query_get_comment(comID)
if comment:
user_info = get_user_info(comment[2])
if user_info:
date_creation = convert_datetext_to_dategui(str(comment[4]))
msg = _("%s wrote on %s:")% (user_info[2], date_creation)
msg += "\n\n" + comment[3]
msg = email_quote_txt(text=msg)
return (webcomment_templates.tmpl_add_comment_form(recID, uid, nickname, ln, msg, warnings), errors, warnings)
else:
errors.append(('ERR_WEBCOMMENT_COMMENTS_NOT_ALLOWED',))
# check before submitting form
elif action == 'SUBMIT':
if reviews and cfg_webcomment_allow_reviews:
if note.strip() in ["", "None"]:
warnings.append(('WRN_WEBCOMMENT_ADD_NO_TITLE',))
if score == 0 or score > 5:
warnings.append(("WRN_WEBCOMMENT_ADD_NO_SCORE",))
if msg.strip() in ["", "None"]:
warnings.append(('WRN_WEBCOMMENT_ADD_NO_BODY',))
# if no warnings, submit
if len(warnings) == 0:
if reviews:
can_submit = check_user_can_review(recID, client_ip_address, uid)
else:
can_submit = check_user_can_comment(recID, client_ip_address, uid)
if can_submit:
success = query_add_comment_or_remark(reviews, recID=recID, uid=uid, msg=msg,
note=note, score=score, priority=0,
client_ip_address=client_ip_address)
else:
success = 1 #already added!
if success > 0:
if cfg_webcomment_admin_notification_level > 0:
notify_admin_of_new_comment(comID=success)
return (webcomment_templates.tmpl_add_comment_successful(recID, ln, reviews), errors, warnings)
else:
errors.append(('ERR_WEBCOMMENT_DB_INSERT_ERROR'))
# if are warnings or if inserting comment failed, show user where warnings are
if reviews and cfg_webcomment_allow_reviews:
return (webcomment_templates.tmpl_add_comment_form_with_ranking(recID, uid, nickname, ln, msg, score, note, warnings), errors, warnings)
else:
return (webcomment_templates.tmpl_add_comment_form(recID, uid, nickname, ln, msg, warnings), errors, warnings)
# unknown action send to display
else:
warnings.append(('WRN_WEBCOMMENT_ADD_UNKNOWN_ACTION',))
if reviews and cfg_webcomment_allow_reviews:
return (webcomment_templates.tmpl_add_comment_form_with_ranking(recID, uid, ln, msg, score, note, warnings), errors, warnings)
else:
return (webcomment_templates.tmpl_add_comment_form(recID, uid, ln, msg, warnings), errors, warnings)
return ('', errors, warnings)
def notify_admin_of_new_comment(comID):
"""
Sends an email to the admin with details regarding comment with ID = comID
"""
comment = query_get_comment(comID)
if len(comment) > 0:
(comID2,
id_bibrec,
id_user,
body,
date_creation,
star_score, nb_votes_yes, nb_votes_total,
title,
nb_abuse_reports) = comment
else:
return
user_info = query_get_user_contact_info(id_user)
if len(user_info) > 0:
(nickname, email, last_login) = user_info
if not len(nickname) > 0:
nickname = email.split('@')[0]
else:
nickname = email = last_login = "ERROR: Could not retrieve"
from cdsware.search_engine import print_record
record = print_record(recID=id_bibrec, format='hs')
review_stuff = '''
Star score = %s
Title = %s''' % (star_score, title)
out = '''
The following %(comment_or_review)s has just been posted (%(date)s).
AUTHOR:
Nickname = %(nickname)s
Email = %(email)s
User ID = %(uid)s
RECORD CONCERNED:
Record ID = %(recID)s
Record =
<!-- start record details -->
%(record_details)s
<!-- end record details -->
%(comment_or_review_caps)s:
%(comment_or_review)s ID = %(comID)s %(review_stuff)s
Body =
<!-- start body -->
%(body)s
<!-- end body -->
ADMIN OPTIONS:
To delete comment go to %(weburl)s/admin/webcomment/webcommentadmin.py/delete?comid=%(comID)s
''' % \
{ 'comment_or_review' : star_score>0 and 'review' or 'comment',
'comment_or_review_caps': star_score>0 and 'REVIEW' or 'COMMENT',
'date' : date_creation,
'nickname' : nickname,
'email' : email,
'uid' : id_user,
'recID' : id_bibrec,
'record_details' : record,
'comID' : comID2,
'review_stuff' : star_score>0 and review_stuff or "",
'body' : body.replace('<br>','\n'),
'weburl' : weburl
}
from_addr = 'CDS Alert Engine <%s>' % alertengineemail
to_addr = adminemail
subject = "A new comment/review has just been posted"
from cdsware.alert_engine import send_email, forge_email
out = forge_email(from_addr, to_addr, subject, out)
send_email(from_addr, to_addr, out)
def check_recID_is_in_range(recID, warnings=[], ln=cdslang):
"""
Check that recID is >= 0
Append error messages to errors listi
@param recID: record id
@param warnings: the warnings list of the calling function
@return tuple (boolean, html) where boolean (1=true, 0=false)
and html is the body of the page to display if there was a problem
"""
# Make errors into a list if needed
if type(warnings) is not list:
errors = [warnings]
try:
recID = int(recID)
except:
pass
if type(recID) is int:
if recID > 0:
from cdsware.search_engine import record_exists
success = record_exists(recID)
if success == 1:
return (1,"")
else:
warnings.append(('ERR_WEBCOMMENT_RECID_INEXISTANT', recID))
return (0, webcomment_templates.tmpl_record_not_found(status='inexistant', recID=recID, ln=ln))
elif recID == 0:
warnings.append(('ERR_WEBCOMMENT_RECID_MISSING',))
return (0, webcomment_templates.tmpl_record_not_found(status='missing', recID=recID, ln=ln))
else:
warnings.append(('ERR_WEBCOMMENT_RECID_INVALID', recID))
return (0, webcomment_templates.tmpl_record_not_found(status='invalid', recID=recID, ln=ln))
else:
warnings.append(('ERR_WEBCOMMENT_RECID_NAN', recID))
return (0, webcomment_templates.tmpl_record_not_found(status='nan', recID=recID, ln=ln))
def check_int_arg_is_in_range(value, name, errors, gte_value, lte_value=None):
"""
Check that variable with name 'name' >= gte_value and optionally <= lte_value
Append error messages to errors list
@param value: variable value
@param name: variable name
@param errors: list of error tuples (error_id, value)
@param gte_value: greater than or equal to value
@param lte_value: less than or equal to value
@return boolean (1=true, 0=false)
"""
# Make errors into a list if needed
if type(errors) is not list:
errors = [errors]
if type(value) is not int or type(gte_value) is not int:
errors.append(('ERR_WEBCOMMENT_PROGRAMNING_ERROR',))
return 0
if type(value) is not int:
errors.append(('ERR_WEBCOMMENT_ARGUMENT_NAN', value))
return 0
if value < gte_value:
errors.append(('ERR_WEBCOMMENT_ARGUMENT_INVALID', value))
return 0
if lte_value:
if type(lte_value) is not int:
errors.append(('ERR_WEBCOMMENT_PROGRAMNING_ERROR',))
return 0
if value > lte_value:
errors.append(('ERR_WEBCOMMENT_ARGUMENT_INVALID', value))
return 0
return 1
diff --git a/modules/webcomment/lib/webcomment_config.py b/modules/webcomment/lib/webcomment_config.py
index 2eba6d9cc..135caba80 100644
--- a/modules/webcomment/lib/webcomment_config.py
+++ b/modules/webcomment/lib/webcomment_config.py
@@ -1,64 +1,64 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__lastupdated__ = """FIXME: last updated"""
cfg_webcomment_error_messages = \
{ 'ERR_WEBCOMMENT_RECID_INVALID' : '_("%s is an invalid record ID")',
'ERR_WEBCOMMENT_RECID_NAN' : '_("Record ID %s is not a number")',
'ERR_WEBCOMMENT_UID_INVALID' : '_("%s is an invalid user ID")',
'ERR_WEBCOMMENT_DB_ERROR' : '%s',
'ERR_WEBCOMMENT_COMMENTS_NOT_ALLOWED': '_("Comments on library record have been disallowed by the Administrator")',
'ERR_WEBCOMMENT_ARGUMENT_NAN' : '_("%s is not a number")',
'ERR_WEBCOMMENT_ARGUMENT_INVALID' : '_("%s invalid argument")',
'ERR_WEBCOMMENT_PROGRAMMING_ERROR' : '_("Programming error, please inform the Administrator")',
'ERR_WEBCOMMENT_FOR_TESTING_PURPOSES': ' THIS IS FOR TESTING PURPOSES ONLY var1=%s var2=%s var3=%s var4=%s var5=%s var6=%s ',
'ERR_WEBCOMMENT_REPLY_REVIEW' : '_("Cannot reply to a review")',
'ERR_WEBCOMMENT_DB_INSERT_ERROR' : '_("Failed to insert your comment to the database. Please try again.")'
}
cfg_webcomment_warning_messages = \
{ 'WRN_WEBCOMMENT_INVALID_PAGE_NB': '_("Bad page number --> showing first page")',
'WRN_WEBCOMMENT_INVALID_NB_RESULTS_PER_PAGE': '_("Bad number of results per page --> showing 10 results per page")',
'WRN_WEBCOMMENT_INVALID_REVIEW_DISPLAY_ORDER': '_("Bad display order --> showing most helpful first")',
'WRN_WEBCOMMENT_INVALID_DISPLAY_ORDER': '_("Bad display order --> showing oldest first")',
'WRN_WEBCOMMENT_FEEDBACK_RECORDED': '_("Your feedback has been recorded, many thanks")',
'WRN_WEBCOMMENT_FEEDBACK_NOT_RECORDED': '_("Your feedback could not be recorded, please try again")',
'WRN_WEBCOMMENT_ALREADY_VOTED': '_("Sorry, you have already voted. This vote hasn\'t been recorded.")',
'WRN_WEBCOMMENT_ALREADY_REPORTED': '_("You already have reported an abuse with this comment.")',
'WRN_WEBCOMMENT_ADD_NO_TITLE': '_("You must enter a title")',
'WRN_WEBCOMMENT_ADD_NO_SCORE': '_("You must choose a score")',
'WRN_WEBCOMMENT_ADD_NO_BODY': '_("You must enter a text")',
'WRN_WEBCOMMENT_ADD_UNKNOWN_ACTION': '_("Unknown action --> showing you the default add comment form")',
'WRN_WEBCOMMENT_ADMIN_COMID_NAN': '_("comment ID must be a number, try again")',
'WRN_WEBCOMMENT_ADMIN_INVALID_COMID': '_("Invalid comment ID, try again")',
'WRN_WEBCOMMENT_ADMIN_COMID_INEXISTANT': '_("Comment ID %s does not exist, try again")',
'ERR_WEBCOMMENT_RECID_MISSING': '_("No record ID was given")',
'ERR_WEBCOMMENT_RECID_INEXISTANT': '_("Record ID %s does not exist in the database")',
'ERR_WEBCOMMENT_RECID_INVALID': '_("Record ID %s is an invalid ID")',
'ERR_WEBCOMMENT_RECID_NAN': '_("Record ID %s is not a number")'
}
cfg_webcomment_action_code = {
'ADD_COMMENT': 'C',
'ADD_REVIEW': 'R',
'VOTE': 'V',
'REPORT_ABUSE': 'A'
}
diff --git a/modules/webcomment/lib/webcomment_templates.py b/modules/webcomment/lib/webcomment_templates.py
index 19f6300ad..71be91da9 100644
--- a/modules/webcomment/lib/webcomment_templates.py
+++ b/modules/webcomment/lib/webcomment_templates.py
@@ -1,1308 +1,1308 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""HTML Templates for commenting features """
__lastupdated__ = """$Date$"""
# non CDSware imports
import string
# CDSware imports
from cdsware.webuser import get_user_info
from cdsware.dateutils import convert_datetext_to_dategui
from cdsware.webmessage_mailutils import email_quoted_txt2html
from cdsware.config import weburl, \
cdslang, \
cdsnameintl,\
cfg_webcomment_nb_reviews_in_detailed_view, \
cfg_webcomment_allow_reviews, \
cfg_webcomment_allow_comments, \
cfg_webcomment_nb_comments_in_detailed_view
from cdsware.messages import gettext_set_language
from cdsware.textutils import indent_text
class Template:
"""templating class, refer to webcomment.py for examples of call"""
def tmpl_get_first_comments_without_ranking(self, recID, ln, comments, nb_comments_total, warnings):
"""
@param recID: record id
@param ln: language
@param comments: tuple as returned from webcomment.py/query_retrieve_comments_or_remarks
@param nb_comments_total: total number of comments for this record
@param warnings: list of warning tuples (warning_msg, arg1, arg2, ...)
@return html of comments
"""
# load the right message language
_ = gettext_set_language(ln)
# naming data fields of comments
c_nickname = 0
c_user_id = 1
c_date_creation = 2
c_body = 3
c_id = 4
warnings = self.tmpl_warnings(warnings, ln)
report_link = '%s/comments.py/report?recid=%s&amp;ln=%s&amp;comid=%%(comid)s&amp;reviews=0' % (weburl, recID, ln)
# comments
comment_rows = ''
for comment in comments:
if comment[c_nickname]:
nickname = comment[c_nickname]
display = nickname
else:
(uid, nickname, display) = get_user_info(comment[c_user_id])
messaging_link = self.create_messaging_link(nickname, display, ln)
comment_rows += """
<tr>
<td>"""
comment_rows += self.tmpl_get_comment_without_ranking(ln, messaging_link, comment[c_date_creation], comment[c_body])
comment_rows += """
<br><br>
</td>
</tr>"""
# write button
write_button_label = _("Write a comment")
write_button_link = '%s/comments.py/add' % (weburl,)
write_button_form = """ <input type="hidden" name="recid" value="%s"/>
<input type="hidden" name="ln" value="%s"/>
<input type="hidden" name="reviews" value="0"/>""" % (recID, ln)
write_button_form = self.createhiddenform(action=write_button_link, method="Get", text=write_button_form, button=write_button_label)
# output
if nb_comments_total > 0:
out = warnings
comments_label = cfg_webcomment_nb_comments_in_detailed_view and \
cfg_webcomment_nb_comments_in_detailed_view>1 and \
_("Showing the latest %i comments:")% cfg_webcomment_nb_comments_in_detailed_view or ""
out += """
<table>
<tr>
<td class="blocknote">%(comment_title)s</td>
</tr>
</table>
%(comments_label)s<br />
<table border="0" cellspacing="5" cellpadding="5" width="100%%">
%(comment_rows)s
</table>
%(view_all_comments_link)s
<br />
<br />
%(write_button_form)s<br />""" % \
{'comment_title': _("Discuss this document:"),
'comments_label': comments_label,
'nb_comments_total' : nb_comments_total,
'recID': recID,
'comment_rows': comment_rows,
'tab': '&nbsp;'*4,
'weburl': weburl,
's': cfg_webcomment_nb_comments_in_detailed_view>1 and 's' or "",
'view_all_comments_link': nb_comments_total>0 and '''<a href="%s/comments.py/display?recid=%s&amp;reviews=0">View all %s comments</a>''' \
% (weburl, recID, nb_comments_total) or "",
'write_button_form': write_button_form,
'nb_comments': cfg_webcomment_nb_comments_in_detailed_view>1 and cfg_webcomment_nb_comments_in_detailed_view or ""
}
else:
out = """
<!-- comments title table -->
<table>
<tr>
<td class="blocknote">%(discuss_label)s:</td>
</tr>
</table>
%(detailed_info)s
<br />
%(form)s
<br />""" % {'form': write_button_form,
'discuss_label': _("Discuss this document"),
'detailed_info': _("Start a discussion about any aspect of this document.")
}
return out
def tmpl_record_not_found(self, status='missing', recID="", ln=cdslang):
"""
Displays a page when bad or missing record ID was given.
@param status: 'missing' : no recID was given
'inexistant': recID doesn't have an entry in the database
'nan' : recID is not a number
'invalid' : recID is an error code, i.e. in the interval [-99,-1]
@param return: body of the page
"""
_ = gettext_set_language(ln)
if status == 'inexistant':
body = _("Sorry, the record %s does not seem to exist.") % (recID,)
elif status == 'nan':
body = _("Sorry, the record %s does not seem to be a number.") % (recID,)
elif status == 'invalid':
body = _("Sorry, the record %s is not a valid ID value.") % (recID,)
else:
body = _("Sorry, no record ID was provided.")
body += "<br /><br />"
link = "<a href=\"%s?ln=%s\">%s</a>." % (weburl, ln, cdsnameintl[ln])
body += _("You may want to start browsing from &s") % link
return body
def tmpl_get_first_comments_with_ranking(self, recID, ln, comments=None, nb_comments_total=None, avg_score=None, warnings=[]):
"""
@param recID: record id
@param ln: language
@param comments: tuple as returned from webcomment.py/query_retrieve_comments_or_remarks
@param nb_comments_total: total number of comments for this record
@param avg_score: average score of all reviews
@param warnings: list of warning tuples (warning_msg, arg1, arg2, ...)
@return html of comments
"""
# load the right message language
_ = gettext_set_language(ln)
# naming data fields of comments
c_nickname = 0
c_user_id = 1
c_date_creation = 2
c_body = 3
c_nb_votes_yes = 4
c_nb_votes_total = 5
c_star_score = 6
c_title = 7
c_id = 8
warnings = self.tmpl_warnings(warnings, ln)
#stars
if avg_score > 0:
avg_score_img = 'stars-' + str(avg_score).split('.')[0] + '-' + str(avg_score).split('.')[1] + '.png'
else:
avg_score_img = "stars-0-0.png"
# voting links
useful_dict = { 'weburl' : weburl,
'recID' : recID,
'ln' : ln,
'yes_img' : 'smchk_gr.gif', #'yes.gif',
'no_img' : 'iconcross.gif' #'no.gif'
}
link = '<a href="%(weburl)s/comments.py/vote?recid=%(recID)s&amp;ln=%(ln)s&amp;comid=%%(comid)s&amp;reviews=1' % useful_dict
useful_yes = link + '&amp;com_value=1">' + _("Yes") + '</a>'
useful_no = link + '&amp;com_value=-1">' + _("No") + '</a>'
report_link = '%(weburl)s/comments.py/report?recid=%(recID)s&amp;ln=%(ln)s&amp;comid=%%(comid)s&amp;reviews=1' % useful_dict
#comment row
comment_rows = ' '
for comment in comments:
if comment[c_nickname]:
nickname = comment[c_nickname]
display = nickname
else:
(uid, nickname, display) = get_user_info(comment[c_user_id])
messaging_link = self.create_messaging_link(nickname, display, ln)
comment_rows += '''
<tr>
<td>'''
comment_rows += self.tmpl_get_comment_with_ranking(ln, messaging_link, comment[c_date_creation], comment[c_body], comment[c_nb_votes_total], comment[c_nb_votes_yes], comment[c_star_score], comment[c_title])
comment_rows += '''
%s %s / %s<br />''' % (_("Was this review helpful?"), useful_yes % {'comid':comment[c_id]}, useful_no % {'comid':comment[c_id]})
comment_rows += '''
<br />
</td>
</tr>'''
# write button
write_button_link = '''%s/comments.py/add''' % (weburl,)
write_button_form = ''' <input type="hidden" name="recid" value="%s"/>
<input type="hidden" name="ln" value="%s"/>
<input type="hidden" name="reviews" value="1"/>''' % (recID, ln )
write_button_form = self.createhiddenform(action=write_button_link, method="Get", text=write_button_form, button=_("Write a review"))
if nb_comments_total > 0:
score = _("Average review score: %s based on %s reviews")
score %= ('</b><img src="%(weburl)s/img/%(avg_score_img)s" alt="%(avg_score)s" />',
'%(nb_comments_total)s')
score %= {'weburl': weburl,
'avg_score_img': avg_score_img,
'avg_score': avg_score,
'nb_comments_total': nb_comments_total}
useful_label = _("Readers found the following %s reviews to be most helpful.")
useful_label %= cfg_webcomment_nb_reviews_in_detailed_view > 1 and cfg_webcomment_nb_reviews_in_detailed_view or ""
view_all_comments_link ='<a href="%s/comments.py/display?recid=%s&amp;ln=%s&amp;do=hh&amp;reviews=1">' % (weburl, recID, ln)
view_all_comments_link += _("View all %s reviews") % nb_comments_total
view_all_comments_link += '</a><br />'
out = warnings + """
<!-- review title table -->
<table>
<tr>
<td class="blocknote">%(comment_title)s:</td>
</tr>
</table>
<b>%(score_label)s<br />
%(useful_label)s
<!-- review table -->
<table style="border: 0px; border-collapse: separate; border-spacing: 5px; padding: 5px; width: 100%%">
%(comment_rows)s
</table>
%(view_all_comments_link)s
%(write_button_form)s<br>
""" % \
{ 'comment_title' : _("Rate this document"),
'score_label' : score,
'useful_label' : useful_label,
'recID' : recID,
'view_all_comments' : _("view all %s reviews") % (nb_comments_total,),
'write_comment' : _("write a review"),
'comment_rows' : comment_rows,
'tab' : '&nbsp;'*4,
'weburl' : weburl,
'view_all_comments_link': nb_comments_total>0 and view_all_comments_link or "",
'write_button_form' : write_button_form
}
else:
out = '''
<!-- review title table -->
<table>
<tr>
<td class="blocknote">%s:</td>
</tr>
</table>
%s<br />
%s
<br>''' % (_("Rate this document"),
_("Be the first to review this document."),
write_button_form)
return out
def tmpl_get_comment_without_ranking(self, ln, nickname, date_creation, body, reply_link=None, report_link=None):
"""
private function
@param ln: language
@param nickname: nickname
@param date_creation: date comment was written
@param body: comment body
@param reply_link: if want reply and report, give the http links
@param repot_link: if want reply and report, give the http links
@return html table of comment
"""
# load the right message language
_ = gettext_set_language(ln)
date_creation = convert_datetext_to_dategui(date_creation)
out = ''
final_body = email_quoted_txt2html(body)
title = nickname + ' ' + _("wrote on") + ' <i>' + date_creation + '</i>'
links = '<a href="%s">' + _("Reply") +'</a>'
links += ' | '
links += '<a href="%s">' + _("Report abuse") + '</a>'
out += """
<table style="width: 100%%">
<tr>
<td>%(title)s</td>
<td align=right>%(links)s</td>
</tr>
<tr>
<td class="commentbox" colspan="2">
%(body)s
</td>
</tr>
</table>""" % \
{'title' : title,
'body' : indent_text(final_body, 3),
'links' : (report_link!=None and reply_link!=None) and links % (reply_link, report_link) or ""
}
return out
def tmpl_get_comment_with_ranking(self, ln, nickname, date_creation, body, nb_votes_total, nb_votes_yes, star_score, title):
"""
private function
@param ln: language
@param nickname: nickname
@param date_creation: date comment was written
@param body: comment body
@param nb_votes_total: total number of votes for this review
@param nb_votes_yes: number of positive votes for this record
@param star_score: star score for this record
@param title: title of review
@return html table of review
"""
# load the right message language
_ = gettext_set_language(ln)
if star_score > 0:
star_score_img = 'stars-' + str(star_score) + '-0.png'
else:
star_score_img = 'stars-0-0.png'
out = ""
date_creation = convert_datetext_to_dategui(date_creation)
reviewed_label = _("Reviewed by %s on %s") % (nickname, date_creation)
useful_label = _("%i out of %i people found this review useful")
useful_label %= (nb_votes_yes, nb_votes_total)
out += """
<table width="100%%">
<tr>
<td>
<img src="%(weburl)s/img/%(star_score_img)s" alt="%(star_score)s" style="margin-right:10px;"/><b>%(title)s</b><br />
%(reviewed_label)s<br />
%(useful_label)s
</td>
</tr>
<tr>
<td>
<blockquote>
%(body)s
</blockquote>
</td>
</tr>
</table>""" % {'weburl' : weburl,
'star_score_img': star_score_img,
'star_score' : star_score,
'title' : title,
'reviewed_label': reviewed_label,
'useful_label' : useful_label,
'body' : indent_text(body, 4)
}
return out
def tmpl_get_comments(self, recID, ln,
nb_per_page, page, nb_pages,
display_order, display_since,
cfg_webcomment_allow_reviews,
comments, total_nb_comments,
avg_score,
warnings,
border=0, reviews=0):
"""
Get table of all comments
@param recID: record id
@param ln: language
@param nb_per_page: number of results per page
@param page: page number
@param display_order: hh = highest helpful score, review only
lh = lowest helpful score, review only
hs = highest star score, review only
ls = lowest star score, review only
od = oldest date
nd = newest date
@param display_since: all= no filtering by date
nd = n days ago
nw = n weeks ago
nm = n months ago
ny = n years ago
where n is a single digit integer between 0 and 9
@param cfg_webcomment_allow_reviews: is ranking enable, get from config.py/cfg_webcomment_allow_reviews
@param comments: tuple as returned from webcomment.py/query_retrieve_comments_or_remarks
@param total_nb_comments: total number of comments for this record
@param avg_score: average score of reviews for this record
@param warnings: list of warning tuples (warning_msg, color)
@param border: boolean, active if want to show border around each comment/review
@param reviews: booelan, enabled for reviews, disabled for comments
"""
# load the right message language
_ = gettext_set_language(ln)
# naming data fields of comments
if reviews:
c_nickname = 0
c_user_id = 1
c_date_creation = 2
c_body = 3
c_nb_votes_yes = 4
c_nb_votes_total = 5
c_star_score = 6
c_title = 7
c_id = 8
else:
c_nickname = 0
c_user_id = 1
c_date_creation = 2
c_body = 3
c_id = 4
# voting links
useful_dict = { 'weburl' : weburl,
'recID' : recID,
'ln' : ln,
'do' : display_order,
'ds' : display_since,
'nb' : nb_per_page,
'p' : page,
'reviews' : reviews
}
useful_yes = '<a href="%(weburl)s/comments.py/vote?recid=%(recID)s&amp;ln=%(ln)s&amp;comid=%%(comid)s&amp;com_value=1&amp;do=%(do)s&amp;ds=%(ds)s&amp;nb=%(nb)s&amp;p=%(p)s&amp;reviews=%(reviews)s&amp;referer=%(weburl)s/comments.py/display">' + _("Yes") + '</a>'
useful_yes %= useful_dict
useful_no = '<a href="%(weburl)s/comments.py/vote?recid=%(recID)s&amp;ln=%(ln)s&amp;comid=%%(comid)s&amp;com_value=-1&amp;do=%(do)s&amp;ds=%(ds)s&amp;nb=%(nb)s&amp;p=%(p)s&amp;reviews=%(reviews)s&amp;referer=%(weburl)s/comments.py/display">' + _("No") + '</a>'
useful_no %= useful_dict
warnings = self.tmpl_warnings(warnings, ln)
## record details
from search_engine import print_record
record_details = print_record(recID=recID, format='hb')
link_dic = { 'weburl' : weburl,
'module' : 'comments.py',
'function' : 'index',
'arguments' : 'recid=%s&amp;do=%s&amp;ds=%s&amp;nb=%s&amp;reviews=%s' % (recID, display_order, display_since, nb_per_page, reviews),
'arg_page' : '&amp;p=%s' % page,
'page' : page }
## comments table
comments_rows = ''
for comment in comments:
if comment[c_nickname]:
nickname = comment[c_nickname]
display = nickname
else:
(uid, nickname, display) = get_user_info(comment[c_user_id])
messaging_link = self.create_messaging_link(nickname, display, ln)
# do NOT delete the HTML comment below. It is used for parsing... (I plead unguilty!)
comments_rows += """
<!-- start comment row -->
<tr>
<td>"""
if not reviews:
report_link = '%(weburl)s/comments.py/report?recid=%(recID)s&amp;ln=%(ln)s&amp;comid=%%(comid)s&amp;do=%(do)s&amp;ds=%(ds)s&amp;nb=%(nb)s&amp;p=%(p)s&amp;reviews=%(reviews)s&amp;referer=%(weburl)s/comments.py/display' % useful_dict % {'comid':comment[c_id]}
reply_link = '%(weburl)s/comments.py/add?recid=%(recID)s&amp;ln=%(ln)s&amp;action=REPLY&amp;comid=%%(comid)s' % useful_dict % {'comid':comment[c_id]}
comments_rows += indent_text(self.tmpl_get_comment_without_ranking(ln, messaging_link, comment[c_date_creation], comment[c_body], reply_link, report_link), 2)
else:
report_link = '%(weburl)s/comments.py/report?recid=%(recID)s&amp;ln=%(ln)s&amp;comid=%%(comid)s&amp;do=%(do)s&amp;ds=%(ds)s&amp;nb=%(nb)s&amp;p=%(p)s&amp;reviews=%(reviews)s&amp;referer=%(weburl)s/comments.py/display' % useful_dict % {'comid': comment[c_id]}
comments_rows += indent_text(self.tmpl_get_comment_with_ranking(ln, messaging_link, comment[c_date_creation], comment[c_body], comment[c_nb_votes_total], comment[c_nb_votes_yes], comment[c_star_score], comment[c_title]), 2)
helpful_label = _("Was this review helpful?")
report_abuse_label = _("(Report abuse)")
comments_rows += """
<table>
<tr>
<td>%(helpful_label)s %(tab)s</td>
<td> %(yes)s </td>
<td> / </td>
<td> %(no)s </td>
<td class="reportabuse">%(tab)s%(tab)s<a href="%(report)s">%(report_abuse_label)s</a></td>
</tr>
</table>""" \
% {'helpful_label': helpful_label,
'yes' : useful_yes % {'comid':comment[c_id]},
'no' : useful_no % {'comid':comment[c_id]},
'report' : report_link % {'comid':comment[c_id]},
'report_abuse_label': report_abuse_label,
'tab' : '&nbsp;'*2}
# do NOT remove HTML comment below. It is used for parsing...
comments_rows += """
</td>
</tr>
<!-- end comment row -->"""
## page links
page_links = ''
# Previous
if page != 1:
link_dic['arg_page'] = 'p=%s' % (page - 1)
page_links += '<a href=\"%(weburl)s/%(module)s/%(function)s?%(arguments)s&amp;%(arg_page)s\">&lt;&lt;</a> ' % link_dic
else:
page_links += ' %s ' % ('&nbsp;'*(len(_('< Previous'))+7))
# Page Numbers
for i in range(1, nb_pages+1):
link_dic['arg_page'] = 'p=%s' % i
link_dic['page'] = '%s' % i
if i != page:
page_links += '''
<a href=\"%(weburl)s/%(module)s/%(function)s?%(arguments)s&amp;%(arg_page)s\">%(page)s</a> ''' % link_dic
else:
page_links += ''' <b>%s</b> ''' % i
# Next
if page != nb_pages:
link_dic['arg_page'] = 'p=%s' % (page + 1)
page_links += '''
<a href=\"%(weburl)s/%(module)s/%(function)s?%(arguments)s&amp;%(arg_page)s\">&gt;&gt;</a> ''' % link_dic
else:
page_links += '%s' % ('&nbsp;'*(len(_('< Next'))+7))
## stuff for ranking if enabled
if reviews:
comments_or_reviews = _('review')
if avg_score > 0:
avg_score_img = 'stars-' + str(avg_score).split('.')[0] + '-' + str(avg_score).split('.')[1] + '.png'
else:
avg_score_img = "stars-0-0.png"
ranking_average = '<br /><b>' + _("Average review score")
ranking_average +=': </b><img src="%(weburl)s/img/%(avg_score_img)s" alt="%(avg_score)s" /> '
ranking_average += _("based on %(nb_comments_total)s reviews") + '<br />'
ranking_average %= { 'weburl' : weburl,
'avg_score' : avg_score,
'avg_score_img' : avg_score_img,
'nb_comments_total' : total_nb_comments }
else:
ranking_average = ""
comments_or_reviews = _('comment')
write_button_link = '''%s/comments.py/add''' % (weburl, )
write_button_form = ''' <input type="hidden" name="recid" value="%s"/>
<input type="hidden" name="ln" value="%s"/>
<input type="hidden" name="reviews" value="%s"/>''' % (recID, ln, reviews)
write_button_form = self.createhiddenform(action=write_button_link, method="Get", text=write_button_form, button=_('Write a %s') % comments_or_reviews)
cmts_label = comments_or_reviews
if comments_or_reviews == _("comment"):
if total_nb_comments > 1:
cmts_label = _("comments")
else:
if total_nb_comments > 1:
cmts_label = _("reviews")
total_label = _("There is a total of %s %s") % (total_nb_comments, cmts_label)
# do NOT remove the HTML comments below. Used for parsing
body = """
<table style="width: 100%%;">
<tr>
<td>
<h1>%(record_label)s %(recid)s</h1>
</td>
<td style="vertical-align:top; align=right" class="backtosearch">
<a href="%(weburl)s/search.py?recid=%(recid)s&amp;ln=%(ln)s">%(back_label)s</a>
</td>
</tr>
</table>
<br />
%(record_details)s
<h2>%(comments_or_reviews_title)s</h2>
%(total_label)s %(ranking_avg)s<br />
%(write_button_form)s<br />
<!-- start comments table -->
<table style="border: %(border)spx solid black; width: 100%%">
%(comments_rows)s
</table>
<!-- end comments table -->
<table style="width:100%%">
<tr>
<td>%(write_button_form_again)s</td>
<td style="align:right;" class="reportabuse">
<a href="%(weburl)s/search.py?recid=%(recid)s&amp;ln=%(ln)s">%(back_label)s</a>
</td>
</tr>
</table>
<br />""" % \
{ 'record_label': _("Record"),
'back_label': _("(Back to search results)"),
'total_label': total_label,
'record_details': record_details,
'write_button_form' : write_button_form,
'write_button_form_again' : total_nb_comments>3 and write_button_form or "",
'comments_rows' : indent_text(comments_rows, 1),
'total_nb_comments' : total_nb_comments,
'comments_or_reviews' : comments_or_reviews,
'comments_or_reviews_title' : comments_or_reviews[0].upper() + comments_or_reviews[1:],
'weburl' : weburl,
'module' : "comments.py",
'recid' : recID,
'ln' : ln,
'border' : border,
'ranking_avg' : ranking_average }
# form is not currently used. reserved for an eventual purpose
#form = """
# Display <select name="nb" size="1"> per page
# <option value="all">All</option>
# <option value="10">10</option>
# <option value="25">20</option>
# <option value="50">50</option>
# <option value="100" selected="selected">100</option>
# </select>
# comments per page that are <select name="ds" size="1">
# <option value="all" selected="selected">Any age</option>
# <option value="1d">1 day old</option>
# <option value="3d">3 days old</option>
# <option value="1w">1 week old</option>
# <option value="2w">2 weeks old</option>
# <option value="1m">1 month old</option>
# <option value="3m">3 months old</option>
# <option value="6m">6 months old</option>
# <option value="1y">1 year old</option>
# </select>
# and sorted by <select name="do" size="1">
# <option value="od" selected="selected">Oldest first</option>
# <option value="nd">Newest first</option>
# %s
# </select>
# """ % \
# (reviews==1 and '''
# <option value=\"hh\">most helpful</option>
# <option value=\"lh\">least helpful</option>
# <option value=\"hs\">highest star ranking</option>
# <option value=\"ls\">lowest star ranking</option>
# </select>''' or '''
# </select>''')
#
#form_link = "%(weburl)s/%(module)s/%(function)s" % link_dic
#form = self.createhiddenform(action=form_link, method="Get", text=form, button='Go', recid=recID, p=1)
pages = """
<br />
%(v_label)s %(comments_or_reviews)s %(results_nb_lower)s-%(results_nb_higher)s <br />
%(page_links)s <br />
""" % \
{'v_label': _("Viewing"),
'page_links': _("Page: ") + page_links ,
'comments_or_reviews': cmts_label,
'results_nb_lower': len(comments)>0 and ((page-1) * nb_per_page)+1 or 0,
'results_nb_higher': page == nb_pages and (((page-1) * nb_per_page) + len(comments)) or (page * nb_per_page) }
if nb_pages > 1:
#body = warnings + body + form + pages
body = warnings + body + pages
else:
body = warnings + body
return body
def create_messaging_link(self, to, display_name, ln=cdslang):
"""prints a link to the messaging system"""
link = "%s/yourmessages.py/write?msg_to=%s&amp;ln=%s" % (weburl, to, ln)
if to:
return '<a href="%s" class="maillink">%s</a>' % (link, display_name)
else:
return display_name
def createhiddenform(self, action="", method="Get", text="", button="confirm", cnfrm='', **hidden):
"""
create select with hidden values and submit button
@param action: name of the action to perform on submit
@param method: 'get' or 'post'
@param text: additional text, can also be used to add non hidden input
@param button: value/caption on the submit button
@param cnfrm: if given, must check checkbox to confirm
@param **hidden: dictionary with name=value pairs for hidden input
@return html form
"""
output = """
<form action="%s" method="%s">""" % (action, string.lower(method).strip() in ['get','post'] and method or 'Get')
output += """
<table>
<tr>
<td style="vertical-align: top">
"""
output += indent_text(text + '\n', 4)
if cnfrm:
output += """
<input type="checkbox" name="confirm" value="1" />"""
for key in hidden.keys():
if type(hidden[key]) is list:
for value in hidden[key]:
output += """
<input type="hidden" name="%s" value="%s" />""" % (key, value)
else:
output += """
<input type="hidden" name="%s" value="%s" />""" % (key, hidden[key])
output += """
</td>
</tr>
<tr>
<td>"""
output += """
<input class="adminbutton" type="submit" value="%s" />""" % (button, )
output += """
</td>
</tr>
</table>
</form>"""
return output
def tmpl_warnings(self, warnings, ln=cdslang):
"""
Prepare the warnings list
@param warnings: list of warning tuples (warning_msg, arg1, arg2, etc)
@return html string of warnings
"""
red_text_warnings = ['WRN_WEBCOMMENT_FEEDBACK_NOT_RECORDED',
'WRN_WEBCOMMENT_ALREADY_VOTED']
green_text_warnings = ['WRN_WEBCOMMENT_FEEDBACK_RECORDED']
from cdsware.errorlib import get_msgs_for_code_list
span_class = 'important'
out = ""
if type(warnings) is not list:
warnings = [warnings]
if len(warnings) > 0:
warnings_parsed = get_msgs_for_code_list(warnings, 'warning', ln)
for (warning_code, warning_text) in warnings_parsed:
if not warning_code.startswith('WRN'):
#display only warnings that begin with WRN to user
continue
if warning_code in red_text_warnings:
span_class = 'important'
elif warning_code in green_text_warnings:
span_class = 'exampleleader'
else:
span_class = 'important'
out += '''
<span class="%(span_class)s">%(warning)s</span><br>''' % \
{ 'span_class' : span_class,
'warning' : warning_text }
return out
else:
return ""
def tmpl_add_comment_form(self, recID, uid, nickname, ln, msg, warnings):
"""
Add form for comments
@param recID: record id
@param uid: user id
@param ln: language
@param msg: comment body contents for when refreshing due to warning
@param warnings: list of warning tuples (warning_msg, color)
@return html add comment form
"""
_ = gettext_set_language(ln)
link_dic = { 'weburl' : weburl,
'module' : 'comments.py',
'function' : 'add',
'arguments' : 'recid=%s&amp;ln=%s&amp;action=%s&amp;reviews=0' % (recID, ln, 'SUBMIT') }
if nickname:
note = _("Note: Your nickname, <i>%s</i>, will be displayed as author of this comment") % nickname
else:
(uid, nickname, display) = get_user_info(uid)
link = '<a href="%s/youraccount.py/edit">' % weburl
note = _("Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will temporarly be displayed as author of this comment.")
note %= (link, '</a>', display)
from cdsware.search_engine import print_record
record_details = print_record(recID=recID, format='hb')
warnings = self.tmpl_warnings(warnings, ln)
form = """
<table width="100%%">
<tr><td>%(record_label)s</td></tr>
<tr><td><blockquote>%(record)s<br><br></blockquote></td></tr>
<tr><td>%(comment_label)s</td></tr>
<tr><td><textarea name="msg" rows="20" cols="80">%(msg)s</textarea></td></tr>
<tr><td class="reportabuse">%(note)s</td></tr>
</table>
<br><br>""" % {'msg': msg,
'note': note,
'record': record_details,
'record_label': _("Article:"),
'comment_label': _("Comment:")}
form_link = "%(weburl)s/%(module)s/%(function)s?%(arguments)s" % link_dic
form = self.createhiddenform(action=form_link, method="Post", text=form, button='Add comment')
return warnings + form
def tmpl_add_comment_form_with_ranking(self, recID, uid, nickname, ln, msg, score, note, warnings):
"""
Add form for reviews
@param recID: record id
@param uid: user id
@param ln: language
@param msg: comment body contents for when refreshing due to warning
@param score: review score
@param note: review title
@param warnings: list of warning tuples (warning_msg, color)
@return html add review form
"""
_ = gettext_set_language(ln)
link_dic = { 'weburl' : weburl,
'module' : 'comments.py',
'function' : 'add',
'arguments' : 'recid=%s&amp;ln=%s&amp;action=%s&amp;reviews=1' % (recID, ln, 'SUBMIT') }
warnings = self.tmpl_warnings(warnings, ln)
from search_engine import print_record
record_details = print_record(recID=recID, format='hb')
note_label = _("Note: Your nickname, <i>%s</i>, will be displayed as the author of this review")
note_label %= nickname
form = """
<table style="width: 100%%">
<tr>
<td>%(article_label)s: </td>
</tr>
<tr>
<td>
<blockquote>%(record)s<br />
<br />
</blockquote>
</td>
</tr>
<tr>
<td style="padding-bottom: 10px;">%(rate_label)s:
<select name=\"score\" size=\"1\">
<option value=\"0\" selected>-%(select_label)s-</option>
<option value=\"5\">***** (best)</option>
<option value=\"4\">****</option>
<option value=\"3\">***</option>
<option value=\"2\">**</option>
<option value=\"1\">* (worst)</option>
</select>
</td>
</tr>
<tr>
<td>%(title_label)s:</td>
</tr>
<tr>
<td style="padding-bottom: 10px;">
<input type="text" name="note" size="80" maxlength="250" value="%(note)s" />
</td>
</tr>
<tr>
<td>%(write_label)s:</td>
</tr>
<tr>
<td>
<textarea name="msg" rows="20" cols="80">%(msg)s</textarea>
</td>
</tr>
<tr>
<td class="reportabuse">%(note_label)s</td></tr>
</table>
<br /><br />
""" % {'article_label': _('Article'),
'rate_label': _("Rate this article"),
'select_label': _("Select a score"),
'title_label': _("Give a title to your review"),
'write_label': _("Write your review"),
'note_label': note_label,
'note' : note!='' and note or "",
'msg' : msg!='' and msg or "",
'record' : record_details }
form_link = "%(weburl)s/%(module)s/%(function)s?%(arguments)s" % link_dic
form = self.createhiddenform(action=form_link, method="Post", text=form, button=_('Add Review'))
return warnings + form
def tmpl_add_comment_successful(self, recID, ln, reviews):
"""
@param recID: record id
@param ln: language
@return html page of successfully added comment/review
"""
_ = gettext_set_language(ln)
link_dic = { 'weburl' : weburl,
'module' : 'comments.py',
'function' : 'display',
'arguments' : 'recid=%s&amp;ln=%s&amp;do=od&amp;reviews=%s' % (recID, ln, reviews) }
link = "%(weburl)s/%(module)s/%(function)s?%(arguments)s" % link_dic
out = _("Your %s was successfully added") + '<br /><br />'
out += '<a href="%s">' % link
out += _('Back to record') + '</a>'
out %= (reviews==1 and _('review') or _('comment'))
return out
def tmpl_create_multiple_actions_form(self,
form_name="",
form_action="",
method="GET",
action_display={},
action_field_name="",
button_label="",
button_name="",
content="",
**hidden):
""" Creates an HTML form with a multiple choice of actions and a button to select it.
@param form_action: link to the receiver of the formular
@param form_name: name of the HTML formular
@param method: either 'GET' or 'POST'
@param action_display: dictionary of actions.
action is HTML name (name of action)
display is the string provided in the popup
@param action_field_name: html name of action field
@param button_label: what's written on the button
@param button_name: html name of the button
@param content: what's inside te formular
@param **hidden: dictionary of name/value pairs of hidden fields.
"""
output = """
<form action="%s" method="%s">""" % (form_action, method)
output += """
<table>
<tr>
<td style="vertical-align: top" colspan="2">
"""
output += indent_text(content + '\n', 4)
for key in hidden.keys():
if type(hidden[key]) is list:
for value in hidden[key]:
output += """
<input type="hidden" name="%s" value="%s" />""" % (key, value)
else:
output += """
<input type="hidden" name="%s" value="%s" />""" % (key, hidden[key])
output += """
</td>
</tr>
<tr>
<td style="text-align:right;">"""
if type(action_display) is dict and len(action_display.keys()):
output += """
<select name="%s">""" % action_field_name
for (key, value) in action_display.items():
output += """
<option value="%s">%s</option>""" % (key, value)
output += """
</select>"""
output += """
</td>
<td style="text-align:left;">
<input class="adminbutton" type="submit" value="%s" name="%s"/>""" % (button_label, button_name)
output += """
</td>
</tr>
</table>
</form>"""
return output
def tmpl_admin_index(self, ln):
"""
"""
# load the right message language
_ = gettext_set_language(ln)
out = '<ol>'
if cfg_webcomment_allow_comments or cfg_webcomment_allow_reviews:
if cfg_webcomment_allow_comments:
out += '''
<li><a href="%(weburl)s/admin/webcomment/webcommentadmin.py/comments?ln=%(ln)s&amp;reviews=0">%(reported_cmt_label)s</a></li>'''
if cfg_webcomment_allow_reviews:
out += '''
<li><a href="%(weburl)s/admin/webcomment/webcommentadmin.py/comments?ln=%(ln)s&amp;reviews=1">%(reported_rev_label)s</a></li>'''
out += '''
<li><a href="%(weburl)s/admin/webcomment/webcommentadmin.py/delete?ln=%(ln)s&amp;comid=-1">%(delete_label)s</a></small></li>
<li><a href="%(weburl)s/admin/webcomment/webcommentadmin.py/users?ln=%(ln)s">%(view_users)s</a></li>
'''
out = out % { 'weburl' : weburl,
'reported_cmt_label': _("View all reported comments"),
'reported_rev_label': _("View all reported reviews"),
'delete_label': _("Delete a specific comment/review (by ID)"),
'view_users': _("View all users who have been reported"),
'ln' : ln }
else:
out += _("Comments and reviews are disabled") + '<br />'
out += '</ol>'
from cdsware.bibrankadminlib import addadminbox
return addadminbox('<b>%s</b>'%_("Menu"), [out])
def tmpl_admin_delete_form(self, ln, warnings):
"""
@param warnings: list of warning_tuples where warning_tuple is (warning_message, text_color)
see tmpl_warnings, color is optional
"""
# load the right message language
_ = gettext_set_language(ln)
warnings = self.tmpl_warnings(warnings, ln)
out = '''
<br />
%s<br />
<br />'''%_("Please enter the ID of the comment/review so that you can view it before deciding to delete it or not")
form = '''
<table>
<tr>
<td>%s:</td>
<td><input type=text name="comid" size="10" maxlength="10" value="" /></td>
</tr>
<tr>
<td><br /></td>
<tr>
</table>
<br />
''' %_("Comment ID")
form_link = "%s/admin/webcomment/webcommentadmin.py/delete?ln=%s" % (weburl, ln)
form = self.createhiddenform(action=form_link, method="Get", text=form, button=_('View Comment'))
return warnings + out + form
def tmpl_admin_users(self, ln, users_data):
"""
@param users_data: tuple of ct, i.e. (ct, ct, ...)
where ct is a tuple (total_number_reported, total_comments_reported, total_reviews_reported, total_nb_votes_yes_of_reported,
total_nb_votes_total_of_reported, user_id, user_email, user_nickname)
sorted by order of ct having highest total_number_reported
"""
_ = gettext_set_language(ln)
u_reports = 0
u_comment_reports = 1
u_reviews_reports = 2
u_nb_votes_yes = 3
u_nb_votes_total = 4
u_uid = 5
u_email = 6
u_nickname = 7
if not users_data:
return self.tmpl_warnings([_(("There have been no reports so far."), 'green')])
user_rows = ""
for utuple in users_data:
com_label = _("View all %s reported comments") % utuple[u_comment_reports]
com_link = '''<a href="%s/admin/webcomment/webcommentadmin.py/comments?ln=%s&amp;uid=%s&amp;reviews=0">%s</a><br />''' % \
(weburl, ln, utuple[u_uid], com_label)
rev_label = _("View all %s reported reviews") % utuple[u_reviews_reports]
rev_link = '''<a href="%s/admin/webcomment/webcommentadmin.py/comments?ln=%s&amp;uid=%s&amp;reviews=1">%s</a>''' % \
(weburl, ln, utuple[u_uid], rev_label)
if not utuple[u_nickname]:
user_info = get_user_info(utuple[u_uid])
nickname = user_info[2]
else:
nickname = utuple[u_nickname]
if cfg_webcomment_allow_reviews:
review_row = """
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>"""
review_row %= (utuple[u_nb_votes_yes],
utuple[u_nb_votes_total] - utuple[u_nb_votes_yes],
utuple[u_nb_votes_total])
review_row = indent_text(review_row, 1)
else:
review_row = ''
user_rows += """
<tr>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%(nickname)s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%(email)s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%(uid)s</td>%(review_row)s
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray; font-weight: bold;">%(reports)s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%(com_link)s%(rev_link)s</td>
</tr>""" % { 'nickname' : nickname,
'email' : utuple[u_email],
'uid' : utuple[u_uid],
'reports' : utuple[u_reports],
'review_row': review_row,
'weburl' : weburl,
'ln' : ln,
'com_link' : cfg_webcomment_allow_comments and com_link or "",
'rev_link' : cfg_webcomment_allow_reviews and rev_link or ""
}
out = "<br />"
out += _("Here is a list, sorted by total number of reports, of all users who have had at least one report to one of their comments.")
out += """
<br />
<br />
<table class="admin_wvar" style="width: 100%%;">
<thead>
<tr class="adminheaderleft">
<th>"""
out += _("Nickname") + '</th>\n'
out += indent_text('<th>' + _("Email") + '</th>\n', 3)
out += indent_text('<th>' + _("User ID") + '</th>\n', 3)
if cfg_webcomment_allow_reviews > 0:
out += indent_text('<th>' + _("Number positive votes") + '</th>\n', 3)
out += indent_text('<th>' + _("Number negative votes") + '</th>\n', 3)
out += indent_text('<th>' + _("Total number votes") + '</th>\n', 3)
out += indent_text('<th>' + _("Total number of reports") + '</th>\n', 3)
out += indent_text('<th>' + _("View all user's reported comments/reviews") + '</th>\n', 3)
out += """
</tr>
</thead>
<tbody>%s
</tbody>
</table>
""" % indent_text(user_rows, 2)
return out
def tmpl_admin_select_comment_checkbox(self, cmt_id):
""" outputs a checkbox named "comidXX" where XX is cmt_id """
return '<input type="checkbox" name="comid%i" />' % int(cmt_id)
def tmpl_admin_user_info(self, ln, nickname, uid, email):
""" prepares informations about a user"""
_ = gettext_set_language(ln)
out = """
%(nickname_label)s: %(messaging)s<br />
%(uid_label)s: %(uid)i<br />
%(email_label)s: <a href="mailto:%(email)s">%(email)s</a>"""
out %= {'nickname_label': _("Nickname"),
'messaging': self.create_messaging_link(uid, nickname, ln),
'uid_label': _("User ID"),
'uid': int(uid),
'email_label': _("email"),
'email': email}
return out
def tmpl_admin_review_info(self, ln, reviews, nb_reports, cmt_id, rec_id):
""" outputs information about a review """
_ = gettext_set_language(ln)
reported_label = _("This %s has been reported %i times")
reported_label %= (reviews and _("review") or _("comment"), int(nb_reports))
out = """
%(reported_label)s<br />
<a href="%(weburl)s/search.py?recid=%(rec_id)i&amp;ln=%(ln)s">%(rec_id_label)s</a><br />
%(cmt_id_label)s"""
out %= {'reported_label': reported_label,
'rec_id_label': _("Record #%s")% str(rec_id),
'weburl': weburl,
'rec_id': int(rec_id),
'cmt_id_label': _("Comment #%s") % str(cmt_id),
'ln': ln}
return out
def tmpl_admin_comments(self, ln, uid, comID, comment_data, reviews):
"""
@param comment_data: same type of tuple as that
which is returned by webcomment.py/query_retrieve_comments_or_remarks i.e.
tuple of comment where comment is
tuple (nickname,
date_creation,
body,
id) if ranking disabled or
tuple (nickname,
date_creation,
body,
nb_votes_yes,
nb_votes_total,
star_score,
title,
id)
"""
_ = gettext_set_language(ln)
comments = []
comments_info = []
checkboxes = []
users = []
for (cmt_tuple, meta_data) in comment_data:
if reviews:
comments.append(self.tmpl_get_comment_with_ranking(ln,
cmt_tuple[0],#nickname
cmt_tuple[2],#date_creation
cmt_tuple[3],#body
cmt_tuple[5],#nb_votes_total
cmt_tuple[4],#nb_votes_yes
cmt_tuple[6],#star_score
cmt_tuple[7]))#title
else:
comments.append(self.tmpl_get_comment_without_ranking(ln,
cmt_tuple[0],#nickname
cmt_tuple[2],#date_creation
cmt_tuple[3],#body
None, #reply_link
None)) #report_link
users.append(self.tmpl_admin_user_info(ln,
meta_data[0], #nickname
meta_data[1], #uid
meta_data[2]))#email
comments_info.append(self.tmpl_admin_review_info(ln,
reviews,
meta_data[5], # nb abuse reports
meta_data[3], # cmt_id
meta_data[4]))# rec_id
checkboxes.append(self.tmpl_admin_select_comment_checkbox(meta_data[3]))
form_link = "%s/admin/webcomment/webcommentadmin.py/del_com?ln=%s" % (weburl, ln)
out = """
<table class="admin_wvar" style="width:100%%;">
<thead>
<tr class="adminheaderleft">
<th>%(review_label)s</th>
<th>%(written_by_label)s</th>
<th>%(review_info_label)s</th>
<th>%(select_label)s</th>
</tr>
</thead>
<tbody>""" % {'review_label': reviews and _("Review") or _("Comment"),
'written_by_label': _("Written by"),
'review_info_label': _("General informations"),
'select_label': _("Select")}
for i in range (0, len(comments)):
out += """
<tr>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintd" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
</tr>
</tbody>""" % (comments[i], users[i], comments_info[i], checkboxes[i])
out += """
</table>"""
reviews = reviews and _('reviews') or _('comments')
action_display = {
'delete': _('Delete selected %s') % reviews,
'unreport': _('Suppress selected abuse report')
}
form = self.tmpl_create_multiple_actions_form(form_name="admin_comment",
form_action=form_link,
method="POST",
action_display=action_display,
action_field_name='action',
button_label=_("Ok"),
button_name="okbutton",
content=out)
if uid > 0:
header = '<br />'
header += _("Here are the reported %s of user %s") % (reviews>0 and _("reviews") or _("comments"), uid)
header += '<br /><br />'
if comID > 0:
header = '<br />' +_("Here is comment/review %s")% comID + '<br /><br />'
if uid > 0 and comID > 0:
header = '<br />' + _("Here is comment/review %s written by user %s") % (comID, uid)
header += '<br/ ><br />'
if uid == 0 and comID == 0:
header = '<br />'
header += _("Here are all reported %s sorted by most reported")
header %= (reviews>0 and _("reviews") or _("comments"))
header += "<br /><br />"
return header + form
def tmpl_admin_del_com(self, del_res, ln=cdslang):
"""
@param del_res: list of the following tuple (comment_id, was_successfully_deleted),
was_successfully_deleted is boolean (0=false, >0=true
"""
_ = gettext_set_language(ln)
table_rows = ''
for deltuple in del_res:
table_rows += """
<tr>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
</tr>""" % (deltuple[0], deltuple[1]>0 and _("Yes") or "<span class=\"important\">" +_("No") + "</span>")
out = """
<table class="admin_wvar">
<tr class="adminheaderleft">
<td style="padding-right:10px;">%s</td>
<td>%s</td>
</tr>%s
<table>""" % (_("comment ID"), _("successfully deleted"), table_rows)
return out
def tmpl_admin_suppress_abuse_report(self, del_res, ln=cdslang):
"""
@param del_res: list of the following tuple (comment_id, was_successfully_deleted),
was_successfully_deleted is boolean (0=false, >0=true
"""
_ = gettext_set_language(ln)
table_rows = ''
for deltuple in del_res:
table_rows += """
<tr>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
<td class="admintdleft" style="padding: 5px; border-bottom: 1px solid lightgray;">%s</td>
</tr>""" % (deltuple[0], deltuple[1]>0 and _("Yes") or "<span class=\"important\">" +_("No") + "</span>")
out = """
<table class="admin_wvar">
<tr class="adminheaderleft">
<td style ="padding-right: 10px;">%s</td>
<td>%s</td>
</tr>%s
<table>""" % (_("comment ID"), _("successfully suppressed abuse report"), table_rows)
return out
diff --git a/modules/webcomment/lib/webcomment_tests.py b/modules/webcomment/lib/webcomment_tests.py
index 99f66324c..1c1a89913 100644
--- a/modules/webcomment/lib/webcomment_tests.py
+++ b/modules/webcomment/lib/webcomment_tests.py
@@ -1,24 +1,24 @@
# -*- coding: utf-8 -*-
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import unittest
from cdsware import webcomment
diff --git a/modules/webcomment/lib/webcommentadminlib.py b/modules/webcomment/lib/webcommentadminlib.py
index e34b70d61..1d24ce919 100644
--- a/modules/webcomment/lib/webcommentadminlib.py
+++ b/modules/webcomment/lib/webcommentadminlib.py
@@ -1,243 +1,243 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__lastupdated__ = """$Date$"""
from cdsware.config import cdslang, weburl
from cdsware.webcomment import query_get_comment
from cdsware.urlutils import wash_url_argument
from cdsware.dbquery import run_sql
from cdsware.messages import gettext_set_language, wash_language
from cdsware.webuser import get_user_info
import cdsware.template
webcomment_templates = cdsware.template.load('webcomment')
def getnavtrail(previous = '', ln=cdslang):
"""Get the navtrail"""
previous = wash_url_argument(previous, 'str')
ln = wash_language(ln)
_ = gettext_set_language(ln)
navtrail = """<a class=navtrail href="%s/admin/">%s</a> &gt; <a class=navtrail href="%s/admin/webcomment/">%s</a> """ % (weburl, _("Admin Area"), weburl, _("WebComment Admin"))
navtrail = navtrail + previous
return navtrail
def perform_request_index(ln=cdslang):
"""
"""
return webcomment_templates.tmpl_admin_index(ln=ln)
def perform_request_delete(comID=-1, ln=cdslang):
"""
"""
warnings = []
ln = wash_language(ln)
comID = wash_url_argument(comID, 'int')
if comID is not None:
if comID <= 0:
if comID != -1:
warnings.append(("WRN_WEBCOMMENT_ADMIN_INVALID_COMID",))
return (webcomment_templates.tmpl_admin_delete_form(ln, warnings),None, warnings)
comment = query_get_comment(comID)
if comment:
c_star_score = 5
if comment[c_star_score] > 0:
reviews = 1
else:
reviews = 0
return (perform_request_comments(ln=ln, comID=comID, reviews=reviews), None, warnings)
else:
warnings.append(('WRN_WEBCOMMENT_ADMIN_COMID_INEXISTANT', comID))
return (webcomment_templates.tmpl_admin_delete_form(ln, warnings), None, warnings)
else:
return (webcomment_templates.tmpl_admin_delete_form(ln, warnings), None, warnings)
def perform_request_users(ln=cdslang):
"""
"""
ln = wash_language(ln)
users_data = query_get_users_reported()
return webcomment_templates.tmpl_admin_users(ln=ln, users_data=users_data)
def query_get_users_reported():
"""
Get the users who have been reported at least one.
@return tuple of ct, i.e. (ct, ct, ...)
where ct is a tuple (total_number_reported, total_comments_reported, total_reviews_reported,
total_nb_votes_yes_of_reported, total_nb_votes_total_of_reported, user_id, user_email, user_nickname)
sorted by order of ct having highest total_number_reported
"""
query1 = "SELECT c.nb_abuse_reports, c.nb_votes_yes, c.nb_votes_total, u.id, u.email, u.nickname, c.star_score " \
"FROM user AS u, cmtRECORDCOMMENT AS c " \
"WHERE c.id_user=u.id AND c.nb_abuse_reports > 0 " \
"ORDER BY u.id "
res1 = run_sql(query1)
if type(res1) is None:
return ()
users = {}
for cmt in res1:
uid = int(cmt[3])
if users.has_key(uid):
users[uid] = (users[uid][0]+int(cmt[0]), int(cmt[6])>0 and users[uid][1] or users[uid][1]+1, int(cmt[6])>0 and users[uid][2]+1 or users[uid][2],
users[uid][3]+int(cmt[1]), users[uid][4]+int(cmt[2]), int(cmt[3]), cmt[4], cmt[5])
else:
users[uid] = (int(cmt[0]), int(cmt[6])==0 and 1 or 0, int(cmt[6])>0 and 1 or 0, int(cmt[1]), int(cmt[2]), int(cmt[3]), cmt[4], cmt[5])
users = users.values()
users.sort()
users.reverse()
users = tuple(users)
return users
def perform_request_comments(ln=cdslang, uid="", comID="", reviews=0):
"""
"""
ln = wash_language(ln)
uid = wash_url_argument(uid, 'int')
comID = wash_url_argument(comID, 'int')
reviews = wash_url_argument(reviews, 'int')
comments = query_get_comments(uid, comID, reviews, ln)
return webcomment_templates.tmpl_admin_comments(ln=ln, uid=uid,
comID=comID,
comment_data=comments,
reviews=reviews)
def query_get_comments(uid, cmtID, reviews, ln):
"""
private function
tuple of comment where comment is
tuple (nickname, uid, date_creation, body, id) if ranking disabled or
tuple (nickname, uid, date_creation, body, nb_votes_yes, nb_votes_total, star_score, title, id)
"""
qdict = {'id': 0, 'id_bibrec': 1, 'uid': 2, 'date_creation': 3, 'body': 4,
'nb_abuse_reports': 5, 'nb_votes_yes': 6, 'nb_votes_total': 7,
'star_score': 8, 'title': 9, 'email': -2, 'nickname': -1}
query = """SELECT c.id, c.id_bibrec, c.id_user,
c.date_creation, c.body,
c.nb_abuse_reports,
%s
u.email, u.nickname
FROM cmtRECORDCOMMENT c LEFT JOIN user u
ON c.id_user = u.id
%s
ORDER BY c.nb_abuse_reports DESC, c.nb_votes_yes DESC, c.date_creation
"""
select_fields = reviews and 'c.nb_votes_yes, c.nb_votes_total, c.star_score, c.title,' or ''
where_clause = "WHERE " + (reviews and 'c.star_score>0' or 'c.star_score=0')
if uid:
where_clause += ' AND c.id_user=%i' % uid
if cmtID:
where_clause += ' AND c.id=%i' % cmtID
else:
where_clause += ' AND c.nb_abuse_reports>0'
res = run_sql(query % (select_fields, where_clause))
output = []
for qtuple in res:
nickname = qtuple[qdict['nickname']] or get_user_info(qtuple[qdict['uid']], ln)[2]
if reviews:
comment_tuple = (nickname,
qtuple[qdict['uid']],
qtuple[qdict['date_creation']],
qtuple[qdict['body']],
qtuple[qdict['nb_votes_yes']],
qtuple[qdict['nb_votes_total']],
qtuple[qdict['star_score']],
qtuple[qdict['title']],
qtuple[qdict['id']])
else:
comment_tuple = (nickname,
qtuple[qdict['uid']],
qtuple[qdict['date_creation']],
qtuple[qdict['body']],
qtuple[qdict['id']])
general_infos_tuple = (nickname,
qtuple[qdict['uid']],
qtuple[qdict['email']],
qtuple[qdict['id']],
qtuple[qdict['id_bibrec']],
qtuple[qdict['nb_abuse_reports']])
out_tuple = (comment_tuple, general_infos_tuple)
output.append(out_tuple)
return tuple(output)
def perform_request_del_com(ln=cdslang, comIDs=[]):
"""
private function
Delete the comments and say whether successful or not
@param ln: language
@param comIDs: list of comment ids
"""
ln = wash_language(ln)
comIDs = wash_url_argument(comIDs, 'list')
# map ( fct, list, arguments of function)
comIDs = map(wash_url_argument, comIDs, ('int '*len(comIDs)).split(' ')[:-1])
if not comIDs:
comIDs = map(coerce, comIDs, ('0 '*len(comIDs)).split(' ')[:-1])
return webcomment_templates.tmpl_admin_del_com(del_res=comIDs, ln=ln)
del_res=[]
for id in comIDs:
del_res.append((id, query_delete_comment(id)))
return webcomment_templates.tmpl_admin_del_com(del_res=del_res, ln=ln)
def suppress_abuse_report(ln=cdslang, comIDs=[]):
"""
private function
suppress the abuse reports for the given comIDs.
@param ln: language
@param comIDs: list of ids to suppress attached reports.
"""
ln = wash_language(ln)
comIDs = wash_url_argument(comIDs, 'list')
# map ( fct, list, arguments of function)
comIDs = map(wash_url_argument, comIDs, ('int '*len(comIDs)).split(' ')[:-1])
if not comIDs:
comIDs = map(coerce, comIDs, ('0 '*len(comIDs)).split(' ')[:-1])
return webcomment_templates.tmpl_admin_del_com(del_res=comIDs, ln=ln)
del_res=[]
for id in comIDs:
del_res.append((id, query_suppress_abuse_report(id)))
return webcomment_templates.tmpl_admin_suppress_abuse_report(del_res=del_res, ln=ln)
def query_suppress_abuse_report(comID):
""" suppress abuse report for a given comment
@return integer 1 if successful, integer 0 if not
"""
query = "UPDATE cmtRECORDCOMMENT SET nb_abuse_reports=0 WHERE id=%i"
params = comID
res = run_sql(query%params)
return int(res)
def query_delete_comment(comID):
"""
delete comment with id comID
@return integer 1 if successful, integer 0 if not
"""
query1 = "DELETE FROM cmtRECORDCOMMENT WHERE id=%s"
params1 = (comID,)
res1 = run_sql(query1, params1)
return int(res1)
diff --git a/modules/webcomment/web/Makefile.am b/modules/webcomment/web/Makefile.am
index 27cee6f76..aea1b09a4 100644
--- a/modules/webcomment/web/Makefile.am
+++ b/modules/webcomment/web/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
webappdir = $(WEBDIR)
webapp_DATA = comments.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp comments.pyc
diff --git a/modules/webcomment/web/admin/Makefile.am b/modules/webcomment/web/admin/Makefile.am
index 89406f72a..83186f2f0 100644
--- a/modules/webcomment/web/admin/Makefile.am
+++ b/modules/webcomment/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/webcomment
webapp_DATA = webcommentadmin.py
EXTRA_DIST = webcommentadmin.py
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/webcomment/web/admin/webcommentadmin.py b/modules/webcomment/web/admin/webcommentadmin.py
index bf8221ce6..9487969a3 100644
--- a/modules/webcomment/web/admin/webcommentadmin.py
+++ b/modules/webcomment/web/admin/webcommentadmin.py
@@ -1,203 +1,203 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
__lastupdated__ = """$Date$"""
from cdsware.webcommentadminlib import *
from cdsware.bibrankadminlib import check_user
from cdsware.webpage import page, create_error_box
from cdsware.config import weburl,cdslang
from cdsware.webuser import getUid, page_not_authorized
from cdsware.urlutils import wash_url_argument, redirect_to_url
from cdsware.messages import wash_language, gettext_set_language
def index(req, ln=cdslang):
"""
Menu of admin options
@param ln: language
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
navtrail_previous_links = getnavtrail()
navtrail_previous_links +=' &gt; <a class="navtrail" href="%s/admin/webcomment/webcommentadmin.py/">' % weburl
navtrail_previous_links += _("Comment Management") + '</a>'
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
(auth_code, auth_msg) = check_user(uid, 'cfgwebcomment')
if not auth_code:
return page(title=_("Comment Management"),
body=perform_request_index(ln=ln),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__,
req=req)
else:
return page_not_authorized(req=req, text=auth_msg, navtrail=navtrail_previous_links)
def delete(req, ln=cdslang, comid=""):
"""
Delete a comment by giving its comment id
@param ln: language
@param comid: comment id
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
navtrail_previous_links = getnavtrail()
navtrail_previous_links += ' &gt; <a class="navtrail" href="%s/admin/webcomment/webcommentadmin.py/">' % weburl
navtrail_previous_links += _("Comment Management") + '</a>'
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
(auth_code, auth_msg) = check_user(uid,'cfgwebcomment')
if not auth_code:
(body, errors, warnings) = perform_request_delete(ln=ln, comID=comid)
return page(title=_("Delete Comment"),
body=body,
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
req = req,
errors = errors,
warnings = warnings,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth_msg, navtrail=navtrail_previous_links)
def comments(req, ln=cdslang, uid="", comid="", reviews=0):
"""
View reported comments, filter by either user or a specific comment (only one given at a time)
@param ln: language
@param uid: user id
@param comid: comment id
@param reviews: boolean enabled for reviews, disabled for comments
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
navtrail_previous_links = getnavtrail()
navtrail_previous_links += ' &gt; <a class="navtrail" href="%s/admin/webcomment/webcommentadmin.py/">' % weburl
navtrail_previous_links += _("Comment Management") + '</a>'
try:
auid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
(auth_code, auth_msg) = check_user(auid,'cfgwebcomment')
if not auth_code:
if reviews==0:
raise ValueError
return page(title=_("View all Reported %s") % (reviews>0 and _("Reviews") or _("Comments")),
body=perform_request_comments(ln=ln, uid=uid, comID=comid, reviews=reviews),
uid=auid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__,
req=req)
else:
return page_not_authorized(req=req, text=auth_msg, navtrail=navtrail_previous_links)
def users(req, ln=cdslang):
"""
View a list of all the users that have been reported, sorted by most reported
@param ln: language
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
navtrail_previous_links = getnavtrail()
navtrail_previous_links += ' &gt; <a class="navtrail" href="%s/admin/webcomment/webcommentadmin.py/">' % weburl
navtrail_previous_links += _("Comment Management") + '</a>'
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
(auth_code, auth_msg) = check_user(uid,'cfgwebcomment')
if not auth_code:
return page(title=_("View all Reported Users"),
body=perform_request_users(ln=ln),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__,
req=req)
else:
return page_not_authorized(req=req, text=auth_msg, navtrail=navtrail_previous_links)
def del_com(req, ln=cdslang, action="delete", **hidden):
"""
private funciton
Delete a comment
@param ln: language
@param **hidden: ids of comments to delete sent as individual variables comidX=on, where X is id
"""
ln = wash_language(ln)
action = wash_url_argument(action, 'str')
_ = gettext_set_language(ln)
navtrail_previous_links = getnavtrail()
navtrail_previous_links += ' &gt; <a class="navtrail" href="%s/admin/webcomment/webcommentadmin.py/">' % weburl
navtrail_previous_links += _("Comment Management") + '</a>'
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
(auth_code, auth_msg) = check_user(uid,'cfgwebcomment')
if not auth_code:
comIDs = []
args = hidden.keys()
for var in args:
try:
comIDs.append(int(var.split('comid')[1]))
except:
pass
if action == 'delete':
body = perform_request_del_com(ln=ln, comIDs=comIDs)
title = _("Delete comments")
elif action == 'unreport':
body = suppress_abuse_report(ln=ln, comIDs=comIDs)
title = _("Suppress abuse reports")
else:
redirect_to_url(req, weburl + '/admin/webcomment/webcommentadmin.py')
return page(title=title,
body=body,
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__,
req=req)
else:
return page_not_authorized(req=req, text=auth_msg, navtrail=navtrail_previous_links)
diff --git a/modules/webcomment/web/comments.py b/modules/webcomment/web/comments.py
index 71264b0ff..587aa193e 100644
--- a/modules/webcomment/web/comments.py
+++ b/modules/webcomment/web/comments.py
@@ -1,255 +1,255 @@
# -*- coding: utf-8 -*-
## $Id$
## Comments and reviews for records.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Comments and reviews for records: web interface """
__lastupdated__ = """$Date$"""
__revision__ = """$Id$"""
from cdsware.webcomment import check_recID_is_in_range, \
perform_request_display_comments_or_remarks,\
perform_request_add_comment_or_remark,\
perform_request_vote,\
perform_request_report
from cdsware.config import cdslang, \
weburl,\
cfg_webcomment_allow_comments,\
cfg_webcomment_allow_reviews
from cdsware.webuser import getUid, page_not_authorized, isGuestUser
from cdsware.webaccount import create_login_page_box
from cdsware.webpage import page
from cdsware.search_engine import create_navtrail_links, guess_primary_collection_of_a_record
from cdsware.urlutils import get_client_ip_address, \
redirect_to_url, \
wash_url_argument
from cdsware.messages import wash_language, gettext_set_language
def index(req):
"""
Redirects to display function
"""
redirect_to_url(req,"%s/comments.py/display?%s" % (weburl, req.args))
def display(req, recid=-1, ln=cdslang, do='od', ds='all', nb=100, p=1, voted=-1, reported=-1, reviews=0):
"""
Display comments (reviews if enabled) associated with record having id recid where recid>0.
This function can also be used to display remarks associated with basket having id recid where recid<-99.
@param ln: language
@param recid: record id, integer
@param do: display order hh = highest helpful score, review only
lh = lowest helpful score, review only
hs = highest star score, review only
ls = lowest star score, review only
od = oldest date
nd = newest date
@param ds: display since all= no filtering by date
nd = n days ago
nw = n weeks ago
nm = n months ago
ny = n years ago
where n is a single digit integer between 0 and 9
@param nb: number of results per page
@param p: results page
@param voted: boolean, active if user voted for a review, see vote function
@param reported: boolean, active if user reported a certain comment/review, see report function
@param reviews: boolean, enabled for reviews, disabled for comments
@return the full html page.
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
uid = getUid(req)
check_warnings = []
(ok, problem) = check_recID_is_in_range(recid, check_warnings, ln)
if ok:
(body, errors, warnings) = perform_request_display_comments_or_remarks(recID=recid, display_order=do, display_since=ds, nb_per_page=nb, page=p, ln=ln, voted=voted, reported=reported, reviews=reviews)
navtrail = create_navtrail_links(cc=guess_primary_collection_of_a_record(recid))
navtrail += '&gt; <a class="navtrail" href="%s/search.py?recid=%s&ln=%s">'% (weburl, recid, ln)
navtrail += _("Detailed record #%s") % recid
navtrail += '</a>'
navtrail += ' &gt; <a class="navtrail">%s</a>' % (reviews==1 and _("Reviews") or _("Comments"))
return page(title="",
body=body,
navtrail=navtrail,
uid=uid,
verbose=1,
req=req,
language=ln,
errors=errors, warnings=warnings)
else:
return page(title=_("Record Not Found"),
body=problem,
uid=uid,
verbose=1,
req=req,
language=ln,
warnings=check_warnings, errors=[])
def add(req, ln=cdslang, recid=-1, action='DISPLAY', msg="", note="", score="", reviews=0, comid=-1):
"""
Add a comment (review) to record with id recid where recid>0
Also works for adding a remark to basket with id recid where recid<-99
@param ln: languange
@param recid: record id
@param action: 'DISPLAY' to display add form
'SUBMIT' to submit comment once form is filled
'REPLY' to reply to an already existing comment
@param msg: the body of the comment/review or remark
@param score: star score of the review
@param note: title of the review
@param comid: comment id, needed for replying
@return the full html page.
"""
ln = wash_language(ln)
_ = gettext_set_language(ln)
reviews = wash_url_argument(reviews, 'int')
action = wash_url_argument(action, 'str')
comid = wash_url_argument(comid, 'int')
actions = ['DISPLAY', 'REPLY', 'SUBMIT']
uid = getUid(req)
client_ip_address = get_client_ip_address(req)
check_warnings = []
(ok, problem) = check_recID_is_in_range(recid, check_warnings, ln)
if ok:
navtrail = create_navtrail_links(cc=guess_primary_collection_of_a_record(recid))
navtrail += ' &gt; <a class="navtrail" href="%s/search.py?recid=%s&ln=%s">'% (weburl, recid, ln)
navtrail += _("Detailed record #%s") % recid
navtrail += '</a>'
navtrail += '&gt; <a class="navtrail" href="%s/comments.py/display?recid=%s&ln=%s">%s</a>' % (weburl, recid, ln, reviews==1 and _('Reviews') or _('Comments'))
if action not in actions:
action = 'DISPLAY'
# is page allowed to be viewed
if uid == -1 or (not cfg_webcomment_allow_comments and not cfg_webcomment_allow_reviews):
return page_not_authorized(req, "../comments.py/add")
# if guest, must log in first
if isGuestUser(uid):
msg = _("Before you add your comment, you need to log in first")
referer = "%s/comments.py/add?recid=%s&amp;ln=%s&amp;reviews=%s&amp;comid=%s&amp;action=%s" % (weburl, recid, ln, reviews, comid, action)
login_box = create_login_page_box(referer=referer, ln=ln)
return page(title=_("Login"),
body=msg+login_box,
navtrail=navtrail,
uid=uid,
language=cdslang,
verbose=1,
req=req)
# user logged in
else:
(body, errors, warnings) = perform_request_add_comment_or_remark(recID=recid, uid=uid, action=action, msg=msg, note=note, score=score, reviews=reviews, comID=comid, client_ip_address=client_ip_address)
if reviews:
title = _("Add Review")
else:
title = _("Add Comment")
return page(title=title,
body=body,
navtrail=navtrail,
uid=uid,
language=cdslang,
verbose=1,
errors=errors,
warnings=warnings,
req=req)
# id not in range
else:
return page(title=_("Record Not Found"),
body=problem,
uid=uid,
verbose=1,
req=req,
warnings=check_warnings, errors=[])
def vote(req, comid=-1, com_value=0, recid=-1, ln=cdslang, do='od', ds='all', nb=100, p=1, referer=None, reviews=0):
"""
Vote positively or negatively for a comment/review.
@param comid: comment/review id
@param com_value: +1 to vote positively
-1 to vote negatively
@param recid: the id of the record the comment/review is associated with
@param ln: language
@param do: display order hh = highest helpful score, review only
lh = lowest helpful score, review only
hs = highest star score, review only
ls = lowest star score, review only
od = oldest date
nd = newest date
@param ds: display since all= no filtering by date
nd = n days ago
nw = n weeks ago
nm = n months ago
ny = n years ago
where n is a single digit integer between 0 and 9
@param nb: number of results per page
@param p: results page
@param referer: http address of the calling function to redirect to (refresh)
@param reviews: boolean, enabled for reviews, disabled for comments
"""
client_ip_address = get_client_ip_address(req)
uid = getUid(req)
success = perform_request_vote(comid, client_ip_address, com_value, uid)
if referer:
referer += "?recid=%s&amp;ln=%s&amp;do=%s&amp;ds=%s&amp;nb=%s&amp;p=%s&amp;voted=%s&amp;reviews=%s" % (recid, ln, do, ds, nb, p, success, reviews)
redirect_to_url(req, referer)
else:
#Note: sent to commetns display
referer = "%s/comments.py/display?recid=%s&amp;ln=%s&amp;reviews=1&amp;voted=1"
referer %= (weburl, recid, ln)
redirect_to_url(req, referer)
def report(req, comid=-1, recid=-1, ln=cdslang, do='od', ds='all', nb=100, p=1, referer=None, reviews=0):
"""
Report a comment/review for inappropriate content
@param comid: comment/review id
@param recid: the id of the record the comment/review is associated with
@param ln: language
@param do: display order hh = highest helpful score, review only
lh = lowest helpful score, review only
hs = highest star score, review only
ls = lowest star score, review only
od = oldest date
nd = newest date
@param ds: display since all= no filtering by date
nd = n days ago
nw = n weeks ago
nm = n months ago
ny = n years ago
where n is a single digit integer between 0 and 9
@param nb: number of results per page
@param p: results page
@param referer: http address of the calling function to redirect to (refresh)
@param reviews: boolean, enabled for reviews, disabled for comments
"""
client_ip_address = get_client_ip_address(req)
uid = getUid(req)
success = perform_request_report(comid, client_ip_address, uid)
if referer:
referer += "?recid=%s&amp;ln=%s&amp;do=%s&amp;ds=%s&amp;nb=%s&amp;p=%s&amp;reported=%s&amp;reviews=%s" % (recid, ln, do, ds, nb, p, success, reviews)
redirect_to_url(req, referer)
else:
#Note: sent to comments display
referer = "%s/comments.py/display?recid=%s&amp;ln=%s&amp;reviews=1&amp;voted=1"
referer %= (weburl, recid, ln)
redirect_to_url(referer)
diff --git a/modules/webhelp/Makefile.am b/modules/webhelp/Makefile.am
index a81edf060..429171223 100644
--- a/modules/webhelp/Makefile.am
+++ b/modules/webhelp/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = web
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/webhelp/web/Makefile.am b/modules/webhelp/web/Makefile.am
index 0a9e507e4..c318b3575 100644
--- a/modules/webhelp/web/Makefile.am
+++ b/modules/webhelp/web/Makefile.am
@@ -1,53 +1,53 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
docdir = $(WEBDIR)/help
doc_DATA=index.en.html index.fr.html index.de.html index.pl.html index.pt.html index.es.html index.ca.html index.it.html index.ja.html index.ru.html index.sk.html index.cs.html index.no.html index.sv.html index.el.html index.uk.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.en.html %.fr.html %.de.html %.es.html %.ca.html %.pl.html %.pt.html %.it.html %.ja.html %.ru.html %.sk.html %.cs.html %.no.html %.sv.html %.el.html %.uk.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(MO)
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$*.en.html \
-o\(ALL-LANG_*\)+LANG_FR:$*.fr.html \
-o\(ALL-LANG_*\)+LANG_DE:$*.de.html \
-o\(ALL-LANG_*\)+LANG_ES:$*.es.html \
-o\(ALL-LANG_*\)+LANG_CA:$*.ca.html \
-o\(ALL-LANG_*\)+LANG_PL:$*.pl.html \
-o\(ALL-LANG_*\)+LANG_PT:$*.pt.html \
-o\(ALL-LANG_*\)+LANG_IT:$*.it.html \
-o\(ALL-LANG_*\)+LANG_JA:$*.ja.html \
-o\(ALL-LANG_*\)+LANG_RU:$*.ru.html \
-o\(ALL-LANG_*\)+LANG_SK:$*.sk.html \
-o\(ALL-LANG_*\)+LANG_CS:$*.cs.html \
-o\(ALL-LANG_*\)+LANG_NO:$*.no.html \
-o\(ALL-LANG_*\)+LANG_SV:$*.sv.html \
-o\(ALL-LANG_*\)+LANG_EL:$*.el.html \
-o\(ALL-LANG_*\)+LANG_UK:$*.uk.html $<
for lang in $(LINGUAS); do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.$${lang}.html" ; \
done
diff --git a/modules/webhelp/web/admin/Makefile.am b/modules/webhelp/web/admin/Makefile.am
index 06eae6db5..21831c570 100644
--- a/modules/webhelp/web/admin/Makefile.am
+++ b/modules/webhelp/web/admin/Makefile.am
@@ -1,53 +1,53 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = howto
docdir = $(WEBDIR)/admin
doc_DATA=index.en.html index.fr.html index.de.html index.es.html index.ca.html index.pl.html index.pt.html index.it.html index.ja.html index.ru.html index.sk.html index.cs.html index.no.html index.sv.html index.el.html index.uk.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.en.html %.fr.html %.de.html %.es.html %.ca.html %.pl.html %.pt.html %.it.html %.ja.html %.ru.html %.sk.html %.cs.html %.no.html %.sv.html %.el.html %.uk.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(MO)
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$*.en.html \
-o\(ALL-LANG_*\)+LANG_FR:$*.fr.html \
-o\(ALL-LANG_*\)+LANG_DE:$*.de.html \
-o\(ALL-LANG_*\)+LANG_ES:$*.es.html \
-o\(ALL-LANG_*\)+LANG_CA:$*.ca.html \
-o\(ALL-LANG_*\)+LANG_PL:$*.pl.html \
-o\(ALL-LANG_*\)+LANG_PT:$*.pt.html \
-o\(ALL-LANG_*\)+LANG_IT:$*.it.html \
-o\(ALL-LANG_*\)+LANG_JA:$*.ja.html \
-o\(ALL-LANG_*\)+LANG_RU:$*.ru.html \
-o\(ALL-LANG_*\)+LANG_SK:$*.sk.html \
-o\(ALL-LANG_*\)+LANG_CS:$*.cs.html \
-o\(ALL-LANG_*\)+LANG_NO:$*.no.html \
-o\(ALL-LANG_*\)+LANG_SV:$*.sv.html \
-o\(ALL-LANG_*\)+LANG_EL:$*.el.html \
-o\(ALL-LANG_*\)+LANG_UK:$*.uk.html $<
for lang in $(LINGUAS); do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.$${lang}.html" ; \
done
diff --git a/modules/webhelp/web/admin/howto/Makefile.am b/modules/webhelp/web/admin/howto/Makefile.am
index 66be12295..9c0a18256 100644
--- a/modules/webhelp/web/admin/howto/Makefile.am
+++ b/modules/webhelp/web/admin/howto/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/howto
doc_DATA=index.html marc.html migrate.html run.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webhelp/web/admin/howto/index.html.wml b/modules/webhelp/web/admin/howto/index.html.wml
index 5ef962455..2a21bd0ea 100644
--- a/modules/webhelp/web/admin/howto/index.html.wml
+++ b/modules/webhelp/web/admin/howto/index.html.wml
@@ -1,52 +1,52 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Admin HOWTOs" \
navbar_name="admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/>Admin Area</a>" \
navbar_select="howto"
<p>The HOWTO guides will give you both short and not-so-short
recipes and thoughts on some of the most frequently encountered
administrative tasks.
<blockquote>
<dl>
<dt><a href="marc.html">HOWTO MARC</a>
<dd>Describes how to choose the MARC representation of your metadata
and how it will be stored in CDSware.
<dt><a href="migrate.html">HOWTO Migrate</a>
<dd>Describes how to migrate a bunch of your old data from any format
you might have into CDSware.
<dt><a href="run.html">HOWTO Run</a>
<dd>Describes how to run your CDSware installation and how to take
care of its normal operation day by day.
</dl>
</blockquote>
<p>Haven't found what you were looking for? <a href="mailto:<ADMINEMAIL>" title="CDSware-Suggest-a-HOWTO">Suggest a HOWTO</a>.
diff --git a/modules/webhelp/web/admin/howto/marc.html.wml b/modules/webhelp/web/admin/howto/marc.html.wml
index caf8ccf95..cec9b698e 100644
--- a/modules/webhelp/web/admin/howto/marc.html.wml
+++ b/modules/webhelp/web/admin/howto/marc.html.wml
@@ -1,2261 +1,2261 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="HOWTO MARC Your Bibliographic Data" \
navbar_name="admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/>Admin Area</a> &gt; <a class=navtrail href=<WEBURL>/admin/howto/>Admin HOWTOs</a>" \
navbar_select="howto_marc"
Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Why to MARC at all?</h2>
<p>All the bibliographic data in the CDSware system are
internally represented in the <a
href="http://www.loc.gov/marc/bibliographic/">MARC 21</a> format.
There are several good reasons for this:
<ul>
<li>MARC format is <em>the</em> standard in the library world. It is
well established and has been used since 1960s.
<li>MARC is flexible enough to represent any metadata structure you
may need now or in the future. Therefore, CDSware can adapt to your
needs without altering its internal data structure.
<li>MARC technology, albeit developed in the punch card times
(1960s!), can be well combined with recent technologies like XML. In
fact, whenever bibliographic metadata are to be worked with externally
in a file format, CDSware uses recently standardized <a
href="http://www.loc.gov/standards/marcxml/">MARC XML</a> format
provided by the Library of Congress.
</ul>
<h2>Choosing MARC representation of your metadata</h2>
<p>Basically, you are in one of the following three situations:
<ol>
<li><p>You do not care much about internal MARC metadata structure as
far as you can work with "more meaningful" metadata concepts like
<em>author</em>, <em>abstract</em>, <em>title</em>, etc. In this case
we simply recommend you to stick to CDSware defaults that preset for
you the most commonly used metadata fields (in alphabetical order;
non-exhaustive list):
<blockquote>
<pre>
METADATA CONCEPT PROPOSED MARC 21 REPRESENTATION
------------------------ -------------------------------
Abstract 520 $a
Author, first 100 $a
Author(s), additional 700 $a
Collection identifier 980 $a
Email 8560 $f
Imprint 260 $a,b,c; 300 $a
Keywords 6531 $a
Language 041 $a
OAI identifier 909CO $o
Publication info 909C4 $* [many subfields]
References 999C5 $* [many subfields]
Primary report number 037 $a [unique throughout the system!]
Additional report number(s) 088 $a
Series 490 $a,v
Subject 65017 $a
Title 245 $a
URL (e.g. to fulltext) 8564 $u, $z
</pre>
</blockquote>
<p>The advantage of using these CDSware defaults is that you can use
pre-defined configurations of <a href="../bibconvert/">BibConvert</a>,
<a href="../bibformat/">BibFormat</a>, and <a
href="../bibindex/">BibIndex</a>.
<li><p>You do not care much about internal MARC metadata structure, so
you are using CDSware defaults, but you need to introduce a new
metadata concept. For example, you would like to store also the
document shelf number, and you want to make it separately searchable.
In this case you are free to choose any MARC tag of your own, for
example <code>963 $6</code>. After that you would configure CDSware
as follows:
<ul>
<li>configure <a href="../bibindex/">BibIndex</a> to create a new
logical field called <em>document shelf</em> and associate it with
<code>963 $6</code> physical MARC tag;
<li>run <a href="../bibindex/">BibIndex</a> to create word tables for
the new searchable index;
<li>configure <a href="../websubmit/">WebSubmit</a> to let the
submission interface know of the existence of the new field;
<li>configure <a href="../websearch/">WebSearch</a> to introduce the
new searchable field into collections of your choice;
<li>configure <a href="../bibformat/">BibFormat</a> to include
document shelf information in the record display on search results
pages.
</ul>
<p>which should give you the functionality you need.
<li><p>You have some constraints on the MARC level, for example you
would like to use MARC markup scheme of your own. You are free to
define your own scheme and even invert the meaning of our default
configurations. For each field you would simply follow the
above-mentioned configuration procedure.
<p>However, when designing your own MARC scheme, you need to think of
two CDSware-related restrictions:
<ul>
<li>There should be no clash in the meaning of the same MARC tag in
two different collections. For example, the tag <code>100</code>
should not mean <em>first author</em> in the Preprints collection and
<em>title</em> in the Videotapes collection. The MARC tags are
considered to be chosen globally, in a collection-independent way.
This means that we cannot have several collections reusing the same
MARC code for their own different purposes. (This should never happen
in well designed database system anyway, but if you have a merge of
various databases coming from various groups of users, and if you do
not have the liberty to remap their MARC tags, this may be a problem.)
<li>Also, our database design assumes that the order of repetitive
subfields inside the same field instance does not matter. For
example, let us consider the tag <code>100</code> with the value
<code>$a Foo $a Bar $a Baz</code>. Then, the question "what is the
second <code>$a</code> of the tag <code>100</code>?" is invalid within
the CDSware MARC paradigm. The CDSware would store a tag like that,
but not the order of repetitive subfields themselves. In our MARC
paradigm, we prefer to code that information either (i) into different
subfields within the same field instance (<code>100 $a Foo $b Bar $c
Baz</code>), or (ii) into the same subfield but inside several field
instances (<code>100 $a Foo</code>; <code>100 $a Bar</code>; <code>100
$a Baz</code>), according to what is more appropriate. (We think that
to rely on the order of repetitive subfields inside the same field
instance is a suspicious database design.)
</ul>
<p>These two restrictions were introduced in order to keep CDSware
bibliographic tables both simple and fast. As explained above, we
believe that any good database design will avoid these techniques
anyway.
</ol>
<h2>MARC representation in use at CERN</h2>
<p>MARC schema that is used in the CERN library differs in some ways
from the schema found in the CDSware default configuration and in the
demo records, described under point 1 of the preceding section. This
has got both an advantage and a disadvantage: (i) an advantage that it
permits us to easily test the behaviour of CDSware in the context of
different metadata schemata used by different CDSware installations in
the world, and (ii) a disadvantage that the default schema may be
prone to different extensions by different CDSware installations in
the world, while these extensions could have possibly been avoided by
building local extensions on top of a richer default. (There will
probably always be local tag schema differences due to various local
cataloguing traditions.)
<p>As an example of an extensive MARC schema that could provide a
possible richer default for the CDSware installations in the world, we
are listing below all MARC tags that are in production in the CERN
Library. Please note that in some cases the metadata choice was
dictated by local policy of a Swiss library network that the CERN
Library is participating at, and that it may deliberately differ from
the Library of Congress recommendations in some places to some extent.
(See especially tags 024, 035, 037, 518, 700, 710, 711, 720, 721, 722,
723, 724, 725, 773, 866.)
<p>If this schema is found interesting, we may also provide CERN
BibFormat etc configurations that implement it for CDSware.
<pre>
<protect>
GUIDE TO MARC21 TAGS FOR CERN AND CDSWARE
an attempt to present the actual setup of different MARC tags in use in AL500
at CERN
Maja Gracco
1 September 2004
NOTE:
1. The abbreviations "NR" and "R" are MARC21 standards and stands for
"Not repetitive" and "Repetitive". At CERN the rule is to make a tag repetitive,
when possible [only tags 1xx are not-repetitive] but to make subfields
non-repetitive [there are a couple of exceptions].
2. Subfield codes in AL300 are marked with $$ and subfield codes in AL500
are marked with $.
3. When different indicators are used, the tag will be repeated for each of
them like tag 246
4. [CERN] indicates, that some modifications have been done to the tag to
suit the CERN Library needs, like adding one or more subfield code(s) like
tag "773" or slightly change the content of the field like tag "037"
5. [CDSware/MySQL] indicates, that this tag is exlusively used for CDSware;
this technic is mainly used, when AL500 proposes an alpha-tag like "BAS"
6. To be able to find previous fields/tags mentioned under the title:
"Additional field(s)/tag(s):", you can use the Find-command on your browser
001 CONTROL NUMBER (NR)
This field has no indicators or subfield codes.
It contains the control number assigned by the organization
creating, using or distributing the record. - [ARC,CER,IEX,MAN,MMD]
{Created automatically at input via GUI/Cataloguing module}
NOTE: In MySQL used for CDSware record ID
003 CONTROL NUMBER IDENTIFIER (NR)
This field has no indicators or subfield codes.
It contains the MARC code for the agency whose system control
number is present in field 001. - [ARC,CER,IEX,MAN,MMD]
[Additional field(s)/tag(s)]:
{Not in use in AL300}
005 DATE AND TIME OF LAST TRANSACTION (NR)
This field has no indicators or subfield codes.
It contains 16 characters that specify the date and time
of the last record transaction. - [ARC,CER,IEX,MAN,MMD]
[Additional field(s)/tag(s):]
{Not in use in AL300}
020 INTERNATIONAL STANDARD BOOK NUMBER (R)
Indicators - Both undefined
Subfield Code(s)
$a International Standard Book Number (NR) - [CER]
[Additional field(s)/tag(s): IS]
[IS * -> 020 $a {To be used when the base is not "3n" but monograph}]
022 INTERNATIONAL STANDARD SERIAL NUMBER (R)
Indicators - Both undefined
Subfield Code(s)
$a International Standard Serial Number (NR) - [CER]
[Additional field(s)/tag(s): IS]
[IS * -> 022 $a {To be used when the base is "3n" periodical}]
024 OPEN ARCHIVES INITIATIVE (R) [CERN]
Indicators
First Unspecified type of standard number or code
8
Second - undefined
Subfield Code(s)
$a OAI - [CER]
$p OAI-set indicator - [CER]
[Additional field(s)/tag(s): 909CO]
[909CO $$a -> 0248 $a]
{Not in use in AL300}
030 CODEN DESIGNATION (R)
Indicators - Both undefined
Subfield Code(s)
$a CODEN (NR) - [CER]
[Additional field(s)/tag(s): CD]
[CD * -> 030 $a]
035 SYSTEM CONTROL NUMBER (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a System control number (NR) - [CER,IEX,MAN,MMD,WAI/UDC]
$9 System control number: Inst. (NR) - [CER,"CERN annual report",
"CERN ISOLDE",IEX,MAN,MMD,WAI/UDC]
[Additional field(s)/tag(s): ON,OS,SYSNO,909C0,909C6,909C7]
[ON $c, * -> 909C6 $c -> 035 $a; "CERN annual report" -> $9]
[OS $a-$z -> 035 $a; $9 {Not in use in AL300}]
[909C7 $i -> 035 $a; "CERN ISOLDE" -> $9]
[SYSNO * -> 909C0 $o -> 035 $a; $9 global-local-library as in AL300]
NOTE:
[SYSNO * -> 909C0 $o -> 035 ALL but IEX/DIR]
[SYSNO * -> 035 $a {IEX/DIR: System number}]
[035 $9 {IEX/DIR: Add "PIE" into this field} {Not in use in AL300}]
037 SOURCE OF ACQUISITION (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Electronically retrievable number (NR) - [CER,MAN,MMD]
[Additional field(s)/tag(s): ER]
[ER * -> 037 $a]
041 LANGUAGE CODE (NR)
Indicators - Both undefined
Subfield Code(s)
$a Language code (NR) - [ARC,CER,IEX,MAN,MMD]
[Additional field(s)/tag(s): LN]
[LN * -> 041 $a]
044 COUNTRY OF PUBLISHING/PRODUCING ENTITY CODE (NR)
Indicators - Both undefined
Subfield Code(s)
$a Country of publishing/producing entity code (NR) - [CER base=3n]
[Additional field(s)/tag(s): SW]
[SW $$c -> 044 $a]
080 UNIVERSAL DECIMAL CLASSIFICATION NUMBER (R)
Indicators - Both undefined
Subfield Code(s)
$a Universal Decimal Classification number (NR) - [CER,WAI/UDC]
[Additional field(s)/tag(s): UD]
[UD * -> 080 $a]
088 REPORT NUMBER (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Report number (NR) - [ARC,CER,MAN,MMD]
$9 CERN internal number (NR) - [CER,MMD]
[Additional field(s)/tag(s): RN,RN1,FRAME,909C0,909C1]
[RN * -> 088 $a]
[RN1 * -> 909C0 $r -> 909C1 $a -> 088 $9]
[FRAME * -> 909C0 $r -> 909C1 $a -> 088 $9]
100 MAIN ENTRY--PERSONAL NAME (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [CER,MAN,MMD]
$e Relator term (NR) - [CER,MMD]
$u Affiliation (NR) - [CER]
$v Second and onwards affiliation (R) - [CER]
[Additional field(s)/tag(s): AU1,AU2]
[AU1 * -> 100 $a]
[AU2 * -> 100 $a]
[AU1 $$e -> 100 $e {MMD}]
[AU1 $$2 -> 100 $e]
[AU2 $$2 -> 100 $e]
[AU2 $$u -> 100 $u]
[AU2 $$v -> 100 $v]
110 MAIN ENTRY--CORPORATE NAME (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Corporate name (NR) - [CER,IEX]
$b Subordinate unit (NR) - [IEX]
$g Acronym (NR) - [IEX]
[Additional field(s)/tag(s): ACRO,CA1,DEPT,ORG]
[CA1 * -> 110 $a]
[ORG * -> 110 $a]
[DEPT * -> 110 $b]
[ACRO * -> 110 $g]
Don't use this tag for base=3n use tag 931
111 MAIN ENTRY--MEETING NAME (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Meeting: conference, school, workshop (NR) - [CER,MAN]
$c Location of meeting (NR) - [CER]
$d Date of meeting (NR) - [CER]
$f Year of meetig (NR) - [CER]
$g Conference code (NR) - [CER]
$n Number of part/section/meeting (NR) - [CER]
$w Country (NR) - [CER]
$z Closing date (NR) - [CER]
$9 Opening date (NR) - [CER]
[Additional field(s)/tag(s): CF]
[CF * -> 111 $a]
[CF $$p -> 111 $c]
[CF $$d -> 111 $d]
[CF $$y -> 111 $f]
[CF $$c -> 111 $g]
[CF $$n -> 111 $n]
[Not in use in AL300 -> 111 $w]
[Not in use in AL300 -> 111 $z]
[CF $$o -> 111 $9]
145 MAIN TITLE STATEMENT (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Remainder of title (NR) - [CER]
$b Remainder of subtitle (NR) - [CER]
[Not in use in AL300]
210 ABBREVIATED TITLE (NR)
Indicators - Both undefined
Subfield Code(s)
$a Abbreviated title (NR) - [CER base=3n]
[Additional field(s)/tag(s): TI5]
[TI5 * -> 210 $a]
222 KEY TITLE (R)
Indicators - Both undefined
Subfield Code(s)
$a Key title (NR) - [CER base=3n]
[Additional field(s)/tag(s):]
[Created automatically by the system from tag 245 {Not in use in AL300}]
242 TRANSLATION OF TITLE BY CATALOGING AGENCY (R)
Indicators - Both undefined
Subfield Code(s)
$a Title (NR) - [CER bas=17]
$b Remainder of title (NR) - [CER bas=17]
$y Language code of translated title (NR) - [CER bas=17]
[Additional field(s)/tag(s): RT]
[RT * -> 242_1 $a {MMD} -> 242 $a {CER}]
[242_1 $b {MMD} -> 242 $b {CER}; {Not in use on AL300}]
[RT $$y -> 242_1 $y {MMD} -> 242 $y {CER}]
245 TITLE STATEMENT (NR)
Indicators - Both undefined
Subfield Code(s)
$a Title (NR) - [ARC,CER,IEX,MAN,MMD]
$b Remainder of title (NR) - [ARC,CER,IEX,MAN,MMD]
$k Form (NR) - [MAN]
[Additional field(s)/tag(s): TI,TI1,TI3,TYPE]
[TI * -> 245 $a]
[TI1 * -> 245 $a]
[TI3 * -> 245 $a {CER base=3n}]
[TI $$s -> 245 $b]
[TI1 $$s -> 245 $b]
[TI3 $$f -> 245 $b {CER base=3n}]
[TI3 $$s -> 245 $b {CER base=3n}]
[TI $$s -> 245 $ b]
[TYPE * -> 245 $ k]
246 VARYING FORM OF TITLE:1 (R)
Indicators - Both undefined
Subfield Code(s)
$a Title proper/short title (NR) - [CER not base=3n]
$b Remainder of title (NR) - [CER not base=3n]
$g Miscellaneous information (NR) - [CER not base=3n]
$i Display text (NR) - [CER not base=3n]
$n Number of part/section of a work (R) - [CER not base=3n]
$p Name of part/section of a work (R) - [CER not base=3n]
[Additional field(s)/tag(s): MRT,VO]
[MRT * -> 246 $a]
[MRT $$s -> 246 $b]
[MRT $$e -> 246 $g]
[MRT $$1 -> 246 $i]
[VO $$n -> 245 $n -> 246 $n]
[VO $$t -> 245 $p -> 246 $p]
246 VARYING FORM OF TITLE:2 (R)
Indicators
First - undefined
Second Type of title
1 Parallel title
Subfield Code(s)
$a Title proper/short title (NR) - [CER base=3n,MAN,MMD]
$i Display text (NR) - [CER base=3n]
[Additional field(s)/tag(s): 246_1,TI4,TIF]
[TI4 * -> 246_1 $a]
[TIF * -> 246_1 $a]
[TI4 $$1 -> 246_1 $i {parallel title}]
246 VARYING FORM OF TITLE:3 (R)
Indicators
First - undefined
Second Type of title
3 Other title
Subfield Code(s)
$a Title proper/short title (NR) - [CER base=3n]
$i Display text (NR) - [CER base=3n]
$9 Siglum "sigle" (NR) - [CER base=3n]
[Additional field(s)/tag(s): 246_3,TI4]
[TI4 * -> 246_3 $a]
[TI4 $$1 -> 246_3 $i {cross reference}]
[TI4 $$g -> 246_3 $9]{"sigle"]
250 EDITION STATEMENT (NR)
Indicators - Both undefined
Subfield Code(s)
$a Edition statement (NR) - [CER not base=3n,IEX]
[Additional field(s)/tag(s): TI, TI1]
[TI $$e -> 250 $a]
[TI1 $$e -> 250 $a]
260 PUBLICATION, DISTRIBUTION, ETC. (IMPRINT) (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Place of publication (NR) - [CER base=2n,41-45]
$b Name of publisher (NR) - [CER base=2n,41-45]
$c Date of publication [only year] (NR) - [ARC,CER,IEX,MAN,MMD]
$g Reprinted editions (NR) - [CER base=2n,41-45]
[Additional field(s)/tag(s): IM,YR,909CY]
[IM $$p -> 260 $a {CER base=2n,41-45}]
[IM $$n -> 260 $b {CER base=2n,41-45}]
[IM $$d -> 260 $c]{CER base=2n,41-45}]
[YR * -> 909CY $a -> 260 $c {ARC,CER,IEX,MAN,MMD}]
[NO $$g -> 260 $g {CER base=2n,41-45}]
NOTE: This tag is not used for base=3n [use tag 933]
269 PUBLICATION, DISTRIBUTION, ETC. (IMPRINT) (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Place of publ. (NR) - [ARC,CER not base=2n,41-45,IEX,MAN,MMD]
$b Name of publ. (NR) - [ARC,CER not base=2n,41-45,IEX,MAN,MMD]
$c Complete date (NR) - [ARC,CER not base=2n,41-45,IEX,MAN,MMD]
[Additional field(s)/tag(s):
{Not in use in AL300}]
NOTE: Don't use the following lines for CER base=2n,41-45 !!
[IM $$p -> 260 $a -> 269 $a]
[IM $$n -> 260 $b -> 269 $b]
[IM $$d -> 260 $c -> 269 $c]
270 ADDRESS (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Address or Alternate address (NR) - [CER,IEX]
$b City or Alternate city (NR) - [IEX]
$d Country (NR) - [CER,IEX]
$e Postal code for City or Alt. city (NR)- [IEX]
$k Telephone number (R) - [CER,IEX]
$l Fax number (R) - [CER,IEX]
$m Electronic mail address (NR) - [CER,IEX,MMD]
$p Contact person (NR) - [CER,IEX,MMD]
$s City or Alternate city: Suffix (NR) - [IEX]
$9 Telex (NR) - [CER,IEX]
[Additional field(s)/tag(s):AADDR,ADDR,ATOWN,CONT,CT,CTRY,RE,TELn,
TFAXn,TOWN,TOWN1]
[AADDR * -> 270 $a {alternate address}]
[ADDR * -> 270 $a {address}]
[CT $$a -> 270 $a]
[ATOWN * -> 270 $b {alternate town}]
[TOWN * -> 270 $b]
[CTRY * -> 270 $d {IEX}]
[ATOWN $$l -> 270 $e {alternate town: postal address}]
[TOWN $$l -> 270 $e]
[CT $$t -> 270 $k {CER}]
[TEL1-TEL9 $$c,a,l -> 270 $k {IEX}]
[CT $$f -> 270 $l {CER}]
[TFAX1-TFAX3 $$c,a,l -> 270 $l {IEX}]
[CONT $$e -> 270 $m]
[CT * -> 270 $m {MMD}]
[CT $$e -> 270 $m {CER}]
[CONT * -> 270 $$p]
[CT * -> 270 $p {IEX}]
[CT $$p -> 270 $p {MMD}]
[ATOWN $$t -> 270 $s {alternate town: suffix}]
[TOWN $$t -> 270 $s]
[RE $$z -> 270 $9 {CER}]
[TELEX * -> 270 $9 {IEX}]
300 PHYSICAL DESCRIPTION (R)
Indicators - Both undefined
Subfield Code(s)
$a Pagination (NR) - [ARC,CER,MAN,MMD]
[Additional field(s)/tag(s): IM]
[IM $$c -> 300 $a]
310 CURRENT PUBLICATION FREQUENCY (NR)
Indicators - Both undefined
Subfield Code(s)
$a Current publication frequency (NR) - [CER base=3n]
[Additional field(s)/tag(s): SW]
[SW $$f -> 310 $a]
340 PHYSICAL MEDIUM (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Material base and configuration (NR) - [ARC,CER,MAN,MMD]
$c Materials applied to surface (NR) - [ARC]
$d Information recording technique (NR) - [ARC]
$9 CD-ROM [code concatinated]
[Additional field(s)/tag(s): ME,CDR,909CZ]
[ME * -> 340 $a]
[CDR $$a,$$c,$$m,$$n,$$p,$$t,$$w -> 909CZ $a,$c,$m,$n,$p,$t,$w -> 340 $9]
490 SERIES STATEMENT (R)
Indicators - Both undefined
Subfield Code(s)
$a Series statement (NR) - [CER]
$v Volume/sequential designation (NR) - [CER]
[Additional field(s)/tag(s): SR,SR1]
[SR * -> 490 $a]
[SR1 * -> 490 $a]
[SR $$n -> 490 $v]
[SR1 $$n -> 490 $v]
500 GENERAL NOTE (R)
Indicators - Both undefined
Subfield Code(s)
$a General note (NR) - [ARC,CER,IEX,MAN,MMD]
[Additional field(s)/tag(s): NO,OB,PROG]
[NO * -> 500 $a]
[OB * -> 500 $a {MAN}]
[PROG * -> 500 $a {IEX} Scientific program]
NOTE: Don't use this tag for base=3n use tag 935
502 DISSERTATION NOTE (R)
Indicators - Both undefined
Subfield Code(s)
$a Diploma (NR) - [CER base=14]
$b University (NR) - [CER base=14]
$c Date of year of defense - [CER base=14]
[Additional field(s)/tag(s): NO1]
[NO1 * -> 502 $a]
506 RESTRICTIONS ON ACCESS NOTE (R)
Indicators - Both undefined
Subfield Code(s)
$a Terms governing access (NR) - [ARC,MAN,MMD]
$9 Local information (NR) - [ARC]
[Additional field(s)/tag(s): AV, CX]
[AV * -> 506 $a {ARC,MAN,MMD}]
[AV $$d -> 506 $a {MAN}]
[CX * -> 506 $a {ARC,MAN]
518 DATE/TIME AND PLACE OF AN EVENT NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$d Lectures: date (NR) - [CER]
$g Lectures: conference identification (NR) - [CER]
$h Lectures: starting time (NR) - [CER]
$l Lectures: length of speech (NR) - [CER]
$r Lectures: meeting (NR) - [CER]
[Additional field(s)/tag(s): NO1,909CC]
[NO1 $$d -> 909CC $ d -> 518 $d]
[NO1 $$g -> 909CC $ g -> 518 $g]
[NO1 $$h -> 909CC $ h -> 518 $h]
[NO1 $$l -> 909CC $ l -> 518 $l]
[NO1 * -> 909CC $$r -> 518 $r]
NOTE: This tag is only in use for CER base=10-13,16,19
520 ENGLISH SUMMARY, ETC. (R)
Indicators - Both undefined
Subfield Code(s)
$a Summary, etc. note (NR) - [ARC,CER,IEX,MAN,MMD]
$b Expansion of summary note (NR) - [MMD]
[Additional field(s)/tag(s): AB,RT]
[AB * -> 520 $a]
[RT * -> 520 $a {MMD/BUL} Abs. short Eng]
[AB * -> 520 $b {MMD/BUL} Abs. long Eng]
541 IMMEDIATE SOURCE OF ACQUISITION NOTE (R) [CER]
Indicators - Both undefined
Subfield Code(s)
$a Source of acquisition (NR) - [ARC,CER,MAN]
$d Date of acquisition (NR) - [ARC]
$e Accession number (NR) - [MMD]
$f Owner (NR) - [ARC]
$h Price paid by Bookshop [CER]
$9 Price for the user to pay [CER]
[Additional field(s)/tag(s): OS,SI]
[SI * -> 541 $a]
[SI $$b -> 541 $d]
[OS * -> 541 $e]
[SI $$c -> 541 $f]
546 LANGUAGE NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Language of source (NR) - [MAN]
$g Target language (NR) - [MAN
[Additional field(s)/tag(s): LN,TR,919CJ]
[LN * -> 919CJ $a -> 546 $a]
[TR $$t -> 919CJ $b -> 546 $g]
555 CUMULATIVE INDEX/FINDING AIDS NOTE (R)
Indicators - Both undefined
Subfield Code(s)
$a Cumulative index/finding aids note (NR) - [CER base=3n]
[Additional field(s)/tag(s): PNO]
[PNO $$c -> 555 $a]
583 ACTION NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Action (NR) - [CERN:BOOKSHOP,MAN]
$c Time/date of action (NR) - [CERN:BOOKSHOP,MAN]
$i Mail; Method of action (NR) - [MAN]
$z Note (NR) - [CERN:ALD]
[Additional field(s)/tag(s): ACT,DDLN,MAIL,SENDC,919CG]
[ACT * -> 583 $a]
[SENDC * -> 583 $a]
[DDLN * -> 583 $c]
[MAIL * -> 919CG $a -> 583 $i]
590 FRENCH SUMMARY NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Summary, etc. note in French (NR) - [MMD]
$b Expansion of summary note in French (NR) - [MMD]
[Additional field(s)/tag(s): ABF,RTF]
[ABF * -> 590 $a NOT base=75]
[RTF * -> 590 $a only base=75]
[ABF * -> 590 $b only base=75]
594 TYPE OF DOCUMENT (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Type of document (NR) - [ARDA]
[Additional field(s)/tag(s):]
{Not in use in AL300}
595 INTERNAL NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Internal note (NR) - [ARC,CER,IEX,MAN,MMD]
$d Control field (NR)
$i INSPEC number
$s Subject note (NR) - [MMD]
[Additional field(s)/tag(s): NI,OB]
[NI * -> 595 $a]
[OB * -> 595 $a {MMD}]
[NI $$d -> 595 $d]
[NI $$i -> 595 $i]
[NI $$s -> 595 $s]
NOTE: Don't use this tag for base=3n use tag 937
596 SLAC NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a SLAC note (NR) - [CER]
[Additional field(s)/tag(s): NS]
[NS * -> 596 $a]
597 OBSERVATION IN FRENCH (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Observation in French (NR) - [MMD]
[Additional field(s)/tag(s): OBF]
[OBF * -> 597 $a]
598 COPYRIGHT (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Copyright (NR) - [MMD]
[Additional field(s)/tag(s): CR]
[CR * -> 598 $a]
599 STATISTICS FOR THE CERN BOOKSHOP (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Total number of books bought by the Bookshop (NR) - [CER]
$b Total number of books sold by the Bookshop (NR) - [CER]
$c The values of $a minus the values of $b (NR) - [CER]
{Not in use in AL300}
600 SUBJECT ADDED ENTRY--PERSONAL NAME (R)
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [ARC]
$c Titles and other words associated with a name (NR) - [ARC]
[Additional field(s)/tag(s): NA]
[NA * -> 600 $a]
[NA $$c -> 600 $c]
650 SUBJECT ADDED ENTRY--TOPICAL TERM:1 (R)
Indicators
First Level of subject
1 Primary
Second Subject heading system/thesaurus
7 Source specified in subfield $2
Subfield Code(s)
$a Topical term or geographic name (NR) - [CER,MAN,MMD]
$2 Source of heading or term (NR) - [CER,MAN,MMD]
[Additional field(s)/tag(s): 65017,SU]
NOTE: Only 1st occurrence of SU
[SU * -> 65017 $a]
[SU $2 {Not in use in AL300}]
650 SUBJECT ADDED ENTRY--TOPICAL TERM:2 (R)
Indicators
First Level of subject
2 Secondary
Second Subject heading system/thesaurus
7 Source specified in subfield $2
Subfield Code(s)
$a Topical term or geographic name (NR) - [CER,MAN,MMD]
$2 Source of heading or term (NR) - [CER,MAN,MMD]
[Additional field(s)/tag(s): 65027,SU,SUA]
NOTE: Only 2nd occurrence of SU
[SU * -> 65027 $a]
[SUA * -> 65027 $a {MMD}]
[SU $2 {Not in use in AL300} {CER}]
653 ENGLISH INDEX TERM--UNCONTROLLED:1 (R) [CERN]
Indicators
First Level of index term
1 Primary
Second Undefined
Subfield Code(s)
$a Uncontrolled term (NR) - [ARC,CER,MAN,MMD,WAI/UDC]
$9 Institute of the uncontrolled term (NR) - [CER]
[Additional field(s)/tag(s): 6531,KW]
[KW * -> 6531 $a {Databases (see above) CER only older records}]
[KW a-z -> 6531 $a {CER newer records}]
[KW $9 {Not in use in AL300}]
653 FRENCH INDEX TERM--UNCONTROLLED:2 (R)
Indicators
First Level of index term
2 Secondary [in French]
Second Undefined
Subfield Code(s)
$a Uncontrolled term (NR) - [CER,WAI/UDC]
$9 Institute of the uncontrolled term (NR) - [CER,WAI/UDC]
[Additional field(s)/tag(s): 6532,KW6]
[KW6 * -> 6532 $a]
[KW6 $9 {Not in use in AL300}]
690 SUBJECT INDICATOR (R) [CERN]
Indicators
First Origine of indicator
C CERN
Second indicator undefined
Subfield Code(s)
$a Term (NR) - [ARC,CER,IEX,MAN,MMD]
[Additional field(s)/tag(s): 690C,IN,TYPE]
[IN * -> 690C $a]
[TYPE $$a -> 690C $a {Type of research: Accelerator} {IEX}]
[TYPE $$e -> 690C $a {Type of research: Experimental {IEX}]
[TYPE $$o -> 690C $a {Type of research: Other} {IEX}]
[TYPE $$t -> 690C $a {Type of research: Theoretical} {IEX}]
691 OBSERVATION (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Observation (NR) - [ARC,MAN]
[Additional field(s)/tag(s): OB,919C3]
[OB * -> 919C3 $a -> 691 $a]
[OB1 * -> 919C3 $a -> 691 $a {ARC}]
[OB2 * -> 919C3 $a -> 691 $a {ARC}]
692 BEAM (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$e Elements (NR) - [CER]
$i Isotope (NR) - [CER]
$m Minimum intensity (NR) - [CER]
[Additional field(s)/tag(s): BEAM,909CK]
[BEAM $$e -> 909CK $e -> 692 $e]
[BEAM $$i -> 909CK $i -> 692 $i]
[BEAM $$m -> 909CK $m -> 692 $m]
693 ACCELERATOR/EXPERIMENT (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Accelerator (NR) - [CER,IEX,MMD]
$e Experiment (NR) - [CER,IEX,MAN,MMD]
$f Facility
[Additional field(s)/tag(s): AC,ACCL,AE,EX]
[AC * -> 693 $a {CER,IEX base=50,MMD}]
[ACCL * -> 693 $a {IEX base=71}]
[AE $$a -> 693 $a {CER}]
[AE $$e -> 693 $e {CER}]
[EX * -> 693 $e {CER,IEX,MAN,MMD}]
694 CLASSIFICATION TERMS (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Uncontrolled term (NR) - [CER]
$9 Institute of the uncontrolled term (NR) - [CER]
[Additional field(s)/tag(s): KL]
[KL $a-$z -> 694 $a]
[KL $9 {Not in use in AL300}]
695 THESAURUS TERMS (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Uncontrolled term (NR) - [CER]
$9 Institute of the uncontrolled term (NR) - [CER]
[Additional field(s)/tag(s): KW2,TH]
[KW2 * -> 695 $a]
[KW2 $9 {Not in use in AL300}]
[TH $$a-$$z -> 695 $a]
[TH $9 {Not in use in AL300}]
699 SUBJECT CATEGORY FOR CERN BOOKSHOP (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Uncontrolled term (NR) - [CER]
$9 Institute of the uncontrolled term (NR) - [CER]
{Not in use in AL300}
700 ADDED ENTRY--PERSONAL NAME (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [ARC,CER,MMD]
$e Relator term (NR) - [ARC,CER,MMD]
$u Affiliation (NR) - [CER,IEX,MMD]
$v Affiliation (NR) - [CER]
[Additional field(s)/tag(s): AU,AU2,AU3]
[AU * -> 700 $a]
[AU2 * -> 700 $a]
[AU3 * -> 700 $a]
[AU $$2 -> 700 $e]
[AU2 $$2 -> 700 $e]
[AU3 $$2 -> 700 $e]
[AU $$u -> 700 $u]
[AU $$i -> 700 $u {IEX}]
[AU $$v -> 700 $v]
710 ADDED ENTRY--CORPORATE NAME (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Corporate name (NR) - [ARC,CER,MAN]
$b Subordinate unit (NR) - [CER,MAN]
$g Collaboration (NR) - [CER]
$5 CERN Paper (NR) - [CER,MAN,MMD]
$9 CERN Work (NR) - [CER]
[Additional field(s)/tag(s): CA,CE,CO,DI,GP,909CW]
[CA * -> 710 $a {CER}]
[CE * -> 710 $a {ARC}]
[GP * -> 909CW $a -> 710 $b]
[CO * -> 710 $g]
[CO $$n -> 710 $g]
[DI * -> 710 $5 {MAN}]
[DI $$p -> 710 $5]
[DI $$w -> 710 $9]
Don't use this tag for base=3n use tag 532
711 ADDED ENTRY--MEETING NAME (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Meeting name (NR) - [CER]
$c Location of meeting (NR) - [CER]
$d Date of meeting (NR) - [CER]
$f Date of a work (NR) - [CER]
$g Conference code (NR) - [CER]
$n Number of part/section/meeting (NR) - [CER]
$9 Conference opening date (NR) - [CER]
[Additional field(s)/tag(s): CF2,CF3,KF2]
[CF2 * -> 711 $a]
[CF3 * -> 711 $a]
[KF2 * -> 711 $a]
[CF2 $$p -> 711 $c]
[CF3 $$p -> 711 $c]
[KF2 $$p -> 711 $c]
[CF2 $$d -> 711 $d]
[CF3 $$d -> 711 $d]
[KF2 $$d -> 711 $d]
[CF2 $$y -> 711 $f]
[CF3 $$y -> 711 $f]
[KF2 $$y -> 711 $f]
[CF2 $$c -> 711 $g]
[CF3 $$c -> 711 $g]
[KF2 $$c -> 711 $g]
[CF2 $$n -> 711 $n]
[CF3 $$n -> 711 $n]
[KF2 $$n -> 711 $n]
[Not in use in AL300 -> 111 $w]
[Not in use in AL300 -> 111 $z]
[CF2 $$o -> 711 $9]
[CF3 $$o -> 711 $9]
[KF2 $$o -> 711 $9]
720 AUTHOR AS ON DOCUMENT / AUTHOR IN ARCHIVE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [ARC,CER]
[Additional field(s)/tag(s): PE,919C4,YAU,909CB]
[YAU * -> 909CB $y -> 720 $a {CER}]
[PE * -> 919C4 $a -> 720 $a {ARC}]
721 TRANSLATOR (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [MAN]
$l Words translated (NR) - [MAN]
[Additional field(s)/tag(s): AU,919CH]
[AU $$t -> 919CH $a -> 721 $a]
[AU $$w -> 919CH $l -> 721 $l]
722 REVISOR (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [MAN]
[Additional field(s)/tag(s): TR,919CI]
[TR $$r -> 919CI $a -> 722 $a]
723 RE-READER (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [MAN]
$l Words re-read (NR) - [MAN]
$s Language (NR) - [MAN]
[Additional field(s)/tag(s): 919CK]
[919CK $$a -> 723 $a]
[919CK $$l -> 723 $l]
[919CK $$s -> 723 $s]
724 "COMPOSER" OF MINUTES (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [MAN]
$l Words composed (NR) - [MAN]
$s Language (NR) - [MAN]
[Additional field(s)/tag(s)]
{Not in use before mid-April 2004}
725 "TYPIST" OF MINUTES (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [MAN]
$l Words composed (NR) - [MAN]
[Additional field(s)/tag(s)]
{Not in use before mid-June 2004}
770 SUPPLEMENT/SPECIAL ISSUE ENTRY (R)
Indicators - Both undefined
Subfield Code(s)
$i Display text (NR) - [CER base=3n]
$t Title (NR) - [CER base=3n]
$w Record control number (R) - [CER base=3n]
[Additional field(s)/tag(s): RT]
[RT $$1 -> 770 $i {Has the supplement}]
[RT $$t -> 770 $t]
[RT $$w -> 770 $w]
772 PARENT RECORD ENTRY (R)
Indicators - Both undefined
Subfield Code(s)
$i Display text (NR) - [CER base=3n]
$t Title (NR) - [CER base=3n]
$w Record control number (R) - [CER base=3n]
[Additional field(s)/tag(s): RT]
[RT $$1 -> 772 $i {Supplement to}]
[RT $$t -> 772 $t]
[RT $$w -> 772 $w]
773 HOST ITEM ENTRY (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a "DOI" (NR) - [CER]
$c Pagination (NR) - [ARC,CER,MMD]
$d Complete date (NR) - [CER,MMD]
$n Number [issue] (NR) - [ARC,CER,MMD]
$p Title (NR) - [ARC,CER,MMD]
$u URL (NR) - [MMD]
$v Volume (NR) - [CER,MMD]
$y Year (NR) - [ARC,CER,MMD]
[Additional field(s)/tag(s): PR,909C4]
[The same subfield codes are used as in PR and 909C4]
780 PRECEDING ENTRY (R)
Indicators - Both undefined
Subfield Code(s)
$i Display text (NR) - [CER base=3n]
$t Title (NR) - [CER base=3n]
$w Record control number (R) - [CER base=3n]
[Additional field(s)/tag(s): RT]
[RT $$1 -> 780 $i {Continues}]
[RT $$t -> 780 $t]
[RT $$w -> 780 $w]
785 SUCCEEDING ENTRY (R)
Indicators - Both undefined
Subfield Code(s)
$i Display text (NR) - [CER base=3n]
$t Title (NR) - [CER base=3n]
$w Record control number (R) - [CER base=3n]
[Additional field(s)/tag(s): RT]
[RT $$1 -> 785 $i {Continued by}]
[RT $$t -> 785 $t]
[RT $$w -> 785 $w]
787 NONSPECIFIC RELATIONSHIP ENTRY (R)
Indicators - Both undefined
Subfield Code(s)
$i Display text (NR) - [CER base=3n]
$t Title (NR) - [CER base=3n]
$w Record control number (R) - [CER base=3n]
[Additional field(s)/tag(s): RT]
[RT $$1 -> 787 $i {other forms of relation}]
[RT $$t -> 787 $t]
[RT $$w -> 787 $w]
852 LOCATION (R)
Indicators - Both undefined
Subfield Codes
$a Location (NR) - [ARC,CER,MAN,MMD]
$c Shelving location (NR) - [ARC,CER]
[Additional field(s)/tag(s): LO]
[LO * -> 852 $a {ARC,MAN}]
[LO $$a -> 852 $a {MMD}]
[LO $$b -> 852 $c {ARC,CER}]
856 ELECTRONIC LOCATION AND ACCESS:1 (R)
Indicators
First Access method
4 HTTP
Second Relationship
^ No information provided
Subfield Code(s)
$q Electronic format type (NR) - [IEX,MMD]
$u Uniform Resource Identifier (NR) - [ARC,CER,IEX,MAN,MMD]
$x Nonpublic note (NR) - [CER,MMD]
$y Link text (NR) - [ARC,CER,IEX,MAN,MMD]
[Additional field(s)/tag(s): 8564,EXT,MAP,EDL,ICO]
[EXT $$x -> 8564 $q {$x EDL; MMD/PHO: IF .jpeg $x picture}]
[ICO * -> 8564 $q {MMD [bases80-89][.gif] -> $x icon}]
[EDL $$x -> 8564 $u {base=55, MMD}]
[EXT * -> 8564 $u {IEX}; $$x -> $u]
[MAP $$x -> 8564 $u {base=3n}]
[EXT $$t -> 8564 $x] {MMD}]
[MAP $$k -> 8564 $x {base=3n}]
[EDL $$n -> 8564 $y {base=55, MMD}]
[EXT $$n -> 8564 $y]
[MAP $$n -> 8564 $y {base=3n}]
856 ELECTRONIC LOCATION AND ACCESS:2 (R)
Indicators
First Access method
4 HTTP
Second Relationship
2 Periodicals [TOC]
Subfield Code(s)
$u Uniform Resource Identifier (NR) - [CER base=3n]
$x Nonpublic note (NR) - [CER base=3n]
$y Link text (NR) - [CER base=3n]
[Additional field(s)/tag(s): 85642,TOC]
[TOC $$x -> 85642 $u]
[TOC $$k -> 85642 $x]
[TOC $$n -> 85642 $y]
859 ELECTRONIC MAIL MESSAGE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$f E-mail address (NR) - [CER,IEX,MAN,MMD]
[Additional field(s)/tag(s): 8560,EM,EMAIL]
[EM * -> 8560 $f -> 859 $f]
[EMAIL * -> 8560 $f -> 859 $f {IEX}]
866 TEXTUAL HOLDINGS--BASIC BIBLIOGRAPHIC UNIT (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Alternative holdings statement (NR) - [CER base=3n]
$b Library (NR) - [CER base=3n]
$c Collection (NR) - [CER base=3n]
$g Subscription status code (NR) - [CER base=3n]
$v Volume (NR) - [CER base=3n]
$x Retention code (NR) - [CER base=3n]
$z Public note (NR) - [CER base=3n]
[Additional field(s)/tag(s): HN,852]
[HN $$a -> 866 $a]
[HN $$y -> 866 $a]
[HN $$l -> 852 $b -> 866 $b]
[HN $$c -> 852 $c -> 866 $c]
[HN $$s -> 852 $g -> 866 $g]
[HN $$v -> 866 $v
[HN $$r -> 852 $x -> 866 $x]
[HN $$n -> 852 $z -> 866 $z]
901 AFFILIATION AT CONVERSION AL300/AL500 (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$u Name of institute (NR) - [CER,MAN]
[Additional field(s)/tag(s): AF,909CA]
[AF * -> 909CA $$u -> 901 $u]
902 OTHER INSTITUTES (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Name of other institute (NR) - [CER]
[Additional field(s)/tag(s): OI,909CD]
[OI * -> 909CD $a -> 902 $a]
903 "GREY BOOK" (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Approval (NR) - [CER]
$b Beam (NR) - [CER,IEX]
$d Status date (NR) - [IEX]
$s Status (NR) - [CER,IEX]
[Additional field(s)/tag(s): BEAM,NO1,ST,909CE]
[NO1 * -> 909CE $a -> 903 $a {IN= GREY BOOK; NO1=Approved...}]
[BEAM * -> 909CE $b -> 903 $b {IEX}]
[NO1 * -> 909CE $b -> 903 $b {IN= GREY BOOK; NO1=Beam...}]
[ST $$d -> 909CE $d -> 903 $d {IEX}]
[NO1 * -> 909CE $s -> 903 $s {IN= GREY BOOK; NO1=Status...}]
[ST * -> 909CE $s -> 903 $s {CER,IEX}]
904 BEAMS PER SHIFT (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$s Beams per shift (NR) - [CER]
[Additional field(s)/tag(s): SH,909CF]
[SH $$s -> 909CF $s -> 904 $s]
905 SPOKESMAN (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Address (NR) - [CER]
$k Telephone (NR) - [CER]
$l Fax (NR) - [CER]
$m E-mail (NR) - [CER]
$p Personal name (NR) - [CER,IEX]
$q Private address (NR) - [CER]
[Additional field(s)/tag(s): SPK,909CG]
[SPK $$a -> 909CG $a -> 905 $a]
[SPK $$p -> 909CG $k -> 905 $k]
[SPK $$f -> 909CG $l -> 905 $l]
[SPK $$e -> 909CG $m -> 905 $m]
[SPK $$n -> 909CG $p -> 905 $p]
[SPK * -> 909CG $p -> 905 $p {IEX}]
[SPK $$d -> 909CG $q -> 905 $q]
906 RESPONSIBLE PERSON / REFEREE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Address (NR) - [CER]
$k Telephone (NR) - [CER]
$l Fax (NR) - [CER]
$m E-mail (NR) - [CER]
$p Personal name (NR) - [CER]
$q Private address (NR) - [CER]
[Additional field(s)/tag(s): RESP,909CH]
[RESP $$a -> 909CH $a -> 905 $a]
[RESP $$p -> 909CH $k -> 905 $k]
[RESP $$f -> 909CH $l -> 905 $l]
[RESP $$e -> 909CH $m -> 905 $m]
[RESP $$n -> 909CH $p -> 905 $p]
[RESP $$d -> 909CH $q -> 905 $q]
907 INTC: RESOURCE COORDINATOR (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [CER,IEX]
[Additional field(s)/tag(s): RESP,909CI]
[RESP $$r -> 909CI $a -> 907 $a]
908 INTC: TECHNICAL COORDINATOR (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [CER,IEX]
[Additional field(s)/tag(s): RESP,909CJ]
[RESP $$t -> 909CJ $a -> 908 $a]
909 DEPUTY SPOKESMAN (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$d Personal name (NR) - [IEX]
[Additional field(s)/tag(s): RESP,919C7]
[RESP $$d -> 919C7 $d -> 909 $d]
910 FSGO (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$f Personal name (NR) - [IEX]
[Additional field(s)/tag(s): RESP,919C8]
[RESP $$f -> 919C8 $f -> 910 $f]
911 GLIMOS (R) [CERN] [CERN]
Indicators - Both undefined
Subfield Code(s)
$g Personal name (NR) - [IEX]
[Additional field(s)/tag(s): RESP,919C9]
[RESP $$g -> 919C9 -> 911 $g]
912 REGISTRATION FOR CONFERENCE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Abstracts deadline (NR) - [CER]
$f Fee (NR) - [CER]
$i "By invitation only" (NR) - [CER]
$n Number of participants (NR) - [CER]
$p Paper deadline (NR) - [CER]
$r Registration deadline (NR) - [CER]
[Additional field(s)/tag(s): RE,909CR]
[The same subfield codes are used as in RE and 909CR]
913 CITATION (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$c Citation (NR) - [CER]
$p Unformatted references (NR) - [IEX]
$t Title abbreviation (NR) - [CER]
$u Uniform Resource Identifier (NR) - [CER,IEX]
$v Volume (NR) - [CER]
$y Year (NR) - [CER]
[Additional field(s)/tag(s): CN,909C5]
[CN $$c -> 909C5 $c -> 913 $c]
[CN $$p -> 909C5 $p -> 913 $p]
[CN * -> 909C5 $t -> 913 $t {base=1n,n=1-3}]
[CN * -> 909C5 $u -> 913 $u {CER if IN=GREY BOOK}]
[CN * -> 909C5 $u -> 913 $u {IEX}]
[CN $$v -> 909C5 $v -> 913 $v
[CN $$y -> 909C5 $y -> 913 $y
914 UNIVERSAL DECIMAL CLASSIFICATION (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$u Secondary UDC number (NR) - [WAI/UDC]
$v Library shelving code (NR) - [WAI/UDC]
[Additional field(s)/tag(s): UD,UD2,UD3,909CU]
[UD2 * -> 909CU $u -> 914 $u]
[UD3 * -> 909CU $v -> 914 $v]
[UD $$s -> 909CU $v -> 914 $v]
916 "STATUS WEEK" (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Acquisition of proceedings code (NR) - [CER]
$d Display period for books (NR) - [CER]
$s Status of record (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$w Status week (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$y Year for Annual list (NR) - [CER]
$z CERN paper or CERN work (candidates for Ann. Report)(NR) - [CER]
[Additional field(s)/tag(s): DISP,SW,909CS,909CT]
[SW $$a -> 909CS $a -> 916 $a {NOT bas=3n}]
[DISP * -> 909CT $a -> 916 $d]
[SW $$s -> 909CS $s -> 916 $s]
[SW $$w -> 909CS $w -> 916 $w]
[SW $$y -> 909CS $y -> 916 $y]
917 CABLE
Indicators - Both undefined
Subfield Code(s)
$a Cable (NR) - [IEX]
[Additional field(s)/tag(s): CABLE,919CB]
[CABLE * -> 919CB $$a -> 917 $a]
918 DEPARTMENT INDEX (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Department index (NR) - [IEX]
[Additional field(s)/tag(s): DEPTI,919CC]
[DEPTI * -> 919CC $a -> 918 $a]
919 ORGANIZATION INDEX (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Organization index (NR) - [IEX]
[Additional field(s)/tag(s): ORGI,919CD]
[ORGI * -> 919CD $a -> 919 $a]
920 TOWN INDEX (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Town index (NR) - [IEX]
[Additional field(s)/tag(s): TOWNI,919CE]
[TOWNI * -> 919CE $$a -> 920 $a]
921 MICROCOSM: LOANS (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$d Loan date (NR) - [MMD]
$e Exhibition loan (NR) - [MMD]
$i Borrower institute (NR) - [MMD]
$t Loan to (NR) - [MMD]
$x Exhibition name (NR) - [MMD]
[Additional field(s)/tag(s): LD,EL,ISB,LT,XI,919CL]
[LD $$a -> 919CL $a -> 921 $d]
[EL $$e -> 919CL $e -> 921 $e]
[ISB * -> 919CL $i -> 921 $i]
[LT * -> 919CL $t -> 921 $t]
[XI $$a -> 919CL $x -> 921 $x]
922 MICROCOSM: PHYSICAL VALUES (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$d Diameter (NR) - [MMD]
$h Height (NR) - [MMD]
$i Interactive objects (NR) - [MMD]
$l Length (NR) - [MMD]
$p Depth (NR) - [MMD]
$w Weight (NR) - [MMD]
[Additional field(s)/tag(s): DIA,HI,IA,WI,DE,WE,919CM]
[DIA $$a -> 919CM $d -> 922 $d]
[HI $$a -> 919CM $h -> 922 $h]
[IA * -> 919CM $i -> 922 $i]
[WI $$a -> 919CM $l -> 922 $l]
[DE $$a -> 919CM $p -> 922 $p]
[WE $$a -> 919CM $w -> 922 $w]
923 PLACE OF PHOTO (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$p Place of photo (NR) - [MMD]
$r Requestor (NR) - [MAN,MMD]
[Additional field(s)/tag(s): PL,REQ,919CP]
[PL * -> 919CP $p -> 923 $p]
[REQ * -> 919CP $r -> 923 $r]
924 PHOTOLAB (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a "Tirage" (NR) - [MMD]
[Additional field(s)/tag(s): TIR,919CQ]
[TIR * -> 919CQ $a -> 924 $a]
[TIR $$a -> 919CQ $a -> 924 $a]
925 DATES (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Opening date/Date received (NR) - [ARC,MAN]
$b Closing date/Date completed (NR) - [ARC,MAN]
[Additional field(s)/tag(s): DA,919C0]
[DA $$a -> 919C0 $a -> 925 $a {ARC}]
[DA $$r -> 919C0 $a -> 925 $a {MAN}]
[DA $$b -> 919C0 $b -> 925 $b {ARC}]
[DA $$c -> 919C0 $b -> 925 $b {MAN}]
926 RECIPIENT (NR) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [ARC,CER,MAN]
[Additional field(s)/tag(s): DEST,919C1]
[DEST * -> 919C1 $a -> 926 $a]
927 FILE NUMBER (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a File number (NR) - [ARC,MAN]
[Additional field(s)/tag(s): FN,919C2]
[FN * -> 919C2 $a -> 927 $a]
928 ADDITIONAL RECIPIENT(S) (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Personal name (NR) - [CER,MAN]
[Additional field(s)/tag(s):
{Not in use in AL300}
929 RETENTION (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Retention (NR) - [ARC,MAN]
$d Retention date (NR) - [MAN]
[Additional field(s)/tag(s): RT,919C5]
[RT * -> 919C5 $a -> 929 $a]
[RT $$b -> 919C5 $d -> 929 $d {ARC}]
[RT $$d -> 919C5 $d -> 929 $d {MAN}]
931 PERI: MAIN CORPORATE AUTHOR (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Corporate name (NR) - [CER base=3n]
[Additional field(s)/tag(s): CA,909CQ]
[CA * -> 909CQ $a -> 931 $a]
932 PERI: ADDITIONAL CORPORATE AUTHOR (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Corporate name (NR) - [CER base=3n]
[Additional field(s)/tag(s): CA2,909CQ]
[CA2 * -> 909CQ $g -> 932 $a]
933 PERI: IMPRINT (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Place of publisher (NR) - [CER base=3n]
$b Name of publisher (NR) - [CER base=3n]
[Additional field(s)/tag(s): PIM,260,909CP]
[PIM $$p -> 260 $a -> 909CP $a -> 933 $a]
[PIM $$n -> 260 $b -> 909CP $b -> 933 $b]
934 PERI: IMPRINT OF E-JOURNALS (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Place of publisher (NR) - [CER base=3n]
$b Name of publisher (NR) - [CER base=3n]
$l Link for publisher (NR) - [CER base=3n]
$x Non-public note (NR) - [CER base=3n]
[Additional field(s)/tag(s): PIM2,909CM]
[PIM2 $$p -> 909CM $a -> 934 $a]
[PIM2 $$n -> 909CM $b -> 934 $b]
[PIM2 $$l -> 909CM $l -> 934 $l]
[$x not in use in AL300]
935 PERI: USER NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a User note (NR) - [CER base=3n]
[Additional field(s)/tag(s): PNO,909CX,500]
[PNO $$p -> 500 $a -> 909CX $a -> 935 $a]
936 PERI: E-J USER NOTE (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a E-J user note (NR) - [CER base=3n]
[Additional field(s)/tag(s): PNO2,909CN]
[PNO2 * -> 909CN $a -> 936 $a]
937 PERI: INTERNAL NOTE (R) - [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Internal note (NR) - [CER base=3n]
[Additional field(s)/tag(s): PNI,595,909CV]
[PNI * -> 595 $a -> 909CV $a -> 937 $a]
938 PERI: LOCAL INFORMATION (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Frequncy given as numbers (NR) - [CER base=3n]
$f Impact factor (NR) - [CER base=3n]
$i Index (NR) - [CER base=3n]
$p Title status (NR) - [CER base=3n]
[Additional field(s)/tag(s): SW,909CL]
[SW $$a -> 909CL $a -> 938 $a]
[SW $$o -> 909CL $f -> 938 $f]
[SW $$i -> 909CL $i -> 938 $i]
[SW $$p -> 909CL $p -> 938 $p]
940 LINK TO COMPANY (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$u URL address (NR) - [CERN:BOOKSHOP,MAN]
$y URL note (NR) - [CERN:BOOKSHOP,MAN]
[Additional field(s)/tag(s):]
{Not in use in AL300}
941 RELATED DOCUMENT NUMBER (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a Related document number (NR) - [MAN]
[Additional field(s)/tag(s):]
{Not in use in AL300}
960 BASE (R) [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a Base number (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
Taken from AL500 BAS
961 CAT (R) [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a Cataloguer (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$b Cataloguer level (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$c Modification date (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$l Library (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$h Hour - (NR) [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$x Creation date(NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
Taken from AL500 CAT
962 ALEPH Linking Field (R) [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a - link type
UP link to another BIB type record. A record can have only one
link of this type. "DN" link is automatically built in the
opposite direction.
DN "down" link to another BIB type record. Multiple links
are possible. "UP" link is automatically built in the
opposite direction.
PAR parallel link from BIB record to BIB record.
"PAR" link is automatically built in the opposite direction.
HOL link from HOL record to BIB record. Link is built from
BIB to HOL.
ADM link from ADM record to BIB record. Link is built from
BIB to ADM.
ANA is a link between bibliographic records of different levels.
When an anayltic link is created the system generates UP / DWN
links between the two records and an item link between the source
record and the item that corresponds to it (according to vol.,
part,year and pages) on the ADM record of the second record.
ITM links are created between a Bibliographic record and an ADM
record when there is no relationship between the two Bib records,
for example when two items are bound together. [NR} - [ARC]
{Only used for ARC in AL300}
$b - sysno of the linked document record (NR) - [ARC,CER,MMD]
$l - library where linked record is located (NR) - [ARC,CER,MMD]
$n - note regarding a DN (down record) link - (NR) [ARC,CER]
$m - note regarding an UP (up record) link - [not yet in use at CERN]
$y - analytic link - year link - [not yet in use at CERN]
$v - analytic link - volume link - [not yet in use at CERN]
$p - analytic link - part link - [not yet in use at CERN]
$i - analytic link - issue link - [not yet in use at CERN]
$k - analytic link - pages (NR) - [ARC,CER]
$t - base=3n [for paper version of e-journals]/title - (NR) - [CER,MMD
Taken from AL500 LKR
963 OWNER (NR) [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a Owner - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
Taken from AL500 OWN
964 ITEM (NR) [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a Owner - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
Taken from AL500 ITM
970 SYSTEM NUMBER (NR) [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a AL500 sysno (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
Taken from AL500 SYS
980 COLLECTION INDICATOR (R) [CERN] [CDSware/MySQL]
Indicators - Both undefined
Subfield Code(s)
$a Primary indicator (NR) - [ARC,CER,IEX,MAN,MMD]
$b Secondary indicator (NR) - [ARC,CER,IEX,MAN,MMD]
$c Deleted indicator (NR) - [ARC,CER,IEX,MAN,MMD
Generated and used in MySQL; accepted in AL500
981 SYSTEM NUMBER OF DELETED DOUBLE RECORDS (R) [CERN]
Indicators - Both undefined
Subfield Code(s)
$a System number (NR) - [ARC,CER,IEX,MAN,MMD,WAI]
{Not in use in AL300; to be added for users of MySQL}
999 REFERENCES (R) [CERN] [CDSware/MySQL]
Indicators
First Origine of indicator
C CERN
Second Type
5 References
Subfield Code(s)
$o Order number [contains [ ] line number] (NR)
$m Miscellaneous [contains 1st part of reference] (R)
$t Journal Title abbreviation (NR)
$p Page (NR)
$v Volume (NR)
$y Year (NR)
$n Issue Number (NR)
$u Uniform Resource Identifier (NR)
$r Report Number (NR)
NOT YET IMPLEMENTED
BAS BASE
Indicators - Both undefined
Subfield Code(s)
$a Base number (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
For MySQL use tag 960
[Additional field(s)/tag(s): BA]
[BA * -> BAS $a {used for input}]
[BASE * -> BAS $a {used for bath}]
CAT CAT (R)
Indicators - Both undefined
Subfield Code(s)
$a Cataloguer (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$b Cataloguer level (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$c Modification date (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$l Library (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$h Hour - (NR) [ARC,CER,IEX,MAN,MMD,WAI/UDC]
$x Creation date(NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
For MySQL use tag 961
[Additional field(s)/tag(s): CATZZ]
[CATZZ $$a -> CAT $a]
[CATZZ $$b -> CAT $b]
[CATZZ $$d -> CAT $c]
[{Not in use in AL300} -> CAT $l]
[{Not in use in AL300} -> CAT $h
[CATZZ $$c -> CAT $x]
FMT FORMAT
This field has no indicators or subfield codes.
It contains the Scope of material [2 character code]
Not used in MySQL
{Not in use in AL300}
ITM ITEM (NR)
Indicators - Both undefined
Subfield Code(s)
$a Owner - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
For MySQL use tag 964
{Not in use in AL300}
LKR ALEPH Linking Field (R)
Indicators - Both undefined
Subfield Code(s)
$a - link type
UP link to another BIB type record. A record can have only one
link of this type. "DN" link is automatically built in the
opposite direction.
DN "down" link to another BIB type record. Multiple links
are possible. "UP" link is automatically built in the
opposite direction.
PAR parallel link from BIB record to BIB record.
"PAR" link is automatically built in the opposite direction.
HOL link from HOL record to BIB record. Link is built from
BIB to HOL.
ADM link from ADM record to BIB record. Link is built from
BIB to ADM.
ANA is a link between bibliographic records of different levels.
When an anayltic link is created the system generates UP / DWN
links between the two records and an item link between the source
record and the item that corresponds to it (according to vol.,
part,year and pages) on the ADM record of the second record.
ITM links are created between a Bibliographic record and an ADM
record when there is no relationship between the two Bib records,
for example when two items are bound together. [NR} - [ARC]
{Only used for ARC in AL300}
$b - sysno of the linked document record (NR) - [ARC,CER,MMD]
$l - library where linked record is located (NR) - [ARC,CER,MMD]
$n - note regarding a DN (down record) link - (NR) [ARC,CER]
$m - note regarding an UP (up record) link - [not yet in use at CERN]
$y - analytic link - year link - [not yet in use at CERN]
$v - analytic link - volume link - [not yet in use at CERN]
$p - analytic link - part link - [not yet in use at CERN]
$i - analytic link - issue link - [not yet in use at CERN]
$k - analytic link - pages (NR) - [ARC,CER]
$t - base=3n [for paper version of e-journals]/title - (NR) - [CER,MMD]
For MySQL use tag 962
[Additional field(s)/tag(s): 909CK]
[LKR $$a -> 909CK $a -> LKR $a {ARC}]
[LKR $$b -> 909CK $b -> LKR $b {ARC,CER,MMD}]
[LKR $$l -> 909CK $l -> LKR $l {ARC,CER,MMD}]
[LKR $$d -> 909CK $n -> LKR $n {ARC,CER}]
[LKR $$t -> 909CK $n -> LKR $n {CER base=3n}]
[LKR $$e -> 909CK $k -> LKR $k {ARC,CER}]
[LKR $$t -> 909CK $t -> LKR $t {CER base=3n,MMD}]
OWN OWNER (NR)
Indicators - Both undefined
Subfield Code(s)
$a Owner - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
For MySQL use tag 963
{Not in use in AL300}
SYS SYSTEM NUMBER (NR)
Indicators - Both undefined
Subfield Code(s)
$a AL500 sysno (NR) - [ARC,CER,IEX,MAN,MMD,WAI/UDC]
For MySQL use tag 970
</protect>
</pre>
diff --git a/modules/webhelp/web/admin/howto/migrate.html.wml b/modules/webhelp/web/admin/howto/migrate.html.wml
index eed0d41dc..7cf10bb67 100644
--- a/modules/webhelp/web/admin/howto/migrate.html.wml
+++ b/modules/webhelp/web/admin/howto/migrate.html.wml
@@ -1,95 +1,95 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="HOWTO Migrate Your Old Documents Into CDSware" \
navbar_name="admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/>Admin Area</a> &gt; <a class=navtrail href=<WEBURL>/admin/howto/>Admin HOWTOs</a>" \
navbar_select="howto_migrate"
Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Overview</h2>
<p>CDSware comes as a suite of several independent flexible modules
that enable you to easily convert your data from any existing format
and to upload them into the CDSware system. This document briefly
describes how you proceed.
<h2>Quick instructions for the impatient CDSware admin</h2>
<blockquote>
<pre>
$ cd /tmp
$ cp /my/own/doc/system/datadump.txt .
$ vi dump.cfg
$ bibconvert -cdatadump.cfg < datadump.txt > datadump.xml
$ bibupload datadump.xml
$ bibsched
</pre>
</blockquote>
<h2>Detailed instructions for the patient CDSware admin</h2>
<blockquote>
<dl>
<dt><code>$ cd /tmp</code>
<dd><blockquote>Go to a temporary directory.</blockquote>
<dt><code>$ cp /my/own/doc/system/datadump.txt .</code>
<dd><blockquote>Copy your old data into a text file or some other
format of your choice. Preferably, the data should be well
structured. (Anyhow, even a free text format may be attepmted to be
matched!)</blockquote>
<dt><code>$ vi dump.cfg</code>
<dd><blockquote>Describe the format of your data in the <a
href="<WEBURL>/admin/bibconvert/">BibConvert</a> language. This
will enable you to transform them into XML MARC format that the
CDSware system internally uses for bibliographic data handling. (If
you have not chosen yet your MARC scheme, please read the <a
href="marc.html">MARC HOWTO</a>.)</blockquote>
<dt><code>$ bibconvert -cdatadump.cfg < datadump.txt > datadump.xml</code>
<dd><blockquote>Convert the data from your own format into XML MARC,
using the configuration you just wrote in the previous step. FIXME:
add a note about creating collection indicators (980) and OAI
IDs.</blockquote>
<dt><code>$ bibupload datadump.xml</code>
<dd><blockquote>Upload thusly converted metadata into CDSware
bibliographic databases.</blockquote>
<dt><code>$ bibsched</code>
<dd><blockquote>Watch the progress how the metadata are being
uploaded, indexed, and formatted.</blockquote>
</dl>
<p>Congratulations! At this point you should have successfully
migrated your old data into the CDSware system.
</blockquote>
diff --git a/modules/webhelp/web/admin/howto/run.html.wml b/modules/webhelp/web/admin/howto/run.html.wml
index fcfe4191d..abb3120c2 100644
--- a/modules/webhelp/web/admin/howto/run.html.wml
+++ b/modules/webhelp/web/admin/howto/run.html.wml
@@ -1,198 +1,198 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="HOWTO Run Your CDSware Installation" \
navbar_name="admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/>Admin Area</a> &gt; <a class=navtrail href=<WEBURL>/admin/howto/>Admin HOWTOs</a>" \
navbar_select="howto_run"
Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Overview</h2>
<p>This HOWTO guide intends to give you ideas on how to run your
CDSware installation and how to take care of its normal operation day
by day.
<h2>BibSched Periodical Tasks</h2>
<p>Many tasks that manipulate the bibliographic record database can be
set to run in a periodical mode. For example, we want to have the
indexing engine to scan periodically for newly arrived documents to
index them as soon as they enter into the system. It is the role of
the BibSched system to take care of the task scheduling and the task
execution.
<p>Periodical tasks (such as regular metadata indexing) as well as
one-time tasks (such as a batch upload of acquired metadata file)
are not executed straight away but are stored in the BibSched task
queue. BibSched daemon looks periodically in the queue and launches
the tasks according to their order or the date of programmed runtime.
You can consider BibSched to be a kind of cron daemon for
bibliographic tasks.
<p>This means that after CDSware installation you want to have
BibSched daemon running permanently. To launch BibSched daemon, do:
<blockquote>
<pre>
$ bibsched -d
</pre>
</blockquote>
To setup indexing, reformatting, and collection updating daemons to
run periodically with a sleeping period of, say, 1 hour:
<blockquote>
<pre>
$ bibindex -f50000 -s1h
$ bibreformat -oHB,HD -s1h
$ webcoll -v0 -s1h
$ bibrank -f50000 -s1h
</pre>
</blockquote>
<strong>HINT:</strong> It is good to have these three tasks
permanently in your BibSched queue so that your newly submitted
documents will be further processed automatically.
<p> Note that the BibSched daemon automatic mode stops as soon as some
of the tasks ends with an error. It it therefore a good idea to
inspect BibSched queue from time to time. This can be done by running
the BibSched command-line admin interface:
<blockquote>
<pre>
$ bibsched
</pre>
</blockquote>
that will permit you to stop/start the daemon mode, to delete the
tasks already submitted, to run some of the tasks manually, etc. Note
also that BibSched daemon writes log and error files on its operation
and on the operation of its tasks. The log and error files can be
found on your system at <LOGDIR>.
<p><strong>HINT:</strong> You may want to launch the
<code>bibsched</code> command from time to time (say a couple of times
per day) to inspect the BibSched queue and to verify the status of the
BibSched system.
<p><strong>HINT:</strong> You may want to clean up the old BibSched
tasks with the DONE status, let us say once per month, to make the
task table slim and the bibsched daemon both faster and less memory
hungry:
<blockquote>
<pre>
$ echo "DELETE FROM schTASK WHERE status='DONE' AND runtime&lt;DATE_SUB(NOW(), INTERVAL 1 MONTH);" | dbexec
</pre>
</blockquote>
<h2>Recalculate ranking weights</h2>
<p>When you are adding new records to the system, the word frequency
ranking weights for old records aren't recalculated by default in
order to speed up the insertion of new records. This may influence a
bit the precision of word similarity searches. It is therefore
advised to expressely run bibrank in the recalculating mode once in a
while by doing:
<blockquote>
<pre>
$ bibrank -wwrd -R
</pre>
</blockquote>
You may want to do this either (i) periodically, say once per month,
or (ii) depending on the number of newly added records, say when the
database size grows by 2-3 percent.
<h2>Guest Users Cleanup</h2>
<p>Guest users create a lot of entries in <CDSNAME> tables that are
related to their web sessions, their search history, personal baskets,
etc. This data has to be garbage-collected periodically. At the
moment this is done via a command line program:
<blockquote>
<pre>
$ sessiongc
</pre>
</blockquote>
<strong>HINT:</strong> You may want to launch this command every day.
In the future the garbage collection task may be done via BibSched task
queue. <!--FIXME-->
<h2>Alert Engine</h2>
<p><CDSNAME> users may set up an automatic notification email alerts
that would send them documents corresponding to the user profile by
email either daily, weekly, or monthly. It is the job of the alert
engine to do this. The alert engine has to be run every day:
<blockquote>
<pre>
$ alertengine
</pre>
</blockquote>
<strong>HINT:</strong> You may want to set up an external cron job
to call <code>alertengine</code> each day.
<h2>Cleaning Up the Filesystem</h2>
<p>BibSched creates log and err files in <code>&lt;prefix&gt;/var/log</code>
directory that is good to clean up from time to time. For example:
<blockquote>
<pre>
$ find /usr/local/cdsware-DEMO/var/log -name "bibsched_task_*" -size 0c -exec \rm -f {} \;
$ find /usr/local/cdsware-DEMO/var/log -name "bibsched_task_*" -atime +28 -exec \rm -f {} \;
$ find /usr/local/cdsware-DEMO/var/log -name "bibsched_task_*" -atime +7 -exec gzip -9 {} \;
</pre>
</blockquote>
<p>BibReformat creates temporary XML files in
<code><prefix>/var/tmp</code> that may be deleted after they are
uploaded. For example:
<blockquote>
<pre>
$ find /usr/local/cdsware-DEMO/var/tmp -name "rec_fmt_*.xml" -size 0c -exec \rm -f {} \;
$ find /usr/local/cdsware-DEMO/var/tmp -name "rec_fmt_*.xml" -atime +28 -exec \rm -f {} \;
$ find /usr/local/cdsware-DEMO/var/tmp -name "rec_fmt_*.xml" -atime +7 -exec gzip -9 {} \;
</pre>
</blockquote>
<p>The BibHarvest admin tool (oaiharvest) creates temporary XML files in
<code><prefix>/var/tmp</code> that may be deleted after they are
uploaded. For example:
<blockquote>
<pre>
$ find /usr/local/cdsware-DEMO/var/tmp -name "bibharvestadmin.*" -exec \rm -f {} \;
$ find /usr/local/cdsware-DEMO/var/tmp -name "bibconvertrun*" -exec \rm -f {} \;
$ find /usr/local/cdsware-DEMO/var/tmp -name "oaiharvest*" -exec gzip -9 {} \;
</pre>
</blockquote>
<p>FIXME: Thoughts on WebSubmit log archives, what to keep, what not.
diff --git a/modules/webhelp/web/admin/index.html.wml b/modules/webhelp/web/admin/index.html.wml
index 98d1285fb..45bfdbd66 100644
--- a/modules/webhelp/web/admin/index.html.wml
+++ b/modules/webhelp/web/admin/index.html.wml
@@ -1,476 +1,476 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="_(Admin Area)_" \
navbar_name="admin" \
navtrail_previous_links="" \
navbar_select="admin"
Welcome to the Admin Area of the <CDSNAME>. You'll find here pointers
to the available runtime admin-level interfaces and admin-level guides
on how to configure and run the CDSware system.
<p>CDSware comes as a suite of several more or less independent
modules. You'll find brief descriptions for each admin module below.
(More background information on each module may be read in the <a
href="<WEBURL>/hacking/modules.html">modules overview</a> article.)
<h3>Admin HOWTO guides</h3>
<p><a href="howto/">Admin HOWTO Guides</a> give you you both short and
not-so-short recipes and thoughts on some of the most frequently
encountered administrative tasks. They tend to answer various
admin-level questions of a rather general level. The specific tasks
are better addressed by module-specific guides and interfaces
presented below.
<h3>Data acquisition related modules</h3>
<p>The metadata input into a running CDSware system can be done in two
ways: <em>(i) admin-oriented batch mode</em>,
i.e. <strong>BibHarvest</strong> to get data from OAI repositories,
<strong>BibConvert</strong> to convert any input data into XML MARC,
and <strong>BibUpload</strong> to upload XML MARC files into CDSware;
and <em>(ii) author-oriented interactive mode</em>,
i.e. <strong>WebSubmit</strong> to submit documents via Web. Once the
data are uploaded in CDSware, you may want to modify them via
<strong>BibEdit</strong> to edit the metadata.
<table border="1" cellpadding="2">
<tr>
<th class="searchboxheader">Admin Module</th>
<th class="searchboxheader">Admin Description</th>
<th class="searchboxheader">Admin Interface</th>
<th class="searchboxheader">Admin Guide</th>
</tr>
<tr>
<td>
<strong>BibHarvest Admin</strong>
</td>
<td>
Enables you to configure OAI metadata harvestor for eventual periodical
batch upload of data. For example, you can define from where to
harvest, with what periodicity, how to transform data before
uploading them into CDSware, etc.
</td>
<td>
<a href="bibharvest/bibharvestadmin.py">BibHarvest Admin Interface</a>
</td>
<td>
<a href="bibharvest/guide.html">BibHarvest Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibConvert Admin</strong>
</td>
<td>
Explains how to use bibliographic data convertor. Useful for batch
upload of data. For example, when migrating the metadata from
your old system, or when integrating metadata acquisitions from
non-OAI sources, or just about any line-based
not-so-well-structured metadata.
</td>
<td>
<small class="note">command-line program</small>
</td>
<td>
<a href="bibconvert/guide.html">BibConvert Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibMatch Admin</strong>
</td>
<td>
Tools for matching XML MARC files against the repository content.
Useful when importing third-party metadata files.
</td>
<td>
<small class="note">command-line program</small>
</td>
<td>
<a href="bibmatch/guide.html">BibMatch Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibUpload Admin</strong>
</td>
<td>
Enables you to configure eventual local special operations to be
done on the data being uploaded.
</td>
<td>
<small class="note">command-line program</small>
</td>
<td>
<a href="bibupload/guide.html">BibUpload Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebSubmit Admin</strong>
</td>
<td>
Enables you to configure the submit interface and logic for various document types.
For example, you can define which metadata fields should be submitted for various
doctypes, what to do with the inputted values before uploading,
possible peer review and approval strategy, etc.
</td>
<td>
<a href="websubmit/">WebSubmit Admin Interface</a>
</td>
<td>
<a href="websubmit/guide/">WebSubmit Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>ElmSubmit Admin</strong>
</td>
<td>
Enables you to configure the submission of documents by electronic mail.
</td>
<td>
<small class="note">command-line program</small>
</td>
<td>
<a href="elmsubmit/guide.html">ElmSubmit Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibEdit Admin</strong>
</td>
<td>
Enables you to directly manipulate bibliographic data, edit a single
record, do global replacements, and other cataloguing tasks.
</td>
<td>
<a href="bibedit/bibeditadmin.py">BibEdit Admin Interface</a>
</td>
<td>
<a href="bibedit/guide.html">BibEdit Admin Guide</a>
</td>
</tr>
</table>
<h3>Data provision related modules</h3>
<p>The metadata output from a running CDSware system to the end-user
is covered by several modules: <strong>BibIndex</strong> to index the
metadata, <strong>BibRank</strong> to eventually rank them,
<strong>BibFormat</strong> to format them for the output,
<strong>WebSearch</strong> to provide search interfaces and search
engine.
<table border="1">
<tr>
<th class="searchboxheader">Admin Module</th>
<th class="searchboxheader">Admin Description</th>
<th class="searchboxheader">Admin Interface</th>
<th class="searchboxheader">Admin Guide</th>
</tr>
<tr>
<td>
<strong>BibIndex Admin</strong>
</td>
<td>
Enables you to configure "word files", i.e. to define which
bibliographic fields are indexed into which word indexes. The word
indexes are then used by the search interface. For example, you can
define that the logical author index is constructed from physical
<code>100 $a</code> and <code>700 $a</code> bibliographic tags, you
can force reindexing of the fulltext index, etc.
</td>
<td>
<a href="bibindex/">BibIndex Admin Interface</a>
</td>
<td>
<a href="bibindex/guide.html">BibIndex Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibRank Admin</strong>
</td>
<td>
Enables you to configure various ranking methods to be used by the search engine.
You can rebalance existing ranking sets, create new ranking methods, etc.
</td>
<td>
<a href="bibrank/">BibRank Admin Interface</a>
</td>
<td>
<a href="bibrank/guide.html">BibRank Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibClassify Admin</strong>
</td>
<td>
Enables you to automatically classify documents according to
ontologies and keyword thesauri.
</td>
<td>
<a href="bibclassify/">BibClassify Admin Interface</a>
</td>
<td>
<a href="bibclassify/guide.html">BibClassify Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>BibFormat Admin</strong>
</td>
<td>
Enables you to specify how the bibliographic data is presented to
the end user in the search interface. You can decide that titles should be
presented in bold font, that for each author an automatic link to
author's home page should be created according to some receipt, etc.
</td>
<td>
<a href="bibformat/">BibFormat Admin Interface</a>
</td>
<td>
<a href="bibformat/guide.html">BibFormat Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebSearch Admin</strong>
</td>
<td>
Enables you to configure the search interface for various metadata
collections. You can define new collections and organize them in
the tree, you can define various portalboxes that would appear on
the screen, you can define search options and search fields to
present, etc.
</td>
<td>
<a href="websearch/">WebSearch Admin Interface</a>
</td>
<td>
<a href="websearch/guide.html">WebSearch Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebStat Admin</strong>
</td>
<td>
Enables you to configure the usage statistics reporting system.
</td>
<td>
<small class="note">command-line configuration</small>
</td>
<td>
<a href="webstat/guide.html">WebStat Admin Guide</a>
</td>
</tr>
</table>
<h3>Personalization related modules</h3>
<p>The CDSware interface can be personalized to suit different needs
of different end-users. This functionality is covered by several
modules: <strong>WebSession</strong> to identify users and their
personal configurations, <strong>WebBasket</strong> to provide
personal baskets or document carts, and <strong>WebAlert</strong> to
set up personal email notification alerts.
<table border="1">
<tr>
<th class="searchboxheader">Admin Module</th>
<th class="searchboxheader">Admin Description</th>
<th class="searchboxheader">Admin Interface</th>
<th class="searchboxheader">Admin Guide</th>
</tr>
<tr>
<td>
<strong>WebSession Admin</strong>
</td>
<td>
Enables you to inspect the status of guest sessions and to expire
them; the status and details on registered users, etc.
</td>
<td>
<small class="note">not available, but see the guide for the command-line way</small>
</td>
<td>
<a href="websession/guide.html">WebSession Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebBasket Admin</strong>
</td>
<td>
Enables you to inspect and manipulate user baskets set up on the
system, to make them public/private, etc.
</td>
<td>
<small class="note">not available, but see the guide for the command-line way</small>
</td>
<td>
<a href="webbasket/guide.html">WebBasket Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebAlert Admin</strong>
</td>
<td>
Enables you to inspect and manipulate user alerts set up on the
system, to run the alert engine, etc.
</td>
<td>
<small class="note">not available, but see the guide for the command-line way</small>
</td>
<td>
<a href="webalert/guide.html">WebAlert Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebComment Admin</strong>
</td>
<td>
Enables you to manipulate readers comments and reviews,
see which ones were reported as abuse/spam, delete them, etc.
</td>
<td>
<a href="webcomment/webcommentadmin.py">WebComment Admin Interface</a>
</td>
<td>
<a href="webcomment/guide.html">WebComment Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebMessage Admin</strong>
</td>
<td>
Enables you to configure the messaging system.
</td>
<td>
<small class="note">command-line configuration</small>
</td>
<td>
<a href="webmessage/guide.html">WebMessage Admin Guide</a>
</td>
</tr>
</table>
<h3>System glue modules</h3>
<p>Modules that provide the necessary glue for those presented above
are: <strong>BibSched</strong> to manage and schedule bibliographic
tasks, <strong>WebAccess</strong> to define role-based access control
system to all CDSware services, and <strong>WebStyle</strong> to
define a common look and feel of CDSware web pages.
<table border="1">
<tr>
<th class="searchboxheader">Admin Module</th>
<th class="searchboxheader">Admin Description</th>
<th class="searchboxheader">Admin Interface</th>
<th class="searchboxheader">Admin Guide</th>
</tr>
<tr>
<td>
<strong>BibSched Admin</strong>
</td>
<td>
Enables you to inspect bibliographic task queue, to postpone or
reschedule jobs, to make priorities, to run periodical tasks, etc.
</td>
<td>
<small class="note">command-line program</small>
</td>
<td>
<a href="bibsched/guide.html">BibSched Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebAccess Admin</strong>
</td>
<td>
Enables you to define who has got access or admin rights on various CDSware modules.
For example, you can define that John is the bibliographic
data manager, that Jim can modify the search interface pages, that
Jill is the submission approval editor, etc.
</td>
<td>
<a href="webaccess/">WebAccess Admin Interface</a>
</td>
<td>
<a href="webaccess/guide.html">WebAccess Admin Guide</a>
</td>
</tr>
<tr>
<td>
<strong>WebStyle Admin</strong>
</td>
<td>
Enables you to customize default CDSware page style and the CSS style sheet.
</td>
<td>
<small class="note">not available, but see the guide for the command-line way</small>
</td>
<td>
<a href="webstyle/guide.html">WebStyle Admin Guide</a>
</td>
</tr>
</table>
diff --git a/modules/webhelp/web/hacking/Makefile.am b/modules/webhelp/web/hacking/Makefile.am
index be46300af..a2f26018b 100644
--- a/modules/webhelp/web/hacking/Makefile.am
+++ b/modules/webhelp/web/hacking/Makefile.am
@@ -1,35 +1,35 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking
imgdir = $(WEBDIR)/img
doc_DATA=index.html modules.html style.html concepts.html directory.html cdsware.el \
releases.html testsuite.html
img_DATA=modules.jpeg
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%) modules.jpeg cdsware.el
CLEANFILES = $(wildcard *.html) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webhelp/web/hacking/cdsware.el b/modules/webhelp/web/hacking/cdsware.el
index 74206cdad..df3b3d6b5 100644
--- a/modules/webhelp/web/hacking/cdsware.el
+++ b/modules/webhelp/web/hacking/cdsware.el
@@ -1,60 +1,60 @@
;;; cdsware.el -- CDSware-related Emacs definitions people may find useful.
;;; $Id$
;;;
;;; This file is part of the CERN Document Server Software (CDSware).
-;;; Copyright (C) 2002, 2003, 2004, 2005 CERN.
+;;; Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
;;;
;;; The CDSware 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.
;;;
;;; The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
;;; 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
;; switch off the beep
(setq visible-bell t)
;; spaces instead of tabs:
(setq-default indent-tabs-mode nil)
;; no newlines at the end:
(setq next-line-add-newlines nil)
;; fancy parens and such:
(set-scroll-bar-mode 'right)
(setq blink-cursor nil)
(setq transient-mark-mode t)
(show-paren-mode t)
;; light yellow on dark green is cool:
(when (locate-library "color-theme")
(require 'color-theme)
(color-theme-gnome2))
;; setting color-syntax highlighting:
(require 'font-lock)
(global-font-lock-mode t)
(setq-default font-lock-auto-fontify t)
;; fancy Python mode:
(when (locate-library "ipython")
(require 'ipython))
;; most WML files in CDSware are Python files
(setq auto-mode-alist (cons '("\\.wml$" . python-mode) auto-mode-alist))
;; Pythonic things:
(autoload 'python-mode "python-mode" "Python editing mode." t)
(setq interpreter-mode-alist (cons '("python" . python-mode) interpreter-mode-alist))
;; choosing version control software:
(setq vc-default-back-end 'CVS)
;;; end of file
\ No newline at end of file
diff --git a/modules/webhelp/web/hacking/concepts.html.wml b/modules/webhelp/web/hacking/concepts.html.wml
index 4762849de..f7c4b0edb 100644
--- a/modules/webhelp/web/hacking/concepts.html.wml
+++ b/modules/webhelp/web/hacking/concepts.html.wml
@@ -1,120 +1,120 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Common Concepts" \
navbar_name="hacking-common-concepts" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> " \
navbar_select="hacking-common-concepts"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
The description of concepts you will encounter here and there in the
CDSware. Our interpretation may differ from the practice found in
other products, so please read this carefully.
1. sysno - (ALEPH|old) system number
Stands for (ALEPH|old) system number only. Which means that, for
outside-CERN CDSware installations, stands for an 'old system
number' whatever it is, if they want to publicise it instead of our
internal auto-incremented CDSware record identifiers.
2. recID - CDSware record identifier
Each record has got an auto-incremented ID in the "bibrec" table
(formerly called "bibitem"). This is the basic "record identifier"
concept in CDSware.
3. docID - eventual fulltext document identifier
Each fulltext file may have eventual docID. This will permit us to
interconnect records (recID) with fulltext files (docID), if we
want to. At the moment there is only one-way connection from recID
to docID via HTTP field 856. This is ugly. I think we may
probably profit by introducing recID-docID relationship in several
ways: file protection, reference extraction, fulltext
indexing... (?!)
4. field - logical field concept such as "reportnumber"
A bibliographic record is composed of 'fields' such as title or
author. Note that we consider 'field' to be a logical concept,
that is compound and may consist of several physical MARC fields.
For example, "report number" field consists of several MARC fields
such as 088 $a, 037 $a, 909C0 $r. Another example: "first report
number" consist of only one MARC field, 037 $a.
5. tag - physical field concept such as "088 $a".
Having defined the concept of 'logical field', let's now turn to
the 'physical field' that denotes basically the concept of 'MARC
field' as defined in MARC-21 standard. In addition to tag, a field
may contain two identifiers to describe the data content, and
subfield codes to denote various parts of the content. See our
HOWTO MARC guide on this.
Thus said, in the implementation of our bibliographic tables
(bibXXx) we have sort of generalized the term 'tag' to stand for:
tag = tag code + identifier1 + identifier1 + subfield code
This convention, while taking some freedom from the MARC-21
standard, enables us to write things like "field: base number, tag:
909C0b, value: 11". If this interpretation is indeed too free with
respect to the standard usage of terms, we may change them in the
future.
6. collection - here we distinguish (i) primary collection concept
and (ii) specific collection concept.
The (i) primary collections are basic organizational structure of
how the records are grouped together in collections. The primary
collections are used in the navigable search interface under the
``Narrow search'' box. The (ii) specific collections present an
orthogonal view on the data organization, that is useful to group
together some records from different primary collections, if they
present a common pattern. The specific collections are used in the
search interface under the ``Focus on'' box.
The primary collections are defined mainly by the collection
identifier ("980 $a,b"); and the specific collections are as
defined by any query that is possible for a search engine to
execute (see also "dbquery" column in the "collection" table).
In the past we used to use the term "catalogue", that is now
deprecated, and that can be interchanged with "collection".
7. doctype - stands for web document type concept, used in WebSubmit
The "document type" is used solely for submission purposes, and
fulltext access purposes ("setlink"-like). For example, a document
type "photo" may be used in many collections such as "Foo Photos",
"Bar PhotoLab", etc. Similarly, one collection can cover several
doctypes. (M:N relationship)
8. baskets, alerts, settings - covering personal features
Denote personal features, for which we previously used the terms
"shelf" and "profile" that are now deprecated.
- end of file -
</pre>
diff --git a/modules/webhelp/web/hacking/directory.html.wml b/modules/webhelp/web/hacking/directory.html.wml
index 90a0f9009..d4b068930 100644
--- a/modules/webhelp/web/hacking/directory.html.wml
+++ b/modules/webhelp/web/hacking/directory.html.wml
@@ -1,203 +1,203 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Directory Organization" \
navbar_name="hacking-directory-organization" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> " \
navbar_select="hacking-directory-organization"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
Please find some notes below on how the source (as well as the target)
directory structure is organized, where the sources get installed to,
and how the visible URLs are organized.
1. CDSware will generally install into two directories, taken from
--with-prefix and --with-webdir configuration variables. These
are discussed in points 2 and 3 below, respectively.
2. The first directory (--with-prefix) specifies general CDSware
install directory, where we'll put CLI binaries, Python and PHP
libraries, manpages, log and cache directories for the running
installation, and any other dirs as needed. They will all live
under one common hood.
For example, configure --with-prefix=/usr/local/cdsware-DEMODEV,
and you'll obtain the following principal directories:
/usr/local/cdsware-DEMODEV/
/usr/local/cdsware-DEMODEV/bin
/usr/local/cdsware-DEMODEV/lib
/usr/local/cdsware-DEMODEV/lib/php
/usr/local/cdsware-DEMODEV/lib/python
/usr/local/cdsware-DEMODEV/lib/wml
/usr/local/cdsware-DEMODEV/var
/usr/local/cdsware-DEMODEV/var/cache
/usr/local/cdsware-DEMODEV/var/log
with the obvious meaning:
- bin : for command-line executable binaries and scripts
- lib/php : for our own PHP libraries, see below
- lib/python : for our own Python libraries, see below
- lib/wml : for our own WML libraries, see below
- var : for installation-specific runtime stuff
- var/log : for all sorts of runtime logging, e.g. search.log
- var/cache : for all sorts of runtime caching, e.g. OAI
retention harvesting, collection cache, etc
This scheme copies to some extent the usual Unix filesystem
convention, so it may be easily expanded later according to our
future needs.
3. The second directory (--with-webdir) should be located under Apache
htdocs tree and specifies where to put the Web scripts (PHP,
mod_python), HTML documents and images, and so on. This is where
webuser-seen files are located. Basically, the files there contain
only the interface to the functionality that is provided by the
libraries stored under the library directory.
The WEBDIR directory is further structured according to whom it
provides services. We distinguish user-level, admin-level and
hacker-level access to the site, as reflected by the visible URL
structure.
a) The user-level access point is provided by the main WEBURL
address and its subdirs. All the user-level documentation is
available under WEBURL/help/. The module-specific user-level
documentation is available under WEBURL/help/&lt;module&gt;/.
b) The admin-level access is provided by WEBURL/admin/ entry
point. The admin-level documentation is accessible from the
same place. The admin-level module-specific functionality and
help is available under WEBURL/admin/&lt;module&gt;/. (If
it's written in mod_python, it usually points to
WEBURL/&lt;module&gt;admin.py/ since we configure the server to
have all mod_python scripts under the WEBDIR root directory.)
c) The hacker-level documentation is provided by WEBURL/hacking/
entry point. There is no hacker-level functionality possible
via Web, of course, so that unlike admin-level entry point,
the hacker-level entry point provides only a common access to
available hacking documention, etc. The module-specific
information is available under WEBURL/hacking/&lt;module&gt;/.
4. Let's now return a bit more closely to the role Python and PHP
library directories outside of the Apache tree:
/usr/local/cdsware-DEMODEV/lib/php
/usr/local/cdsware-DEMODEV/lib/python
Here we put not only (a) libraries that may be reused across
CDSware modules, but also (b) all the "core" functionality of
CDSware that is not directly callable by the end users. The
"callable" functionality is put under "webdir" in case of web
scripts and documents, and under "bindir" in case of CLI
executables.
As for (a), for example in the PHP cdsware library you'll find
currently the common PHP error handling code that is shared between
BibFormat and WebSubmit; in the Python cdsware library (in fact,
cdsware Pythonic 'module', but we are reserving the word 'module'
to denote 'CDSware module' in this text) you'll find config.py
containing WML-supplied site parameters, dbquery.py containing DB
persistent query module, or webpage.py with templates and functions
to produce mod_python web pages with common look and feel. These
could and should be reused across all our modules. Note that I
created only a small number of "broad" libraries at the moment. In
case we want to reuse more code parts, we'd refactor the code more,
as needed.
As for (b), for example the existing search engine was split into
search.py that only contains three "callable" functions, which goes
into WEBDIR, while the search engine itself is composed of
search_engine.py and search_engine_config.py living under LIBDIR.
In this way we can easily create "real" CLI search, that will
depend only on the search libraries in LIBDIR, and that will get
installed into BINDIR.
To recap:
- For each CDSware module, I'm differentiating between
"callable" and "core" parts. The former go into WEBDIR or
BINDIR, the latter into LIBDIR.
- Our PHP/Pythonic libraries contain several sorts of thing:
- the implementation of the "callable" functions
- non-callable internal "core" or "library" code parts, as
stated above. Not shared across CDSware modules.
- utility code meant for reuse across CDSware modules, such
as dbquery.py
- Pythonic config files out of user-supplied WML (non-MySQL)
configuration parameters (see
e.g. search_engine_config.py)
5. The same strategy is reflected in the organization of source
directories inside CDSware CVS. Each CDSware module lives in a
separate directory located under "modules" directory of the
sources. Further on, each module contains usually several
subdirectories that reflect the above-mentioned packaging choice.
For example, in case of WebSearch you'll find:
./modules/websearch
./modules/websearch/bin
./modules/websearch/doc
./modules/websearch/doc/hacking
./modules/websearch/doc/admin
./modules/websearch/lib
./modules/websearch/web
./modules/websearch/web/admin
with the following straightforward meaning:
- bin : for callable CLI binaries and scripts
- doc : for documentation. The user-level documentation is
located in this directory. The admin-level
documentation is located in the "admin" subdir. The
programmer-level documentation is located in the
"hacking" subdir.
- lib : for uncallable "core" functionality, see the comments
above
- web : for callable web scripts and pages. The user- and
admin- level is separated similarly as in the "doc"
directory (see above).
The structure is respected throughout all the CDSware modules, a
notable exception being the MiscUtil module that contains subdirs
like "sql" (for the table creating/dropping SQL commands, etc) or
"demo" (for creation of Atlantis Institute of Science, our demo
site.)
- end of file -
</pre>
diff --git a/modules/webhelp/web/hacking/index.html.wml b/modules/webhelp/web/hacking/index.html.wml
index 5447cd248..0939f99e5 100644
--- a/modules/webhelp/web/hacking/index.html.wml
+++ b/modules/webhelp/web/hacking/index.html.wml
@@ -1,82 +1,82 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Hacking CDSware" \
navbar_name="hacking" \
navtrail_previous_links="" \
navbar_select="hacking"
Welcome to the CDSware Developers' corner. Before diving into the
source, make sure you don't miss our <a
href="<WEBURL>/help/">user-level</a> and <a
href="<WEBURL>/admin/">admin-level</a> documentation as well. And now, back to the source, and happy hacking!
<h2>General information, coding practices</h2>
<blockquote>
<dl>
<dt><a href="concepts.html">Common Concepts</a></dt>
<dd>Summarizing common terms you will encounter here and there.</dd>
<dt><a href="style.html">Coding Style</a></dt>
<dd>A policy we try to follow, for good or bad.</dd>
<dt><a href="releases.html">Release Numbering Scheme</a></dt>
<dd>Presenting the version numbering scheme adopted for CDSware stable and development releases.</dd>
<dt><a href="directory.html">Directory Organization</a></dt>
<dd>How the source and target directories are organized, where the
sources get installed to, what is the visible URL policy, etc.</dd>
<dt><a href="modules.html">Modules Overview</a></dt>
<dd>Presenting a summary of various CDSware modules and their relationships.</dd>
<dt><a href="testsuite.html">Test Suite Strategy</a></dt>
<dd>Describes our test suite strategy.</dd>
</dl>
</blockquote>
<h2>Module-specific information</h2>
<blockquote>
<dl>
<dt><a href="bibrank/index.html">BibRank Internals</a></dt>
<dd>Describes information useful to understand how the various
ranking methods available in bibrank works, and how they can
be tweaked to give various output.</dd>
<dt><a href="miscutil/index.html">MiscUtil Internals</a></dt>
<dd>Describes information useful to understand what can be found inside the miscellaneous utilities
module, like database access, error management, date handling library, etc.</dd>
<dt><a href="websearch/index.html">WebSearch Internals</a></dt>
<dd>Describes information useful to understand the search process
internals, like the different search stages, the high- and low-level
API, etc.</dd>
<dt><a href="webaccess/index.html">WebAccess Internals</a></dt>
<dd>Describes information useful to understand the access control process
internals, its API, etc.</dd>
</dl>
</blockquote>
diff --git a/modules/webhelp/web/hacking/modules.html.wml b/modules/webhelp/web/hacking/modules.html.wml
index ca6d66967..8937648f2 100644
--- a/modules/webhelp/web/hacking/modules.html.wml
+++ b/modules/webhelp/web/hacking/modules.html.wml
@@ -1,219 +1,219 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Modules Overview" \
navbar_name="hacking-modules" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> " \
navbar_select="hacking-modules"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<p>CDSware consists of several more or less independent modules with
precisely defined functionality. The general criterion for module
names is to use the ``Bib'' prefix to denote modules that work more
with the bibliographic data, and the ``Web'' prefix to denote modules
that work more with the Web interface. (The difference is of course
blurred in some cases, as in the case of search engine that has got a
web interface but searches bibliographic data.)
<p>Follows a brief description of what each module does. After
descriptions the module relationship diagram is presented.
<ul>
<li><strong>BibCheck</strong>: FIXME
<li><strong>BibClassify</strong>: FIXME
<li><strong>BibConvert</strong> allows metadata conversion from any
structured or semi-structured proprietary format into any other
format, typically the <a
href="http://www.loc.gov/standards/marcxml/">MARC XML</a> that is
natively used in CDSware. Nevertheless the input and output formats
are fully configurable and have been tested on data importations from
more than one hundred data sources. The power of this utility lies in
the fact that no structural attributes of data source are presumed,
but they are defined in an extensive data source
configuration. Inevitably, this leads to a high complexity of the
BibConvert configuration language. Most frequent configurations are
provided with the CDSware distribution, such as a sample
configuration from Qualified Dublin Core into the MARCXML.
<br>In general the BibConvert configuration consists from the source
data descriptions and target data descriptions. The processor then
analyzes and parses the input data and creates the resulting data
structure, similarly as the XSLT processor would do. Typically the
BibConvert is aimed at usage for input data that do not dispose of an
XML representation. The source data is required to be structured or
semi-structured, (i.e. not expressed in natural language that is a
subject of information extraction task) and its processing involves
several steps including record separation and field extraction upto
transformation of source field values and their formatting.
<li><strong>BibEdit</strong>: FIXME.
<li><strong>BibFormat</strong> presents a powerful module to format
the bibliographic metadata in numerous ways. This truly enables the
separation of data content administration and formatting layout,
effectively allowed by the XML technology. Formatting can either be
carried out as a batch task or invoked on the fly. The formatter
allows a dynamic creation of automatic links according to destination
descriptions.
<li><strong>BibHarvest</strong> represents the <a
href="http://www.openarchives.org/">OAi-PMH</a> compatible harvester
allowing the repository to gather metadata from fellow OAi-compliant
repositories and the OAi-PMH repository management. Repository is
built directly on top of the database and disposes of an OAi
repository manager that allows to perform the administrative tasks on
the repository aside from the principal generic data administration
module. The database can be partially or completely open for
harvesting in the scope of the OAi-PMH protocol. In this case, all
data is provided in raw form, where the semantics of individual tags
is indicated uniquely by the MARC21 naming convention. This is
particularly interesting for institutes that are specialized in
cross-archive and cross-disciplinary services provision, as for
example the ARC service provider.
<li><strong>BibIndex</strong> module takes care of the indexation of
metadata, references and full text files.  Two kinds of indexes --
word and phrase index -- are being maintained.  The user can define
several logical indexes (e.g. author index, title index, etc.) and
the correspondence of which physical MARC21 metadata tag goes into
which logical field index.  An index consists of two parts: (i) a
forward index listing various words (or phrases) found in the given
field, with the set of record identifiers where the given word can be
found; and (ii) a reverse index listing record identifiers, with the
set of words of the given record that go to the forward index.  Such
a two-part indexing technique allows one to rapidly update only those
words that have changed in the input metadata record.  The indexes
were designed with the aim to provide fast user-response search times
and are faster than native MySQL (full text) indexes.
<li><strong>BibMatch</strong>: FIXME.
<li><strong>BibRank</strong>: FIXME
<li><strong>BibSched</strong> The bibliographic task scheduler is
central unit of the system that allows all other modules to access
the bibliographic database in a controlled manner, preventing sharing
violation threats and assuring the coherent execution of the database
update tasks. The module comes with an administrative interface that
allows to monitor the task queue including various possibilities of a
manual intervention, for example to re-schedule queued tasks, change
the task order, etc.
<li><strong>BibUpload</strong> allows to load the new bibliographic
data into the database. To effectuate this task the data must be a
well-formed XML file that complies with the current metadata tag
selection schema. Usually, the properly structured input files of
BibUpload come from the BibConvert utility.
<li><strong>ElmSubmit</strong>: FIXME
<li><strong>MiscUtil</strong> is a collection of miscellaneous
utilities that other modules are using, like the international
messages, etc.
<li><strong>WebAccess</strong> module is responsible for granting
access to users for performing various actions within the system.  A
Role-Based Access Control (RBAC) technique is used, where users
belong to several groups according to their role in the system.  Each
user group can be granted to perform certain actions depending on
possible one more action arguments.  WebAccess is presently used
mainly for the administrative interface.  There are basically two
kinds of actions: (i) configuration of administrative modules and
(ii) running administrative tasks.
<li><strong>WebAlert</strong> module allows the end user to be
alerted whenever a new document matching her personal criteria is
inserted into the database.  The criteria correspond to a typical
user query as if it would be done via the search interface.  For
example, a user may want to get notified whenever a new document
containing certain words, or of a certain subject, is inserted.  A
user may create several alerts with a daily, weekly, or a monthly
frequency.  The results of alert searches are either sent back to the
user by email or can also be stored into her baskets.
<li><strong>WebBasket</strong> module enables the end user of the
system to store the documents she is interested in in a personal
basket or a personal shelf.  The concept is similar to popular
shopping carts.  One user may own several baskets.  A basket can be
either private or public, allowing a simple document sharing
mechanism within a group.
<li><strong>WebComment</strong>: FIXME.
<li><strong>WebHelp</strong> presents some global user-level,
admin-level, and hacker-level documenation on CDSware. The
module-specific documentation is included within each particular
module.
<li><strong>WebMessage</strong>: FIXME.
<li><strong>WebSearch</strong> module handles user requests to search
for a certain words or phrases in the database.  Two types of
searching can be performed: a word search or a phrase search.  The
system allows for complex boolean queries, regular expression
searching, or a combined metadata, references and full text file
searching in one go.  Users have a possibility to browse for present
index terms.  If no direct match could have been found with the
user-typed query pattern, the system proposes alternative matches as
a search guidance.  The search indexes were designed to provide fast
response times for middle-sized data collections of up to 106
records. 
<br>The metadata corpus is organized into metadata collections that
are directly accessible through the browse function, similarly to the
popular concept of Web Directories.  Orthogonal views on the document
corpus are enabled in the search interface via a concept of virtual
collections: for example, a document may be classified both according
to its type (e.g. preprint, book) and according to its Dewey decimal
classification number.  Such a flexible organization views allows for
the creation of easy navigation schemata to the end users.
<li><strong>WebSession</strong> is a session and user management
module that permits to differentiate between users. Useful for
personalization of the interface and services like personal baskets
and alerts.
<li><strong>WebStat</strong>: FIXME
<li><strong>WebStyle</strong> is a library of design-related modules
that defines look and feel of CDSware pages.
<li><strong>WebSubmit</strong> is a comprehensive submission system
allowing authorized individuals (authors, secretaries and repository
maintenance staff) to submit individual documents into the
system. The submission system disposes of a flow-control mechanism
that assures the data approval by authorized units. In total there
are several different exploitable submission schemas at a disposal,
including an automated full text document conversion from various
textual and image formats. This module also disposes of information
extraction functionality, focusing on bibliographic entities such as
references, authors, keywords or other implicit metadata.
</ul>
<p>Relationship between the modules:
<p><img src="<WEBURL>/img/modules.jpeg" border=0>
diff --git a/modules/webhelp/web/hacking/releases.html.wml b/modules/webhelp/web/hacking/releases.html.wml
index eb90cdaee..5d25cca00 100644
--- a/modules/webhelp/web/hacking/releases.html.wml
+++ b/modules/webhelp/web/hacking/releases.html.wml
@@ -1,104 +1,104 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Release Numbering Scheme" \
navbar_name="hacking-release-version-numbering-scheme" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> " \
navbar_select="hacking-release-version-numbering-scheme"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
CDSware uses the classical major.minor.patchlevel release version
numbering scheme that is commonly used in the GNU/Linux world and
elsewhere. Each release is labelled by
major.minor.patchlevel
release version number. For example, a release version 4.0.1 means:
4 - 4th major version, i.e. the whole system has been already
4th times either fully rewritten or at least in its very
essential components. The upgrade from one major version
to another may be rather hard, may require new prerequisite
technologies, full data dump, reload and reindexing, as
well as other major configuration adapatations, possibly
with an important manual intervention.
0 - 0th minor version, i.e. the first minor release of the 4th
major rewrite. (Increments go 4.1, 4.2, ... 4.9, 4.10,
4.11, 4.12, ... until some important rewrite is done,
e.g. the database philosophy dramatically changes, leading
to a non-trivial upgrade, and we have 5.0.) The upgrade
from one minor version to another may be laborious but is
relatively painless, in that some table changes and data
manipulations may be necessary but they are somewhat
smaller in nature, easier to grasp, and possibly done by an
automated script.
1 - 1st patch level to 4.0, fixing bugs in 4.0.0 but not adding
any substantially new functionality. That is, the only new
functionality that is added is that of a `bug fix' nature.
The upgrade from one patch level to another is usually
straightforward.
(Packages often seem to break this last rule, e.g. Linux
kernel adopting new important functionality (such as
ReiserFS) within the stable 2.4.x branch. It can be easily
seen that it is somewhat subjective to judge what is
qualitatively more like a minor new functionality and what
is more like a patch to the existing behaviour. We have
tried to quantify these notions with respect to whether
table structure and/or technology change require small or
large upgrade jobs and eventual manual efforts.)
So, if we have a version 4.3, a bug fix would mean to release 4.3.1,
some minor new functionality and upgrade would mean to release 4.4,
some important database structure rewrite or an imaginary exchange of
Python for Common Lisp would mean to release 5.0, etc.
In addition, the two-branch release policy is adopted:
a) stable branch - releases in the stable branch are numbered with
even minor version number, like 0.2, 0.4, etc. These releases
are usually well tested. The configuration files and features
usually don't change often from one release to another. The
release frequency is low.
b) development branch - releases in the development branch are
number with the odd minor version number, like 0.1, 0.3, etc.
These releases are more experimental and may be less tested than
the stable ones. The configuration files and features change
more rapidly from one release to another. The release frequency
is higher.
It can be seen that the above scheme is somewhat similar to the Linux
kernel version numbering scheme.
Currently, CDSware 0.0.9 represents the stable branch release and
0.1.0 the development branch release. We are going to frequently
update it to provide 0.1.1, 0.1.2, etc as the currently missing admin
functionality is being added into the development branch, until later
on, when some release, say 0.1.8, will achieve a status of
satisfaction, at which point we release it as the next stable version
(0.2 or 1.0), and start a new development branch (0.3 or 1.1).
- end of file -
</pre>
diff --git a/modules/webhelp/web/hacking/style.html.wml b/modules/webhelp/web/hacking/style.html.wml
index 2d0f4b287..bae7b7bc4 100644
--- a/modules/webhelp/web/hacking/style.html.wml
+++ b/modules/webhelp/web/hacking/style.html.wml
@@ -1,179 +1,179 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Coding Style" \
navbar_name="hacking-coding-style" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> " \
navbar_select="hacking-coding-style"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
A brief description of things we strive at, more or less unsuccessfully.
1. Packaging
We use the classical GNU Autoconf/Automake approach, for tutorial
see e.g. <a href="http://www.amath.washington.edu/~lf/tutorials/autoconf/tutorial_toc.html">Learning the GNU development tools</a> or the <a href="http://sources.redhat.com/autobook/autobook/autobook_toc.html">AutoBook</a>.
2. Modules
CDSware started as a set of pretty independent modules developed by
independent people with independent styles. This was even more
pronounced by the original use of many different languages
(e.g. Python, PHP, Perl). Now the CDSware code base is striving to
use Python everywhere, except in speed-critical parts when a
compiled language such as Common Lisp may come to the rescue in the
near future.
When modifying an existing module, we propose to strictly continue
using whatever coding style the module was originally written into.
When writing new modules, we propose to stick to the
below-mentioned standards.
The code integration across modules is happening, but is slow.
Therefore, don't be surprised to see that there is a lot of room to
refactor.
3. WML/ePerl/etc
This is not so important, because not many lines-of-code were
written in WML/ePerl. We prefer to loosely follow the GNU way, as
always.
4. Python
We aim at following recommendations from <a
href="http://www.python.org/peps/pep-0008.html">PEP 8</a>, although
the existing code surely do not fulfil them here and there.
The most easily notable exception from PEP 8 is perhaps the line
width, that usually exceeds 72 characters per line in our sources,
as we tend to use fullscreen editors. The code indentation is done
via spaces only, please do not use tabs. One tab counts as four
spaces. Emacs users can look into our <a
href="cdsware.el">cdsware.el</a> for inspiration.
All the Python code should be extensively documented via
docstrings, so you can always try to run pydoc file.py to
peruse a module's documentation in one go.
Do not forget to run pylint on your code to check errors like
uninitialized variables and to improve its quality and conformance
to coding standards. The typical incantation may be:
$ cd <LIBDIR>/python/cdsware
$ pylint --max-line-length=160 oai_repository.py | most
Read and implement pylint suggestions.
Do not hardcode magic constants in your code. Every magic string or
a number should be put into accompanying file_config.py with
symbol name beginning by cfg_modulename_*.
Clearly separate interfaces from implementation. Document your
interfaces. Do not expose to other modules anything that does not
have to be exposed. Apply principle of least information.
Create as few new library files as possible. Do not create many
nested files in nested modules; rather put all the lib files in one
dir with bibindex_foo and bibindex_bar names.
Use imperative/functional paradigm rather then OO. If you do use
OO, then stick to as simple class hierarchy as possible. Recall
that method calls and exception handling in Python are quite
expensive.
Use rather the good old foo_bar naming convention for symbols (both
variables and function names) instead of fooBar CaMelCaSe
convention. (Except for Class names where UppercaseSymbolNames are
to be used.)
Pay special attention to name your symbols descriptively. Your
code is going to be read and work with by others and its symbols
should be self-understandable without any comments and without
studying other parts of the code. For example, use proper English
words, not abbreviations that can be misspelled in many a way; use
words that go in pair (e.g. create/destroy, start/stop; never
create/stop); use self-understandable symbol names
(e.g. list_of_file_extensions rather than list2); never misname
symbols (e.g. score_list should hold the list of scores and nothing
else - if in the course of development you change the semantics of
what the symbol holds then change the symbol name too). Do not be
afraid to use long descriptive names; good editors such as Emacs
can tab-complete symbols for you.
When hacking module A, pay close attention to ressemble existing
coding convention in A, even if it is legacy-weird and even if we
use a different technique elsewhere. (Unless the whole module A is
going to be refactored, of course.)
All core code should come with a suitable set of test cases, see
the <a href="testsuite.html">test suite strategy</a> for details.
Speed-critical parts should be profiled with pyprof. Do not forget
to use tricks like psyco.
For more hints, thoughts, and other ruminations, see <a
href="http://simko.info/vademecum/">Vademecum and Essays</a>.
5. PHP
We are moving slowly away out of PHP so that there may be several
practices in place with the PHP code present in CDSware. Usually
this is consistent within modules but inconsistent across modules.
For example, some old code used Emacs' perl-mode, following
traditional K&R C style, while some other old code tried to stick
to <a href="http://pear.php.net/manual/en/standards.php">PEAR recommendations</a>.
6. MySQL
Table naming policy is, roughly and briefly:
- "foo": table names in lowercase, without prefix, used by me
for WebSearch
- "foo_bar": underscores represent M:N relationship between
"foo" and "bar", to tie the two tables together
- "bib*": many tables to hold the metadata and relationships
between them
- "idx*": idx is the table name prefix used by BibIndex
- "rnk*": rnk is the table name prefix used by BibRank
- "flx*": flx is the table name prefix used by FlexElink (also known as
BibFormat)
- "sbm*": sbm is the table name prefix used by WebSubmit
- "sch*": sch is the table name prefix used by BibSched
- "collection*": many tables to describe collections and search
interface pages
- "user*" : many tables to describe personal features (baskets,
alerts)
- end of file -
</pre>
diff --git a/modules/webhelp/web/hacking/testsuite.html.wml b/modules/webhelp/web/hacking/testsuite.html.wml
index 55e33520d..7d938f170 100644
--- a/modules/webhelp/web/hacking/testsuite.html.wml
+++ b/modules/webhelp/web/hacking/testsuite.html.wml
@@ -1,392 +1,392 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Test Suite Strategy" \
navbar_name="hacking-test-suite-strategy" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> " \
navbar_select="hacking-test-suite-strategy"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">General considerations</a></strong><br>
<strong>2. <a href="#2">Running test suite</a></strong><br>
<strong>3. <a href="#3">Writing test code</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1 <a href="#3.1">Testing core code logic (Unit Testing)</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2 <a href="#3.2">Testing overall functionality (Regression Testing)</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.3 <a href="#3.3">Testing user interface pages</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.4 <a href="#3.4">File organization</a><br>
<strong>7. <a href="#4">Conclusions</a></strong><br>
<strong>8. <a href="#5">Additional information</a></strong><br>
<a name="1"></a><h2>1. General considerations</h2>
<p>This documents presents guidelines for unit testing and regression
testing homogenisation throughout all CDSware modules.
<p>Testing is an important coding activity. Most authors believe that
writing test cases should take between 10% and 30% of the project
time. But, even with such a large fraction, don't put too much belief
on such a testing. It cannot find bugs that aren't tested for. So,
while testing is an important activity inherent to safe software
development practices, it cannot become a substitute for pro-active
bug hunting, source code inspection, and bugfree-driven development
approach from the start.
<p>Testing should happen alongside with coding. If you write a
function, immediately load it into your toplevel, evaluate its
definition, and call it for a couple of arguments to make sure the
function works as expected. If not, then change the function
definition, re-evaluate it, re-call it, etc. Dynamic languages with
interactive toplevel such as Common Lisp or Python makes this easy for
you. Dynamic redefinition capabilities (full in Common Lisp, partial
in Python) are very programmer-friendly in this respect. If your test
cases are interesting to be kept, then keep them in a test file.
(It's almost all the time a good idea to store them in the test file,
since you cannot predict whether you won't want to change something in
the future.) We'll see below how to store your tests in a test file.
<p>When testing, it is nice to know some rules of thumb, like: check
your edge cases (e.g. null array), check atypical input values
(e.g. laaarge array instead of typically 5-6 elements only), check
your termination conditions, ask whether your arguments have already
been safe-proofed or whether it is in your mandate to check them,
write a test case for each `if-else' branch of the code to explore all
the possibilites, etc. Another interesting rule of thumb is the bug
frequency distribution. Experience has shown that the bugs tend to
cluster. If you discover a bug, there are chances that other bugs are
in the neighborhood. The famous 80/20 rule of thumb applies here too:
about 80% of bugs are located in about 20% of the code. Another rule
of thumb: if you find a bug caused by some coding practice pattern
thay may be used elsewhere too, look and fix other pattern instances.
<p>In a nutshell, the best advice to write bug-free code is: <em>think
ahead</em>. Try to prepare in advance for unusual usage scenarios, to
foresee problems before they happen. Don't rely on typical input and
typical usage scenarios. Things have a tendency to become atypical
one day. Recall that testing is necessary, but not sufficient, to
write good code. Therefore, think ahead!
<a name="2"></a><h2>2. Running test suite</h2>
<p>The CDSware test suite can be run in the source directory:
<blockquote>
<pre>
$ make test
</pre>
</blockquote>
or anytime after the installation:
<blockquote>
<pre>
$ /usr/local/cdsware-DEMO/bin/testsuite
</pre>
</blockquote>
The ``testsuite'' executable will run all available unit tests,
regression tests, and all the other kind of tests provided with
CDSware.
<p>The informative output is of the form:
<blockquote>
<pre>
$ make test
CDSware v0.3.2.20040519 test suite results:
===========================================
search engine washing of query patterns ... ok
search engine washing of URL arguments ... ok
search engine stripping of accented letters ... ok
bibindex engine list union ... ok
----------------------------------------------------------------------
Ran 4 tests in 0.121s
OK
</pre>
</blockquote>
In case of problems you will see failures like:
<blockquote>
<pre>
CDSware v0.3.2.20040519 test suite results:
===========================================
search engine washing of query patterns ... FAIL
search engine washing of URL arguments ... ok
search engine stripping of accented letters ... ok
bibindex engine list union ... ok
======================================================================
FAIL: search engine washing of query patterns
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/cdsware-DEMO/lib/python/cdsware/search_engine_tests.py", line 25, in test_wash_pattern
self.assertEqual("ell*", search_engine.wash_pattern('ell*'))
File "/usr/lib/python2.3/unittest.py", line 302, in failUnlessEqual
raise self.failureException, \
AssertionError: 'ell*' != 'ell'
----------------------------------------------------------------------
Ran 4 tests in 0.091s
FAILED (failures=1)
</pre>
</blockquote>
The test suite compliance should be checked before each CVS commit.
(And, obviously, double-checked before each CDSware release.)
<a name="3"></a><h2>3. Writing test code</h2>
In this section, we shall firstly briefly touch ideas behind various
kinds of test code. Then we'll discuss more earthly matters, like how
to write the test code, where to put it, etc.
<a name="3.1"></a><h3>3.1 Testing core code logic (Unit Testing)</h3>
<p>Core functionality, such as the hit set intersection for the search
engine, or the text input manipulating functions of the BibConvert
language, should come with a couple of test cases to assure proper
behaviour of the core functionality. The test cases should cover
typical input (e.g. hit set corresponding to the query for ``ellis''),
as well as the edge cases (e.g. empty/full hit set) and other unusual
situations (e.g. non-UTF-8 accented input for BibConvert functions to
test a situation of different number of bytes per char).
<p>The test cases should be written for most important core
functionality. Not every function or class in the code is to be
throughly tested. Common sense will tell.
<p>For more information on Pythonic unit testing, see the
documentation to the unittest module at <a
href="http://docs.python.org/lib/module-unittest.html">http://docs.python.org/lib/module-unittest.html</a>.
For a tutorial, see for example <a
href="http://diveintopython.org/unit_testing/">http://diveintopython.org/unit_testing/</a>.
<a name="3.2"></a><h3>3.2 Testing overall functionality (Regression Testing)</h3>
<p>In addition to the above-mentioned unit testing of important
functions, a regression testing should ensure that the existing
program's overall functionality is not altered by new changes. This
is especially important if a bug had been previously found. Then a
regression test case should be written to assure that it will never
reapper. (It also helps to scan the neighborhood of the bug, see the
80/20 thumb rule cited above.)
<p>As an example of a regression test, we have several BibConvert
example configurations (*.cfg) in CDSware already. For each
configuration, we could write more or less complex input examples
(*.dat) -- some of them are already in the distribution -- that would
trigger a use of many or all BibConvert functionality. In addition we
would provide in the distribution the expected results file (*.res or
*.out or whatever) for that particular config file and that particular
input file. The test suite would then simply run a shell process to
run bibconvert with the sample configuration on the sample data and
would compare the output to the known one.
<p>For more information on regression testing, see for example <a
href="http://c2.com/cgi/wiki?RegressionTesting">http://c2.com/cgi/wiki?RegressionTesting</a>.
<a name="3.3"></a><h3>3.3 Testing user interface pages</h3>
<p>Web interfaces are an important part of our application, so that we
should possibly test the most important user interface pages too.
<p>It may be hard to test GUI stuff, though there are ways, see for
example <a
href="http://www.xp123.com/xplor/xp0001/index.shtml">http://www.xp123.com/xplor/xp0001/index.shtml</a>.
In our case mod_python is very unfriendly in this direction, it's
impossible to run code from within Emacs or command line. But, if the
GUI code is structured in the usual CDSware way, then it may be done
via string comparisons. That is, for functionality like printing of a
basket we typically have a web-seen function
<code>print_basket()</code> that looks, schematically:
<blockquote>
<pre>
$ cat /path/to/apache/htdocs/yourbaskets.py
[...]
from cdsware.webbasketlib import perform_print_basket
def print_basket(req, basket_name)
uid = getUid(req)
return perform_print_basket(uid, basket_name)
[...]
</pre>
</blockquote>
with all the logic being done inside the library
<code>perform_print_basket()</code>:
<blockquote>
<pre>
$ cat /path/to/cdsware/lib/python/cdsware/webbasketlib.py
[...]
def perform_print_basket(uid, basket_name):
out = ""
## function body goes here
return out
[...]
</pre>
</blockquote>
The latter function can run outside of Apache, it accepts `normal'
input variables and returns `normal' text. The function can therefore
be easily tested via unit testing technique described above.
<p>Usually, when testing GUIs, we don't want to go as far as to test
sessions, logins, redirections and stuff. In case it is interesting
to automate these tests too, we could look at, for example, WebUnit
that could be used for these purposes. <a
href="http://webunit.sourceforge.net/">http://webunit.sourceforge.net/</a>.
<a name="3.4"></a><h3>3.4 File organization</h3>
<p>Each core file that is located in the lib directory (such as the
<code>webbasketlib.py</code> in the example above) should come with a
testing file where the test cases are stored. The test file is to be
named identically as the lib file it tests, but with the suffix
<code>_tests</code> (in our example,
<code>webbasketlib_tests.py</code>).
<p>The test cases are written using Pythonic unittest TestCase class.
An example for testing search engine query parameter washing function:
<blockquote>
<pre>
$ cat /path/to/cdsware/lib/python/cdsware/search_engine_tests.py
[...]
import search_engine
import unittest
class TestWashQueryParameters(unittest.TestCase):
"""Test for washing of search query parameters."""
def test_wash_url_argument(self):
"""search engine washing of URL arguments"""
self.assertEqual(1, search_engine.wash_url_argument(['1'],'int'))
self.assertEqual("1", search_engine.wash_url_argument(['1'],'str'))
self.assertEqual(['1'], search_engine.wash_url_argument(['1'],'list'))
self.assertEqual(0, search_engine.wash_url_argument('ellis','int'))
self.assertEqual("ellis", search_engine.wash_url_argument('ellis','str'))
self.assertEqual(["ellis"], search_engine.wash_url_argument('ellis','list'))
self.assertEqual(0, search_engine.wash_url_argument(['ellis'],'int'))
self.assertEqual("ellis", search_engine.wash_url_argument(['ellis'],'str'))
self.assertEqual(["ellis"], search_engine.wash_url_argument(['ellis'],'list'))
[...]
</pre>
</blockquote>
<p>In addition, each test file is supposed to define a
<code>create_test_suite()</code> function that will return test suite
with all the tests available in this file:
<blockquote>
<pre>
$ cat /path/to/cdsware/lib/python/cdsware/search_engine_tests.py
[...]
def create_test_suite():
"""Return test suite for the search engine."""
return unittest.TestSuite((unittest.makeSuite(TestWashQueryParameters,'test'),
unittest.makeSuite(TestStripAccents,'test')))
[...]
</pre>
</blockquote>
<p>This will enable us to later include this file into
<code>testsuite</code> executable:
<blockquote>
<pre>
$ cat /path/to/cdsware/source/modules/miscutil/bin/testsuite.wml
[...]
from cdsware import search_engine_tests
from cdsware import bibindex_engine_tests
def create_all_test_suites():
"""Return all tests suites for all CDSware modules."""
return unittest.TestSuite((search_engine_tests.create_test_suite(),
bibindex_engine_tests.create_test_suite()))
[...]
</pre>
</blockquote>
<p>In this way, all the test cases defined in the file
<code>search_engine_tests.py</code> will be executed when the global
<code>testcase</code> executable is called.
<p>Note that it may be time-consuming to run all the tests in one go.
If you are interested in running tests only on a certain file (say
<code>search_engine_tests.py</code>), then launch:
<blockquote>
<pre>
$ python /path/to/cdsware/lib/python/cdsware/search_engine_tests.py
</pre>
</blockquote>
<p>For feature-full examples, consult the following files in the
source distribution:
<pre>
./modules/websearch/lib/search_engine.py.wml
./modules/websearch/lib/search_engine_tests.py.wml
./modules/bibindex/lib/bibindex_engine.py.wml
./modules/bibindex/lib/bibindex_engine_tests.py.wml
./modules/miscutil/bin/testsuite.wml
</pre>
<a name="4"></a><h2>4. Conclusions</h2>
A uniform testing technique and a test suite for CDSware is
introduced. Python unittest module is used for both unit testing and
regression testing, with proper calling of external scripts. The
functional core code is the most obvious candidate to start the
testing process with, but we should also remeber to test the most
important web page elements too. Each programmer should plan to write
the test code alongside the core code development. The guidelines
were given as to how to do it in a uniform way.
<a name="5"></a><h2>5. Additional information</h2>
<dl>
<dt>More information can be found on the URLs mentioned above:
<dd>
<pre>
<a href="http://c2.com/cgi/wiki?UnitTest">http://c2.com/cgi/wiki?UnitTest</a>
<a href="http://c2.com/cgi/wiki?RegressionTesting">http://c2.com/cgi/wiki?RegressionTesting</a>
<a href="http://docs.python.org/lib/module-unittest.html">http://docs.python.org/lib/module-unittest.html</a>
<a href="http://diveintopython.org/unit_testing/">http://diveintopython.org/unit_testing/</a>
<a href="http://www.xp123.com/xplor/xp0001/index.shtml">http://www.xp123.com/xplor/xp0001/index.shtml</a>
<a href="http://webunit.sourceforge.net/">http://webunit.sourceforge.net/</a>
</pre>
</dl>
<dl>
<dt>and elsewhere:
<dd>
<pre>
Steve McConnell: "Code Complete"
FIXME: list of other interesting references, like Kent Beck papers, etc
</pre>
</dl>
diff --git a/modules/webhelp/web/index.html.wml b/modules/webhelp/web/index.html.wml
index fe1b65796..4b161aeb0 100644
--- a/modules/webhelp/web/index.html.wml
+++ b/modules/webhelp/web/index.html.wml
@@ -1,83 +1,83 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="_(Help Central)_" \
navbar_name="help" \
navtrail_previous_links="" \
navbar_select="tips"
<p>
<en>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</en>
<fr>Bienvenu au _(Help Central)_ de <CDSNAMEINTL>.</fr>
<de>Herzlich Willkommen in der _(Help Central)_ von <CDSNAMEINTL>.</de>
<es>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</es>
<ca>Benvinguts al _(Help Central)_ de <CDSNAMEINTL>.</ca>
<pl>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</pl>
<pt>Bem vindo à _(Help Central)_ do <CDSNAMEINTL>.</pt>
<it>Benvenuti nell'_(Help Central)_ di <CDSNAMEINTL>.</it>
<ru>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</ru>
<sk>Víta Vás _(Help Central)_ <CDSNAMEINTL>.</sk>
<cs>Vítá Vás _(Help Central)_ <CDSNAMEINTL>.</cs>
<no>Velkommen til _(Help Central)_ for <CDSNAMEINTL>.</no>
<sv>Välkommen till _(Help Central)_en för <CDSNAMEINTL>.</sv>
<el>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</el>
<uk>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</uk>
<ja>Welcome to _(Help Central)_ of the <CDSNAMEINTL>.</ja>
<blockquote>
<dl>
<dt><a href="search/<lang:star: index.*.html>">_(Search Help)_</a>
<dd><en>Get help with searching <CDSNAMEINTL>.</en>
<fr>Obtenez de l'aide avec la recherche sur <CDSNAMEINTL>.</fr>
<de>Hier können Sie die Suchhilfe für den <CDSNAMEINTL> konsultieren.</de>
<es>Get help with searching <CDSNAMEINTL>.</es>
<ca>Ajuda en la cerca de <CDSNAMEINTL>.</ca>
<pl>Get help with searching <CDSNAMEINTL>.</pl>
<pt>Obtenha ajuda em buscas no <CDSNAMEINTL>.</pt>
<it>Aiuto alla ricerca in <CDSNAMEINTL>.</it>
<ru>Get help with searching <CDSNAMEINTL>.</ru>
<sk>Pomoc pre hľadanie <CDSNAMEINTL>.</sk>
<cs>Nápověda pro hledání <CDSNAMEINTL>.</cs>
<no>Få hjelp til søking i <CDSNAMEINTL>.</no>
<sv>För hjälp med sökning av <CDSNAMEINTL>.</sv>
<el>Get help with searching <CDSNAMEINTL>.</el>
<uk>Get help with searching <CDSNAMEINTL>.</uk>
<ja>Get help with searching <CDSNAMEINTL>.</ja>
<dt><a href="submit/<lang:star: index.*.html>">_(Submit Help)_</a>
<dd><en>Get help with submitting to <CDSNAMEINTL>.</en>
<fr>Obtenez de l'aide avec la soumission dans <CDSNAMEINTL>.</fr>
<de>Hier können Sie die Eintragehilfe für den <CDSNAMEINTL> konsultieren.</de>
<es>Get help with submitting to <CDSNAMEINTL>.</es>
<ca>Ajuda per la tramesa de documents a <CDSNAMEINTL>.</ca>
<pl>Get help with submitting to <CDSNAMEINTL>.</pl>
<pt>Obtenha ajuda em submissões ao <CDSNAMEINTL>.</pt>
<it>Aiuto per la sottomissione di documenti ad <CDSNAMEINTL>.</it>
<ru>Get help with submitting to <CDSNAMEINTL>.</ru>
<sk>Pomoc pre pridávanie do <CDSNAMEINTL>.</sk>
<cs>Nápověda pro přidávaní do <CDSNAMEINTL>.</cs>
<no>FÃ¥ hjelp til innsending til <CDSNAMEINTL>.</no>
<sv>För hjälp med publicering i <CDSNAMEINTL>.</sv>
<el>Get help with submitting to <CDSNAMEINTL>.</el>
<uk>Get help with submitting to <CDSNAMEINTL>.</uk>
<ja>Get help with submitting to <CDSNAMEINTL>.</ja>
</dl>
</blockquote>
diff --git a/modules/webmessage/Makefile.am b/modules/webmessage/Makefile.am
index 21582bfd9..591a7e8c3 100644
--- a/modules/webmessage/Makefile.am
+++ b/modules/webmessage/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = lib web doc bin
CLEANFILES = *~
diff --git a/modules/webmessage/bin/Makefile.am b/modules/webmessage/bin/Makefile.am
index 0adc089b9..5bf379a34 100644
--- a/modules/webmessage/bin/Makefile.am
+++ b/modules/webmessage/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = webmessageadmin
EXTRA_DIST = webmessageadmin.in
CLEANFILES = *~ *.tmp
diff --git a/modules/webmessage/bin/webmessageadmin.in b/modules/webmessage/bin/webmessageadmin.in
index 19d16a67d..c4819d77b 100644
--- a/modules/webmessage/bin/webmessageadmin.in
+++ b/modules/webmessage/bin/webmessageadmin.in
@@ -1,98 +1,98 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""WebMessage Admin -- clean messages"""
__version__ = "$Id$"
try:
import getpass
import readline
import sys
from cdsware.config import supportemail
from cdsware.webmessage_dblayer import clean_messages
from cdsware.dbquery import run_sql
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
def usage(code, msg=''):
"""Print usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("WebMessage Admin -- cleans forgotten messages")
sys.stderr.write("Usage: %s [options] <command>\n" % sys.argv[0])
sys.stderr.write("Command options:\n")
sys.stderr.write(" <command> = clean\n")
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.exit(code)
def main():
"""CLI to clean_messages. The function finds the needed
arguments in sys.argv.
If the number of arguments is wrong it prints help.
Return 1 on success, 0 on failure. """
alen = len(sys.argv)
action = ''
# print help if wrong arguments
if alen > 1 and sys.argv[1] in ["-h", "--help"]:
usage(0)
elif alen > 1 and sys.argv[1] in ["-V", "--version"]:
print __version__
sys.exit(0)
if alen != 2 or sys.argv[1] not in ['clean']:
usage(1)
# getting input from user
print 'User: ',
user = raw_input()
password = getpass.getpass()
# validating input
perform = 0
# check password
if user == supportemail:
perform = run_sql("""select * from user where email = '%s' and password = '%s' """ % (supportemail, password)) and 1 or 0
if not perform:
# wrong password or user not recognized
print 'User not authorized'
return perform
# perform chosen action
if sys.argv[1] == 'clean':
cleaned = clean_messages()
print 'Database cleaned. %i suppressed messages' % int(cleaned)
return perform
if __name__ == '__main__':
main()
diff --git a/modules/webmessage/doc/Makefile.am b/modules/webmessage/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/webmessage/doc/Makefile.am
+++ b/modules/webmessage/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/webmessage/doc/admin/Makefile.am b/modules/webmessage/doc/admin/Makefile.am
index d2aa31f99..ac47a62ec 100644
--- a/modules/webmessage/doc/admin/Makefile.am
+++ b/modules/webmessage/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webmessage
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webmessage/doc/admin/guide.html.wml b/modules/webmessage/doc/admin/guide.html.wml
index 8b942d06f..689566f64 100644
--- a/modules/webmessage/doc/admin/guide.html.wml
+++ b/modules/webmessage/doc/admin/guide.html.wml
@@ -1,27 +1,27 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebMessage Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/webmessage/>WebMessage Admin</a>" \
navbar_name="admin" \
navbar_select="webmessage-admin-guide"
FIXME
diff --git a/modules/webmessage/doc/admin/index.html.wml b/modules/webmessage/doc/admin/index.html.wml
index 15d5eec65..9ce1daa2a 100644
--- a/modules/webmessage/doc/admin/index.html.wml
+++ b/modules/webmessage/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebMessage Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="webmessage"
<dl>
<dt><a href="guide.html">WebMessage Admin Guide</a></dt>
<dd>Everything you want to know about configuring WebMessage.</dd>
</dl>
diff --git a/modules/webmessage/lib/Makefile.am b/modules/webmessage/lib/Makefile.am
index 85b48b312..259eab894 100644
--- a/modules/webmessage/lib/Makefile.am
+++ b/modules/webmessage/lib/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir=$(libdir)/python/cdsware
pylib_DATA=webmessage.py webmessage_templates.py webmessage_config.py webmessage_dblayer.py webmessage_mailutils.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webmessage/lib/webmessage.py b/modules/webmessage/lib/webmessage.py
index 1558a5965..c889628f9 100644
--- a/modules/webmessage/lib/webmessage.py
+++ b/modules/webmessage/lib/webmessage.py
@@ -1,483 +1,483 @@
# -*- coding: utf-8 -*-
## $Id$
## Messaging system (internal)
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" WebMessage module, messaging system"""
__lastupdated__ = "$Date$"
__version__ = "$Id$"
# CDSWare imports
from cdsware.webmessage_dblayer import *
from cdsware.webmessage_config import *
from cdsware.config import cdslang
from cdsware.messages import gettext_set_language
from cdsware.dateutils import datetext_default, get_datetext
from cdsware.webuser import list_users_in_roles
from cdsware.search_engine import wash_url_argument
import cdsware.template
try:
webmessage_templates = cdsware.template.load('webmessage')
except:
pass
def perform_request_display_msg(uid, msgid, ln = cdslang):
"""
Displays a specific message
@param uid: user id
@param msgid: message id
@return a (body, errors[], warnings[]) formed tuple
"""
# Wash the arguments...
uid = wash_url_argument(uid, 'int')
msgid = wash_url_argument(msgid, 'int')
errors = []
warnings = []
body = ""
if (check_user_owns_message(uid, msgid) == 0):
# The user doesn't own this message
errors.append(('ERR_WEBMESSAGE_NOTOWNER',))
else:
(msg_id,
msg_from_id,
msg_from_nickname,
msg_sent_to,
msg_sent_to_group,
msg_subject,
msg_body,
msg_sent_date,
msg_received_date,
msg_status) = get_message(uid, msgid)
if (msg_id == ""):
# The message exists in table user_msgMESSAGE
# but not in table msgMESSAGE => table inconsistency
errors.append(('ERR_WEBMESSAGE_NOMESSAGE',))
else:
if (msg_status == cfg_webmessage_status_code['NEW']):
set_message_status(uid, msgid, cfg_webmessage_status_code['READ'])
body = webmessage_templates.tmpl_display_msg(msg_id,
msg_from_id,
msg_from_nickname,
msg_sent_to,
msg_sent_to_group,
msg_subject,
msg_body,
msg_sent_date,
msg_received_date,
ln)
return (body, errors, warnings)
def perform_request_display(uid, errors=[], warnings=[], infos=[], ln=cdslang):
"""
Displays the user's Inbox
@param uid: user id
@return a (body, [errors], [warnings]) formed tuple
"""
# Wash the arguments...
uid = wash_url_argument(uid, 'int')
body = ""
rows = []
rows = get_all_messages_for_user(uid)
nb_messages = 0
no_quota_users = list_users_in_roles(cfg_webmessage_roles_without_quota)
if (not(uid in no_quota_users)):
nb_messages = count_nb_messages(uid)
body = webmessage_templates.tmpl_display_inbox(messages=rows,
infos=infos,
warnings=warnings,
nb_messages=nb_messages,
ln=ln)
return (body, errors, warnings)
def perform_request_delete_msg(uid, msgid, ln=cdslang):
"""
Delete a given message from user inbox
@param uid: user id (int)
@param msgid: message id (int)
@param ln: language
@return a (body, errors, warning tuple)
"""
# Wash the arguments...
uid = wash_url_argument(uid, 'int')
msgid = wash_url_argument(msgid, 'int')
_ = gettext_set_language(ln)
errors = []
warnings = []
infos = []
if (check_user_owns_message(uid, msgid) == 0):
# The user doesn't own this message
errors.append(('ERR_WEBMESSAGE_NOTOWNER',))
else:
if (delete_message_from_user_inbox(uid, msgid)==0):
warnings.append(_("The message could not be deleted"))
else:
infos.append(_("Delete successful"))
return perform_request_display(uid, errors, warnings, infos, ln)
def perform_request_delete_all(uid, confirmed=0, ln=cdslang):
"""
Delete every message for a given user
@param uid: user id (int)
@param confirmed: 0 will produce a confirmation message
@param ln: language
@return a (body, errors, warnings) tuple
"""
infos = []
warnings = []
errors = []
confirmed = wash_url_argument(confirmed, 'int')
_ = gettext_set_language(ln)
if confirmed:
delete_all_messages(uid)
infos = [_("Your mailbox has been emptied")]
return perform_request_display(uid, warnings, errors, infos, ln)
else:
body = webmessage_templates.tmpl_confirm_delete(ln)
return (body, errors, warnings)
def perform_request_write(uid,
msg_reply_id="",
msg_to="",
msg_to_group="",
ln=cdslang):
"""
Display a write a message page.
@param uid: user id (int)
@param msg_reply_id: if this message is a reply to another, other's ID (int)
@param msg_to: comma separated usernames (string)
@param msg_to_group: comma separated groupnames (string)
@param ln: language
@return a (body, errors, warnings) tuple
"""
# wash arguments
uid = wash_url_argument(uid, 'int')
msg_reply_id = wash_url_argument(msg_reply_id, 'int')
msg_to = wash_url_argument(msg_to, 'str')
msg_to_group = wash_url_argument(msg_to_group, 'str')
# ln has already been washed in yourmessages.py
errors = []
warnings = []
body = ""
msg_from_nickname = ""
msg_subject = ""
msg_body = ""
msg_id = 0
if (msg_reply_id):
if (check_user_owns_message(uid, msg_reply_id) == 0):
# The user doesn't own this message
errors.append(('ERR_WEBMESSAGE_NOTOWNER',))
else:
# Junk== make pylint happy!
junk = 0
(msg_id,
msg_from_id,
msg_from_nickname,
junk,
junk,
msg_subject,
msg_body,
junk,
junk,
junk) = get_message(uid, msg_reply_id)
if (msg_id == ""):
# The message exists in table user_msgMESSAGE
# but not in table msgMESSAGE => table inconsistency
errors.append(('ERR_WEBMESSAGE_NOMESSAGE',))
else:
msg_to = msg_from_nickname or str(msg_from_id)
body = webmessage_templates.tmpl_write(msg_to=msg_to,
msg_to_group=msg_to_group,
msg_id=msg_id,
msg_subject=msg_subject,
msg_body=msg_body,
warnings=[],
ln=ln)
return (body, errors, warnings)
def perform_request_write_with_search(msg_to_user="",
msg_to_group="",
msg_subject="",
msg_body="",
msg_send_year=0,
msg_send_month=0,
msg_send_day=0,
names_selected=[],
search_pattern="",
results_field='none',
add_values=0,
ln=cdslang):
"""
Display a write message page, with prefilled values
@param msg_to_user: comma separated usernames (str)
@param msg_to_group: comma separated groupnames (str)
@param msg_subject: message subject (str)
@param msg_bidy: message body (string)
@param msg_send_year: year to send this message on (int)
@param_msg_send_month: month to send this message on (int)
@param_msg_send_day: day to send this message on (int)
@param users_to_add: list of usernames ['str'] to add to msg_to_user
@param groups_to_add: list of groupnames ['str'] to add to msg_to_group
@param user_search_pattern: will search users with this pattern (str)
@param group_search_pattern: will search groups with this pattern (str)
@param mode_user: if 1 display user search box, else group search box
@param add_values: if 1 users_to_add will be added to msg_to_user field..
@param ln: language
@return a (body, errors, warnings) formed tuple.
"""
# wash arguments
names_selected = wash_url_argument(names_selected, 'list')
msg_send_year = wash_url_argument(msg_send_year, 'int')
msg_send_month = wash_url_argument(msg_send_month, 'int')
msg_send_day = wash_url_argument(msg_send_day, 'int')
warnings = []
errors = []
search_results_list = []
def cat_names(name1, name2):
""" name1, name2 => 'name1, name2' """
return name1 + cfg_webmessage_separator + " " + name2
if results_field == 'user':
if add_values and len(names_selected):
usernames_to_add = reduce(cat_names, names_selected)
if msg_to_user:
msg_to_user = cat_names(msg_to_user, usernames_to_add)
else:
msg_to_user = usernames_to_add
users_found = get_nicknames_like(search_pattern)
if users_found:
for user_name in users_found:
search_results_list.append((user_name[0], user_name[0] in names_selected))
elif results_field == 'group':
if add_values and len(names_selected):
groupnames_to_add = reduce(cat_names, names_selected)
if msg_to_group:
msg_to_group = cat_names(msg_to_group, groupnames_to_add)
else:
msg_to_group = groupnames_to_add
groups_found = get_groupnames_like(search_pattern)
if groups_found:
for group_name in groups_found:
search_results_list.append((group_name[0], group_name[0] in names_selected))
body = webmessage_templates.tmpl_write(msg_to=msg_to_user,
msg_to_group=msg_to_group,
msg_subject=msg_subject,
msg_body=msg_body,
msg_send_year=msg_send_year,
msg_send_month=msg_send_month,
msg_send_day=msg_send_day,
warnings=warnings,
search_results_list=search_results_list,
search_pattern=search_pattern,
results_field=results_field,
ln=ln)
return (body, errors, warnings)
def perform_request_send(uid,
msg_to_user="",
msg_to_group="",
msg_subject="",
msg_body="",
msg_send_year=0,
msg_send_month=0,
msg_send_day=0,
ln=cdslang):
"""
send a message. if unable return warnings to write page
@param uid: id of user from (int)
@param msg_to_user: comma separated usernames (recipients) (str)
@param msg_to_group: comma separated groupnames (recipeints) (str)
@param msg_subject: subject of message (str)
@param msg_body: body of message (str)
@param msg_send_year: send this message on year x (int)
@param msg_send_month: send this message on month y (int)
@param msg_send_day: send this message on day z (int)
@param ln: language
@return a (body, errors, warnings) tuple
"""
# wash arguments
msg_to_user = wash_url_argument(msg_to_user, 'str')
msg_to_group = wash_url_argument(msg_to_group, 'str')
msg_subject = wash_url_argument(msg_subject, 'str')
msg_body = wash_url_argument(msg_body, 'str')
msg_send_year = wash_url_argument(msg_send_year, 'int')
msg_send_month = wash_url_argument(msg_send_month, 'int')
msg_send_day = wash_url_argument(msg_send_day, 'int')
_ = gettext_set_language(ln)
def strip_spaces(str):
"""suppress spaces before and after x (str)"""
return str.strip()
# wash user input
users_to = map(strip_spaces, msg_to_user.split(cfg_webmessage_separator))
groups_to = map(strip_spaces, msg_to_group.split(cfg_webmessage_separator))
if users_to == ['']:
users_to = []
if groups_to == ['']:
groups_to = []
warnings = []
errors = []
infos = []
problem = None
users_to_str = cfg_webmessage_separator.join(users_to)
groups_to_str = cfg_webmessage_separator.join(groups_to)
send_on_date = get_datetext(msg_send_year, msg_send_month, msg_send_day)
if (msg_send_year == msg_send_month == msg_send_day == 0):
status = cfg_webmessage_status_code['NEW']
else:
status = cfg_webmessage_status_code['REMINDER']
if send_on_date == datetext_default:
warning = _("The chosen date (%(year)i/%(month)i/%(day)i) is invalid")
warning = warning % {'year': msg_send_year,
'month': msg_send_month,
'day': msg_send_day}
warnings.append(warning)
problem = 1
if not(users_to_str or groups_to_str):
# <=> not(users_to_str) AND not(groups_to_str)
warnings.append(_("Please enter a user name or a group name"))
problem = 1
if len(msg_body) > cfg_webmessage_max_size_of_message:
warnings.append(_("""Your message is too long, please edit it.
Max size allowed is %i characters
""")%(cfg_webmessage_max_size_of_message,))
problem = 1
users_dict = get_uids_from_nicks(users_to)
users_to = users_dict.items() # users_to=[(nick, uid),(nick2, uid2)]
groups_dict = get_gids_from_groupnames(groups_to)
groups_to = groups_dict.items()
gids_to = []
for (group_name, group_id) in groups_to:
if not(group_id):
warnings.append(_("Group '%s' doesn't exist\n")% (group_name))
problem = 1
else:
gids_to.append(group_id)
# Get uids from gids
uids_from_group = get_uids_members_of_groups(gids_to)
# Add the original uids, and make sure there is no double values.
tmp_dict = {}
for uid_receiver in uids_from_group:
tmp_dict[uid_receiver] = None
for (user_nick, user_id) in users_to:
if user_id:
if user_id not in tmp_dict:
uids_from_group.append(user_id)
tmp_dict[user_id] = None
else:
if type(user_nick) == int or type(user_nick) == str and user_nick.isdigit():
user_nick = int(user_nick)
if user_exists(user_nick) and user_nick not in tmp_dict:
uids_from_group.append(user_nick)
tmp_dict[user_nick] = None
else:
warnings.append(_("User '%s' doesn't exist\n")% (user_nick))
problem = 1
if problem:
body = webmessage_templates.tmpl_write(msg_to=users_to_str,
msg_to_group=groups_to_str,
msg_subject=msg_subject,
msg_body=msg_body,
msg_send_year=msg_send_year,
msg_send_month=msg_send_month,
msg_send_day=msg_send_day,
warnings=warnings,
ln=ln)
title = _("Write a message")
navtrail = get_navtrail(ln, title)
return (body, errors, warnings, title, navtrail)
else:
msg_id = create_message(uid,
users_to_str,
groups_to_str,
msg_subject,
msg_body,
send_on_date)
uid_problem = send_message(uids_from_group, msg_id, status)
if len(uid_problem) > 0:
usernames_problem_dict = get_nicks_from_uids(uid_problem)
usernames_problem = usernames_problem_dict.values()
def listing(name1, name2):
""" name1, name2 => 'name1, name2' """
return str(name1) + ", " + str(name2)
warning = _("Your message couldn't be sent to the following recipients\n")
warning += _("These users are overquota: ")
warnings.append(warning + reduce(listing, usernames_problem))
if len(uids_from_group) != len(uid_problem):
infos.append(_("Your message has been sent."))
else:
check_if_need_to_delete_message_permanently([msg_id])
(body, errors, warnings) = perform_request_display(uid, errors, warnings, infos, ln)
title = _("Your Messages")
return (body, errors, warnings, title, get_navtrail(ln))
def account_new_mail(uid, ln=cdslang):
"""
display new mail info for myaccount.py page.
@param uid: user id (int)
@param ln: language
@return html body
"""
nb_new_mail = get_nb_new_messages_for_user(uid)
total_mail = get_nb_readable_messages_for_user(uid)
return webmessage_templates.tmpl_account_new_mail(nb_new_mail, total_mail, ln)
def get_navtrail(ln=cdslang, title=""):
"""
gets the navtrail for title...
@param title: title of the page
@param ln: language
@return HTML output
"""
navtrail = webmessage_templates.tmpl_navtrail(ln, title)
return navtrail
diff --git a/modules/webmessage/lib/webmessage_config.py b/modules/webmessage/lib/webmessage_config.py
index 1ea04d6d6..538f069bf 100644
--- a/modules/webmessage/lib/webmessage_config.py
+++ b/modules/webmessage/lib/webmessage_config.py
@@ -1,55 +1,55 @@
# -*- coding: utf-8 -*-
## $Id$
##
## Configuration for webmessage module
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
webmessage config file, here you can manage error messages, size of messages,
quotas, and some db related fields...
"""
__revision__ = '1.3, 15 nov 2005 '
# error messages. (should not happen, except in case of reload, or url altering)
cfg_webmessage_error_messages = \
{ 'ERR_WEBMESSAGE_NOTOWNER': '_("This message is not in your mailbox")',
'ERR_WEBMESSAGE_NONICKNAME':'_("No nickname or user for uid #%s")',
'ERR_WEBMESSAGE_NOMESSAGE': '_("This message doesn\'t exist")'
}
# status of message (table user_msgMESSAGE)
cfg_webmessage_status_code = \
{
'NEW': 'N',
'READ': 'R',
'REMINDER': 'M'
}
# separator used in every list of recipients
cfg_webmessage_separator = ','
# max length of a message
cfg_webmessage_max_size_of_message = 20000
# quota for messages for users (admins, see below)
cfg_webmessage_max_nb_of_messages = 30
# list of roles (find them in accROLE table) without quota
cfg_webmessage_roles_without_quota = ['superadmin']
cfg_webmessage_days_before_delete_orphans = 60
diff --git a/modules/webmessage/lib/webmessage_dblayer.py b/modules/webmessage/lib/webmessage_dblayer.py
index aca5bc5a4..51e79ce8f 100644
--- a/modules/webmessage/lib/webmessage_dblayer.py
+++ b/modules/webmessage/lib/webmessage_dblayer.py
@@ -1,564 +1,564 @@
# -*- coding: utf-8 -*-
## $Id$
##
## Every db-related function of module webmessage
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from MySQLdb import escape_string
from time import localtime, mktime
from cdsware.dbquery import run_sql
from cdsware.webmessage_config import cfg_webmessage_status_code, \
cfg_webmessage_max_nb_of_messages, \
cfg_webmessage_roles_without_quota, \
cfg_webmessage_days_before_delete_orphans
from cdsware.dateutils import datetext_default, \
convert_datestruct_to_datetext
from cdsware.webuser import list_users_in_roles
def check_user_owns_message(uid, msgid):
"""
Checks whether a user owns a message
@param uid: user id
@param msgid: message id
@return 1 if the user owns the message, else 0
"""
query = """SELECT count(*)
FROM user_msgMESSAGE
WHERE id_user_to=%(user_id)i AND
id_msgMESSAGE=%(message_id)i"""
params = {'user_id': int(uid),
'message_id': int(msgid)}
res = run_sql(query%params)
return int(res[0][0])
def get_message(uid, msgid):
"""
get a message with its status
@param uid: user id
@param msgid: message id
@return a (message_id,
id_user_from,
nickname_user_from,
sent_to_user_nicks,
sent_to_group_names,
subject,
body,
sent_date,
received_date,
status)
formed tuple or 0 (ZERO) if none found
"""
query = """SELECT m.id,
m.id_user_from,
u.nickname,
m.sent_to_user_nicks,
m.sent_to_group_names,
m.subject,
m.body,
DATE_FORMAT(m.sent_date, '%%Y-%%m-%%d %%H:%%i:%%s'),
DATE_FORMAT(m.received_date, '%%Y-%%m-%%d %%H:%%i:%%s'),
um.status
FROM msgMESSAGE m,
user_msgMESSAGE um,
user u
WHERE m.id=%(message_id)i AND
um.id_msgMESSAGE=%(message_id)i AND
um.id_user_to=%(user_id)i AND
u.id=m.id_user_from"""
params = {'message_id': int(msgid),
'user_id': int(uid)}
res = run_sql(query%params)
if res:
return res[0]
else:
return 0
def set_message_status(uid, msgid, new_status):
"""
Change the status of a message (e.g. from "new" to "read").
the status is a single character string, specified in constant
cfg_webmessage_status_code in file webmessage_config.py
examples:
N: New message
R: alreay Read message
M: reminder
@param uid: user ID
@param msgid: Message ID
@param new_status: new status. Should be a single character
@return 1 if succes, 0 if not
"""
query = """UPDATE user_msgMESSAGE
SET status='%s'
WHERE id_user_to=%i AND
id_msgMESSAGE=%i"""
params = (escape_string(new_status), uid, msgid)
return int(run_sql(query%params))
def get_nb_new_messages_for_user(uid):
""" Get number of new mails for a given user
@param uid: user id (int)
@return number of new mails as int.
"""
update_user_inbox_for_reminders(uid)
new_status = cfg_webmessage_status_code['NEW']
query = """SELECT count(id_msgMESSAGE)
FROM user_msgMESSAGE
WHERE id_user_to=%i AND
BINARY status='%s'"""
params = (int(uid), escape_string(new_status))
res = run_sql(query% params)
if res:
return res[0][0]
return 0
def get_nb_readable_messages_for_user(uid):
""" Get number of mails of a fiven user. Reminders are not counted
@param uid: user id (int)
@return number of messages (int)
"""
reminder_status = cfg_webmessage_status_code['REMINDER']
query = """SELECT count(id_msgMESSAGE)
FROM user_msgMESSAGE
WHERE id_user_to=%i AND
BINARY status!='%s'"""
params = (int(uid), reminder_status)
res = run_sql(query% params)
if res:
return res[0][0]
return 0
def get_all_messages_for_user(uid):
"""
Get all messages for a user's inbox, without the eventual
non-expired reminders.
@param uid: user id
@return [(message_id,
id_user_from,
nickname_user_from,
message_subject,
message_sent_date,
message_status)]
"""
update_user_inbox_for_reminders(uid)
reminder_status = cfg_webmessage_status_code['REMINDER']
query = """SELECT m.id,
m.id_user_from,
u.nickname,
m.subject,
DATE_FORMAT(m.sent_date, '%%Y-%%m-%%d %%H:%%i:%%s'),
um.status
FROM user_msgMESSAGE um,
msgMESSAGE m,
user u
WHERE um.id_user_to = %(user_to)i AND
!(BINARY um.status='%(status)s') AND
um.id_msgMESSAGE=m.id AND
u.id=m.id_user_from
ORDER BY m.sent_date DESC
"""
params = {'user_to': int(uid),
'status': escape_string(reminder_status)
}
return run_sql(query%params)
def count_nb_messages(uid):
"""
@param uid: user id
@return integer of number of messages a user has, 0 if none
"""
uid = int(uid)
query = """SELECT count(id_user_to)
FROM user_msgMESSAGE
WHERE id_user_to=%i
"""
res = run_sql(query%uid)
if res:
return int(res[0][0])
else:
return 0
def delete_message_from_user_inbox(uid, msg_id):
"""
Delete message from users inbox
If this message was does not exist in any other user's inbox,
delete it permanently from the database
@param uid: user id
@param msg_id: message id
@return integer 1 if delete was successful, integer 0 else
"""
query1 = """DELETE FROM user_msgMESSAGE
WHERE id_user_to=%i AND
id_msgMESSAGE=%i"""
params1 = (int(uid), int(msg_id))
res1 = run_sql(query1%params1)
check_if_need_to_delete_message_permanently([msg_id])
return int(res1)
def check_if_need_to_delete_message_permanently(msg_ids):
"""
Checks if a list of messages exist in anyone's inbox, if not,
delete them permanently
@param msg_id: sequence of message ids
@return number of deleted messages
"""
if not((type(msg_ids) is list) or (type(msg_ids) is tuple)):
msg_ids = [msg_ids]
query1 = """SELECT count(id_msgMESSAGE)
FROM user_msgMESSAGE
WHERE id_msgMESSAGE=%i"""
messages_to_delete = []
for msg_id in msg_ids:
nb_users = int(run_sql(query1%(int(msg_id),))[0][0])
if nb_users == 0:
messages_to_delete.append(int(msg_id))
if len(messages_to_delete) > 0:
query2 = """DELETE FROM msgMESSAGE
WHERE"""
for msg_id in messages_to_delete[0:-1]:
query2 += " id=%i" % (msg_id,) + " OR"
query2 += " id=%i" % (messages_to_delete[-1])
run_sql(query2)
return len(messages_to_delete)
def delete_all_messages(uid):
"""
Delete all messages of a user (except reminders)
@param uid: user id
@return the number of messages deleted
"""
reminder_status = cfg_webmessage_status_code['REMINDER']
query1 = """SELECT id_msgMESSAGE
FROM user_msgMESSAGE
WHERE id_user_to=%i AND
NOT(BINARY status like '%s')"""
params = (int(uid), reminder_status)
msg_ids = map(get_element, run_sql(query1%params))
query2 = """DELETE FROM user_msgMESSAGE
WHERE id_user_to=%i AND
NOT(BINARY status like '%s')"""
nb_messages = int(run_sql(query2%params))
check_if_need_to_delete_message_permanently(msg_ids)
return nb_messages
def get_uids_from_nicks(nicks):
"""
Get the association uid/nickname of given nicknames
@param nicks: list or sequence of strings, each string being a nickname
@return a dictionary {nickname: uid}
"""
if not((type(nicks) is list) or (type(nicks) is tuple)):
nicks = [nicks]
users = {}
query = "SELECT nickname, id FROM user WHERE BINARY nickname in("
if len(nicks)> 0:
for nick in nicks:
users[nick] = None
for nick in users.keys()[0:-1]:
query += "'%s'," % escape_string(nick)
query += "'%s')" % escape_string(users.keys()[-1])
res = run_sql(query)
def enter_dict(couple):
""" takes a a tuple and enters it into dict users """
users[couple[0]] = int(couple[1])
map(enter_dict, res)
return users
def get_nicks_from_uids(uids):
"""
Get the association uid/nickname of given uids
@param uids: list or sequence of uids
@return a dictionary {uid: nickname} where empty value is possible
"""
if not((type(uids) is list) or (type(uids) is tuple)):
uids = [uids]
users = {}
query = "SELECT id, nickname FROM user WHERE id in("
if len(uids) > 0:
for uid in uids:
users[uid] = None
for uid in users.keys()[0:-1]:
query += "%i," % int(uid)
query += "%i)" % int(users.keys()[-1])
res = run_sql(query)
for (user_id, nickname) in res:
users[int(user_id)] = nickname
return users
def get_gids_from_groupnames(groupnames):
"""
Get the gids of given groupnames
@param groupnames: list or sequence of strings, each string being a groupname
@return a dictionary {groupname: gid}
"""
if not((type(groupnames) is list) or (type(groupnames) is tuple)):
groupnames = [groupnames]
groups = {}
query = "SELECT name, id FROM usergroup WHERE BINARY name in("
if len(groupnames) > 0:
for groupname in groupnames:
groups[groupname] = None
for groupname in groups.keys()[0:-1]:
query += "'%s'," % escape_string(groupname)
query += "'%s')" % escape_string(groups.keys()[-1])
res = run_sql(query)
def enter_dict(couple):
""" enter a tuple into dictionary groups """
groups[couple[0]] = int(couple[1])
map(enter_dict, res)
return groups
def get_uids_members_of_groups(gids):
"""
Get the distinct ids of users members of given groups.
@param groupnames: list or sequence of group ids
@return a list of uids.
"""
if not((type(gids) is list) or (type(gids) is tuple)):
gids = [gids]
query = "SELECT DISTINCT id_user FROM user_usergroup WHERE"
if len(gids) > 0:
for gid in gids[0:-1]:
query += " id_usergroup=" + str(int(gid)) + " OR"
query += " id_usergroup=" + str(int(gids[-1]))
return map(get_element, run_sql(query))
return []
def user_exists(uid):
""" checks if a user exists in the system, given his uid. return 0 or 1"""
query = "SELECT count(id) FROM user WHERE id=%i GROUP BY id"
res = run_sql(query % uid)
if res:
return int(res[0][0])
return 0
def create_message(uid_from,
users_to_str="",
groups_to_str="",
msg_subject="",
msg_body="",
msg_send_on_date=datetext_default):
"""
Creates a message in the msgMESSAGE table. Does NOT send the message.
This function is like a datagramPacket...
@param uid_from: uid of the sender (int)
@param users_to_str: a string, with nicknames separated by semicolons (';')
@param groups_to_str: a string with groupnames separated by semicolons
@param msg_subject: string containing the subject of the message
@param msg_body: string containing the body of the message
@param msg_send_on_date: date on which message must be sent. Has to be a
datetex format (i.e. YYYY-mm-dd HH:MM:SS)
@return id of the created message
"""
now = convert_datestruct_to_datetext(localtime())
query = """INSERT INTO msgMESSAGE(id_user_from,
sent_to_user_nicks,
sent_to_group_names,
subject,
body,
sent_date,
received_date)
VALUES(%i,'%s','%s','%s','%s','%s','%s')"""
params = (int(uid_from),
escape_string(users_to_str),
escape_string(groups_to_str),
escape_string(msg_subject),
escape_string(msg_body),
escape_string(now),
escape_string(msg_send_on_date))
msg_id = run_sql(query%params)
return int(msg_id)
def send_message(uids_to, msgid, status=cfg_webmessage_status_code['NEW']):
"""
Send message to uids
@param uids: sequence of user ids
@param msg_id: id of message
@param status: status of the message. (single char, see webmessage_config.py).
@return a list of users having their mailbox full
"""
if not((type(uids_to) is list) or (type(uids_to) is tuple)):
uids_to = [uids_to]
user_problem = []
if len(uids_to) > 0:
users_quotas = check_quota(cfg_webmessage_max_nb_of_messages - 1)
query = """INSERT INTO user_msgMESSAGE
(id_user_to, id_msgMESSAGE, status)
VALUES """
fixed_value = ",%i,'%s')" % (int(msgid), status)
def not_users_quotas_has_key(key):
""" not(is key in users over quota?)"""
return not(users_quotas.has_key(key))
user_ids_to = filter(not_users_quotas_has_key, uids_to)
user_problem = filter(users_quotas.has_key, uids_to)
if len(user_ids_to) > 0:
for uid_to in user_ids_to[0:-1]:
query += "(%i%s," % (int(uid_to), fixed_value)
query += "(%i%s" % (int(user_ids_to[-1]), fixed_value)
run_sql(query)
return user_problem
def check_quota(nb_messages):
"""
@param nb_messages: max number of messages a user can have
@return a dictionary of users over-quota
"""
where = ''
no_quota_users = list_users_in_roles(cfg_webmessage_roles_without_quota)
if len(no_quota_users) > 0:
where = """WHERE """
for uid in no_quota_users[:-1]:
where += "id_user_to!=%i AND " % uid
where += "id_user_to!=%i" % no_quota_users[-1]
query = """SELECT id_user_to,
count(id_user_to)
FROM user_msgMESSAGE
%s
GROUP BY id_user_to
HAVING count(id_user_to)>%i"""
res = run_sql(query % (where, int(nb_messages)))
user_over_quota = {}
def enter_dict(couple):
""" enter a tuple in user_over_quota dict """
user_over_quota[int(couple[0])] = int(couple[1])
map(enter_dict, res)
return user_over_quota
def update_user_inbox_for_reminders(uid):
"""
Updates user's inbox with any reminders that should have arrived
@param uid: user id
@return integer number of new expired reminders
"""
now = convert_datestruct_to_datetext(localtime())
reminder_status = cfg_webmessage_status_code['REMINDER']
new_status = cfg_webmessage_status_code['NEW']
query1 = """SELECT m.id
FROM msgMESSAGE m,
user_msgMESSAGE um
WHERE um.id_user_to=%(uid)i AND
um.id_msgMESSAGE=m.id AND
m.received_date <= '%(date)s' AND
um.status like binary '%(old_status)s'
"""
params1 = {'uid': int(uid),
'date': now,
'old_status': reminder_status}
res_ids = run_sql(query1%params1)
out = len(res_ids)
if (out>0):
query2 = """UPDATE user_msgMESSAGE
SET status='%(new_status)s'
WHERE id_user_to=%(uid)i AND ("""
for msg_id in res_ids[0:-1]:
query2 += "id_msgMESSAGE=" + str(int(msg_id[0])) + " OR "
params2 = {'uid': int(uid),
'new_status': new_status,
}
query2 += "id_msgMESSAGE=" + str(int(res_ids[-1][0])) + ")"
run_sql(query2%params2)
return out
def get_nicknames_like(pattern):
"""get nicknames like pattern"""
if pattern:
query = "SELECT nickname FROM user WHERE nickname RLIKE '%s'"
pattern = escape_string(pattern)
res = run_sql(query%pattern)
return res
return ()
def get_groupnames_like(pattern):
"""Get groupnames like pattern"""
if pattern:
query = "SELECT name FROM usergroup WHERE name RLIKE '%s'"
pattern = escape_string(pattern)
res = run_sql(query%pattern)
return res
return ()
def get_element(sql_res):
"""convert mySQL output
@param x: a tuple like this: (6789L,)
@return integer conversion of the number in tuple
"""
return int(sql_res[0])
def clean_messages():
""" Cleans msgMESSAGE table"""
current_time = localtime()
seconds = mktime(current_time)
seconds -= cfg_webmessage_days_before_delete_orphans * 86400
format = "%Y-%m-%d %H:%M:%S"
sql_date = convert_datestruct_to_datetext(localtime(seconds))
deleted_items = 0
#find id and email from every user who has got an email
query1 = """SELECT distinct(umsg.id_user_to),
user.email
FROM user_msgMESSAGE umsg
LEFT JOIN user ON
umsg.id_user_to=user.id"""
res1 = run_sql(query1)
# if there is no email, user has disappeared
users_deleted = map(lambda u: int(u[0]), filter(lambda x: x[1] == None, res1))
# find ids from messages in user's inbox
query2 = """SELECT distinct(umsg.id_msgMESSAGE),
msg.id
FROM user_msgMESSAGE umsg
LEFT JOIN msgMESSAGE msg ON
umsg.id_msgMESSAGE=msg.id"""
res2 = run_sql(query2)
# if there is no id, message was deleted from table msgMESSAGE...
messages_deleted = map(lambda u: int(u[0]), filter(lambda x: x[1] == None, res2))
def tuplize(el1, el2):
return str(el1) + ',' + str(el2)
if len(users_deleted) or len(messages_deleted):
# Suppress every referential error from user_msgMESSAGE
query3 = "DELETE FROM user_msgMESSAGE WHERE "
if len(users_deleted):
query3 += "id_user_to IN (%s)" % reduce(tuplize, users_deleted)
if len(messages_deleted):
query3 += ' OR '
if len(messages_deleted):
query3 += "id_msgMESSAGE IN (%s)" % reduce(tuplize, messages_deleted)
deleted_items = int(run_sql(query3))
# find every message that is nobody's inbox
query4 = """SELECT msg.id
FROM msgMESSAGE msg
LEFT JOIN user_msgMESSAGE umsg
ON msg.id=umsg.id_msgMESSAGE
WHERE msg.sent_date<'%s'
GROUP BY umsg.id_msgMESSAGE
HAVING count(umsg.id_msgMESSAGE)=0
"""
res4 = map(lambda x: x[0], run_sql(query4% sql_date))
if len(res4):
# delete these messages
query5 = "DELETE FROM msgMESSAGE WHERE "
query5 += "id IN (%s)" % reduce(tuplize, res4)
deleted_items += int(run_sql(query5))
return deleted_items
diff --git a/modules/webmessage/lib/webmessage_mailutils.py b/modules/webmessage/lib/webmessage_mailutils.py
index a9a517c46..7f847e052 100644
--- a/modules/webmessage/lib/webmessage_mailutils.py
+++ b/modules/webmessage/lib/webmessage_mailutils.py
@@ -1,116 +1,116 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Library for quoting text, email style """
def email_quoted_txt2html(text,
tabs_before=0,
indent_txt='>>',
linebreak_txt="\n",
indent_html=('<div class="commentbox">', "</div>"),
linebreak_html='<br/>'):
"""
Takes a typical mail quoted text, e.g.:
hello,
you told me:
>> Your mother was a hamster and your father smelt of elderberries
I must tell you that I'm not convinced. Then in this discussion:
>>>> Is there someone else up there we could talk to?
>> No. Now, go away, or I shall taunt you a second time-a!
I think we're not going to be friends!
and return an html formatted output, e.g.:
hello,<br/>
you told me:<br/>
<div>
Your mother was a hamster and your father smelt of elderberries
</div>
I must tell you that I'm not convinced. Then in this discussion:
<div>
<div>
Is there someone else up there we could talk to?
</div>
No. Now, go away, or I shall taunt you a second time-a!
</div>
I think we're not going to be friends!
@param text: the text in quoted format
@param tabs_before: number of tabulations before each line
@param indent_str: quote separator in email (default:'>>')
@param linebreak_str: line separator in email (default: '\n')
@param indent_html: tuple of (opening, closing) html tags.
default: ('<div class="commentbox">', "</div>")
@param linebreak_html: line separator in html (default: '<br/>')
@return string containing html formatted output
"""
final_body = ""
nb_indent = 0
lines = text.split(linebreak_txt)
for line in lines:
new_nb_indent = line.count(indent_txt)
if (new_nb_indent > nb_indent):
for _ in range(nb_indent, new_nb_indent):
final_body += tabs_before*"\t" + indent_html[0] + "\n"
tabs_before += 1
elif (new_nb_indent < nb_indent):
for _ in range(new_nb_indent, nb_indent):
tabs_before -= 1
final_body += (tabs_before)*"\t" + indent_html[1] + "\n"
final_body += tabs_before*"\t" + line.replace(indent_txt, '')
final_body += linebreak_html + "\n"
nb_indent = new_nb_indent
for _ in range(0, nb_indent):
tabs_before -= 1
final_body += (tabs_before)*"\t" + "</div>\n"
return final_body
def email_quote_txt(text,
indent_txt='>>',
linebreak_input="\n",
linebreak_output="\n"):
"""
Takes a text and returns it in a typical mail quoted format, e.g.:
C'est un lapin, lapin de bois.
>>Quoi?
Un cadeau.
>>What?
A present.
>>Oh, un cadeau.
will return:
>>C'est un lapin, lapin de bois.
>>>>Quoi?
>>Un cadeau.
>>>>What?
>>A present.
>>>>Oh, un cadeau.
@param text: the string to quote
@param indent_txt: the string used for quoting (default: '>>')
@param linebreak_input: in the text param, string used for linebreaks
default: '\n'
@param linebreak_output: linebreak used for output
default: '\n'
@return the text as a quoted string
"""
if (text == ""):
return ""
lines = text.split(linebreak_input)
text = ""
for line in lines:
text += indent_txt + line + linebreak_output
return text
diff --git a/modules/webmessage/lib/webmessage_templates.py b/modules/webmessage/lib/webmessage_templates.py
index b0e989d21..e0beaac4b 100644
--- a/modules/webmessage/lib/webmessage_templates.py
+++ b/modules/webmessage/lib/webmessage_templates.py
@@ -1,641 +1,641 @@
# -*- coding: utf-8 -*-
## $Id$
##
## handles rendering of webmessage module
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" templates for webmessage module """
# CDS imports
from cdsware.webmessage_mailutils import email_quoted_txt2html, email_quote_txt
from cdsware.webmessage_config import cfg_webmessage_status_code, \
cfg_webmessage_separator, \
cfg_webmessage_max_nb_of_messages
from cdsware.textutils import indent_text
from cdsware.dateutils import convert_datetext_to_dategui, \
datetext_default, \
create_day_selectbox, \
create_month_selectbox, \
create_year_selectbox
from cdsware.config import weburl, cdslang
from cdsware.messages import gettext_set_language
from cdsware.webuser import get_user_info
class Template:
def tmpl_display_inbox(self, messages, infos=[], warnings=[], nb_messages=0, ln=cdslang):
"""
Displays a list of messages, with the appropriate links and buttons
@param messages: a list of tuples:
[(message_id,
user_from_id,
user_from_nickname,
subject,
sent_date,
status=]
@param infos: a list of informations to print on top of page
@param ln: language of the page.
@return the list in HTML format
"""
_ = gettext_set_language(ln)
junk = 0
inbox = self.tmpl_warning(warnings, ln)
inbox += self.tmpl_infobox(infos, ln)
inbox += self.tmpl_quota(nb_messages, ln)
inbox += """
<table class="mailbox">
<thead class="mailboxheader">
<tr class="inboxheader">
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>
</thead>
<tfoot>
<tr style="height:0px;">
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
<tbody class="mailboxbody">""" %(_("Subject"), _("Sender"), _("Date"), _("Action"))
if len(messages) == 0:
inbox += """
<tr class="mailboxrecord" style="height: 100px;">
<td colspan="4" style="text-align: center;">
<b>%s</b>
</td>
</tr>""" %(_("No new mail"),)
for (msgid, id_user_from, user_from_nick, subject, sent_date, status) in messages:
if not(subject):
subject = _("[No subject]")
subject_link = '<a href="display_msg?msgid=%i&amp;ln=%s">%s</a>'% (msgid,
ln,
subject)
if user_from_nick:
from_link = '%s'% (user_from_nick)
else:
from_link = get_user_info(id_user_from, ln)[2]
action_link = '<a href="write?msg_reply_id=%i&amp;ln=%s">%s</a> / '% (msgid,
ln,
_("Reply"))
action_link += '<a href="delete?msgid=%i&amp;ln=%s">%s</a>'% (msgid,
ln,
_("Delete"))
s_date = convert_datetext_to_dategui(sent_date, ln)
stat_style = ''
if (status == cfg_webmessage_status_code['NEW']):
stat_style = ' style="font-weight:bold"'
inbox += """
<tr class="mailboxrecord">
<td%s>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>""" %(stat_style, subject_link, from_link, s_date, action_link)
inbox += """
<tr class="mailboxfooter">
<td colspan="2">
<form name="newMessage" action="write?ln=%(ln)s" method="post">
<input type="submit" name="del_all" value="%(write_label)s" class="formbutton" />
</form>
</td>
<td>&nbsp;</td>
<td>
<form name="deleteAll" action="delete_all?ln=%(ln)s" method="post">
<input type="submit" name="del_all" value="%(delete_all_label)s" class="formbutton" />
</form>
</td>
</tr>
</tbody>
</table>""" % {'ln': ln,
'write_label': _("Write new message"),
'delete_all_label': _("Delete All")}
return indent_text(inbox, 2)
def tmpl_write(self,
msg_to="",
msg_to_group="",
msg_id=0,
msg_subject="",
msg_body="",
msg_send_year=0,
msg_send_month=0,
msg_send_day=0,
warnings=[],
search_results_list=[],
search_pattern="",
results_field='none',
ln=cdslang):
"""
Displays a writing message form with optional prefilled fields
@param msg_to: nick of the user (prefills the To: field)
@param msg_subject: subject of the message (prefills the Subject: field)
@param msg_body: body of the message (prefills the Message: field)
@param msg_send_year: prefills to year field
@param msg_send_month: prefills the month field
@param msg_send_day: prefills the day field
@param warnings: display warnings on top of page
@param search_results_list: list of tuples. (user/groupname, is_selected)
@param search_pattern: pattern used for searching
@param results_field: 'none', 'user' or 'group'
@param ln: language of the form
@return the form in HTML format
"""
_ = gettext_set_language(ln)
write_box = self.tmpl_warning(warnings)
# escape forbidden character
msg_to = msg_to.replace('"', '&quot;')
msg_to_group = msg_to_group.replace('"', '&quot;')
msg_subject = msg_subject.replace('"', '&quot;')
search_pattern = search_pattern.replace('"','&quot;')
to_select = self.tmpl_user_or_group_search(search_results_list,
search_pattern,
results_field,
ln)
if (msg_id != 0):
msg_subject = _("Re: ") + msg_subject
msg_body = email_quote_txt(msg_body)
msg_body = msg_body.replace('>', '&gt;')
write_box += """
<form name="write_message" action="send" method="post">
<input type="hidden" name="ln" value="%(ln)s"/>
<div style="float: left; vertical-align:text-top; margin-right: 10px;">
<table class="mailbox">
<thead class="mailboxheader">
<tr>
<td class="inboxheader" colspan="2">
<table class="messageheader">
<tr>
<td class="mailboxlabel">%(to_label)s</td>
<td class="mailboxlabel">%(users_label)s</td>
<td style="width:100%%;">
<input class="mailboxinput" type="text" name="msg_to_user" value="%(to_users)s" />
</td>
</tr>
<tr>
<td class="mailboxlabel">&nbsp;</td>
<td class="mailboxlabel">%(groups_label)s</td>
<td style="width:100%%;">
<input class="mailboxinput" type="text" name="msg_to_group" value="%(to_groups)s" />
</td>
</tr>
<tr>
<td class="mailboxlabel">&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td class="mailboxlabel">%(subject_label)s</td>
<td colspan="2">
<input class="mailboxinput" type="text" name="msg_subject" value="%(subject)s" />
</td>
</tr>
</table>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td style="height:0px" colspan="2"></td>
</tr>
</tfoot>
<tbody class="mailboxbody">
<tr>
<td class="mailboxlabel">%(message_label)s</td>
<td>
<textarea name="msg_body" rows="10" cols="50">"""
write_box = indent_text(write_box, 2)
write_box_part2 = """
</td>
</tr>
<tr>
<td class="mailboxlabel">%(send_later_label)s</td>
<td>
%(day_field)s
%(month_field)s
%(year_field)s
</td>
</tr>
<tr class="mailboxfooter">
<td colspan="2" class="mailboxfoot">
<input type="submit" name="send_button" value="%(send_label)s" class="formbutton"/>
</td>
</tr>
</tbody>
</table>
</div>
<div style="vertical-align:top; margin-left: 5px; float: left;">
%(to_select)s
</div>
</form>
"""
write_box_part2 = indent_text(write_box_part2, 2)
write_box += "%(body)s" "</textarea>"+ write_box_part2
day_field = create_day_selectbox('msg_send_day', msg_send_day, ln)
month_field = create_month_selectbox('msg_send_month', msg_send_month, ln)
year_field = create_year_selectbox('msg_send_year', -1, 10, msg_send_year, ln)
write_box = write_box % {'to_users' : msg_to,
'to_groups': msg_to_group,
'subject' : msg_subject,
'body' : msg_body,
'ln': ln,
'day_field': day_field,
'month_field': month_field,
'year_field': year_field,
'to_select': to_select,
'send_later_label': _("Send later?"),
'to_label': _("To:"),
'users_label': _("Users"),
'groups_label': _("Groups"),
'subject_label': _("Subject:"),
'message_label': _("Message:"),
'send_label': _("SEND")}
return write_box
def tmpl_display_msg(self,
msg_id="",
msg_from_id="",
msg_from_nickname="",
msg_sent_to="",
msg_sent_to_group="",
msg_subject="",
msg_body="",
msg_sent_date="",
msg_received_date=datetext_default,
ln=cdslang):
"""
Displays a given message
@param msg_id: id of the message
@param msg_from_id: id of user who sent the message
@param msg_from_nickname: nickname of the user who sent the message
@param msg_sent_to: list of users who received the message
(comma separated string)
@param msg_sent_to_group: list of groups who received the message
(comma separated string)
@param msg_subject: subject of the message
@param msg_body: body of the message
@param msg_sent_date: date at which the message was sent
@param msg_received_date: date at which the message had to be received
(if this argument != 0000-00-00 => reminder
@param ln: language of the page
@return the message in HTML format
"""
# load the right message language
_ = gettext_set_language(ln)
sent_to_link = ''
tos = msg_sent_to.split(cfg_webmessage_separator)
if (tos):
for to in tos[0:-1]:
to_display = to
if to.isdigit():
(junk, to, to_display) = get_user_info(int(to), ln)
sent_to_link += '<a href="write?msg_to=%s&amp;ln=%s">'% (to, ln)
sent_to_link += '%s</a>%s '% (to_display, cfg_webmessage_separator)
to_display = tos[-1]
to = tos[-1]
if to.isdigit():
(junk, to, to_display) = get_user_info(int(to), ln)
sent_to_link += '<a href="write?msg_to=%s&amp;ln=%s">%s</a>'% (to, ln, to_display)
group_to_link = ""
groups = msg_sent_to_group.split(cfg_webmessage_separator)
if (groups):
for group in groups[0:-1]:
group_to_link += '<a href="write?msg_to_group=%s&amp;ln=%s">'% (group, ln)
group_to_link += '%s</a>%s '% (group, cfg_webmessage_separator)
group_to_link += '<a href="write?msg_to_group=%s&amp;ln=%s">%s</a>'% (groups[-1], ln, groups[-1])
# format the msg so that the '>>' chars give vertical lines
final_body = email_quoted_txt2html(msg_body)
out = """
<table class="mailbox" style="width: 70%%;">
<thead class="mailboxheader">
<tr>
<td class="inboxheader" colspan="2">
<table class="messageheader">
<tr>
<td class="mailboxlabel">%(from_label)s:</td>
<td><a href="write?msg_to=%(from)s&amp;ln=%(ln)s">%(from_display)s</a></td>
</tr>
<tr>
<td class="mailboxlabel">%(subject_label)s:</td>
<td style="width: 100%%;">%(subject)s</td>
</tr>
<tr>
<td class="mailboxlabel">%(sent_label)s:</td>
<td>%(sent_date)s</td>
</tr>"""
if (msg_received_date != datetext_default):
out += """
<tr>
<td class="mailboxlabel">%(received_label)s:</td>
<td>%(received_date)s</td>
</tr>"""
out += """
<tr>
<td class="mailboxlabel">%(sent_to_label)s:</td>
<td>%(sent_to)s</td>
</tr>"""
if (msg_sent_to_group != ""):
out += """
<tr>
<td class="mailboxlabel">%(groups_label)s:</td>
<td>%(sent_to_group)s:</td>
</tr>"""
out += """
</table>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
</tr>
</tfoot>
<tbody class="mailboxbody">
<tr class="mailboxrecord">
<td colspan="2">%(body)s</td>
</tr>
<tr class="mailboxfooter">
<td>
<form name="reply" action="write?msg_reply_id=%(msg_id)s" method="post">
<input class="formbutton" name="reply" value="%(reply_but_label)s" type="submit" />
</form>
</td>
<td>
<form name="deletemsg" action="delete?msgid=%(msg_id)s&amp;ln=%(ln)s" method="post">
<input class="formbutton" name="delete" value="%(delete_but_label)s" type="submit" />
</form>
</td>
</tr>
</tbody>
</table>
"""
if msg_from_nickname:
msg_from_display = msg_from_nickname
else:
msg_from_display = get_user_info(msg_from_id, ln)[2]
msg_from_nickname = msg_from_id
out = out % {'from' : msg_from_nickname,
'from_display': msg_from_display,
'sent_date' : convert_datetext_to_dategui(msg_sent_date, ln),
'received_date': convert_datetext_to_dategui(msg_received_date, ln),
'sent_to': sent_to_link,
'sent_to_group': group_to_link,
'subject' : msg_subject,
'body' : final_body,
'reply_to': msg_from_id,
'msg_id': msg_id,
'ln': ln,
'from_label':_("From"),
'subject_label':_("Subject"),
'sent_label': _("Sent on"),
'received_label':_("Received on"),
'sent_to_label': _("Sent to"),
'groups_label': _("Sent to groups"),
'reply_but_label':_("REPLY"),
'delete_but_label': _("DELETE")}
return indent_text(out, 2)
def tmpl_navtrail(self, ln=cdslang, title=""):
"""
display the navtrail, e.g.:
Your account > Your messages > title
@param title: the last part of the navtrail. Is not a link
@param ln: language
return html formatted navtrail
"""
_ = gettext_set_language(ln)
nav_h1 = '<a class="navtrail" href="%s/youraccount.py/display">%s</a>'
nav_h2 = ""
if (title != ""):
nav_h2 = ' &gt; <a class="navtrail" href="%s/yourmessages.py/display">%s</a>'
nav_h2 = nav_h2 % (weburl, _("Your Messages"))
return nav_h1% (weburl,_("Your Account")) + nav_h2
def tmpl_confirm_delete(self, ln=cdslang):
"""
display a confirm message
@param ln: language
@return html output
"""
_ = gettext_set_language(ln)
out = """
<table class="confirmoperation">
<tr>
<td colspan="2" class="confirmmessage">
%(message)s
</td>
</tr>
<tr>
<td>
<form name="validate" action="delete_all" method="post">
<input type="hidden" name="confirmed" value="1" />
<input type="hidden" name="ln" value="%(ln)s" />
<input type="submit" value="%(yes_label)s" class="formbutton" />
</form>
</td>
<td>
<form name="cancel" action="display" method="post">
<input type="hidden" name="ln" value="%(ln)s" />
<input type="submit" value="%(no_label)s" class="formbutton" />
</form>
</td>
</tr>
</table>"""% {'message': _("Are your sure you want to empty your whole mailbox?"),
'ln':ln,
'yes_label': _("Yes"),
'no_label': _("No")}
return indent_text(out, 2)
def tmpl_infobox(self, infos, ln=cdslang):
"""Display len(infos) information fields
@param infos: list of strings
@param ln=language
@return html output
"""
_ = gettext_set_language(ln)
if not((type(infos) is list) or (type(infos) is tuple)):
infos = [infos]
infobox = ""
for info in infos:
infobox += "<div class=\"infobox\">"
lines = info.split("\n")
for line in lines[0:-1]:
infobox += line + "<br/>\n"
infobox += lines[-1] + "</div><br/>\n"
return infobox
def tmpl_warning(self, warnings, ln=cdslang):
"""
Display len(warnings) warning fields
@param infos: list of strings
@param ln=language
@return html output
"""
if not((type(warnings) is list) or (type(warnings) is tuple)):
warnings = [warnings]
warningbox = ""
if warnings != []:
warningbox = "<div class=\"warningbox\">\n <b>Warning:</b>\n"
for warning in warnings:
lines = warning.split("\n")
warningbox += " <p>"
for line in lines[0:-1]:
warningbox += line + " <br/>\n"
warningbox += lines[-1] + " </p>"
warningbox += "</div><br/>\n"
return warningbox
def tmpl_quota(self, nb_messages=0, ln=cdslang):
"""
Display a quota bar.
@nb_messages: number of messages in inbox.
@ln=language
@return html output
"""
_ = gettext_set_language(ln)
quota = float(cfg_webmessage_max_nb_of_messages)
ratio = float(nb_messages) / quota
out = """
%(quota_label)s<br/>
<div class="quotabox">
<div class="quotabar" style="width:%(width)ipx"></div>
</div>""" %{'quota_label' : _("Quota: %.1f%%")%(ratio * 100.0),
'width' : int(ratio * 200)
}
return out
def tmpl_multiple_select(self, select_name, tuples_list, ln=cdslang):
"""displays a multiple select environment
@param tuples_list: a list of (value, isSelected) tuples
@return HTML output
"""
_ = gettext_set_language(ln)
if not((type(tuples_list) is list) or (type(tuples_list) is tuple)):
tuples_list = [tuples_list]
out = """
<select name="%s" multiple="multiple" style="width:100%%">"""% (select_name)
if len(tuples_list) > 0:
out += ' <option disabled="disabled">%s</option>\n' % _("Please select one or more:")
for (value, is_selected) in tuples_list:
out += ' <option value="%s"'% value
if is_selected:
out += " selected=\"selected\""
out += ">%s</option>\n"% value
out += "</select>\n"
return out
def tmpl_user_or_group_search(self,
tuples_list=[],
search_pattern="",
results_field='none',
ln=cdslang):
"""
Display a box for user searching
@param tuples_list: list of (value, is_selected) tuples
@param search_pattern: text to display in this field
@param results_field: either 'none', 'user', 'group'
@param ln: language
@return html output
"""
_ = gettext_set_language(ln)
multiple_select = ''
add_button = ''
if results_field != 'none' and results_field in ('user', 'group'):
if len(tuples_list):
multiple_select = self.tmpl_multiple_select('names_selected', tuples_list)
add_button = '<input type="submit" name="%s" value="%s" class="nonsubmitbutton" />'
if results_field == 'user':
add_button = add_button % ('add_user', _("Add to users"))
else:
add_button = add_button % ('add_group', _("Add to groups"))
else:
if results_field == 'user':
multiple_select = _("No matching user")
else:
multiple_select = _("No matching group")
out = """
<table class="mailbox">
<thead class="mailboxheader">
<tr class ="inboxheader">
<td colspan="3">
%(title_label)s
<input type="hidden" name="results_field" value="%(results_field)s" />
</td>
</tr>
</thead>
<tbody class="mailboxbody">
<tr class="mailboxsearch">
<td>
<input type="text" name="search_pattern" value="%(search_pattern)s" />
</td>
<td>
<input type="submit" name="search_user" value="%(search_user_label)s" class="nonsubmitbutton" />
</td>
<td>
<input type="submit" name="search_group" value="%(search_group_label)s" class="nonsubmitbutton" />
</td>
</tr>
<tr class="mailboxresults">
<td colspan="2">
%(multiple_select)s
</td>
<td>
%(add_button)s
</td>
</tr>
</tbody>
</table>
"""
out = out% {'title_label' : _("Find users or groups:"),
'search_user_label' : _("Find a user"),
'search_group_label' : _("Find a group"),
'results_field' : results_field,
'search_pattern' : search_pattern,
'multiple_select' : multiple_select,
'add_button' : add_button}
return out
def tmpl_account_new_mail(self, nb_new_mail=0, total_mail=0, ln=cdslang):
"""
display infos about inbox (used by myaccount.py)
@param nb_new_mail: number of new mails
@param ln: language
return: html output.
"""
_ = gettext_set_language(ln)
out = _("You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%i total messages</a>")% (nb_new_mail, weburl, ln, total_mail)
return out
diff --git a/modules/webmessage/web/Makefile.am b/modules/webmessage/web/Makefile.am
index c50fb0aec..536a2217c 100644
--- a/modules/webmessage/web/Makefile.am
+++ b/modules/webmessage/web/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)
webapp_DATA = yourmessages.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/webmessage/web/yourmessages.py b/modules/webmessage/web/yourmessages.py
index 830153207..1a1cffbb3 100644
--- a/modules/webmessage/web/yourmessages.py
+++ b/modules/webmessage/web/yourmessages.py
@@ -1,278 +1,278 @@
# -*- coding: utf-8 -*-
## $Id$
## Messaging system (internal)
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
""" Web interface for WebMessage """
__lastupdated__ = """$Date$"""
# CDSWare imports
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
from cdsware.config import weburl, cdslang
from cdsware.webuser import getUid, isGuestUser, page_not_authorized
from cdsware.webmessage import *
from cdsware.webpage import page
from cdsware.messages import wash_language, gettext_set_language
from cdsware.urlutils import redirect_to_url
### CALLABLE INTERFACE
def index(req):
""" The function called by default
"""
redirect_to_url(req, "%s/yourmessages.py/display?%s" % (weburl, req.args))
def display(req, ln=cdslang):
"""
Displays the Inbox of a given user
@param ln: language
@return the page for inbox
"""
# Check if user is logged
uid = getUid(req)
if uid == -1 or isGuestUser(uid) or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "%s/yourmessages.py/display" % (weburl,))
# wash language argument
ln = wash_language(ln)
_ = gettext_set_language(ln)
(body, errors, warnings) = perform_request_display(uid=uid,
ln=ln)
return page(title = _("Your Messages"),
body = body,
navtrail = get_navtrail(ln),
uid = uid,
lastupdated = __lastupdated__,
req = req,
language = ln,
errors = errors,
warnings = warnings)
def write(req, msg_reply_id="", msg_to="", msg_to_group="", mode_user=1, ln=cdslang):
""" write(): interface for message composing
@param msg_reply_id: if this message is a reply to another, id of the other
@param msg_to: if this message is not a reply, nickname of the user it must be
delivered to.
@param msg_to_group: name of group to send message to
@param ln: language
@return the compose page
"""
# Check if user is logged
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1 or isGuestUser(uid):
return page_not_authorized(req, "%s/yourmessages.py/write" % (weburl,))
# wash language argument
ln = wash_language(ln)
_ = gettext_set_language(ln)
# Request the composing page
(body, errors, warnings) = perform_request_write(uid=uid,
msg_reply_id=msg_reply_id,
msg_to=msg_to,
msg_to_group=msg_to_group,
ln=ln)
title = _("Write a message")
return page(title = title,
body = body,
navtrail = get_navtrail(ln, title),
uid = uid,
lastupdated = __lastupdated__,
req = req,
language = ln,
errors = errors,
warnings = warnings)
def send(req,
msg_to_user="",
msg_to_group="",
msg_subject="",
msg_body="",
msg_send_year="0000",
msg_send_month="00",
msg_send_day="00",
results_field='none',
names_selected=[],
search_pattern="",
send_button="",
search_user="",
search_group="",
add_group="",
add_user="",
ln=cdslang):
"""
Sends the message
@param msg_to_user: comma separated usernames (str)
@param msg_to_group: comma separated groupnames (str)
@param msg_subject: message subject (str)
@param msg_bidy: message body (string)
@param msg_send_year: year to send this message on (int)
@param_msg_send_month: month to send this message on (int)
@param_msg_send_day: day to send this message on (int)
@param names_to_add: list of usernames ['str'] to add to msg_to_user / group
@param search_pattern: will search for users/groups with this pattern (str)
@param add_values: if 1 users_to_add will be added to msg_to_user field..
@param *button: which button was pressed
@param ln: language
@return a (body, errors, warnings) formed tuple.
"""
# Check if user is logged
uid = getUid(req)
if uid == -1 or isGuestUser(uid) or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "%s/yourmessages.py/send" % (weburl,))
# wash language argument
ln = wash_language(ln)
_ = gettext_set_language(ln)
if send_button:
(body, errors, warnings, title, navtrail) = perform_request_send(uid,
msg_to_user,
msg_to_group,
msg_subject,
msg_body,
msg_send_year,
msg_send_month,
msg_send_day,
ln)
else:
title = _('Write a message')
navtrail = get_navtrail(ln, title)
if search_user:
results_field = 'user'
elif search_group:
results_field = 'group'
add_values = 0
if add_group or add_user:
add_values = 1
(body, errors, warnings) = perform_request_write_with_search(msg_to_user,
msg_to_group,
msg_subject,
msg_body,
msg_send_year,
msg_send_month,
msg_send_day,
names_selected,
search_pattern,
results_field,
add_values,
ln=cdslang)
return page(title = title,
body = body,
navtrail = navtrail,
uid = uid,
lastupdated = __lastupdated__,
req = req,
language = ln,
errors = errors,
warnings = warnings)
def delete(req, msgid=-1, ln = cdslang):
"""
Suppress a message
@param msgid: id of message
@param ln: language
@return page
"""
# Check if user is logged
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1 or isGuestUser(uid):
return page_not_authorized(req, "%s/yourmessages.py/delete_msg" % (weburl,))
# wash language argument
ln = wash_language(ln)
_ = gettext_set_language(ln)
# Generate content
(body, errors, warnings) = perform_request_delete_msg(uid, msgid, ln)
return page(title = _("Your Messages"),
body = body,
navtrail = get_navtrail(ln),
uid = uid,
lastupdated = __lastupdated__,
req = req,
language = ln,
errors = errors,
warnings = warnings)
def delete_all(req, confirmed=0, ln=cdslang):
"""
Empty user's inbox
@param confimed: 1 if message is confirmed
@param ln: language
\return page
"""
# Check if user is logged
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1 or isGuestUser(uid):
return page_not_authorized(req, "%s/yourmessages.py/delete_all" % (weburl,))
# wash language argument
ln = wash_language(ln)
_ = gettext_set_language(ln)
# Generate content
(body, errors, warnings) = perform_request_delete_all(uid, confirmed, ln)
return page(title = _("Your Messages"),
body = body,
navtrail = get_navtrail(ln),
uid = uid,
lastupdated = __lastupdated__,
req = req,
language = ln,
errors = errors,
warnings = warnings)
def display_msg(req, msgid=-1, ln=cdslang):
"""
Display a message
@param msgid: id of message
@param ln: languae
@return page
"""
# Check if user is logged
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1 or isGuestUser(uid):
return page_not_authorized(req, "%s/yourmessages.py/display_msg" % (weburl,))
# wash language argument
ln = wash_language(ln)
_ = gettext_set_language(ln)
# Generate content
(body, errors, warnings) = perform_request_display_msg(uid, msgid, ln)
title = _("Read a message")
return page(title = title,
body = body,
navtrail = get_navtrail(ln, title),
uid = uid,
lastupdated = __lastupdated__,
req = req,
language = ln,
errors = errors,
warnings = warnings)
diff --git a/modules/websearch/Makefile.am b/modules/websearch/Makefile.am
index ce16c5c0d..10488862b 100644
--- a/modules/websearch/Makefile.am
+++ b/modules/websearch/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = lib bin doc web
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/websearch/bin/Makefile.am b/modules/websearch/bin/Makefile.am
index 3b186e3d1..26cd0097e 100644
--- a/modules/websearch/bin/Makefile.am
+++ b/modules/websearch/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = webcoll
EXTRA_DIST = webcoll.in
CLEANFILES = *~ *.tmp
diff --git a/modules/websearch/bin/webcoll.in b/modules/websearch/bin/webcoll.in
index 966bdebc7..2ae89697e 100644
--- a/modules/websearch/bin/webcoll.in
+++ b/modules/websearch/bin/webcoll.in
@@ -1,1134 +1,1134 @@
#!@PYTHON@
## -*- mode: python; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Creates CDSware collection specific pages, using WML and MySQL configuration tables."""
__version__ = "$Id$"
## import modules:
try:
import calendar
import copy
import getopt
import getpass
import marshal
import signal
import sys
import cgi
import sre
import os
import math
import string
import urllib
import zlib
import MySQLdb
import Numeric
import time
import traceback
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
try:
from cdsware.config import *
from cdsware.messages import gettext_set_language, language_list_long
from cdsware.search_engine import HitSet, search_pattern, get_creation_date, nice_number, get_field_i18nname
from cdsware.search_engine_config import cfg_author_et_al_threshold, cfg_instant_browse, cfg_max_recID, cfg_narrow_search_show_grandsons
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.bibrank_record_sorter import get_bibrank_methods
import cdsware.template
websearch_templates = cdsware.template.load('websearch')
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
## global vars
collection_house = {} # will hold collections we treat in this run of the program; a dict of {collname2, collobject1}, ...
options = {} # will hold task options
# cfg_cache_last_updated_timestamp_tolerance -- cache timestamp
# tolerance (in seconds), to account for the fact that an admin might
# accidentally happen to edit the collection definitions at exactly
# the same second when some webcoll process was about to be started.
# In order to be safe, let's put an exaggerated timestamp tolerance
# value such as 20 seconds:
cfg_cache_last_updated_timestamp_tolerance = 20
# cfg_cache_last_updated_timestamp_file -- location of the cache
# timestamp file:
cfg_cache_last_updated_timestamp_file = "%s/collections/last_updated" % cachedir
def get_collection(colname):
"""Return collection object from the collection house for given colname.
If does not exist, then create it."""
if not collection_house.has_key(colname):
colobject = Collection(colname)
collection_house[colname] = colobject
return collection_house[colname]
## auxiliary functions:
def mymkdir(newdir, mode=0777):
"""works the way a good mkdir should :)
- already exists, silently complete
- regular file in the way, raise an exception
- parent directory(ies) does not exist, make them as well
"""
if os.path.isdir(newdir):
pass
elif os.path.isfile(newdir):
raise OSError("a file with the same name as the desired " \
"dir, '%s', already exists." % newdir)
else:
head, tail = os.path.split(newdir)
if head and not os.path.isdir(head):
mymkdir(head, mode)
if tail:
os.umask(022)
os.mkdir(newdir, mode)
def escape_string(s):
"Escapes special chars in string. For MySQL queries."
s = MySQLdb.escape_string(s)
return s
def is_selected(var, fld):
"Checks if the two are equal, and if yes, returns ' selected'. Useful for select boxes."
if var == fld:
return " selected"
else:
return ""
def write_message(msg, stream=sys.stdout):
"""Write message and flush output stream (may be sys.stdout or sys.stderr). Useful for debugging stuff."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
return
def get_field(recID, tag):
"Gets list of field 'tag' for the record with 'recID' system number."
out = []
digit = tag[0:2]
bx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag='%s'" \
% (bx, bibx, recID, tag)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def print_record(recID, format='hb', ln=cdslang):
"Prints record 'recID' formatted accoding to 'format'."
out = ""
# HTML brief format by default
query = "SELECT value FROM bibfmt WHERE id_bibrec='%s' AND format='%s'" % (recID, format)
res = run_sql(query, None, 1)
if res:
# record 'recID' is formatted in 'format', so print it
out += "%s" % zlib.decompress(res[0][0])
else:
# record 'recID' does not exist in format 'format', so print some default format:
# firstly, title:
titles = get_field(recID, "245__a")
# secondly, authors:
authors = get_field(recID, "100__a") + get_field(recID, "700__a")
# thirdly, date of creation:
dates = get_field(recID, "260__c")
# thirdly bis, report numbers:
rns = get_field(recID, "037__a") + get_field(recID, "088__a")
# fourthly, beginning of abstract:
abstracts = get_field(recID, "520__a")
# fifthly, fulltext link:
urls_z = get_field(recID, "8564_z")
urls_u = get_field(recID, "8564_u")
out += websearch_templates.tmpl_record_body(
weburl = weburl,
titles = titles,
authors = authors,
dates = dates,
rns = rns,
abstracts = abstracts,
urls_u = urls_u,
urls_z = urls_z
)
# at the end of HTML mode, print "Detailed record" and "Mark record" functions:
out += websearch_templates.tmpl_record_links(
weburl = weburl,
recid = recID,
ln = ln
)
return out
class Collection:
"Holds the information on collections (id,name,dbquery)."
def __init__(self, name=""):
"Creates collection instance by querying the MySQL configuration database about 'name'."
self.calculate_reclist_run_already = 0 # to speed things up wihtout much refactoring
self.update_reclist_run_already = 0 # to speed things up wihtout much refactoring
self.reclist_with_nonpublic_subcolls = HitSet()
if not name:
self.name = cdsname # by default we are working on the home page
self.id = 1
self.dbquery = None
self.nbrecs = None
self.reclist = HitSet()
else:
self.name = name
query = "SELECT id,name,dbquery,nbrecs,reclist FROM collection WHERE name='%s'" % escape_string(name)
try:
res = run_sql(query, None, 1)
if res:
self.id = res[0][0]
self.name = res[0][1]
self.dbquery = res[0][2]
self.nbrecs = res[0][3]
try:
self.reclist = HitSet(Numeric.loads(zlib.decompress(res[0][5])))
except:
self.reclist = HitSet()
else: # collection does not exist!
self.id = None
self.dbquery = None
self.nbrecs = None
self.reclist = HitSet()
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
sys.exit(1)
def get_name(self, ln=cdslang, name_type="ln", prolog="", epilog="", prolog_suffix=" ", epilog_suffix=""):
"""Return nicely formatted collection name for language LN.
The NAME_TYPE may be 'ln' (=long name), 'sn' (=short name), etc."""
out = prolog
i18name = ""
res = run_sql("SELECT value FROM collectionname WHERE id_collection=%s AND ln=%s AND type=%s", (self.id, ln, name_type))
try:
i18name += res[0][0]
except IndexError:
pass
if i18name:
out += i18name
else:
out += self.name
out += epilog
return out
def get_ancestors(self):
"Returns list of ancestors of the current collection."
ancestors = []
id_son = self.id
while 1:
query = "SELECT cc.id_dad,c.name FROM collection_collection AS cc, collection AS c "\
"WHERE cc.id_son=%d AND c.id=cc.id_dad" % int(id_son)
res = run_sql(query, None, 1)
if res:
col_ancestor = get_collection(res[0][1])
ancestors.append(col_ancestor)
id_son = res[0][0]
else:
break
ancestors.reverse()
return ancestors
def restricted_p(self):
"""Predicate to test if the collection is restricted or not. Return the contect of the
`restrited' column of the collection table (typically Apache group). Otherwise return
None if the collection is public."""
out = None
query = "SELECT restricted FROM collection WHERE id=%d" % self.id
res = run_sql(query, None, 1)
try:
out = res[0][0]
except:
pass
return out
def get_sons(self, type='r'):
"Returns list of direct sons of type 'type' for the current collection."
sons = []
id_dad = self.id
query = "SELECT cc.id_son,c.name FROM collection_collection AS cc, collection AS c "\
"WHERE cc.id_dad=%d AND cc.type='%s' AND c.id=cc.id_son ORDER BY score DESC, c.name ASC" % (int(id_dad), type)
res = run_sql(query)
for row in res:
sons.append(get_collection(row[1]))
return sons
def get_descendants(self, type='r'):
"Returns list of all descendants of type 'type' for the current collection."
descendants = []
id_dad = self.id
query = "SELECT cc.id_son,c.name FROM collection_collection AS cc, collection AS c "\
"WHERE cc.id_dad=%d AND cc.type='%s' AND c.id=cc.id_son ORDER BY score DESC" % (int(id_dad), type)
res = run_sql(query)
for row in res:
col_desc = get_collection(row[1])
descendants.append(col_desc)
descendants += col_desc.get_descendants()
return descendants
def write_cache_file(self, filename='', filebody=''):
"Write a file inside collection cache."
# open file:
dirname = "%s/collections/%d" % (cachedir, self.id)
mymkdir(dirname)
fullfilename = dirname + "/%s.html" % filename
try:
os.umask(022)
f = open(fullfilename, "w")
except IOError, v:
try:
(code, message) = v
except:
code = 0
message = v
print "I/O Error: " + str(message) + " (" + str(code) + ")"
sys.exit(1)
# print user info:
if options["verbose"] >= 6:
write_message("... creating %s" % fullfilename)
sys.stdout.flush()
# print page body:
f.write(filebody)
# close file:
f.close()
def update_webpage_cache(self):
"""Create collection page header, navtrail, body (including left and right stripes) and footer, and
call write_cache_file() afterwards to update the collection webpage cache."""
## do this for each language:
for lang, lang_fullname in language_list_long():
# load the right message language
_ = gettext_set_language(lang)
## first, update navtrail:
for as in range(0,2):
self.write_cache_file("navtrail-as=%s-ln=%s" % (as, lang), self.create_navtrail_links(as, lang))
## second, update page body:
for as in range(0,2): # do both simple search and advanced search pages:
body = websearch_templates.tmpl_webcoll_body(
weburl = weburl,
te_portalbox = self.create_portalbox(lang, 'te'),
searchfor = self.create_searchfor(as, lang),
np_portalbox = self.create_portalbox(lang, 'np'),
narrowsearch = self.create_narrowsearch(as, lang, _("Narrow by collection:")),
focuson = self.create_narrowsearch(as, lang, _("Focus on:"), "v"),
ne_portalbox = self.create_portalbox(lang, 'ne')
)
self.write_cache_file("body-as=%s-ln=%s" % (as, lang), body)
## third, write portalboxes:
self.write_cache_file("portalbox-tp-ln=%s" % lang, self.create_portalbox(lang, "tp"))
self.write_cache_file("portalbox-te-ln=%s" % lang, self.create_portalbox(lang, "te"))
self.write_cache_file("portalbox-lt-ln=%s" % lang, self.create_portalbox(lang, "lt"))
self.write_cache_file("portalbox-rt-ln=%s" % lang, self.create_portalbox(lang, "rt"))
## fourth, write 'last updated' information:
self.write_cache_file("last-updated-ln=%s" % lang, time.strftime("%d %b %Y %H:%M:%S %Z", time.localtime()))
return
def create_navtrail_links(self, \
as=0,
ln=cdslang,
separator=" &gt; "):
"""Creates navigation trail links, i.e. links to collection ancestors (except Home collection).
If as==1, then links to Advanced Search interfaces; otherwise Simple Search.
"""
dads = []
for dad in self.get_ancestors():
if dad.name != cdsname: # exclude Home collection
dads.append ((dad.name, dad.get_name(ln)))
return websearch_templates.tmpl_navtrail_links(
as = as,
ln = ln,
weburl = weburl,
separator = separator,
dads = dads)
def create_nbrecs_info(self, ln=cdslang, prolog = None, epilog = None):
"Return information on the number of records."
return websearch_templates.tmpl_nbrecs_info (number = nice_number (self.nbrecs, ln),
prolog = prolog,
epilog = epilog)
def create_portalbox(self, lang=cdslang, position="rt"):
"""Creates portalboxes of language CDSLANG of the position POSITION by consulting MySQL configuration database.
The position may be: 'lt'='left top', 'rt'='right top', etc."""
out = ""
query = "SELECT p.title,p.body FROM portalbox AS p, collection_portalbox AS cp "\
" WHERE cp.id_collection=%d AND p.id=cp.id_portalbox AND cp.ln='%s' AND cp.position='%s' "\
" ORDER BY cp.score DESC" % (self.id, lang, position)
res = run_sql(query)
for row in res:
title, body = row[0], row[1]
if title:
out += websearch_templates.tmpl_portalbox(title = title,
body = body)
else:
# no title specified, so print body ``as is'' only:
out += body
return out
def create_narrowsearch(self, as=0, ln=cdslang, title="Narrow search", type="r"):
"""Creates list of collection descendants of type 'type' under title 'title'.
If as==1, then links to Advanced Search interfaces; otherwise Simple Search.
Suitable for 'Narrow search' and 'Focus on' boxes."""
# get list of sons and analyse it
sons = self.get_sons(type)
# return nothing for type 'v' (virtual collection) if there are no sons:
if type == 'v' and not sons:
return ""
# load instant browse parts, in case no descendants
if not len(sons) and type == 'r':
instant_browse = self.create_instant_browse(ln=ln)
else:
instant_browse = ''
# get descendents
descendants = self.get_descendants(type)
grandsons = []
if cfg_narrow_search_show_grandsons:
# load grandsons for each son
for son in sons:
grandsons.append(son.get_sons())
# return ""
return websearch_templates.tmpl_narrowsearch(
as = as,
ln = ln,
weburl = weburl,
type = type,
father = self,
has_grandchildren = len(descendants)>len(sons),
title = title,
instant_browse = instant_browse,
sons = sons,
display_grandsons = cfg_narrow_search_show_grandsons,
grandsons = grandsons
)
def create_instant_browse(self, rg=cfg_instant_browse, ln=cdslang):
"Searches database and produces list of last 'rg' records."
box = ""
if self.restricted_p():
return websearch_templates.tmpl_box_restricted_content(ln = ln)
else:
url = "%s/search.py?cc=%s&jrec=%d" % (weburl, urllib.quote_plus(self.name), rg+1)
if self.nbrecs and self.reclist:
# firstly, get last 'rg' records:
recIDs = Numeric.nonzero(self.reclist._set)
passIDs = []
for idx in range(self.nbrecs-1, self.nbrecs-rg-1, -1):
if idx>=0:
passIDs.append({'id' : recIDs[idx],
'body' : print_record(recIDs[idx], ln=ln)
})
if not (self.nbrecs > rg):
url = ""
recdates = []
for recid in passIDs:
recid['date'] = get_creation_date(recid['id'], fmt="%Y-%m-%d<br>%H:%i")
return websearch_templates.tmpl_instant_browse(
ln = ln,
recids = passIDs,
more_link = url
)
else:
return websearch_templates.tmpl_box_no_records(ln = ln)
return box
def create_searchoptions(self):
"Produces 'Search options' portal box."
box=""
query = """SELECT DISTINCT(cff.id_field),f.code,f.name FROM collection_field_fieldvalue AS cff, field AS f
WHERE cff.id_collection=%d AND cff.id_fieldvalue IS NOT NULL AND cff.id_field=f.id
ORDER BY cff.score DESC""" % self.id
res = run_sql(query)
if res:
for row in res:
field_id = row[0]
field_code = row[1]
field_name = row[2]
query_bis = """SELECT fv.value,fv.name FROM fieldvalue AS fv, collection_field_fieldvalue AS cff
WHERE cff.id_collection=%d AND cff.type='seo' AND cff.id_field=%d AND fv.id=cff.id_fieldvalue
ORDER BY cff.score_fieldvalue DESC, cff.score DESC, fv.name ASC""" % (self.id, field_id)
res_bis = run_sql(query_bis)
if res_bis:
values = [{'value' : '', 'text' : 'any' + field_name}] # @todo internationalisation of "any"
for row_bis in res_bis:
values.append({'value' : cgi.escape(row_bis[0], 1), 'text' : row_bis[1]})
box += websearch_templates.tmpl_select(
fieldname = field_code,
values = values
)
return box
def create_sortoptions(self, ln=cdslang):
"Produces 'Sort options' portal box."
# load the right message language
_ = gettext_set_language(ln)
box=""
query = """SELECT f.code,f.name FROM field AS f, collection_field_fieldvalue AS cff
WHERE id_collection=%d AND cff.type='soo' AND cff.id_field=f.id
ORDER BY cff.score DESC, f.name ASC""" % self.id
values = [{'value' : '', 'text': "- %s -" % _("latest first")}]
res = run_sql(query)
if res:
for row in res:
values.append({'value' : row[0], 'text': row[1]})
else:
for tmp in ('title', 'author', 'report number', 'year'):
values.append({'value' : tmp.replace(' ', ''), 'text' : get_field_i18nname(tmp, ln)})
box = websearch_templates.tmpl_select(
fieldname = 'sf',
css_class = 'address',
values = values
)
box += websearch_templates.tmpl_select(
fieldname = 'so',
css_class = 'address',
values = [
{'value' : 'a' , 'text' : _("asc.")},
{'value' : 'd' , 'text' : _("desc.")}
]
)
return box
def create_rankoptions(self, ln=cdslang):
"Produces 'Rank options' portal box."
# load the right message language
_ = gettext_set_language(ln)
values = [{'value' : '', 'text': "- %s %s -" % (string.lower(_("OR")), _("rank by"))}]
for (code,name) in get_bibrank_methods(self.id, ln):
values.append({'value' : code, 'text': name})
box = websearch_templates.tmpl_select(
fieldname = 'sf',
css_class = 'address',
values = values
)
return box
def create_displayoptions(self, ln=cdslang):
"Produces 'Display options' portal box."
# load the right message language
_ = gettext_set_language(ln)
values = []
for i in ['10', '25', '50', '100', '250', '500']:
values.append({'value' : i, 'text' : i + ' ' + _("results")})
box = websearch_templates.tmpl_select(
fieldname = 'rg',
css_class = 'address',
values = values
)
if self.get_sons():
box += websearch_templates.tmpl_select(
fieldname = 'sc',
css_class = 'address',
values = [
{'value' : '1' , 'text' : _("split by collection")},
{'value' : '0' , 'text' : _("single list")}
]
)
return box
def create_formatoptions(self, ln=cdslang):
"Produces 'Output format options' portal box."
# load the right message language
_ = gettext_set_language(ln)
box = ""
values = []
query = """SELECT f.code,f.name FROM format AS f, collection_format AS cf
WHERE cf.id_collection=%d AND cf.id_format=f.id ORDER BY cf.score DESC, f.name ASC""" % self.id
res = run_sql(query)
if res:
for row in res:
values.append({'value' : row[0], 'text': row[1]})
else:
values.append({'value' : 'hb', 'text' : "HTML %s" % _("brief")})
box = websearch_templates.tmpl_select(
fieldname = 'of',
css_class = 'address',
values = values
)
return box
def create_searchwithin_selection_box(self, fieldname='f', value='', ln='en'):
"Produces 'search within' selection box for the current collection."
# get values
query = """SELECT f.code,f.name FROM field AS f, collection_field_fieldvalue AS cff
WHERE cff.type='sew' AND cff.id_collection=%d AND cff.id_field=f.id
ORDER BY cff.score DESC, f.name ASC""" % self.id
res = run_sql(query)
values = [{'value' : '', 'text' : get_field_i18nname("any field", ln)}]
if res:
for row in res:
values.append({'value' : row[0], 'text' : row[1]})
else:
if cfg_cern_site:
for tmp in ['title', 'author', 'abstract', 'report number', 'year']:
values.append({'value' : tmp.replace(' ', ''), 'text' : get_field_i18nname(tmp, ln)})
else:
for tmp in ['title', 'author', 'abstract', 'keyword', 'report number', 'year', 'fulltext', 'reference']:
values.append({'value' : tmp.replace(' ', ''), 'text' : get_field_i18nname(tmp, ln)})
return websearch_templates.tmpl_searchwithin_select(
fieldname = fieldname,
ln = ln,
selected = value,
values = values
)
def create_searchexample(self):
"Produces search example(s) for the current collection."
out = "$collSearchExamples = getSearchExample(%d, $se);" % self.id
return out
def create_searchfor(self, as=0, ln=cdslang):
"Produces either Simple or Advanced 'Search for' box for the current collection."
if as == 1:
return self.create_searchfor_advanced(ln)
else:
return self.create_searchfor_simple(ln)
def create_searchfor_simple(self, ln=cdslang):
"Produces simple 'Search for' box for the current collection."
# load the right message language
_ = gettext_set_language(ln)
if self.name != cdsname:
ssearchurl = "?c=%s&amp;as=0&amp;ln=%s" % (urllib.quote_plus(self.name), ln)
asearchurl = "?c=%s&amp;as=1&amp;ln=%s" % (urllib.quote_plus(self.name), ln)
else: # hide cdsname for aesthetical reasons
ssearchurl = "?as=0&amp;ln=%s" % ln
asearchurl = "?as=1&amp;ln=%s" % ln
return websearch_templates.tmpl_searchfor_simple(
ln = ln,
weburl = weburl,
asearchurl = asearchurl,
header = _("Search %s records for:") % self.create_nbrecs_info(ln, "",""),
middle_option = self.create_searchwithin_selection_box(ln=ln),
)
def create_searchfor_advanced(self, ln=cdslang):
"Produces advanced 'Search for' box for the current collection."
# load the right message language
_ = gettext_set_language(ln)
if self.name != cdsname:
ssearchurl = "?c=%s&amp;as=0&amp;ln=%s" % (urllib.quote_plus(self.name), ln)
asearchurl = "?c=%s&amp;as=1&amp;ln=%s" % (urllib.quote_plus(self.name), ln)
else: # hide cdsname for aesthetical reasons
ssearchurl = "?as=0&amp;ln=%s" % ln
asearchurl = "?as=1&amp;ln=%s" % ln
return websearch_templates.tmpl_searchfor_advanced(
ln = ln,
weburl = weburl,
ssearchurl = ssearchurl,
header = _("Search %s records for:") % self.create_nbrecs_info(ln, "",""),
middle_option_1 = self.create_searchwithin_selection_box('f1', ln=ln),
middle_option_2 = self.create_searchwithin_selection_box('f2', ln=ln),
middle_option_3 = self.create_searchwithin_selection_box('f3', ln=ln),
searchoptions = self.create_searchoptions(),
sortoptions = self.create_sortoptions(ln),
rankoptions = self.create_rankoptions(ln),
displayoptions = self.create_displayoptions(ln),
formatoptions = self.create_formatoptions(ln)
)
def calculate_reclist(self):
"""Calculate, set and return the (reclist, reclist_with_nonpublic_subcolls) tuple for given collection."""
if self.calculate_reclist_run_already:
# do we have to recalculate?
return (self.reclist, self.reclist_with_nonpublic_subcolls)
if options["verbose"] >= 6:
write_message("... calculating reclist of %s" % self.name)
reclist = HitSet() # will hold results for public sons only; good for storing into DB
reclist_with_nonpublic_subcolls = HitSet() # will hold results for both public and nonpublic sons; good for deducing total
# number of documents
if not self.dbquery:
# A - collection does not have dbquery, so query recursively all its sons
# that are either non-restricted or that have the same restriction rules
for coll in self.get_sons():
coll_reclist, coll_reclist_with_nonpublic_subcolls = coll.calculate_reclist()
if ((coll.restricted_p() is None) or
(coll.restricted_p() == self.restricted_p())):
# add this reclist ``for real'' only if it is public
reclist.union(coll_reclist)
reclist_with_nonpublic_subcolls.union(coll_reclist_with_nonpublic_subcolls)
else:
# B - collection does have dbquery, so compute it:
reclist = search_pattern(None,self.dbquery)
reclist_with_nonpublic_subcolls = copy.deepcopy(reclist)
# deduce the number of records:
reclist.calculate_nbhits()
reclist_with_nonpublic_subcolls.calculate_nbhits()
# store the results:
self.nbrecs = reclist_with_nonpublic_subcolls._nbhits
self.reclist = reclist
self.reclist_with_nonpublic_subcolls = reclist_with_nonpublic_subcolls
# last but not least, update the speed-up flag:
self.calculate_reclist_run_already = 1
# return the two sets:
return (self.reclist, self.reclist_with_nonpublic_subcolls)
def update_reclist(self):
"Update the record universe for given collection; nbrecs, reclist of the collection table."
if self.update_reclist_run_already:
# do we have to reupdate?
return 0
if options["verbose"] >= 6:
write_message("... updating reclist of %s (%s recs)" % (self.name, self.nbrecs))
sys.stdout.flush()
try:
query = "UPDATE collection SET nbrecs=%d, reclist='%s' WHERE id=%d" % \
(self.nbrecs, escape_string(zlib.compress(Numeric.dumps(self.reclist._set))), self.id)
res = run_sql(query)
self.reclist_updated_since_start = 1
except MySQLdb.Error, e:
print "Database Query Error %d: %s." % (e.args[0], e.args[1])
sys.exit(1)
# last but not least, update the speed-up flag:
self.update_reclist_run_already = 1
return 0
def get_datetime(var, format_string="%Y-%m-%d %H:%M:%S"):
"""Returns a date string according to the format string.
It can handle normal date strings and shifts with respect
to now."""
date = time.time()
shift_re=sre.compile("([-\+]{0,1})([\d]+)([dhms])")
factors = {"d":24*3600, "h":3600, "m":60, "s":1}
m = shift_re.match(var)
if m:
sign = m.groups()[0] == "-" and -1 or 1
factor = factors[m.groups()[2]]
value = float(m.groups()[1])
date = time.localtime(date + sign * factor * value)
date = time.strftime(format_string, date)
else:
date = time.strptime(var, format_string)
date = time.strftime(format_string, date)
return date
def get_current_time_timestamp():
"""Return timestamp corresponding to the current time."""
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
def compare_timestamps_with_tolerance(timestamp1,
timestamp2,
tolerance=0):
"""Compare two timestamps TIMESTAMP1 and TIMESTAMP2, of the form
'2005-03-31 17:37:26'. Optionally receives a TOLERANCE argument
(in seconds). Return -1 if TIMESTAMP1 is less than TIMESTAMP2
minus TOLERANCE, 0 if they are equal within TOLERANCE limit,
and 1 if TIMESTAMP1 is greater than TIMESTAMP2 plus TOLERANCE.
"""
# remove any trailing .00 in timestamps:
timestamp1 = sre.sub(r'\.[0-9]+$', '', timestamp1)
timestamp2 = sre.sub(r'\.[0-9]+$', '', timestamp2)
# first convert timestamps to Unix epoch seconds:
timestamp1_seconds = calendar.timegm(time.strptime(timestamp1, "%Y-%m-%d %H:%M:%S"))
timestamp2_seconds = calendar.timegm(time.strptime(timestamp2, "%Y-%m-%d %H:%M:%S"))
# now compare them:
if timestamp1_seconds < timestamp2_seconds - tolerance:
return -1
elif timestamp1_seconds > timestamp2_seconds + tolerance:
return 1
else:
return 0
def get_database_last_updated_timestamp():
"""Return last updated timestamp for collection-related and
record-related database tables.
"""
database_tables_timestamps = []
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'bibrec'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'bibfmt'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'idxWORD%%'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'collection%%'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'portalbox'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'field%%'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'format%%'")))
database_tables_timestamps.extend(map(lambda x: str(x[11]), run_sql("SHOW TABLE STATUS LIKE 'rnkMETHODNAME'")))
return max(database_tables_timestamps)
def get_cache_last_updated_timestamp():
"""Return last updated cache timestamp."""
try:
f = open(cfg_cache_last_updated_timestamp_file, "r")
except:
return "1970-01-01 00:00:00"
timestamp = f.read()
f.close()
return timestamp
def set_cache_last_updated_timestamp(timestamp):
"""Set last updated cache timestamp to TIMESTAMP."""
try:
f = open(cfg_cache_last_updated_timestamp_file, "w")
except:
pass
f.write(timestamp)
f.close()
return timestamp
def write_message(msg, stream=sys.stdout):
"""Prints message and flush output stream (may be sys.stdout or sys.stderr)."""
if stream == sys.stdout or stream == sys.stderr:
stream.write(time.strftime("%Y-%m-%d %H:%M:%S --> ", time.localtime()))
stream.write("%s\n" % msg)
stream.flush()
else:
sys.stderr.write("Unknown stream %s. [must be sys.stdout or sys.stderr]\n" % stream)
def task_sig_sleep(sig, frame):
"""Signal handler for the 'sleep' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("sleeping...")
task_update_status("SLEEPING")
signal.pause() # wait for wake-up signal
def task_sig_wakeup(sig, frame):
"""Signal handler for the 'wakeup' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("continuing...")
task_update_status("CONTINUING")
def task_sig_stop(sig, frame):
"""Signal handler for the 'stop' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("stopping...")
task_update_status("STOPPING")
pass # FIXME: is there anything to be done?
task_update_status("STOPPED")
sys.exit(0)
def task_sig_suicide(sig, frame):
"""Signal handler for the 'suicide' signal sent by BibSched."""
if options["verbose"] >= 9:
write_message("got signal %d" % sig)
write_message("suiciding myself now...")
task_update_status("SUICIDING")
write_message("suicided")
task_update_status("SUICIDED")
sys.exit(0)
def task_sig_unknown(sig, frame):
"""Signal handler for the other unknown signals sent by shell or user."""
write_message("unknown signal %d ignored" % sig) # do nothing for other signals
def authenticate(user, header="WebColl Task Submission", action="runwebcoll"):
"""Authenticate the user against the user database.
Check for its password, if it exists.
Check for action access rights.
Return user name upon authorization success,
do system exit upon authorization failure.
"""
print header
print "=" * len(header)
if user == "":
print >> sys.stdout, "\rUsername: ",
user = string.strip(string.lower(sys.stdin.readline()))
else:
print >> sys.stdout, "\rUsername: ", user
## first check user pw:
res = run_sql("select id,password from user where email=%s", (user,), 1)
if not res:
print "Sorry, %s does not exist." % user
sys.exit(1)
else:
(uid_db, password_db) = res[0]
if password_db:
password_entered = getpass.getpass()
if password_db == password_entered:
pass
else:
print "Sorry, wrong credentials for %s." % user
sys.exit(1)
## secondly check authorization for the action:
(auth_code, auth_message) = acc_authorize_action(uid_db, action)
if auth_code != 0:
print auth_message
sys.exit(1)
return user
def task_submit(options):
"""Submits task to the BibSched task queue. This is what people will be invoking via command line."""
## sanity check: remove eventual "task" option:
if options.has_key("task"):
del options["task"]
## authenticate user:
user = authenticate(options.get("user", ""))
## submit task:
if options["verbose"] >= 9:
print ""
write_message("storing task options %s\n" % options)
task_id = run_sql("""INSERT INTO schTASK (id,proc,user,runtime,sleeptime,status,arguments)
VALUES (NULL,'webcoll',%s,%s,%s,'WAITING',%s)""",
(user, options["runtime"], options["sleeptime"], marshal.dumps(options)))
## update task number:
options["task"] = task_id
run_sql("""UPDATE schTASK SET arguments=%s WHERE id=%s""", (marshal.dumps(options),task_id))
write_message("Task #%d submitted." % task_id)
return task_id
def task_update_progress(msg):
"""Updates progress information in the BibSched task table."""
global task_id
return run_sql("UPDATE schTASK SET progress=%s where id=%s", (msg, task_id))
def task_update_status(val):
"""Updates status information in the BibSched task table."""
global task_id
return run_sql("UPDATE schTASK SET status=%s where id=%s", (val, task_id))
def task_read_status(task_id):
"""Read status information in the BibSched task table."""
res = run_sql("SELECT status FROM schTASK where id=%s", (task_id,), 1)
try:
out = res[0][0]
except:
out = 'UNKNOWN'
return out
def task_get_options(id):
"""Returns options for the task 'id' read from the BibSched task queue table."""
out = {}
res = run_sql("SELECT arguments FROM schTASK WHERE id=%s AND proc='webcoll'", (id,))
try:
out = marshal.loads(res[0][0])
except:
write_message("Error: WebColl task %d does not seem to exist." % id)
sys.exit(1)
return out
def task_run():
"""Run the WebColl task by fetching arguments from the BibSched task queue.
This is what BibSched will be invoking via daemon call.
The task will update collection reclist cache and collection web pages for
given collection. (default is all).
Arguments described in usage() function.
Return 1 in case of success and 0 in case of failure."""
global task_id, options
task_run_start_timestamp = get_current_time_timestamp()
options = task_get_options(task_id) # get options from BibSched task table
## check task id:
if not options.has_key("task"):
write_message("Error: The task #%d does not seem to be a WebColl task." % task_id)
return 0
## check task status:
task_status = task_read_status(task_id)
if task_status != "WAITING":
write_message("Error: The task #%d is %s. I expected WAITING." % (task_id, task_status))
return 0
## we can run the task now:
if options["verbose"]:
write_message("Task #%d started." % task_id)
task_update_status("RUNNING")
## initialize signal handler:
signal.signal(signal.SIGUSR1, task_sig_sleep)
signal.signal(signal.SIGTERM, task_sig_stop)
signal.signal(signal.SIGABRT, task_sig_suicide)
signal.signal(signal.SIGCONT, task_sig_wakeup)
signal.signal(signal.SIGINT, task_sig_unknown)
colls = []
# decide whether we need to run or not, by comparing last updated timestamps:
if options["verbose"] >= 3:
write_message("Database timestamp is %s." % get_database_last_updated_timestamp())
write_message("Collection cache timestamp is %s." % get_cache_last_updated_timestamp())
if options.has_key("force") or \
compare_timestamps_with_tolerance(get_database_last_updated_timestamp(),
get_cache_last_updated_timestamp(),
cfg_cache_last_updated_timestamp_tolerance) >= 0:
## either forced update was requested or cache is not up to date, so recreate it:
# firstly, decide which collections to do:
if options.has_key("collection"):
coll = get_collection(options["collection"])
if coll.id == None:
usage(1, 'Collection %s does not exist' % coll.name)
colls.append(coll)
else:
res = run_sql("SELECT name FROM collection ORDER BY id")
for row in res:
colls.append(get_collection(row[0]))
# secondly, update collection reclist cache:
i = 0
for coll in colls:
i += 1
if options["verbose"]:
write_message("%s / reclist cache update" % coll.name)
coll.calculate_reclist()
coll.update_reclist()
task_update_progress("Part 1/2: done %d/%d" % (i,len(colls)))
# thirdly, update collection webpage cache:
i = 0
for coll in colls:
i += 1
if options["verbose"]:
write_message("%s / web cache update" % coll.name)
coll.update_webpage_cache()
task_update_progress("Part 2/2: done %d/%d" % (i,len(colls)))
# finally update the cache last updated timestamp:
# (but only when all collections were updated, not when only
# some of them were forced-updated as per admin's demand)
if not options.has_key("collection"):
set_cache_last_updated_timestamp(task_run_start_timestamp)
if options["verbose"] >= 3:
write_message("Collection cache timestamp is set to %s." % get_cache_last_updated_timestamp())
else:
## cache up to date, we don't have to run
if options["verbose"]:
write_message("Collection cache is up to date, no need to run.")
pass
## we are done:
task_update_progress("Done.")
task_update_status("DONE")
if options["verbose"]:
write_message("Task #%d finished." % task_id)
return 1
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write("Command options:\n")
sys.stderr.write(" -c, --collection\t Update cache for the given collection only. [all]\n")
sys.stderr.write(" -f, --force\t Force update even if cache is up to date. [no]\n")
sys.stderr.write("Scheduling options:\n")
sys.stderr.write(" -u, --user=USER \t User name to submit the task as, password needed.\n")
sys.stderr.write(" -t, --runtime=TIME \t Time to execute the task (now), e.g.: +15s, 5m, 3h, 2002-10-27 13:57:26\n")
sys.stderr.write(" -s, --sleeptime=SLEEP \t Sleeping frequency after which to repeat task (no), e.g.: 30m, 2h, 1d\n")
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.stderr.write(" -v, --verbose=LEVEL \t Verbose level (from 0 to 9, default 1).\n")
sys.stderr.write("""Description: %s updates the collection cache
(record universe for a given collection plus web page elements)
based on WML and MySQL configuration parameters.
If the collection name is passed as the second argument, it'll update
this collection only. If the collection name is immediately followed
by a plus sign, it will also update all its desdendants. The
top-level collection name may be entered as the void string.\n""" % sys.argv[0])
sys.exit(exitcode)
def main():
"""Main function that analyzes command line input and calls whatever is appropriate.
Useful for learning on how to write BibSched tasks."""
global task_id
## parse command line:
if len(sys.argv) == 2 and sys.argv[1].isdigit():
## A - run the task
task_id = int(sys.argv[1])
try:
if not task_run():
write_message("Error occurred. Exiting.", sys.stderr)
except StandardError, e:
write_message("Unexpected error occurred: %s." % e, sys.stderr)
write_message("Traceback is:", sys.stderr)
traceback.print_tb(sys.exc_info()[2])
write_message("Exiting.", sys.stderr)
task_update_status("ERROR")
else:
## B - submit the task
# set default values:
options["runtime"] = time.strftime("%Y-%m-%d %H:%M:%S")
options["verbose"] = 1
options["sleeptime"] = ""
# set user-defined options:
try:
opts, args = getopt.getopt(sys.argv[1:], "hVv:u:s:t:c:f",
["help", "version", "verbose=","user=","sleep=","time=","collection=","force"])
except getopt.GetoptError, err:
usage(1, err)
try:
for opt in opts:
if opt[0] in ["-h", "--help"]:
usage(0)
elif opt[0] in ["-V", "--version"]:
print __version__
sys.exit(0)
elif opt[0] in [ "-u", "--user"]:
options["user"] = opt[1]
elif opt[0] in ["-v", "--verbose"]:
options["verbose"] = int(opt[1])
elif opt[0] in [ "-s", "--sleeptime" ]:
get_datetime(opt[1]) # see if it is a valid shift
options["sleeptime"] = opt[1]
elif opt[0] in [ "-t", "--runtime" ]:
options["runtime"] = get_datetime(opt[1])
elif opt[0] in [ "-c", "--collection"]:
options["collection"] = opt[1]
elif opt[0] in [ "-f", "--force"]:
options["force"] = 1
else:
usage(1)
except StandardError, e:
usage(e)
task_submit(options)
return
### okay, here we go:
if __name__ == '__main__':
main()
diff --git a/modules/websearch/doc/Makefile.am b/modules/websearch/doc/Makefile.am
index 4e733fc60..039dce4c1 100644
--- a/modules/websearch/doc/Makefile.am
+++ b/modules/websearch/doc/Makefile.am
@@ -1,56 +1,56 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
docdir = $(WEBDIR)/help/search
doc_DATA=index.en.html index.fr.html index.de.html index.es.html index.ca.html index.pl.html index.pt.html index.it.html index.ja.html index.ru.html index.sk.html index.cs.html index.no.html index.sv.html index.el.html index.uk.html \
tips.en.html tips.fr.html tips.de.html tips.pl.html tips.pt.html tips.es.html tips.ca.html tips.it.html tips.ja.html tips.ru.html tips.sk.html tips.cs.html tips.no.html tips.sv.html tips.el.html tips.uk.html \
guide.en.html guide.fr.html guide.de.html guide.pl.html guide.pt.html guide.es.html guide.ca.html guide.it.html guide.ja.html guide.ru.html guide.sk.html guide.cs.html guide.no.html guide.sv.html guide.el.html guide.uk.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.en.html %.fr.html %.de.html %.es.html %.ca.html %.pl.html %.pt.html %.it.html %.ja.html %.ru.html %.sk.html %.cs.html %.no.html %.sv.html %.el.html %.uk.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(MO)
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$*.en.html \
-o\(ALL-LANG_*\)+LANG_FR:$*.fr.html \
-o\(ALL-LANG_*\)+LANG_DE:$*.de.html \
-o\(ALL-LANG_*\)+LANG_ES:$*.es.html \
-o\(ALL-LANG_*\)+LANG_CA:$*.ca.html \
-o\(ALL-LANG_*\)+LANG_PT:$*.pt.html \
-o\(ALL-LANG_*\)+LANG_PL:$*.pl.html \
-o\(ALL-LANG_*\)+LANG_IT:$*.it.html \
-o\(ALL-LANG_*\)+LANG_JA:$*.ja.html \
-o\(ALL-LANG_*\)+LANG_RU:$*.ru.html \
-o\(ALL-LANG_*\)+LANG_SK:$*.sk.html \
-o\(ALL-LANG_*\)+LANG_CS:$*.cs.html \
-o\(ALL-LANG_*\)+LANG_NO:$*.no.html \
-o\(ALL-LANG_*\)+LANG_SV:$*.sv.html \
-o\(ALL-LANG_*\)+LANG_EL:$*.el.html \
-o\(ALL-LANG_*\)+LANG_UK:$*.uk.html $<
for lang in $(LINGUAS); do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.$${lang}.html" ; \
done
diff --git a/modules/websearch/doc/admin/Makefile.am b/modules/websearch/doc/admin/Makefile.am
index 56412c259..909370950 100644
--- a/modules/websearch/doc/admin/Makefile.am
+++ b/modules/websearch/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/websearch
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/websearch/doc/admin/guide.html.wml b/modules/websearch/doc/admin/guide.html.wml
index 38137989a..c8b88f44d 100644
--- a/modules/websearch/doc/admin/guide.html.wml
+++ b/modules/websearch/doc/admin/guide.html.wml
@@ -1,539 +1,539 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebSearch Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websearch/>WebSearch Admin</a>" \
navbar_name="admin" \
navbar_select="websearch-admin-guide"
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
WARNING: THIS ADMIN GUIDE IS NOT FULLY COMPLETED
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
This Admin Guide is not yet completed. Moreover, some
admin-level functionality for this module exists only in the form of
manual recipes. We are in the process of developing both the
guide as well as the web admin interface. If you are interested
in seeing some specific things implemented with high priority,
please contact us at <SUPPORTEMAIL>. Thanks for your interest!
</td>
</tr>
</tbody>
</table>
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Contents</h2>
<strong>1. <a href="#1">Overview</a></strong><br>
<strong>2. <a href="#2">Edit Collection Tree</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1 <a href="#2.1">Add new collection</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 <a href="#2.2">Add collection to tree</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3 <a href="#2.3">Modify existing tree</a><br>
<strong>3. <a href="#3">Edit Collection Parameters</a></strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.1. <a href="#3.1">Modify collection query</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.2. <a href="#3.2">Modify access restrictions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.3. <a href="#3.3">Modify translations</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.4. <a href="#3.4">Delete collection</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.5. <a href="#3.5">Modify portalboxes</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.6. <a href="#3.6">Modify search fields</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.7. <a href="#3.7">Modify search options</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.8. <a href="#3.8">Modify sort options</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.9. <a href="#3.9">Modify rank options</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.10.<a href="#3.10">Modify output formats</a><br>
<strong>4. <a href="#4">Webcoll Status</a></strong><br>
<strong>5. <a href="#5">Collections Status</a></strong><br>
<strong>6. <a href="#6">Edit Search Engine Parameters</a></strong><br>
<strong>7. <a href="#7">Search Engine Cache</a></strong><br>
<strong>8. <a href="#8">Additional Information</a></strong><br>
<a name="1"></a><h2>1. Overview</h2>
<p>WebSearch Admin interface will help you to configure the search
collections that the end-users see. The WebSearch Admin functionality
can be basically separated into several parts: (i) how to organize
collections into <a href="#2">collection tree</a>; (ii) how to define
and edit <a href="#3">collection parameters</a>; (iii) how to update
collection cache via the <a href="#4">webcoll daemon</a>; and (iv) how
to influence the search engine behaviour and set various <a
href="#5">search engine parameters</a>. These issues will be
subsequently described in the rest of this guide.
<a name="2"></a><h2>2. Edit Collection Tree</h2>
<p>Metadata corpus in CDSware is organized into collections. The
collections are organized in a tree. The collection tree is what the
end-users see when they start to navigate at <a
href="<WEBURL>"><CDSNAME></a>. The collection tree is similar to what
other sites call Web Directories that organize Web into topical
categories, such as <a href="http://www.google.com/dirhp">Google
Directory</a>.
<p>Note that CDSware permits every collection in the tree to have
either "regular" or "virtual" sons. In other words, every node in the
collection tree may see either regular or virtual branches growing out
of it. This permits to create a tree with very complex, multi-level,
nested structures of regular and virtual branches, if needed, with the
aim to ease navigation to end-users from one branch to another. The
difference between a regular and a virtual branch will be explained in
detail further below in the <a href="#2.2">section 2.2</a>.
<a name="2.1"></a><h3>2.1 Add new collection</h3>
<p>To add a new collection, enter its default name in the default
language of the installation (<CDSLANG>) and click on the ADD button
to add it. There are two important actions that you have to perform
after adding a collection:
<ul>
<li>You have to define the set of records that belong to this
collection. This is done by defining a search engine query
that would return all records belonging to this collection.
See hints on <a href="#3.1">modify collection query</a> below.
<li>In order for the collection to appear in the collection
navigation tree, you will have to attach it to some existing
collection in the tree. See hints on <a href="#2.2">add
collection to tree</a> below.
</ul>
<p>After you edit these two things, the collection is fully usable for
the search interface. It will appear in the search interface after
the next run of the <a href="#4">WebColl Daemon</a>.
<p>However, you will probably want to customize further things, like
define collection name translation in various languages, define
collection web page portalboxes, define search options, etc, as
explained in this guide under the section <a href="#3">Edit
Collection Parameters</a>.
<a name="2.2"></a><h3>2.2 Add collection to tree</h3>
<p>To attach a collection to the tree, choose first which collection
do you want to attach, then choose the father collection to attach to,
and then choose the fathership relation type between them (regular,
virtual).
<p>The difference between the regular and the virtual relationship
goes as follows:
<ul>
<li><strong>regular relationship</strong>: If collection A is
composed of B and C, in a way that every document belonging to
A is either B or C, then this schema corresponds to the
regular type of relationship. For example, let A equals to
"Multimedia" and B and C to "Photos" and "Videos",
respectively. The latter collections would then be declared
as regular sons of "Multimedia" and they would appear in the
left-hand-side regular navigation tree entitled "Narrow by
Collection" in the collection tree.
<li><strong>virtual relationship</strong>: In addition to the
regular decomposition of "Multimedia" into "Photos" and
"Videos", it may be advantageous to present a different,
orthogonal point of view on "Multimedia", based not on the
document type as seen above, but rather on the document
creator information. Let us consider that some (large) part
of the multimedia material was created by the "University
Multimedia Service" and some (small) part by an external TV
company such as BBC. It may be advantageous to advertize this
point of view to the end users too, so they they would be able
to easily navigate down to the kind of multimedia material
they are looking for. We can create two more collections
named "University Multimedia Service" and "BBC Pictures and
Videos" and declare them as virtual sons of the "Multimedia"
collection. These collections would then appear in the
right-hand-side virtual navigation tree entitled "Focus on" in
the collection tree.
</ul>
The example presented above would then give us the following picture:
<blockquote>
<pre>
M u l t i m e d i a
Narrow by Collection: Focus on:
-------------------- ---------
[ ] Photos University Multimedia Service
[ ] Videos BBC Pictures and Videos
</pre>
</blockquote>
<p>It is important to note that if a collection A is composed of B and
C as its regular sons, and offers X and Y as its virtual sons, then
every document belonging to A must also belong to either B or C. This
requirement does not apply for X and Y, because X and Y offer only a
"focus-on" orthogonal view on a (possibly small) part of the document
corpus of A. If end-users search the collection A, then they are
actually searching inside B and C, not X and Y. If they want to
search inside X or Y, they have to click upon X or Y first. One can
consider virtual branches as a sort of non-essential searching aid to
the end-user that is activated only when users are interested in a
particular "focus-on" relationship, provided that this "virtual" point
of view on A interests her.
<a name="2.3"></a><h3>2.3 Modify existing tree</h3>
<p>To modify existing tree by WebSearch Admin Interface, click on
icons displayed next to collections. The meaning of icons is as
follows:
<table border="1">
<tr>
<td>
<img border="0" src="<weburl>/img/iconcross.gif">
</td>
<td>
Remove chosen collection with its subcollections from the collection tree,
but do not delete the collection itself.
(For full deletion of a collection, see <a href="#3.4">section 3.4</a>.)
</td>
</tr>
<tr>
<td>
<img border="0" src="<weburl>/img/arrow_up.gif"> &nbsp;
<img border="0" src="<weburl>/img/arrow_down.gif">
</td>
<td>
Move chosen collection up or down among its brothers and sisters, i.e.
change the order of collections inside the same level of the tree.
</td>
</tr>
<tr>
<td>
<img border="0" src="<weburl>/img/move_from.gif">
<img border="0" src="<weburl>/img/move_to.gif">
</td>
<td>
Move chosen collection among branches of the tree.
Press the first icon (<img border="0" src="<weburl>/img/move_from.gif">)
to choose a collection to move, and the second icon
(<img border="0" src="<weburl>/img/move_to.gif">)
to select a new father collection that the chosen collection should be attached to.
</td>
</tr>
</table>
<a name="3"></a><h2>3. Edit Collection Parameters</h2>
<p>To finalize setting up of a collection, you could and should edit
many parameters, such as define list of records belonging to a
collection, define search fields, define search interface page
portalboxes, etc. In this section we will subsequently describe all
the various possibilities as they are presented in the <a
href="<WEBURL>/admin/websearch/websearchadmin.py/editcollection?colID=1">Edit
Collection</a> pages of the WebSearch Admin Interface.
<a name="3.1"></a><h3>3.1 Modify collection query</h3>
<p>The <em>collection query</em> defines which documents belong to the
given collection. It is equal to the search term that retrieves all
documents belonging to the given collection, exactly as you would have
typed it into the search interface. For example, to define a
collection of all papers written by Ellis, you could set up your
collection query to be <code>author:Ellis</code>.
<p>Usually, the collection query is chosen on the basis of the
collection identifier that we store in MARC tag 980. This tag is
indexed in a logical field called <code>collection</code> so that a
collection of Theses could be defined via
<code>collection:THESIS</code>, supposing that every thesis metadata
record has got the text <code>THESIS</code> in MARC tag 980.
(Nitpick: we use the term `collection' in two contexts here: once as a
collection of metadata documents, but also and as a logical field
name. We should have probably called the latter
<code>collectionidentifier</code> or somesuch instead, but we hope the
difference is clear from... the context.)
<p>If a collection does not have any collection query defined, then
its content is defined by means of the content of its descendants
(subcollections). This is the case for composed collections. For
example, the composed collection <em>Articles & Preprints</em> (no
query defined) will be defined as a father of <em>Articles</em>
(query: <code>collection:ARTICLE</code>) and <em>Preprints</em>
(query: <code>collection:PREPRINT</code>). In this case the
collection query for <em>Articles & Preprints</em> can stay empty.
<p>Note that you should avoid defining non-empty collection query in
cases the collection has descendants, since it will prevail and the
descendants may not be taken into account. In the same way, if a
collection doesn't have any query nor any descendants defined, then
its contents will be empty.
<p>To remove the collection query, set the parameter empty.
<a name="3.2"></a><h3>3.2 Modify access restrictions</h3>
<p>If there is a need to restrict access to certain collections, you
can configure which Apache group the access should be granted to.
Users will then be prompted to enter Apache user and password. The
search engine will check whether user has entered appropriate
credentials and whether the user belongs to the Apache group that can
access this restricted collection.
<p>So, from the admin point of view, you should set up corresponding
Apache user and group files, and you should have specified their
location in the appropriate section of CDSware <code>config.wml</code>
file during CDSware compilation.
<p>(Note that in the future we may use CDSware user identities in
order to avoid the Apache way of authentication.)
<p>To remove any access restrictions, set the parameter empty.
<a name="3.3"></a><h3>3.3 Modify translations</h3>
<p>You may define translations of collection names into the languages
of your CDSware installation. Moreover, a collection name may be
different in different contexts (e.g. long name, short name, etc), so
that prior to modifying translations you will be asked to select which
name type you want to change.
<p>The translations aren't mandatory to define. If a translation does
not exist in a language chosen by the end user, the end user will be
shown the collection name in the default language of this
installation.
<p>Note also that the list of available languages depends on the
compile-time configuration (see the general <code>config.wml</code>
file).
<a name="3.4"></a><h3>3.4 Delete collection</h3>
<p>The collection to be deleted must be first removed from the
collection tree. Any metametadata associated with the collection
(such as association to portalboxes, association to records belonging
to this collection, etc) will be lost, but the metadata itself will be
preserved (such as portalboxes themselves, records themselves, etc).
In total, association to records, output formats, translations, search
options, sort options, search fields, ranking method, and access
restriction will be lost. Use with care!
<p>It may be a good idea only to remove the collection from the end
users interface, but to keep it "hidden" in a corner they don't see
and that they can't search when they search from Home. To achieve
this, do not delete the collection but simply remove it from the
collection tree so that it won't be attached to any father collection.
In this case the search interface page for this collection will stay
updated, but won't be neither shown in the tree nor searchable from
Home page. It will only be accessible via bookmarked URL, for
example.
<a name="3.5"></a><h3>3.5 Modify portalboxes</h3>
<p>The search interface HTML page for a given collection may be
customized by what we call <em>portalboxes</em>. Portalboxes are used
to show various kinds of information to the end user, such as a text
box with some inline help information about the given collection, an
illustrative picture, etc.
<p>To create a new portalbox, a title and a body must be given, where
the body can contain HTML if necessary.
<p>To add a portalbox to the collection, you must choose an existing
portalbox, the language for which the portalbox should be shown, the
position of the portalbox on the screen, and the ordering score of
portalboxes.
<ul>
<li>The <em>language</em> could be chosen depending on the language
used in the portalbox body. Since a portalbox is not necessarily
bound to one particular language, one portalbox may be reused for
several languages, which is particularly suitable for portalboxes
containing language-independent content such as images.
<li>The <em>position</em> of the portalbox on the screen is chosen
from several predefined positions, such as right-top, before-title,
after-title, before-narrow-by-collection-box, etc. You may present
several portalboxes on the same position in the same language, in
which case they will be shown by the order of decreasing score.
<li>The <em>score</em> defines the order of portalboxes that are to be
presented in the same position and in the same language context.
</ul>
<a name="3.6"></a><h3>3.6 Modify search fields</h3>
<p>The <em>search field</em> is a logical field (such as author,
title, etc) that will be proposed to the end users in Simple and
Advanced Search interface pages. If you do not set any search fields
for a collection, then a default list (author, title, year, etc) will
be shown.
<p>Note that if you want to add a new logical field or modify existing
physical MARC tags for a logical field, you have to use the <a
href="<WEBURL>/admin/bibindex/">BibIndex Admin</a> interface.
<a name="3.7"></a><h3>3.7 Modify search options</h3>
<p>The <em>search option</em> is like <a href="#3.6">search field</a>
in a way that it permits the end user to narrow down his search to
some logical field such as "subject", but unlike with the search field
the user is not required to type his query in a free text form;
rather, the search interface proposes to the end user several
interesting predefined values prepared by the administrators that the
end user may choose from. For example, an "author search" concept is
a good example of search field usage, since there is plenty of author
names to be matched, so that the end users would usually type the name
they wish to find in free text form; while a "subject search" concept
is a good example for search option usage, since usually there is a
limited number of subjects in the system given by local subject
classification scheme, that the end users do not necessarily know
about and that they are free to choose from a list. As a rule of
thumb, the search field concept denotes the case of unlimited number
possibilites of distinct values to be matched in a given field
(e.g. author, title, keyword); while the search option concept denotes
the case of only a handful or so distinct values to be matched in a
given field (e.g. subject, division, year).
<p>Search options are shown in the "Advanced Search" interfaces only,
while search fields are shown both in "Simple Search" and "Advanced
Search" interface. (Although if you want to add a search option to
the "Simple Search" interface, you can achieve it by creating
appropriate HTML code in a <a href="#3.5">portalbox</a>.) The search
options order, as well as the order of search option values, may be
defined by means of 'move' arrows in the WebSearch Admin interface.
<p>To add a new search option, a field name must first be chosen (for
example "subject") and then a list of possible field values must be
entered (for example "Mathematics", "Physics", "Chemistry", "Biology",
etc). Note that if you want to add a new logical field or modify
existing physical MARC tags for a logical field, you have to use the
<a href="<WEBURL>/admin/bibindex/">BibIndex Admin</a> interface.
<a name="3.8"></a><h3>3.8 Modify sort options</h3>
<p>You may define a list of logical fields that the end users will be
able to choose for the sorting purposes. For example, "first author"
or "year". If you don't select anything, a default list (author,
title, year, etc) will be shown.
<p>Note that if you want to add a new logical field or modify existing
physical MARC tags for a logical field, you have to use the <a
href="<WEBURL>/admin/bibindex/">BibIndex Admin</a> interface.
<a name="3.9"></a><h3>3.9 Modify rank options</h3>
<p>To enable a certain rank method for a collection, select the method
from the "enable rank method" box and add it. The documents in this
collection will then be included in the ranking sets the next time the
BibRank daemon will run. To disable a method the process is the same,
but select the method from the 'disable rank method' box.
<p>Note that if you want to add new ranking method or modify existing
ranking method, you have to use the <a
href="<WEBURL>/admin/bibrank/">BibRank Admin</a> interface.
<a name="3.10"></a><h3>3.10 Modify output formats</h3>
<p>Each collection may have several output formats defined. The end
users will be able to choose a format they want to see their search
results list in. Most formats like HTML brief or XML Dublin Core are
interesting for each collection, but some formats like HTML portfolio
are only interesting for Photographs collection, not for Articles
collection. The interface will permit you to choose the formats
appropriate for a given collection. The order of formats can be
changed using the 'move' arrows.
<p>Note that if you want to add new output format ('behaviour') or
modify existing output format, you have to use the <a
href="<WEBURL>/admin/bibformat/">BibFormat Admin</a> interface.
<a name="4"></a><h2>4. Webcoll Status</h2>
<p>WebColl is the daemon that normally periodically runs via <a
href="<WEBURL>/admin/bibsched/">BibSched</a> and that updates the
collection cache with the collection parameters configured in the
previous section. Alternatively to running webcoll via BibSched, you
can also run it any time you want from the command line, either for
all collections or for selected collection only. See the --help
option.
<p>The WebSearch Admin interface has got a WebColl Status menu that
shows when the collection cache was last updated and when the next
update is scheduled. It warns in case something suspicious was
discovered.
<a name="5"></a><h2>5. Collections Status</h2>
<p>The Collection Status menu of the WebSearch Admin interface shows
the list of all collections and checks if there is anything wrong
regarding configuration of collections, together with the languages
the collection name has been translated into, etc. Here is the
detailed explanation of the functionality:
<blockquote>
<dl>
<dt><strong>ID</strong>
<dd>ID of the collection.
<dt><strong>Name</strong>
<dd>Name of the collection.
<dt><strong>Query</strong>
<dd>The collection definition query. Note that it should be empty if
a collection got subcollections. If not, then a query is needed.
<dt><strong>Subcollections</strong>
<dd>The subcollections that the collection is composed of. Note that
a collection which got defined by a query should not have any
subcollections.
<dt><strong>Restricted</strong>
<dd>A restricted collection can only be accessed by users belonging to
the Apache groups mentioned in this column.
<dt><strong>I18N</strong>
<dd>Show which languages the collection name has been translated into.
<dt><strong>Status</strong>
<dd>If no errors was found, <em>OK</em> is displayed for each
collection. If an error was found, then an error number and short
message are shown. The meaning of the error messages is the
following: <em>1:Query</em> means that the collection was defined via
a query but also via subcollections too; <em>2:Query</em> means that
the collection wasn't defined neither via query nor via
subcollections.
</dl>
</blockquote>
<a name="6"></a><h2>6. Edit Search Engine Parameters</h2>
<a name="7"></a><h2>7. Search Engine Cache</h2>
<a name="8"></a><h2>8. Additional Information</h2>
<a href="<WEBURL>/hacking/websearch/">WebSearch Internals</a>
diff --git a/modules/websearch/doc/admin/index.html.wml b/modules/websearch/doc/admin/index.html.wml
index 745a17df7..04f9090c7 100644
--- a/modules/websearch/doc/admin/index.html.wml
+++ b/modules/websearch/doc/admin/index.html.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebSearch Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="websearch"
<p>
This is the gate to the admin area for WebSearch. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/websearch/">login</a> to enter.
</p>
<dl>
<dt><a href="websearchadmin.py">WebSearch Admin Interface</a></dt>
<dd>Start area for WebSearch administration.</dd>
</dl>
<dl>
<dt><a href="guide.html">WebSearch Admin Guide</a></dt>
<dd>Everything you want to know about WebSearch administration</dd>
</dl>
diff --git a/modules/websearch/doc/guide.html.wml b/modules/websearch/doc/guide.html.wml
index 4724983e4..6f9653fb5 100644
--- a/modules/websearch/doc/guide.html.wml
+++ b/modules/websearch/doc/guide.html.wml
@@ -1,1894 +1,1894 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Search Guide" \
navbar_name="search-new" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/search/<lang:star: index.*.html>>_(Search Help)_</a>" \
navbar_select="guide"
<en>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</en>
<fr>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</fr>
<de>
<p>Unsere Suchmaschine bietet den heutigen Stand der Web-Such
Technologie, die auch von bekannten Suchmaschinen wie zum Beispiel
<a href="http://google.com/">Google</a> angeboten werden. Im Detail
unterscheidet sich jedoch die bibliographische Suche von einer
Web-Suche. Wir bieten mehrere Erweiterungen an, damit eine komplexe
und genau strukturierte Suche möglich wird, inklusiv einer
kombinierten Metadatensuche, Volltextsuche und Referenzsuche. Diese
Seite stellt Tipps und Tricks vor, die für eine effektive Suche
nützlich sind.
</de>
<es>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</es>
<ca>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</ca>
<pl>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</pl>
<pt>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</pt>
<it>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</it>
<ru>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</ru>
<sk>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</sk>
<cs>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</cs>
<no>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</no>
<sv>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</sv>
<el>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</el>
<uk>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</uk>
<ja>
<p>Our search engine tries to offer today's typical web searching
experience, as gained with popular search engines such as <a
href="http://google.com/">Google</a>. The nature of bibliographic
searching differs from that of a web page searching, though. We
provide many extensions to enable a complex and precise structured
search, including an combined metadata, fulltext and reference search
in one go. This page lists several tips and tricks that you may find
useful to this effect.
</ja>
<en>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</en>
<fr>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</fr>
<de>
<h3><strong class="headerboxbodylogo">Inhaltsverzeichnis</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Einfache versus erweiterte Suche</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Grundlagen</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Suche nach Wörtern und Wortgruppen</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolsche Suche</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Spezielle Zeichen und Notation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">Internationale Zeichen</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Trunkierung</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Strukturierte Metadatensuche</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Bereichs-Recherche</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Kombinierte Metadaten-/Volltext-/Zitatsuche</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">FAQ</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">Wie wähle ich am geschicktesten meinen Suchbegriff</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">Wie suche ich nach Publikationen eines bestimmten Autors</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">Wie lasse ich Ergebnisse auf eine bestimmte Weise sortieren</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">Wie bekomme ich Dokumente anderer Server (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">Wie kann ich in verknüpften Volltextdateien suchen</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">Wie kann ich nach Zitaten suchen</a>
</de>
<es>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</es>
<ca>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</ca>
<pl>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</pl>
<pt>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</pt>
<it>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</it>
<ru>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</ru>
<sk>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</sk>
<cs>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</cs>
<no>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</no>
<sv>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</sv>
<el>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</el>
<uk>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</uk>
<ja>
<h3><strong class="headerboxbodylogo">Index</strong></h3>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#simpleadvanced">Simple versus advanced search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#guidance">Search guidance</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#words-vs-phrases">Searching for words versus phrases</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#boolean">Boolean queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#punctuation">Special characters and punctuation</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#unicode">International characters</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#wildcard">Word truncation/stemming</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#structured">Structured metadata search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#regexp">Regular expressions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#span">Span queries</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#combined">Combined metadata/fulltext/citation search</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto">Frequently asked questions</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-choose-terms">How to wisely choose your search terms (speed-wise)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-search-for-author">How to search for publications by a given author</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-sort-pattern">How to sort according to a certain pattern</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-hepdoc">How to get documents from other servers (Google, SPIRES, KEK)</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-fulltext">How to search in fulltext files</a>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#howto-citations">How to search for citations</a>
</ja>
<h3><a name="simpleadvanced">
<en>Simple versus advanced search</en>
<fr>Simple versus advanced search</fr>
<de>Einfache versus erweiterte Suche</de>
<es>Simple versus advanced search</es>
<ca>Simple versus advanced search</ca>
<pl>Simple versus advanced search</pl>
<pt>Simple versus advanced search</pt>
<it>Simple versus advanced search</it>
<ru>Simple versus advanced search</ru>
<sk>Simple versus advanced search</sk>
<cs>Simple versus advanced search</cs>
<no>Simple versus advanced search</no>
<sv>Simple versus advanced search</sv>
<el>Simple versus advanced search</el>
<uk>Simple versus advanced search</uk>
<ja>Simple versus advanced search</ja>
</a></h3>
<p>The default search mode is <strong>simple search</strong> that
basically provides you with one input box where you can type your
query, followed by a possibility to choose one of the common indexes
to search within. You would usually simply type the keywords you are
interested in and hit return. For example, if you are interested in
documents on <em>standard model</em> that are written by (or mention)
<em>Ellis</em>, you would type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="ellis standard model">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
and on the search results page you could further add/remove keywords
to get more precisely at what you are looking for, as is mentioned <a
href="#boolean">below</a>.
<p>The <strong>advanced search</strong> interface provides you with
explicit tools to play with: you can change the matching type from the
default word matching to phrase searching or the regular matching; you
can use boolean queries in several indexes, etc. For example, to find
all the documents written by <em>Ellis, J</em> spelled exactly that
way that contain either of the words <em>muon</em> or
<em>neutrino</em> in the title and that were published in
<em>2001</em>, you would type:
<blockquote>
<form action="<WEBURL>/search.py" method="get">
<input type="hidden" name="cc" value="Atlantis Institute of Science">
<input type="hidden" name="as" value="1">
<table>
<tbody>
<tr valign="bottom">
<td>
<select name="m1">
<option value="a">All of the words:
<option value="o">Any of the words:
<option value="e" selected>Exact phrase:
<option value="p">Partial phrase:
<option value="r">Regular expression:
</select>
<input type="text" name="p1" size="16" value="Ellis, J"></td>
<td class="searchboxbody"><select name="f1"><option value="">any field<option value="abstract">abstract<option value="author" selected>author<option value="collection">collection<option value="division">division<option value="experiment">experiment<option value="fulltext">fulltext<option value="keyword">keyword<option value="reference">reference<option value="reportnumber">report number<option value="subject">subject<option value="title">title<option value="year">year</select></td>
<td class="searchboxbody">
<select name="op1">
<option value="a">AND
<option value="o">OR
<option value="n">AND NOT
</select>
</td>
</tr>
<tr valign="bottom">
<td class="searchboxbody">
<select name="m2">
<option value="a">All of the words:
<option value="o" selected>Any of the words:
<option value="e">Exact phrase:
<option value="p">Partial phrase:
<option value="r">Regular expression:
</select>
<input type="text" name="p2" size="16" value="muon neutrino"></td>
<td class="searchboxbody"><select name="f2"><option value="">any field<option value="abstract">abstract<option value="author">author<option value="collection">collection<option value="division">division<option value="experiment">experiment<option value="fulltext">fulltext<option value="keyword">keyword<option value="reference">reference<option value="reportnumber">report number<option value="subject">subject<option value="title" selected>title<option value="year">year</select></td>
<td class="searchboxbody">
<select name="op2">
<option value="a">AND
<option value="o">OR
<option value="n">AND NOT
</select>
</td>
</tr>
<tr valign="bottom">
<td class="searchboxbody">
<select name="m3">
<option value="a">All of the words:
<option value="o">Any of the words:
<option value="e">Exact phrase:
<option value="p">Partial phrase:
<option value="r">Regular expression:
</select>
<input type="text" name="p3" size="16" value="2001"></td>
<td class="searchboxbody"><select name="f3"><option value="">any field<option value="abstract">abstract<option value="author">author<option value="collection">collection<option value="division">division<option value="experiment">experiment<option value="fulltext">fulltext<option value="keyword">keyword<option value="reference">reference<option value="reportnumber">report number<option value="subject">subject<option value="title">title<option value="year" selected>year</select></td>
<td class="searchboxbody"><input class="formbutton" type="submit" name="action" value="SEARCH"><input class="formbutton" type="submit" name="action" value="Browse">&nbsp;</td>
</tr>
</tbody>
</table>
</form>
</blockquote>
<p>Note that Simple Search can provide you basically the same
functionality, if you make use of special syntax that is explained in
the text below. The simple-versus-advanced does not refer to the
functionality that is being provided but rather to the amount of
parametrization you can "tweak". We conform to the common
use of the simple/advanced terms as found in other search engines.
<p>Much of what follows will deal with a question on "how a power user
would use the simple search interface". Recall that you can always go
to the Advanced Search for more query assistance.
<h3><a name="guidance">
<en>Search guidance</en>
<fr>Search guidance</fr>
<de>Grundlagen</de>
<es>Search guidance</es>
<ca>Search guidance</ca>
<pl>Search guidance</pl>
<pt>Search guidance</pt>
<it>Search guidance</it>
<ru>Search guidance</ru>
<sk>Search guidance</sk>
<cs>Search guidance</cs>
<no>Search guidance</no>
<sv>Search guidance</sv>
<el>Search guidance</el>
<uk>Search guidance</uk>
<ja>Search guidance</ja>
</a></h3>
<p>After you submit your query, the search engine will analyze it and
will try to always guide you in case no exact match could be found.
For example, it would print you a list of closest indexed terms in
case of spelling troubles:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="elllis muon">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>Alternative choices will be printed in red. The search engine
will similarly warn you when your search terms could not be
found, or when they could but your boolean query couldn't be met. The
search engine will also silently try to search for alternative forms
(e.g. remove punctuation), etc.
<p>Thanks to multiple search stages and the guidance provided at each
stage, it is usually sufficient to simple type what you are looking
for and see what the system says in return. If you aren't satisfied,
you would then add/remove words from your query until the satisfactory
reply.
<h3><a name="words-vs-phrases">
<en>Searching for words versus phrases</en>
<fr>Searching for words versus phrases</fr>
<de>Suche nach Wörtern und Wortgruppen</de>
<es>Searching for words versus phrases</es>
<ca>Searching for words versus phrases</ca>
<pl>Searching for words versus phrases</pl>
<pt>Searching for words versus phrases</pt>
<it>Searching for words versus phrases</it>
<ru>Searching for words versus phrases</ru>
<sk>Searching for words versus phrases</sk>
<cs>Searching for words versus phrases</cs>
<no>Searching for words versus phrases</no>
<sv>Searching for words versus phrases</sv>
<el>Searching for words versus phrases</el>
<uk>Searching for words versus phrases</uk>
<ja>Searching for words versus phrases</ja>
</a></h3>
<p>The default search mode is a <strong>search for words</strong>. This
means that any whitespace you type is not significant, but is rather
interpreted to mean "add an automatic boolean AND between words", like
Google does. For example, to find all records that contain both the
word <em>ellis</em> and the word <em>muon</em> anywhere in the record,
type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="ellis muon">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
The whitespace would be significant if you include it within quotes.
There are two phrase searching modes:
<ol>
<li>The double quotes instruct the search engine to <strong>search for
exact phrase</strong>. This phrase search mode will match if and
only if the given metadata field is exactly equal to the input
pattern. For example, to find all documents written by <em>Ellis,
J</em> spelled exactly that way, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="&quot;Ellis, J&quot;">
<select name="f"><option value="">any field<option>title<option selected>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<li>The single quotes instruct the search engine to <strong>search for
partial phrase</strong>. Unlike the exact phrase search, this
mode allows for an extra text appearing before/after given
pattern. This is somewhat similar to the "phrase search mode"
common on Google and other fulltext engines that search for phrase
expressions inside Web pages. For example, to find all the titles
containing the expression <em>muon decay</em> regardless of the
position of the expression in the title, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="'muon decay'">
<select name="f"><option value="">any field<option selected>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Now you see how to search for an author spelled sometimes as
<em>Ellis, J</em> and sometimes as <em>Ellis, Jonathan
Richard</em> (and other authors, such as <em>De Lellis, Jim</em>)
at the same time:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="'Ellis, J'">
<select name="f"><option value="">any field<option>title<option selected>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
(See also our specific <a href="#howto-search-for-author">author
searching tips</a>.)
</ol>
<p>The difference between exact and partial phrase searching modes may
not be obvious upon first look. While the latter is more similar to
what ``phrase search'' usually means in the context of web page search
engines, the former one is usually an order of magnitude faster if you
know the precise values you are looking for.
<p>Another interesting searching mode besides the word and phrase
searches is the <strong>regular expression search</strong>, introduced
by slashes instead of quotes. For example, the above partial phrase
query <code>'muon decay'</code> is fully equivalent to the regular
expression query <code>/muon decay/</code>. The regular expression
syntax is very powerful and permits you to construct very complex
queries. For more information, please consult the <a
href="#regexp">regular expression</a> section of this guide.
<h3><a name="boolean">
<en>Boolean queries</en>
<fr>Boolean queries</fr>
<de>Boolsche Suche</de>
<es>Boolean queries</es>
<ca>Boolean queries</ca>
<pl>Boolean queries</pl>
<pt>Boolean queries</pt>
<it>Boolean queries</it>
<ru>Boolean queries</ru>
<sk>Boolean queries</sk>
<cs>Boolean queries</cs>
<no>Boolean queries</no>
<sv>Boolean queries</sv>
<el>Boolean queries</el>
<uk>Boolean queries</uk>
<ja>Boolean queries</ja>
</a></h3>
We have already seen how whitespace adds a silent boolean AND in the
search for words. The other boolean operators include:
<blockquote>
<table border="1" cellpadding=10>
<tr>
<td rowspan=3 align=center>
<strong>+<br>AND</strong>
</td>
<td>
<code>ellis +muon</code>
</td>
<td>
matches all records that contain both the word
<em>ellis</em> and the the word <em>muon</em>
</td>
</tr>
<tr>
<td>
<code>ellis muon</code>
</td>
<td>
ditto, syntactic sugar
</td>
</tr>
<tr>
<td>
<code>ellis and muon</code>
</td>
<td>
ditto, syntactic sugar
</td>
</tr>
<tr>
<td rowspan=2 align=center>
<strong>-<br>NOT</strong>
</td>
<td>
<code>ellis -muon</code>
</td>
<td>
matches all records that contain the word
<em>ellis</em> but that do not contain the word
<em>muon</em>
</td>
</tr>
<tr>
<td>
<code>ellis not muon</code>
</td>
<td>
ditto, syntactic sugar
</td>
</tr>
<tr>
<td rowspan=2 align=center>
<strong>|<br>OR</strong>
</td>
<td>
<code>ellis |muon</code>
</td>
<td>
matches all records that contain at least one
of the words
</td>
</tr>
<tr>
<td>
<code>ellis or muon</code>
</td>
<td>
ditto, syntactic sugar
</td>
</tr>
</table>
</blockquote>
<p>Logical operations are automatically chained from left to right.
For example, if you want to search for documents written by Ellis on
muons or kaons, write:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="muon or kaon and ellis">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
which looks for <code>(muon or kaon) and ellis</code>. Note that this
gives different results from:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="ellis and muon or kaon">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
which would search for <code>(ellis and muon) or kaon</code>.
<p>The left-to-right chaining behaviour permits you to easily refine
your search by adding/removing words with and/not or +/- operators.
For example, to exclude the documents on decay from the above search,
append <code>-decay</code>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="muon or kaon and ellis -decay">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
to get a refined list. Keep adding/removing terms until you are
satisfied.
<h3><a name="punctuation">
<en>Special characters and punctuation</en>
<fr>Special characters and punctuation</fr>
<de>Spezielle Zeichen und Notation</de>
<es>Special characters and punctuation</es>
<ca>Special characters and punctuation</ca>
<pl>Special characters and punctuation</pl>
<pt>Special characters and punctuation</pt>
<it>Special characters and punctuation</it>
<ru>Special characters and punctuation</ru>
<sk>Special characters and punctuation</sk>
<cs>Special characters and punctuation</cs>
<no>Special characters and punctuation</no>
<sv>Special characters and punctuation</sv>
<el>Special characters and punctuation</el>
<uk>Special characters and punctuation</uk>
<ja>Special characters and punctuation</ja>
</a></h3>
<p>When indexing words, an attention is paid to index it both with and
without punctuation, so that you should be able to search for terms
containing special characters, such as <em>C++</em>, verbatim:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="C++">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="O'Shea">
<select name="f"><option value="">any field<option>title<option selected>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
For example, to find records containing the LaTeX expression
<code>$e^{+}e^{-}$</code> in the title, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="$e^{+}e^{-}$">
<select name="f"><option value="">any field<option selected>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
For example, to find document with the report number
<em>hep-ph/0204133</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="hep-ph/0204133">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Note that the search is case-insensitive:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="BlaCK hOlEs">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<h3><a name="unicode">
<en>International characters</en>
<fr>International characters</fr>
<de>Internationale Zeichen</de>
<es>International characters</es>
<ca>International characters</ca>
<pl>International characters</pl>
<pt>International characters</pt>
<it>International characters</it>
<ru>International characters</ru>
<sk>International characters</sk>
<cs>International characters</cs>
<no>International characters</no>
<sv>International characters</sv>
<el>International characters</el>
<uk>International characters</uk>
<ja>International characters</ja>
</a></h3>
<p>The search engine works with Unicode UTF-8 so you can type your
query strings in any language stored in the database. For
example, to find the documents written by (or on) Пушкин, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="пушкин">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Note that you don't have to type accents to find accented results. For example,
type <code>Lemaitre</code> to find papers by <em>Lemaître</em>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="Lemaitre">
<select name="f"><option value="">any field<option>title<option selected>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<ifeq "<CFG_CERN_SITE>" "1" "
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
IMPORTANT NOTE
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
Currently, words that include accented characters can only be retrieved by entering
accented characters in the query.
</td>
</tr>
</tbody>
</table>
">
<h3><a name="wildcard">
<en>Word truncation/stemming</en>
<fr>Word truncation/stemming</fr>
<de>Trunkierung</de>
<es>Word truncation/stemming</es>
<ca>Word truncation/stemming</ca>
<pl>Word truncation/stemming</pl>
<pt>Word truncation/stemming</pt>
<it>Word truncation/stemming</it>
<ru>Word truncation/stemming</ru>
<sk>Word truncation/stemming</sk>
<cs>Word truncation/stemming</cs>
<no>Word truncation/stemming</no>
<sv>Word truncation/stemming</sv>
<el>Word truncation/stemming</el>
<uk>Word truncation/stemming</uk>
<ja>Word truncation/stemming</ja>
</a></h3>
<p>The word truncation is supported via asterisk (*) wildcard
character. The wildcard instructs the search engine to match any
number of characters in that place. For example, to find records
that contain words <em>muon</em>, <em>muons</em>, <em>muonic</em>
etc, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="muon*">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
The wildcard query works both in prefix and infix position. For
example, to get all the words that start by <em>CERN-TH</em> and
end by <em>31</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="CERN-TH*31">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Note that the wildcard will be ignored if you try to apply it to
very short words, such as <em>a*</em>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="a*">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
The wildcard character can be used also in the phrase searching
mode. For example, to find all the documents whose title starts by
"Neutrino mass", type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="&quot;Neutrino mass*&quot;">
<select name="f"><option value="">any field<option selected>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Recall that we have introduced exact and partial phrase search
modes. Actually, a partial phrase search mode launches an exact
search enclosed within wildcards: we could say that <code>'foo bar
baz'</code> equals to <code>"*foo bar baz*"</code>. Now you can
see why the partial phrase search is slow: due to the usage of two
asterisks in front and after the text, each and every title in the
database has to be looked up to determine whether it matches or
not. (There are currently no partial phrase indexes.)
<h3><a name="structured">
<en>Structured metadata search</en>
<fr>Structured metadata search</fr>
<de>Strukturierte Metadatensuche</de>
<es>Structured metadata search</es>
<ca>Structured metadata search</ca>
<pl>Structured metadata search</pl>
<pt>Structured metadata search</pt>
<it>Structured metadata search</it>
<ru>Structured metadata search</ru>
<sk>Structured metadata search</sk>
<cs>Structured metadata search</cs>
<no>Structured metadata search</no>
<sv>Structured metadata search</sv>
<el>Structured metadata search</el>
<uk>Structured metadata search</uk>
<ja>Structured metadata search</ja>
</a></h3>
<p>Searching within various bibliograpic fields (such as title,
author) is supported via Google's <code>"site:"</code> like syntax.
If a search term is preceded by a field name and a colon, then the
term is searched for inside this field only. For example, to find
documents containing the word <em>ellis</em> within author index,
type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:ellis">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
To select documents written by <em>Ellis</em> that contain words
like <em>muon</em>, <em>muons</em>, <em>muonic</em> within title,
type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:ellis title:muon*">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
To select documents written by the <em>NA60</em> experiment from
the year <em>2001</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="experiment:NA60 year:2001">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
The most common fields you may want to use are
<code>author</code>, <code>title</code>,
<code>reportnumber</code>, <code>abstract</code>,
<code>keyword</code>, <code>year</code>, <code>experiment</code>,
<code>fulltext</code>, and <code>reference</code>.
<h3><a name="regexp">
<en>Regular expressions</en>
<fr>Regular expressions</fr>
<de>Regular expressions</de>
<es>Regular expressions</es>
<ca>Regular expressions</ca>
<pl>Regular expressions</pl>
<pt>Regular expressions</pt>
<it>Regular expressions</it>
<ru>Regular expressions</ru>
<sk>Regular expressions</sk>
<cs>Regular expressions</cs>
<no>Regular expressions</no>
<sv>Regular expressions</sv>
<el>Regular expressions</el>
<uk>Regular expressions</uk>
<ja>Regular expressions</ja>
</a></h3>
<p>The regular expression searching mode is mostly for the power users
acquainted with the traditional Unix/POSIX regexp syntax. In the
Simple Search interface you can trigger it by using slashes instead of
quotes:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="title:/^E.*s$/">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
while in the Advanced Search interface you can select the matching
type explicitely by using the selection box menu. The above example
will find all the titles that start by the letter <em>E</em>, followed
by any number of any characters, and end by the letter <em>s</em>.
<p>Another example could be an author search for an author expressed
in the database as either <em>Ellis, J</em> or <em>Ellis, John</em>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:/^Ellis, (J|John)$/">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>The regular expression search enables you to formulate very
specific word proximity queries. For example, let us find all titles
containing words <em>dense</em> and <em>matter</em> that are separated
by at most one word that doesn't contain the letter <em>l</em>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="title:/dense ([^ l]* )?matter/">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>Note that you can also use character intervals such as
<code>[a-k]</code> and occurrence counts such as <code>{3}</code>.
For example, let us find all preprints that do not follow the year
cataloguing policy, that is <em>YYYY</em> to denote year, optionally
followed by <em>?</em> or by another <em>-YYYY</em>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="collection:PREPRINT -year:/^[0-9]{4}([\?\-]|\-[0-9]{4})?$/">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
You can use also character classes such <code>[:alnum:]</code>, so
that the above query is equivalent to:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="collection:PREPRINT -year:/^[[:digit:]]{4}([\?\-]|\-[[:digit:]]{4})?$/">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>To learn more about POSIX regular expressions, please consult the
<a href="http://en.wikipedia.org/wiki/Regular_expression">Wikipedia
regexp article</a> and the <a
href="http://dev.mysql.com/doc/mysql/en/Regexp.html">MySQL regexp
documentation</a>.
<h3><a name="span">
<en>Span queries</en>
<fr>Span queries</fr>
<de>Bereichs-Recherche</de>
<es>Span queries</es>
<ca>Span queries</ca>
<pl>Span queries</pl>
<pt>Span queries</pt>
<it>Span queries</it>
<ru>Span queries</ru>
<sk>Span queries</sk>
<cs>Span queries</cs>
<no>Span queries</no>
<sv>Span queries</sv>
<el>Span queries</el>
<uk>Span queries</uk>
<ja>Span queries</ja>
</a></h3>
<p>The span query is provided via a <code>-></code> sign. For
example, to search for all documents on <em>muon decay</em> published
between <em>1983</em> and <em>1992</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=30 type="text" name="p" value="muon decay year:1983->1992">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
To find all documents by authors with names ranging from <em>Ellis,
J</em> to <em>Ellis, Qqq</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=30 type="text" name="p" value="author:&quot;Ellis, J&quot;->&quot;Ellis, Qqq&quot;">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<h3><a name="combined">
<en>Combined metadata/fulltext/citation search</en>
<fr>Combined metadata/fulltext/citation search</fr>
<de>Kombinierte Metadaten-/Volltext-/Zitatsuche</de>
<es>Combined metadata/fulltext/citation search</es>
<ca>Combined metadata/fulltext/citation search</ca>
<pl>Combined metadata/fulltext/citation search</pl>
<pt>Combined metadata/fulltext/citation search</pt>
<it>Combined metadata/fulltext/citation search</it>
<ru>Combined metadata/fulltext/citation search</ru>
<sk>Combined metadata/fulltext/citation search</sk>
<cs>Combined metadata/fulltext/citation search</cs>
<no>Combined metadata/fulltext/citation search</no>
<sv>Combined metadata/fulltext/citation search</sv>
<el>Combined metadata/fulltext/citation search</el>
<uk>Combined metadata/fulltext/citation search</uk>
<ja>Combined metadata/fulltext/citation search</ja>
</a></h3>
<p>All the syntax mentioned above can be combined together in one
query. For example, to find documents that have the word
<em>ellis</em> inside author fields, that do not contain words like
<em>muon</em>, 'muonic' etc in any field, that contain the phrase
(or the substring, to be more precise) 'dense quark matter' inside
abstract fields, and that were published in year starting by digits
'200', type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=60 type="text" name="p" value="author:ellis -muon* +abstract:'dense quark matter' year:200*">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Note that the default "any field" global index does contain only the metadata terms,
not the citation nor fulltext terms. You have to explicitely mention <code>fulltext</code>
or <code>reference</code> index to search there. For example, to find the term <em>Higgs</em>
in either metadata, references or fulltext files, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=60 type="text" name="p" value="higgs or reference:higgs or fulltext:higgs">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
This permits an interesting combination of metadata, fulltext and citation search in
the same query. For example, to get all documents written by
<em>Lin</em> whose fulltext files contain the words
<em>Schwarzschild</em> and <em>AdS</em>, and who cite journal
<em>Adv. Theor. Math. Phys.</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=60 type="text" name="p" value="author:lin fulltext:Schwarzschild fulltext:AdS reference:&quot;Adv. Theor. Math. Phys.&quot;">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<ifeq "<CFG_CERN_SITE>" "1" "
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
IMPORTANT NOTE
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
Currently, fulltext files and references are not fully searchable on the CERN site.
Assumed operational time: Q1 2004.
</td>
</tr>
</tbody>
</table>
">
<h3><a name="howto">
<en>Frequently asked questions</en>
<fr>Frequently asked questions</fr>
<de>FAQ</de>
<es>Frequently asked questions</es>
<ca>Frequently asked questions</ca>
<pl>Frequently asked questions</pl>
<pt>Frequently asked questions</pt>
<it>Frequently asked questions</it>
<ru>Frequently asked questions</ru>
<sk>Frequently asked questions</sk>
<cs>Frequently asked questions</cs>
<no>Frequently asked questions</no>
<sv>Frequently asked questions</sv>
<el>Frequently asked questions</el>
<uk>Frequently asked questions</uk>
<ja>Frequently asked questions</ja>
</a></h3>
<h4><a name="howto-choose-terms">
<en>How to wisely choose your search terms (speed-wise)</en>
<fr>How to wisely choose your search terms (speed-wise)</fr>
<de>Wie wähle ich am geschicktesten meinen Suchbegriff</de>
<es>How to wisely choose your search terms (speed-wise)</es>
<ca>How to wisely choose your search terms (speed-wise)</ca>
<pl>How to wisely choose your search terms (speed-wise)</pl>
<pt>How to wisely choose your search terms (speed-wise)</pt>
<it>How to wisely choose your search terms (speed-wise)</it>
<ru>How to wisely choose your search terms (speed-wise)</ru>
<sk>How to wisely choose your search terms (speed-wise)</sk>
<cs>How to wisely choose your search terms (speed-wise)</cs>
<no>How to wisely choose your search terms (speed-wise)</no>
<sv>How to wisely choose your search terms (speed-wise)</sv>
<el>How to wisely choose your search terms (speed-wise)</el>
<uk>How to wisely choose your search terms (speed-wise)</uk>
<ja>How to wisely choose your search terms (speed-wise)</ja>
</a></h4>
<p>
<ul>
<li>Whenever possible, prefer word searches instead of phrase searches.
Search rather for <code>black hole</code> than for <code>"black hole"</code>.
<li>Avoid common terms such as <code>and</code>, <code>of</code>, or <code>CERN</code>.
<li>If you are searching for a specific metadata information, such
as a <em>report number</em>, choose corresponding index.
<li>If you are looking for a specific document collection, such
as <em>Theses</em>, choose the
<a href="<WEBURL>/?c=Theses">Theses</a> collection first, and start your search from there.
</ul>
<h4><a name="howto-search-for-author">
<en>How to search for publications by a given author</en>
<fr>How to search for publications by a given author</fr>
<de>Wie suche ich nach Publikationen eines bestimmten Autors</de>
<es>How to search for publications by a given author</es>
<ca>How to search for publications by a given author</ca>
<pl>How to search for publications by a given author</pl>
<pt>How to search for publications by a given author</pt>
<it>How to search for publications by a given author</it>
<ru>How to search for publications by a given author</ru>
<sk>How to search for publications by a given author</sk>
<cs>How to search for publications by a given author</cs>
<no>How to search for publications by a given author</no>
<sv>How to search for publications by a given author</sv>
<el>How to search for publications by a given author</el>
<uk>How to search for publications by a given author</uk>
<ja>How to search for publications by a given author</ja>
</a></h4>
<p>You can search for an author in many ways, each having its own
advantages and disadvantages.
<ol>
<li>First of all, note that searching for words isn't usually what you
would want here. If you choose to search for the words <code>Ellis
J</code> within the author index, it means that two queries (for the
words <code>Ellis</code> and <code>J</code>) are effected first and a
boolean AND is performed next:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="Ellis J">
<select name="f"><option value="">any field<option>title<option selected>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>Such a query would match also a document whose first author is
<em>Ellis, R</em> and the second author <em>Finch, A J</em>, which is
probably not what you wanted. While the search is very fast and you
would have found the results for the author you were looking for, such
a technique could have returned you many false positives, as the one
cited above. Instead of searching for words, a more suitable
technique to apply in this case is to search for phrases which will
permit you to achieve higher search precisions.
<li>The author names are usually stored in a form containing initials
only, such as <em>Ellis, J</em>. To get the list of publications of
an author whose name is spelled exactly that way, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:&quot;Ellis, J&quot;">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>This way of searching gives you the highest precision and no false
positives. (Assuming there are no other authors whose names are
spelled <em>Ellis, J</em>, an assumption that is often false<a
href="#author-full-names"><sup>*</sup></a>.) The search is very fast.
<li> Sometimes an author's first name may be spelled abbreviated on
some documents (such as <em>Ellis, J</em>) and sometimes full on
others (such as <em>Ellis, John</em>; eventually also with the middle
name: <em>Ellis, John Rolfe</em>). To get the list of publications
for all these forms at the same time, you could use a boolean OR
query:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=60 type="text" name="p" value="author:&quot;Ellis, J&quot; or author:&quot;Ellis, John&quot; or author:&quot;Ellis, John Rolfe&quot;">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>This way of searching still keeps the highest precision and no
false positives. (Assuming there are no other authors whose names are
spelled <em>Ellis, J</em> or <em>Ellis, John</em>, an assumption that
is often false<a href="#author-full-names"><sup>*</sup></a>.) The search is
fast.
<li>To match all of the above forms in a single search term, you can
try to use a wildcard query:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:&quot;Ellis, J*&quot;">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>It would match all author names that start by the text
<code>Ellis, J</code>, i.e. not only the wanted forms <em>Ellis,
J</em> and <em>Ellis, John</em>, but also <em>Ellis, Jim</em>, or
<em>Ellis, John Rolfe</em>, or <em>Ellis, Jonathan Richard</em>.
<p>This way of searching returns you more results, which may be
suitable in case you don't know how the names are spelled in the
database. But you also risk the eventuality of getting false
positives. The search is relatively fast.
<li>Yet another, the most general alternative is to use a partial
phrase matching:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:'Ellis, J'">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<p>It would find not only all the authors mentioned above, but also
the ones whose names contain the expression <code>Ellis, J</code>
anywhere inside the name, such as <em>De Lellis, Jim</em>. It thus
gives you the largest possible number of hits at the largest risk of
false positives. The search is relatively slow.
<p>(Note though that this way of searching may be very handy in case
of compound family names such <em>Pepe-Altarelli, M</em> or <em>'t
Hooft, G</em> where a casual user query for <em>Hooft, G</em> would
match the wanted author, unlike the methods mentioned above.)
<li>Finally, let us note that you can use the <a href="#regexp">regular
expression syntax</a> to construct any complex author query. A simple
example is to search for an author expressed in the database as either
<em>Ellis, J</em> or <em>Ellis, John</em>:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="author:/^Ellis, (J|John)$/">
<select name="f"><option value="">any field<option>title<option selected>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Please consult <a href="#regexp">regular expression searching tips</a>
to know more about regular expression search possibilities.
</ol>
<p><a name="author-full-names"><strong><sup>*</sup>NOTE:</strong></a>
If you produce your own list of publications and you notice that
sometimes your first name is spelled abbreviated and sometimes in
full, or if you want to identify your publications among several
authors with the same abbreviation, please contact the <a
href="mailto:<ADMINEMAIL>">administrators</a> of <CDSNAMEINTL> so that
they could work with you on inputting a consistently spelled and
properly formatted first name everywhere. Only the consistent
database content will ensure a proper author searching behaviour.
<h4><a name="howto-sort-pattern">
<en>How to sort according to a certain pattern</en>
<fr>How to sort according to a certain pattern</fr>
<de>Wie lasse ich Ergebnisse auf eine bestimmte Weise sortieren</de>
<es>How to sort according to a certain pattern</es>
<ca>How to sort according to a certain pattern</ca>
<pl>How to sort according to a certain pattern</pl>
<pt>How to sort according to a certain pattern</pt>
<it>How to sort according to a certain pattern</it>
<ru>How to sort according to a certain pattern</ru>
<sk>How to sort according to a certain pattern</sk>
<cs>How to sort according to a certain pattern</cs>
<no>How to sort according to a certain pattern</no>
<sv>How to sort according to a certain pattern</sv>
<el>How to sort according to a certain pattern</el>
<uk>How to sort according to a certain pattern</uk>
<ja>How to sort according to a certain pattern</ja>
</a></h4>
<p>You may select a certain field according to which sort the search
results, for example to sort the results by main title. However,
sometimes you may want to sort by a report number and it happens
that your documents have several of them. For example, the report
numbers <em>hep-ph/0204140</em>, <em>CERN-TH-2002-069</em> and
<em>RM3-TH-02-4</em> all denote <a
href="<WEBURL>/search.py?p=CERN-TH-2002-069&amp;f=reportnumber">the
same document</a>. Now if you sort your search results set
containing this document, the system will take into consideration
the first report number, that may be either of these three.
Sometimes you may want to classify this document under its
<em>hep-ph</em> number, sometimes under its <em>CERN</em> number,
depending on whether you produce a list of CERN or hep-ph
publications. How can you influence the search engine to prefer
one report number rather than the other?
<p>In other words, the search engine by default answers a query
like "sort by first author" or "sort by first report number", but
sometimes you may want to ask the search engine to "sort by first
report number that starts by the text <em>CERN-</em>". The latter
possibility is available via a "silent" sort parameter called
<code>sp</code> (for "sort pattern") that sorts preferentially
according to the given textual pattern if they can be found. The
parameter is "silent" in a way that it is not present in the search
interface, you have to add it manually to your search URL.
For example, to get all CERN-TH publications of the year 2001
sorted by their CERN-TH numbers, you would search for
<code>CERN-TH-2001*</code> within <code>reportnumber</code> index,
and on the search results page, being satisfied with the results,
you would add <code>&sp=CERN-TH</code> to the URL to sort the
results preferentially by CERN-TH report numbers, to get a <a
href="<WEBURL>/search.py?p=reportnumber%3A%22CERN-TH-2001*%22&sf=reportnumber&so=a&sp=CERN-TH">nicely
sorted list</a> of all CERN-TH 2001 publications.
<h4><a name="howto-hepdoc">
<en>How to get documents from other servers (Google, SPIRES, KEK)</en>
<fr>How to get documents from other servers (Google, SPIRES, KEK)</fr>
<de>Wie bekomme ich Dokumente anderer Server (Google, SPIRES, KEK)</de>
<es>How to get documents from other servers (Google, SPIRES, KEK)</es>
<ca>How to get documents from other servers (Google, SPIRES, KEK)</ca>
<pl>How to get documents from other servers (Google, SPIRES, KEK)</pl>
<pt>How to get documents from other servers (Google, SPIRES, KEK)</pt>
<it>How to get documents from other servers (Google, SPIRES, KEK)</it>
<ru>How to get documents from other servers (Google, SPIRES, KEK)</ru>
<sk>How to get documents from other servers (Google, SPIRES, KEK)</sk>
<cs>How to get documents from other servers (Google, SPIRES, KEK)</cs>
<no>How to get documents from other servers (Google, SPIRES, KEK)</no>
<sv>How to get documents from other servers (Google, SPIRES, KEK)</sv>
<el>How to get documents from other servers (Google, SPIRES, KEK)</el>
<uk>How to get documents from other servers (Google, SPIRES, KEK)</uk>
<ja>How to get documents from other servers (Google, SPIRES, KEK)</ja>
</a></h4>
<p>On the search results page, links to other servers like <a
href="http://google.com/">Google</a>, <a
href="http://www.slac.stanford.edu/spires/hep/">SPIRES</a> or <a
href="http://www-lib.kek.jp/KISS/kiss_prepri.html">KEK</a> are
automatically proposed in a box entitled "Try your search on". You
can simply click on the proposed links to run your query on these
search engines.
<p>Note that the links aren't printed if the search engine doesn't
support it. For example, SPIRES or KEK cannot search for terms within
"any field", so we don't link to them in these cases.
<ifeq "<CFG_CERN_SITE>" "1" "
<p>Note also that KEK has scanned a lot of old CERN reports. If
you find that we don't have fulltext to some old CERN report, it
may be worthy to look there. For example, search for <em>CERN
ISR-MA/73-17</em> in our system:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="CERN ISR-MA/73-17">
<select name="f"><option value="">any field<option>title<option>author<option selected>reportnumber</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
and you will see that CDS contains the document in the archives only, i.e. not in a electronic format.
However, if you follow the proposed <a href="http://www-lib.kek.jp/cgi-bin/kiss_prepri?RP=CERN%20ISR-MA/73-17">KEK search link</a>,
you will see that KEK proposes &quot;scanned images&quot; that you can download.
">
<h4><a name="howto-fulltext">
<en>How to search in fulltext files</en>
<fr>How to search in fulltext files</fr>
<de>Wie kann ich in verknüpften Volltextdateien suchen</de>
<es>How to search in fulltext files</es>
<ca>How to search in fulltext files</ca>
<pl>How to search in fulltext files</pl>
<pt>How to search in fulltext files</pt>
<it>How to search in fulltext files</it>
<ru>How to search in fulltext files</ru>
<sk>How to search in fulltext files</sk>
<cs>How to search in fulltext files</cs>
<no>How to search in fulltext files</no>
<sv>How to search in fulltext files</sv>
<el>How to search in fulltext files</el>
<uk>How to search in fulltext files</uk>
<ja>How to search in fulltext files</ja>
</a></h4>
<p>If a metadata record contains some associated fulltext files, <CDSNAMEINTL>
tries to extract the textual information from the files and index it into a separate <code>fulltext</code> index.
To search for all records that contain the term <em>e-</em> in their fulltext files,
type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="fulltext:e-">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Recall that fulltext words aren't included in the default global ``any field'' index,
but that you may freely combine a fulltext and metadata search. For example, to find all
articles written by <em>Ellis</em> that contain the word <em>muon</em> either in the
metadata or in the fulltext, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="muon or fulltext:muon and author:ellis">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<ifeq "<CFG_CERN_SITE>" "1" "
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
IMPORTANT NOTE
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
Currently, the fulltext indexes aren't available on the CERN site.
Assumed operational time: Q1 2004.
Please use the
<a href="http://weblib.cern.ch/fulltext.shtml">old fulltext interface</a>
instead in the meantime.
</td>
</tr>
</tbody>
</table>
">
<h4><a name="howto-citations">
<en>How to search for citations</en>
<fr>How to search for citations</fr>
<de>Wie kann ich nach Zitaten suchen</de>
<es>How to search for citations</es>
<ca>How to search for citations</ca>
<pl>How to search for citations</pl>
<pt>How to search for citations</pt>
<it>How to search for citations</it>
<ru>How to search for citations</ru>
<sk>How to search for citations</sk>
<cs>How to search for citations</cs>
<no>How to search for citations</no>
<sv>How to search for citations</sv>
<el>How to search for citations</el>
<uk>How to search for citations</uk>
<ja>How to search for citations</ja>
</a></h4>
<p>If a metadata record contains an associated fulltext file, <CDSNAMEINTL>
tries to extract references automatically from that file and index
them into a separate <code>reference</code> index. To search for
all records that cite <em>Ellis</em> in their reference lists,
type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="reference:Ellis">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
To search for all records that cite preprint <em>hep-ph/0103062</em>
in their reference lists, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="reference:hep-ph/0103062">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
To search for all records that cite an article from <em>Giddings</em> and <em>Ross</em> published in
<em>Physical Review D</em> in volume <em>61</em> in year <em>2000</em>, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=70 type="text" name="p" value="reference:giddings reference:ross reference:&quot;Phys. Rev., D&quot; reference:61 reference:2000">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
Recall that citation terms aren't included in the default global "any field" index,
but that you may freely combine a citation search with a metadata search.
For example, to find all articles on <em>standard model</em> that aren't written by
<em>Ellis</em> but that do cite him, type:
<form action="<WEBURL>/search.py" method="get">
<blockquote>
<input size=40 type="text" name="p" value="standard model -author:ellis reference:ellis">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</blockquote>
</form>
<ifeq "<CFG_CERN_SITE>" "1" "
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
IMPORTANT NOTE
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
Currently, the reference indexes aren't available on the CERN site.
The citation search is therefore impossible at the moment.
Assumed operational time: Q1 2004.
</td>
</tr>
</tbody>
</table>
">
diff --git a/modules/websearch/doc/hacking/Makefile.am b/modules/websearch/doc/hacking/Makefile.am
index 800fb75f7..319aaac96 100644
--- a/modules/websearch/doc/hacking/Makefile.am
+++ b/modules/websearch/doc/hacking/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/websearch
doc_DATA=api.html stages.html index.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/websearch/doc/hacking/api.html.wml b/modules/websearch/doc/hacking/api.html.wml
index 17cf0bf31..dd806c0d6 100644
--- a/modules/websearch/doc/hacking/api.html.wml
+++ b/modules/websearch/doc/hacking/api.html.wml
@@ -1,324 +1,324 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Search Engine API" \
navbar_name="hacking-websearch" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=index.html>WebSearch Internals</a> " \
navbar_select="hacking-websearch-api"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<protect>
<pre>
CDSware Search Engine can be called from within your Python programs
via both a high-level and low-level API interface.
1. High-level API
Description:
The high-level access to the search engine is provided by
exactly the same function as called from the web interface when
users submit their queries. This should guarantee exactly the
same behaviour, and means that you can pass to the high-level
API all the arguments as you see them in the URL.
There are two things to note: (i) the function does not check
for eventual restricted status of the collection, so the
restricted collections will be searched without asking for a
password; (ii) the output format argument (``of'') should be set
to ``id'' (which is the default value) meaning to return list of
recIDs. The function returns the list of recIDs in this case.
Signature:
def perform_request_search(req=None, cc=cdsname, c=None, p="", f="", rg="10", sf="", so="d", sp="", rm="", of="id", ot="", as="0",
p1="", f1="", m1="", op1="", p2="", f2="", m2="", op2="", p3="", f3="", m3="", sc="0", jrec="0",
recid="-1", recidb="-1", sysno="", id="-1", idb="-1", sysnb="", action="",
d1y="", d1m="", d1d="", d2y="", d2m="", d2d="", verbose="0", ap="0", ln=cdslang):
"""Perform search or browse request, without checking for
authentication. Return list of recIDs found, if of=id.
Otherwise create web page.
The arguments are as follows:
req - mod_python Request class instance.
cc - current collection (e.g. "ATLAS"). The collection the
user started to search/browse from.
c - collectin list (e.g. ["Theses", "Books"]). The
collections user may have selected/deselected when
starting to search from 'cc'.
p - pattern to search for (e.g. "ellis and muon or kaon").
f - field to search within (e.g. "author").
rg - records in groups of (e.g. "10"). Defines how many hits
per collection in the search results page are
displayed.
sf - sort field (e.g. "title").
so - sort order ("a"=ascending, "d"=descending).
sp - sort pattern (e.g. "CERN-") -- in case there are more
values in a sort field, this argument tells which one
to prefer
rm - ranking method (e.g. "jif"). Defines whether results
should be ranked by some known ranking method.
of - output format (e.g. "hb"). Usually starting "h" means
HTML output (and "hb" for HTML brief, "hd" for HTML
detailed), "x" means XML output, "t" means plain text
output, "id" means no output at all but to return list
of recIDs found. (Suitable for high-level API.)
ot - output only these MARC tags (e.g. "100,700,909C0b").
Useful if only some fields are to be shown in the
output, e.g. for library to control some fields.
as - advanced search ("0" means no, "1" means yes). Whether
search was called from within the advanced search
interface.
p1 - first pattern to search for in the advanced search
interface. Much like 'p'.
f1 - first field to search within in the advanced search
interface. Much like 'f'.
m1 - first matching type in the advanced search interface.
("a" all of the words, "o" any of the words, "e" exact
phrase, "p" partial phrase, "r" regular expression).
op1 - first operator, to join the first and the second unit
in the advanced search interface. ("a" add, "o" or,
"n" not).
p2 - second pattern to search for in the advanced search
interface. Much like 'p'.
f2 - second field to search within in the advanced search
interface. Much like 'f'.
m2 - second matching type in the advanced search interface.
("a" all of the words, "o" any of the words, "e" exact
phrase, "p" partial phrase, "r" regular expression).
op2 - second operator, to join the second and the third unit
in the advanced search interface. ("a" add, "o" or,
"n" not).
p3 - third pattern to search for in the advanced search
interface. Much like 'p'.
f3 - third field to search within in the advanced search
interface. Much like 'f'.
m3 - third matching type in the advanced search interface.
("a" all of the words, "o" any of the words, "e" exact
phrase, "p" partial phrase, "r" regular expression).
sc - split by collection ("0" no, "1" yes). Governs whether
we want to present the results in a single huge list,
or splitted by collection.
jrec - jump to record (e.g. "234"). Used for navigation
inside the search results.
recid - display record ID (e.g. "20000"). Do not
search/browse but go straight away to the Detailed
record page for the given recID.
recidb - display record ID bis (e.g. "20010"). If greater than
'recid', then display records from recid to recidb.
Useful for example for dumping records from the
database for reformatting.
sysno - display old system SYS number (e.g. ""). If you
migrate to CDSware from another system, and store your
old SYS call numbers, you can use them instead of recid
if you wish so.
id - the same as recid, in case recid is not set. For
backwards compatibility.
idb - the same as recid, in case recidb is not set. For
backwards compatibility.
sysnb - the same as sysno, in case sysno is not set. For
backwards compatibility.
action - action to do. "SEARCH" for searching, "Browse" for
browsing. Default is to search.
d1y - first date year (e.g. "1998"). Useful for search
limits on creation date.
d1m - first date month (e.g. "08"). Useful for search
limits on creation date.
d1d - first date day (e.g. "23"). Useful for search
limits on creation date.
d2y - second date year (e.g. "1998"). Useful for search
limits on creation date.
d2m - second date month (e.g. "09"). Useful for search
limits on creation date.
d2d - second date day (e.g. "02"). Useful for search limits
on creation date.
verbose - verbose level (0=min, 9=max). Useful to print some
internal information on the searching process in case
something goes wrong.
ap - alternative patterns (0=no, 1=yes). In case no exact
match is found, the search engine can try alternative
patterns e.g. to replace non-alphanumeric characters by
a boolean query. ap defines if this is wanted.
ln - language of the search interface (e.g. "en"). Useful
for internationalization.
"""
Examples:
>>> # import the function:
>>> from cdsware.search_engine import perform_request_search
>>> # get all hits in a collection:
>>> perform_request_search(cc="ATLAS Communications")
>>> # search for the word `of' in Theses and Books:
>>> perform_request_search(p="of", c=["Theses","Books"])
>>> # search for `muon or kaon' within title:
>>> perform_request_search(p="muon or kaon", f="title")
>>> # phrase search (not the quotes):
>>> perform_request_search(p='"Ellis, J"', f="author")
>>> # regexp search for a system number
>>> perform_request_search(p1="^CERN.*2003-001$", f1="reportnumber", m1="r")
>>> # moi inside Standards gives no hits...
>>> perform_request_search(p="moi", cc="Standards")
>>> # but it does if we use alternative patterns:
>>> perform_request_search(p="moi", cc="Standards", ap=1)
2. Mid-level API
Description:
The mid-level API is provided by a search_pattern() function
that only searches for the given pattern in the given field
according to the given matching pattern. This function does not
know anything about collection. The function does not wash its
arguments, it expects them to be `clean' already. The pattern
is split into `basic search units' for which a boolean query is
launched. The function returns an instance of the HitSet class.
Note that if you want to obtain the list of recIDs (as with the
high-level API), you can invoke the ``tolist()'' method on a
hitset.
Signature:
def search_pattern(req=None, p=None, f=None, m=None, ap=0, of="id", verbose=0):
"""Search for complex pattern 'p' within field 'f' according to
matching type 'm'. Return hitset of recIDs.
The function uses multi-stage searching algorithm in case of no
exact match found. See the Search Internals document for
detailed description.
The 'ap' argument governs whether an alternative patterns are to
be used in case there is no direct hit for (p,f,m). For
example, whether to replace non-alphanumeric characters by
spaces if it would give some hits. See the Search Internals
document for detailed description. (ap=0 forbits the
alternative pattern usage, ap=1 permits it.)
The 'of' argument governs whether to print or not some
information to the user in case of no match found. (Usually it
prints the information in case of HTML formats, otherwise it's
silent).
The 'verbose' argument controls the level of debugging information
to be printed (0=least, 9=most).
All the parameters are assumed to have been previously washed.
This function is suitable as a mid-level API.
"""
Examples:
>>> # import the function:
>>> from cdsware.search_engine import search_pattern
>>> # search for muon or kaon in any field:
>>> search_pattern(p="muon or kaon").tolist()
>>> # the following finds nothing by default...
>>> search_pattern(p="cern-moi").tolist()
>>> # ...but it does find something if we allow alternative patterns:
>>> search_pattern(p="cern-moi", ap=1).tolist()
>>> # wildcard search for a report number:
>>> search_pattern(p="CERN-LHC-PROJECT-REPORT-40*", f="reportnumber").tolist()
>>> # regexp search for a report number with possible trailing subjects:
>>> search_pattern(p="^CERN-LHC-PROJECT-REPORT-40(-|$)", f="reportnumber", m="r").tolist()
3. Low-level API
Description:
The low-level API is provided by search_unit() function that
assumes its arguments to be already the basic search units.
Therefore it does not know anything about boolean queries, etc.
The function returns an instance of the HitSet class. Note that
if you want to obtain the list of recIDs (as with the high-level
API), you can invoke the ``tolist()'' method on a hitset.
Signature:
def search_unit(p, f=None, m=None):
"""Search for basic search unit defined by pattern 'p' and field
'f' and matching type 'm'. Return hitset of recIDs.
All the parameters are assumed to have been previously washed.
'p' is assumed to be already a ``basic search unit'' so that it
is searched as such and is not broken up in any way. Only
wildcard and span queries are being detected inside 'p'.
This function is suitable as a low-level API.
"""
Examples:
>>> # import the function:
>>> from cdsware.search_engine import search_unit
>>> # search moi in any field:
>>> search_unit(p="moi").tolist()
>>> # this one will not match:
>>> search_unit(p="muon or kaon").tolist()
>>> # regexp search for a report number with possible trailing subjects:
>>> search_unit(p="^CERN-PS-99-037(-|$)", f="reportnumber", m="r").tolist()
More entry points may be created, but I think this threesome kind of
access to the search engine should cover all your needs.
</pre>
</protect>
diff --git a/modules/websearch/doc/hacking/index.html.wml b/modules/websearch/doc/hacking/index.html.wml
index 864b56c7f..0e5db99ed 100644
--- a/modules/websearch/doc/hacking/index.html.wml
+++ b/modules/websearch/doc/hacking/index.html.wml
@@ -1,39 +1,39 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebSearch Internals" \
navbar_name="hacking-websearch" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a>" \
navbar_select="hacking-websearch-index"
This page summarizes all the information suitable to dig inside
Search Engine internals.
<blockquote>
<dl>
<dt><a href="stages.html">Search Processing Stages</a> <dd>Explains what
happens after user hits the SEARCH button.
<dt><a href="api.html">Search Engine API</a> <dd>Explains how to call
search engine from your Python programs, should a need arize.
</dl>
</blockquote>
diff --git a/modules/websearch/doc/hacking/stages.html.wml b/modules/websearch/doc/hacking/stages.html.wml
index dc27c74f4..139c434fa 100644
--- a/modules/websearch/doc/hacking/stages.html.wml
+++ b/modules/websearch/doc/hacking/stages.html.wml
@@ -1,166 +1,166 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="Search Processing Stages" \
navbar_name="hacking-websearch" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/hacking/>Hacking CDSware</a> &gt; <a class=navtrail href=index.html>WebSearch Internals</a> " \
navbar_select="hacking-websearch-stages"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
What the search engine does after it receives a user query? Let us
explain the steps it takes for a fictive complex query example in
which a user typed
author:ellis reportnumber:TH-2003-114 -muon +energ* title:"kaon decay"
and selected "Theses" and "Books" collections and the "arrival date"
between the 10th and the 20th of March 2003.
The search engine proceeds as follows.
1. Firstly we classify and break apart our search arguments into a)
basic search units and b+c) additional search options:
a) (p_1, f_1), (p_2, f_2), ..., (p_m, f_m) --- the list of basic
(pattern, field) searching units. The user-typed boolean
query is split into the (p_i, f_i) units according to the
non-significant whitespace. (A whitespace is considered to
be significant when it occurs within quoted expressions for
phrase searching, see Search Tips and user-level
documentation.) In our example, the list of basic search
units is: (author, ellis), (reportnumber, TH-2003-114),
(anyfield, muon), (anyfield, energ*), (title, "kaon decay").
b) c_1, c_2, ..., c_n --- the list of collections the user wanted
to search in. In our example: Theses, Books.
c) l_1, l_2, ..., l_o --- the list of additional limiting search
criteria, such as limit to certain arrival date, certain
language, or certain subject category. The user usually
selects such limits from within Advanced Search interface
and its selection boxes. In our example, the limit is on
the arrival date: (arrivaldate, 20030310->20030320).
The basic search units and additional search arguments are then
dealt with subsequently (from a to c with decreasing priority) in
the following searching stages.
2. For each (p_i, f_i), we verify that at least some hits can be found
regardless of c_j and l_k. In other words, we make sure that p_i
is a known indexed term in f_i. Note that p_i may contain
asterisks and may start and end by a single/double quotes, with the
following special meaning:
foo*bar -- asterisk is a wildcard character, meaning to match
any sequence of characters
"foo and bar" -- double quotes to denote exact phrase matching
'foo and bar' -- single quotes to denote partial phrase matching
The p_i (word or phrase) is then tested for existence in the f_i
(word or phrase) index.
2-1. If p_i was found in the f_i index, we retain the (p_i, f_i)
search unit. We also retain it in the case when p_i wasn't
found in the f_i index but when (p_i, f_i) is joined to the
previous unit or to the next unit by boolean operator OR.
2-2. If p_i wasn't found inside f_i, we then look whether p_i
contains some non-alphanumeric characters, such as a dash or a
slash. If this is so, we try to replace them with a boolean
AND query. In our example, the search unit (reportnumber,
TH-2003-114) would be replaced by a new boolean query for
(reportnumber,TH) and (reportnumber,2003) and
(reportnumber,114). If this new query succeeds, we retain
this new boolean query in place of the old search unit.
2-3. If the preceding step failed, we propose to the end user a
list of nearest indexed terms (words, phrases) around p_i
within f_i index and let the user choose one known indexed
term out of this list. In our example, the phrase "kaon
decay" cannot be found in the title index, so we'll propose
closest titles around "kaon decay ...". Let's suppose that
the user will choose "Kaon decays and the flavour problem" out
of this list.
After all the basic search units (p_i, f_i) have been treated we
may proceed to the following stage 3.
3. At this stage, all search units (p_i, f_i) are known to yield at
least some results. We now continue by trying boolean query as
specified by the user. The execution priority goes from left to
right, the known boolean operators are:
+ for set intersection
- for set difference
| for set union
In our example, we proceed by doing the set intersections of
(author, ellis), (reportnumber,TH), (reportnumber,2003),
(reportnumber,114), followed by set differentiation with (anyfield,
muon), followed by set intersection with (anyfield, energ*) and
(title, "Kaon decays and the flavour problem").
3-1. If this gives some hits, we proceed to stage 4.
3-2. If this does not give any hit, we display the number of hits
found for each search unit, advise the user to combine his
search terms differently, and we stop.
4. At this stage, the boolean query (p_1, f_1), (p_2, f_2), ... ,
(p_n, f_n) is known to yield some results. We now continue by
checking whether these results fall into collections c_j that the
user has chosen. This is done by performing a set intersection of
the results obtained so far with the collection universe for c_j.
4-1. If this gives some hits, we proceed to stage 5.
4-2. If this does not give any hit, we first try to look for the
query in any public collection.
4-2-1. If this gives some hits, we warn the user that no match
could have been found in his c_j choice but that there
are hits in other public collections. We propose a
link to get them and we stop.
4-2-2. If this does not give any hit, then there must have
been some hits in some of the restricted collections.
We display a warning that the restricted collections
must be explicitly selected before searching and we
stop.
5. At this stage, the boolean query (p_i, f_i) within c_j is known to
yield some results. We now proceed by checking additional search
limits l_k imposed by the user. This is done by subsequent set
intersections of the results obtained so far with the universe of
records matching limiting criteria (l_1, l_2, ..., l_o).
5-1. If this gives some hits, we proceed to stage 6.
5-2. If this does not give any hit for a certain l_k, we warn the
user that no match could have been found for his l_o choices
and proceed to stage 6 with the results obtained so far.
6. We are done and may display the results.
</pre>
diff --git a/modules/websearch/doc/index.html.wml b/modules/websearch/doc/index.html.wml
index 2b95bad12..d46d67681 100644
--- a/modules/websearch/doc/index.html.wml
+++ b/modules/websearch/doc/index.html.wml
@@ -1,154 +1,154 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="_(Search Help)_" \
navbar_name="search-new" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a>" \
navbar_select="tips"
<p><en>Find out all about searching</en>
<fr>Trouvez tout sur la recherche de</fr>
<de>Lernen Sie alles über den Suchemöglichkeiten beim</de>
<es>Find out all about searching</es>
<ca>Trobeu tota l'ajuda sobre la cerca</ca>
<pl>Find out all about searching</pl>
<pt>Descubra tudo sobre buscas no</pt>
<it>Tutto quanto vi serve per poter ricercare in</it>
<ru>Find out all about searching</ru>
<sk>Tu nájdete všetko čo sa týka hľadania na serveri</sk>
<cs>Zde naleznete vše co se týče vyhledávání na serveru</cs>
<no>Finn ut alt om søking i</no>
<sv>Finn ut allt om sökning av</sv>
<el>Find out all about searching</el>
<uk>Find out all about searching</uk>
<ja>Find out all about searching</ja>
<CDSNAMEINTL>:
<blockquote>
<dl>
<dt><a href="<lang:star: tips.*.html>">_(Search Tips)_</a>
<dd>
<en>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</en>
<fr>
Cette page vous présente des suggestions et des techniques qui puissent vous être utiles
afin d'utiliser le site de <CDSNAMEINTL> à plein.
</fr>
<de>
Diese Seite zeigt Ihnen alle nützliche Tipps und Techniken die
beim <CDSNAMEINTL> zur Verfügung stehen.
</de>
<es>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</es>
<ca>
Aquesta pàgina us presenta suggeriments i tècniques que us poden
resultar útils per usar <CDSNAMEINTL> en totes les seves possibilitats.
</ca>
<pl>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</pl>
<pt>
Esta página oferece dicas úteis e técnicas para ajuda-lo a usar o sítio do
<CDSNAMEINTL> em toda sua potencialidade.
</pt>
<it>
Questa pagina vi fornisce utili consigli per servirvi al meglio
<CDSNAMEINTL>.
</it>
<ru>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</ru>
<sk>
Táto stránka Vám ponúka užitočné tipy a triky ktoré Vám umožnia
plne využívať možností <CDSNAMEINTL>.
</sk>
<cs>
Tato stránka Vám nabízí užitečné tipy a triky které Vám umožní
plně využívat možností <CDSNAMEINTL>.
</cs>
<no>
Denne siden presenter nyttige tips og teknikker slik at du lettere kan få
fullt utbytte av <CDSNAMEINTL> sine sider.
</no>
<sv>
Denna sida ger dig användbara tips och tekniker för att hjälpa dig att
till fullo använda denna webbplats som <CDSNAMEINTL> erbjuder dig.
</sv>
<el>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</el>
<uk>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</uk>
<ja>
This page presents you with useful tips and techniques in order to
help you use the <CDSNAMEINTL> site to the full.
</ja>
<dt><a href="<lang:star: guide.*.html>">
<en>Search Guide</en>
<fr>Guide de Recherche</fr>
<de>Search Guide</de>
<es>Search Guide</es>
<ca>Guia de Cerca</ca>
<pl>Search Guide</pl>
<pt>Guia de buscas</pt>
<it>Search Guide</it>
<ru>Search Guide</ru>
<sk>Search Guide</sk>
<cs>Search Guide</cs>
<no>Search Guide</no>
<sv>Search Guide</sv>
<el>Search Guide</el>
<uk>Search Guide</uk>
<ja>Search Guide</ja>
</a>
<dd><en>Full guide on how to search</en>
<fr>Le guide complet sur comment rechercher sur</fr>
<de>Full guide on how to search</de>
<es>Full guide on how to search</es>
<ca>Guia completa de com cercar a l'</ca>
<pl>Full guide on how to search</pl>
<pt>Guia completo de como realizar buscas no</pt>
<it>Full guide on how to search</it>
<ru>Full guide on how to search</ru>
<sk>Full guide on how to search</sk>
<cs>Full guide on how to search</cs>
<no>Full guide on how to search</no>
<sv>Full guide on how to search</sv>
<el>Full guide on how to search</el>
<uk>Full guide on how to search</uk>
<ja>Full guide on how to search</ja>
<CDSNAMEINTL>.
</dl>
</blockquote>
diff --git a/modules/websearch/doc/tips.html.wml b/modules/websearch/doc/tips.html.wml
index 82504205b..8659009b6 100644
--- a/modules/websearch/doc/tips.html.wml
+++ b/modules/websearch/doc/tips.html.wml
@@ -1,304 +1,304 @@
## -*- mode: html; coding: utf-8; -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="_(Search Tips)_" \
navbar_name="search-new" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/search/<lang:star: index.*.html>>_(Search Help)_</a>" \
navbar_select="tips"
<h5>How to find any value in any field:</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Empty search box returns all records in the database.
</td>
</tr>
</table>
<h5>How to find documents in a particular collection:</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
<p>
Narrow by collection:
<br>
<input type="checkbox" name="c" value="Preprints" checked>&nbsp;<a href="<WEBURL>/?c=Preprints">Preprints</a>
<br>
<input type="checkbox" name="c" value="Theses" checked>&nbsp;<a href="<WEBURL>/?c=Theses">Theses</a>
</form>
</td>
<td width="50%">
Click on a link below the search box to see and select subcollections
such as Preprints or Theses, or select/deselect the tick boxes next to a
particular collection before doing the search.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="NA60">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
<p>
Narrow by collection:
<br>
<input type="checkbox" name="c" value="Preprints" checked>&nbsp;<a href="<WEBURL>/?c=Preprints">Preprints</a>
<br>
<input type="checkbox" name="c" value="Theses" checked>&nbsp;<a href="<WEBURL>/?c=Theses">Theses</a>
</form>
</td>
<td width="50%">
If you want documents from a 'collection' not proposed by default,
such as NA60 documents, then enter it as a search term.
</td>
</tr>
</table>
<div align="right"><small><a href="<lang:star: guide.*.html#howto-choose-terms>">more on how to wisely choose your search terms...</a></small></div>
<h5>How to search for words/phrases (within titles, abstracts, etc):</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="higgs boson">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records containing words <em>higgs</em> and <em>boson</em>.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="'higgs boson'">
<select name="f"><option value="">any field<option selected>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records containing phrase <em>'higgs boson'</em> in title.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="&quot;higgs boson&quot;">
<select name="f"><option value="">any field<option selected>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records entitled exactly <em>"Higgs boson"</em> but not records such as
<em>"Overview of Higgs boson production"</em>.
</td>
</tr>
</table>
<div align="right"><small><a href="<lang:star: guide.*.html#words-vs-phrases>">more on word and phrase searches...</a></small></div>
<h5>How to use truncation:</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="muon*">
<select name="f"><option value="">any field<option>title<option>author</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records containing words <em>muon</em>, <em>muons</em>, <em>muonic</em>, etc.
</td>
</tr>
</table>
<div align="right"><small><a href="<lang:star: guide.*.html#wildcard>">more on truncation...</a></small></div>
<h5>How to use boolean operators:</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="muon kaon">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
or:
<br>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="muon AND kaon">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records containing both <em>muon</em> and <em>kaon</em>.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="muon OR kaon">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records containing either <em>muon</em> or <em>kaon</em>.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="muon NOT kaon">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Returns records containing <em>muon</em> but not <em>kaon</em>.
</td>
</tr>
</table>
<div align="right"><small><a href="<lang:star: guide.*.html#boolean>">more on Boolean queries...</a></small></div>
<h5>How to find documents from a certain period:</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="2003">
<select name="f"><option value="">any field<option>title<option>author<option selected>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Type 2003 and select the year field.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="year:2003">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Alternatively, type field name colon value.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="year:2003->2004">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
You can enter specific year range.
</td>
</tr>
</table>
<div align="right"><small><a href="<lang:star: guide.*.html#span>">more on span queries...</a></small></div>
<h5>How to search for authors:</h5>
<table width="100%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="Ellis">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Some authors have unique names and
their publications can be retrieved by searching for
the surname in any field.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="Ellis, J R">
<select name="f"><option value="">any field<option>title<option selected>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
For better results, type surname comma initial(s) and select the author field.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="Ellis, John Rolfe">
<select name="f"><option value="">any field<option>title<option selected>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Sometimes authors are indexed with their full name.
</td>
</tr>
<tr>
<td width="50%" nowrap>
<form action="<WEBURL>/search.py" method="get">
<input size=20 type="text" name="p" value="author:&quot;Ellis, J*&quot; year:1990->1993">
<select name="f"><option value="">any field<option>title<option>author<option>year</select>
<input class="formbutton" type="submit" name="action" value="SEARCH">
</form>
</td>
<td width="50%">
Find papers by J.Ellis written from 1990 until 1993, using truncation
to match all first names beginning with J.
</td>
</tr>
</table>
<div align="right"><small><a href="<lang:star: guide.*.html#howto-search-for-author>">more on author searches...</a></small></div>
<h5>More information:</h5>
Special characters, regular expressions, fulltext searching, citation
searching, and other capabilities are fully explained in the complete
<a href="<lang:star: guide.*.html>">Search Guide</a>.
diff --git a/modules/websearch/lib/Makefile.am b/modules/websearch/lib/Makefile.am
index 82b08f242..575c71efc 100644
--- a/modules/websearch/lib/Makefile.am
+++ b/modules/websearch/lib/Makefile.am
@@ -1,27 +1,27 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = websearchadminlib.py websearch_templates.py \
search_engine.py search_engine_config.py search_engine_tests.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/websearch/lib/search_engine.py b/modules/websearch/lib/search_engine.py
index 158b11be4..c55643269 100644
--- a/modules/websearch/lib/search_engine.py
+++ b/modules/websearch/lib/search_engine.py
@@ -1,3511 +1,3511 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Search Engine in mod_python."""
__lastupdated__ = """$Date$"""
__version__ = "$Id$"
## import general modules:
import cgi
import copy
import Cookie
import cPickle
import marshal
import fileinput
import getopt
import string
from string import split
import os
import sre
import sys
import time
import traceback
import urllib
import zlib
import MySQLdb
import Numeric
import md5
import base64
import unicodedata
from xml.dom import minidom
## import CDSware stuff:
from cdsware.config import *
from cdsware.search_engine_config import *
from cdsware.bibrank_record_sorter import get_bibrank_methods,rank_records
from cdsware.bibrank_downloads_similarity import register_page_view_event, calculate_reading_similarity_list
if cfg_experimental_features:
from cdsware.bibrank_citation_searcher import calculate_cited_by_list, calculate_co_cited_with_list
from cdsware.bibrank_citation_grapher import create_citation_history_graph_and_box
from cdsware.bibrank_downloads_grapher import create_download_history_graph_and_box
from cdsware.dbquery import run_sql
try:
from mod_python import apache
from cdsware.webuser import getUid
from cdsware.webpage import pageheaderonly, pagefooteronly, create_error_box
except ImportError, e:
pass # ignore user personalisation, needed e.g. for command-line
from cdsware.messages import gettext_set_language, wash_language
try:
import cdsware.template
websearch_templates = cdsware.template.load('websearch')
except:
pass
## global vars:
search_cache = {} # will cache results of previous searches
cfg_nb_browse_seen_records = 100 # limit of the number of records to check when browsing certain collection
cfg_nicely_ordered_collection_list = 0 # do we propose collection list nicely ordered or alphabetical?
## precompile some often-used regexp for speed reasons:
sre_word = sre.compile('[\s]')
sre_quotes = sre.compile('[\'\"]')
sre_doublequote = sre.compile('\"')
sre_equal = sre.compile('\=')
sre_logical_and = sre.compile('\sand\s', sre.I)
sre_logical_or = sre.compile('\sor\s', sre.I)
sre_logical_not = sre.compile('\snot\s', sre.I)
sre_operators = sre.compile(r'\s([\+\-\|])\s')
sre_pattern_wildcards_at_beginning = sre.compile(r'(\s)[\*\%]+')
sre_pattern_single_quotes = sre.compile("'(.*?)'")
sre_pattern_double_quotes = sre.compile("\"(.*?)\"")
sre_pattern_regexp_quotes = sre.compile("\/(.*?)\/")
sre_pattern_short_words = sre.compile(r'([\s\"]\w{1,3})[\*\%]+')
sre_pattern_space = sre.compile("__SPACE__")
sre_pattern_today = sre.compile("\$TODAY\$")
sre_unicode_lowercase_a = sre.compile(unicode(r"(?u)[áàäâãå]", "utf-8"))
sre_unicode_lowercase_ae = sre.compile(unicode(r"(?u)[æ]", "utf-8"))
sre_unicode_lowercase_e = sre.compile(unicode(r"(?u)[éèëê]", "utf-8"))
sre_unicode_lowercase_i = sre.compile(unicode(r"(?u)[íìïî]", "utf-8"))
sre_unicode_lowercase_o = sre.compile(unicode(r"(?u)[óòöôõø]", "utf-8"))
sre_unicode_lowercase_u = sre.compile(unicode(r"(?u)[úùüû]", "utf-8"))
sre_unicode_lowercase_y = sre.compile(unicode(r"(?u)[ýÿ]", "utf-8"))
sre_unicode_lowercase_c = sre.compile(unicode(r"(?u)[çć]", "utf-8"))
sre_unicode_lowercase_n = sre.compile(unicode(r"(?u)[ñ]", "utf-8"))
sre_unicode_uppercase_a = sre.compile(unicode(r"(?u)[ÁÀÄÂÃÅ]", "utf-8"))
sre_unicode_uppercase_ae = sre.compile(unicode(r"(?u)[Æ]", "utf-8"))
sre_unicode_uppercase_e = sre.compile(unicode(r"(?u)[ÉÈËÊ]", "utf-8"))
sre_unicode_uppercase_i = sre.compile(unicode(r"(?u)[ÍÌÏÎ]", "utf-8"))
sre_unicode_uppercase_o = sre.compile(unicode(r"(?u)[ÓÒÖÔÕØ]", "utf-8"))
sre_unicode_uppercase_u = sre.compile(unicode(r"(?u)[ÚÙÜÛ]", "utf-8"))
sre_unicode_uppercase_y = sre.compile(unicode(r"(?u)[Ý]", "utf-8"))
sre_unicode_uppercase_c = sre.compile(unicode(r"(?u)[ÇĆ]", "utf-8"))
sre_unicode_uppercase_n = sre.compile(unicode(r"(?u)[Ñ]", "utf-8"))
def get_alphabetically_ordered_collection_list(collid=1, level=0):
"""Returns nicely ordered (score respected) list of collections, more exactly list of tuples
(collection name, printable collection name).
Suitable for create_search_box()."""
out = []
query = "SELECT id,name FROM collection ORDER BY name ASC"
res = run_sql(query)
for c_id, c_name in res:
# make a nice printable name (e.g. truncate c_printable for for long collection names):
if len(c_name)>30:
c_printable = c_name[:30] + "..."
else:
c_printable = c_name
if level:
c_printable = " " + level * '-' + " " + c_printable
out.append([c_name, c_printable])
return out
def get_nicely_ordered_collection_list(collid=1, level=0):
"""Returns nicely ordered (score respected) list of collections, more exactly list of tuples
(collection name, printable collection name).
Suitable for create_search_box()."""
colls_nicely_ordered = []
query = "SELECT c.name,cc.id_son FROM collection_collection AS cc, collection AS c "\
" WHERE c.id=cc.id_son AND cc.id_dad='%s' ORDER BY score DESC" % collid
res = run_sql(query)
for c, cid in res:
# make a nice printable name (e.g. truncate c_printable for for long collection names):
if len(c)>30:
c_printable = c[:30] + "..."
else:
c_printable = c
if level:
c_printable = " " + level * '-' + " " + c_printable
colls_nicely_ordered.append([c, c_printable])
colls_nicely_ordered = colls_nicely_ordered + get_nicely_ordered_collection_list(cid, level+1)
return colls_nicely_ordered
def get_index_id(field):
"""Returns first index id where the field code FIELD is indexed.
Returns zero in case there is no table for this index.
Example: field='author', output=4."""
out = 0
query = """SELECT w.id FROM idxINDEX AS w, idxINDEX_field AS wf, field AS f
WHERE f.code='%s' AND wf.id_field=f.id AND w.id=wf.id_idxINDEX
LIMIT 1""" % MySQLdb.escape_string(field)
res = run_sql(query, None, 1)
if res:
out = res[0][0]
return out
def get_words_from_pattern(pattern):
"Returns list of whitespace-separated words from pattern."
words = {}
for word in split(pattern):
if not words.has_key(word):
words[word] = 1;
return words.keys()
def create_basic_search_units(req, p, f, m=None, of='hb'):
"""Splits search pattern and search field into a list of independently searchable units.
- A search unit consists of '(operator, pattern, field, type, hitset)' tuples where
'operator' is set union (|), set intersection (+) or set exclusion (-);
'pattern' is either a word (e.g. muon*) or a phrase (e.g. 'nuclear physics');
'field' is either a code like 'title' or MARC tag like '100__a';
'type' is the search type ('w' for word file search, 'a' for access file search).
- Optionally, the function accepts the match type argument 'm'.
If it is set (e.g. from advanced search interface), then it
performs this kind of matching. If it is not set, then a guess is made.
'm' can have values: 'a'='all of the words', 'o'='any of the words',
'p'='phrase/substring', 'r'='regular expression',
'e'='exact value'.
- Warnings are printed on req (when not None) in case of HTML output formats."""
opfts = [] # will hold (o,p,f,t,h) units
## check arguments: if matching type phrase/string/regexp, do we have field defined?
if (m=='p' or m=='r' or m=='e') and not f:
m = 'a'
if of.startswith("h"):
print_warning(req, "This matching type cannot be used within <em>any field</em>. I will perform a word search instead." )
print_warning(req, "If you want to phrase/substring/regexp search in a specific field, e.g. inside title, then please choose <em>within title</em> search option.")
## is desired matching type set?
if m:
## A - matching type is known; good!
if m == 'e':
# A1 - exact value:
opfts.append(['+',p,f,'a']) # '+' since we have only one unit
elif m == 'p':
# A2 - phrase/substring:
opfts.append(['+',"%"+p+"%",f,'a']) # '+' since we have only one unit
elif m == 'r':
# A3 - regular expression:
opfts.append(['+',p,f,'r']) # '+' since we have only one unit
elif m == 'a' or m == 'w':
# A4 - all of the words:
p = strip_accents(p) # strip accents for 'w' mode, FIXME: delete when not needed
for word in get_words_from_pattern(p):
opfts.append(['+',word,f,'w']) # '+' in all units
elif m == 'o':
# A5 - any of the words:
p = strip_accents(p) # strip accents for 'w' mode, FIXME: delete when not needed
for word in get_words_from_pattern(p):
if len(opfts)==0:
opfts.append(['+',word,f,'w']) # '+' in the first unit
else:
opfts.append(['|',word,f,'w']) # '|' in further units
else:
if of.startswith("h"):
print_warning(req, "Matching type '%s' is not implemented yet." % m, "Warning")
opfts.append(['+',"%"+p+"%",f,'a'])
else:
## B - matching type is not known: let us try to determine it by some heuristics
if f and p[0]=='"' and p[-1]=='"':
## B0 - does 'p' start and end by double quote, and is 'f' defined? => doing ACC search
opfts.append(['+',p[1:-1],f,'a'])
elif f and p[0]=="'" and p[-1]=="'":
## B0bis - does 'p' start and end by single quote, and is 'f' defined? => doing ACC search
opfts.append(['+','%'+p[1:-1]+'%',f,'a'])
elif f and p[0]=="/" and p[-1]=="/":
## B0ter - does 'p' start and end by a slash, and is 'f' defined? => doing regexp search
opfts.append(['+',p[1:-1],f,'r'])
elif f and string.find(p, ',') >= 0:
## B1 - does 'p' contain comma, and is 'f' defined? => doing ACC search
opfts.append(['+',p,f,'a'])
elif f and str(f[0:2]).isdigit():
## B2 - does 'f' exist and starts by two digits? => doing ACC search
opfts.append(['+',p,f,'a'])
else:
## B3 - doing WRD search, but maybe ACC too
# search units are separated by spaces unless the space is within single or double quotes
# so, let us replace temporarily any space within quotes by '__SPACE__'
p = sre_pattern_single_quotes.sub(lambda x: "'"+string.replace(x.group(1), ' ', '__SPACE__')+"'", p)
p = sre_pattern_double_quotes.sub(lambda x: "\""+string.replace(x.group(1), ' ', '__SPACE__')+"\"", p)
p = sre_pattern_regexp_quotes.sub(lambda x: "/"+string.replace(x.group(1), ' ', '__SPACE__')+"/", p)
# wash argument:
p = sre_equal.sub(":", p)
p = sre_logical_and.sub(" ", p)
p = sre_logical_or.sub(" |", p)
p = sre_logical_not.sub(" -", p)
p = sre_operators.sub(r' \1', p)
for pi in split(p): # iterate through separated units (or items, as "pi" stands for "p item")
pi = sre_pattern_space.sub(" ", pi) # replace back '__SPACE__' by ' '
# firstly, determine set operator
if pi[0] == '+' or pi[0] == '-' or pi[0] == '|':
oi = pi[0]
pi = pi[1:]
else:
# okay, there is no operator, so let us decide what to do by default
oi = '+' # by default we are doing set intersection...
# secondly, determine search pattern and field:
if string.find(pi, ":") > 0:
fi, pi = split(pi, ":", 1)
else:
fi, pi = f, pi
# look also for old ALEPH field names:
if fi and cfg_fields_convert.has_key(string.lower(fi)):
fi = cfg_fields_convert[string.lower(fi)]
# wash 'pi' argument:
if sre_quotes.match(pi):
# B3a - quotes are found => do ACC search (phrase search)
if fi:
if pi[0] == '"' and pi[-1] == '"':
pi = string.replace(pi, '"', '') # remove quote signs
opfts.append([oi,pi,fi,'a'])
elif pi[0] == "'" and pi[-1] == "'":
pi = string.replace(pi, "'", "") # remove quote signs
opfts.append([oi,"%"+pi+"%",fi,'a'])
else: # unbalanced quotes, so do WRD query:
opfts.append([oi,pi,fi,'w'])
else:
# fi is not defined, look at where we are doing exact or subphrase search (single/double quotes):
if pi[0]=='"' and pi[-1]=='"':
opfts.append([oi,pi[1:-1],"anyfield",'a'])
if of.startswith("h"):
print_warning(req, "Searching for an exact match inside any field may be slow. You may want to search for words instead, or choose to search within specific field.")
else:
# nope, subphrase in global index is not possible => change back to WRD search
pi = strip_accents(pi) # strip accents for 'w' mode, FIXME: delete when not needed
for pii in get_words_from_pattern(pi):
# since there may be '-' and other chars that we do not index in WRD
opfts.append([oi,pii,fi,'w'])
if of.startswith("h"):
print_warning(req, "The partial phrase search does not work in any field. I'll do a boolean AND searching instead.")
print_warning(req, "If you want to do a partial phrase search in a specific field, e.g. inside title, then please choose 'within title' search option.", "Tip")
print_warning(req, "If you want to do exact phrase matching, then please use double quotes.", "Tip")
elif fi and str(fi[0]).isdigit() and str(fi[0]).isdigit():
# B3b - fi exists and starts by two digits => do ACC search
opfts.append([oi,pi,fi,'a'])
elif fi and not get_index_id(fi):
# B3c - fi exists but there is no words table for fi => try ACC search
opfts.append([oi,pi,fi,'a'])
elif fi and pi.startswith('/') and pi.endswith('/'):
# B3d - fi exists and slashes found => try regexp search
opfts.append([oi,pi[1:-1],fi,'r'])
else:
# B3e - general case => do WRD search
pi = strip_accents(pi) # strip accents for 'w' mode, FIXME: delete when not needed
for pii in get_words_from_pattern(pi):
opfts.append([oi,pii,fi,'w'])
## sanity check:
for i in range(0,len(opfts)):
try:
pi = opfts[i][1]
if pi == '*':
if of.startswith("h"):
print_warning(req, "Ignoring standalone wildcard word.", "Warning")
del opfts[i]
if pi == '' or pi == ' ':
fi = opfts[i][2]
if fi:
if of.startswith("h"):
print_warning(req, "Ignoring empty <em>%s</em> search term." % fi, "Warning")
del opfts[i]
except:
pass
## return search units:
return opfts
def page_start(req, of, cc, as, ln, uid, title_message=None):
"Start page according to given output format."
_ = gettext_set_language(ln)
if not title_message: title_message = _("Search Results")
if not req:
return # we were called from CLI
if of.startswith('x'):
# we are doing XML output:
req.content_type = "text/xml"
req.send_http_header()
req.write("""<?xml version="1.0" encoding="UTF-8"?>\n""")
if of.startswith("xm"):
req.write("""<collection xmlns="http://www.loc.gov/MARC21/slim">\n""")
else:
req.write("""<collection>\n""")
elif of.startswith('t') or str(of[0:3]).isdigit():
# we are doing plain text output:
req.content_type = "text/plain"
req.send_http_header()
elif of == "id":
pass # nothing to do, we shall only return list of recIDs
else:
# we are doing HTML output:
req.content_type = "text/html"
req.send_http_header()
req.write(pageheaderonly(title=title_message,
navtrail=create_navtrail_links(cc, as, ln, 1),
description="%s %s." % (cc, _("Search Results")),
keywords="CDSware, WebSearch, %s" % cc,
uid=uid,
language=ln,
urlargs=req.args))
req.write(websearch_templates.tmpl_search_pagestart(ln = ln))
def page_end(req, of="hb", ln=cdslang):
"End page according to given output format: e.g. close XML tags, add HTML footer, etc."
if of == "id":
return [] # empty recID list
if not req:
return # we were called from CLI
if of.startswith('h'):
req.write(websearch_templates.tmpl_search_pageend(ln = ln)) # pagebody end
req.write(pagefooteronly(lastupdated=__lastupdated__, language=ln, urlargs=req.args))
elif of.startswith('x'):
req.write("""</collection>\n""")
return "\n"
def create_inputdate_box(name="d1", selected_year=0, selected_month=0, selected_day=0, ln=cdslang):
"Produces 'From Date', 'Until Date' kind of selection box. Suitable for search options."
_ = gettext_set_language(ln)
box = ""
# day
box += """<select name="%sd">""" % name
box += """<option value="">%s""" % _("any day")
for day in range(1,32):
box += """<option value="%02d"%s>%02d""" % (day, is_selected(day, selected_day), day)
box += """</select>"""
# month
box += """<select name="%sm">""" % name
box += """<option value="">%s""" % _("any month")
for mm, month in [(1,_("January")), (2,_("February")), (3,_("March")), (4,_("April")), \
(5,_("May")), (6,_("June")), (7,_("July")), (8,_("August")), \
(9,_("September")), (10,_("October")), (11,_("November")), (12,_("December"))]:
box += """<option value="%02d"%s>%s""" % (mm, is_selected(mm, selected_month), month)
box += """</select>"""
# year
box += """<select name="%sy">""" % name
box += """<option value="">%s""" % _("any year")
this_year = int(time.strftime("%Y", time.localtime()))
for year in range(this_year-20, this_year+1):
box += """<option value="%d"%s>%d""" % (year, is_selected(year, selected_year), year)
box += """</select>"""
return box
def create_google_box(cc, p, f, p1, p2, p3, ln=cdslang,
prolog_start="""<table class="googlebox"><tr><th colspan="2" class="googleboxheader">""",
prolog_end="""</th></tr><tr><td class="googleboxbody">""",
column_separator="""</td><td class="googleboxbody">""",
link_separator= """<br>""",
epilog="""</td></tr></table>"""):
"Creates the box that proposes links to other useful search engines like Google. 'p' is the search pattern."
if not p and (p1 or p2 or p3):
p = p1 + " " + p2 + " " + p3
# check suitable p's whether we want to print it
if cfg_google_box == 0 or \
p == "" or \
string.find(p, "recid:")>=0 or \
string.find(p, "sysno:")>=0 or \
string.find(p, "sysnos:")>=0:
return ""
# remove our logical field index names:
p = sre.sub(r'\w+:', '', p)
return websearch_templates.tmpl_google_box(
ln = ln,
cc = cc,
p = p,
f = f,
prolog_start = prolog_start,
prolog_end = prolog_end,
column_separator = column_separator,
link_separator = link_separator,
epilog = epilog,
)
def create_search_box(cc, colls, p, f, rg, sf, so, sp, rm, of, ot, as, ln, p1, f1, m1, op1, p2, f2, m2, op2, p3, f3, m3, sc, pl,
d1y, d1m, d1d, d2y, d2m, d2d, action=""):
"Create search box for 'search again in the results page' functionality."
# load the right message language
_ = gettext_set_language(ln)
# some computations
if cc == cdsname:
cc_intl = cdsnameintl[ln]
else:
cc_intl = get_coll_i18nname(cc, ln)
colls_nicely_ordered = []
if cfg_nicely_ordered_collection_list:
colls_nicely_ordered = get_nicely_ordered_collection_list()
else:
colls_nicely_ordered = get_alphabetically_ordered_collection_list()
colls_nice = []
for (cx, cx_printable) in colls_nicely_ordered:
if not cx.startswith("Unnamed collection"):
colls_nice.append({ 'value' : cx,
'text' : cx_printable
})
coll_selects = []
if colls and colls[0] != cdsname:
# some collections are defined, so print these first, and only then print 'add another collection' heading:
for c in colls:
if c:
temp = []
temp.append({ 'value' : '',
'text' : '*** %s ***' % _("any collection")
})
for val in colls_nice:
# print collection:
if not cx.startswith("Unnamed collection"):
temp.append({ 'value' : val['value'],
'text' : val['text'],
'selected' : (c == sre.sub("^[\s\-]*","", val['value']))
})
coll_selects.append(temp)
coll_selects.append([{ 'value' : '',
'text' : '*** %s ***' % _("add another collection")
}] + colls_nice)
else: # we searched in CDSNAME, so print 'any collection' heading
coll_selects.append([{ 'value' : '',
'text' : '*** %s ***' % _("any collection")
}] + colls_nice)
sort_formats = [{
'value' : '',
'text' : _("latest first")
}]
query = """SELECT DISTINCT(f.code),f.name FROM field AS f, collection_field_fieldvalue AS cff
WHERE cff.type='soo' AND cff.id_field=f.id
ORDER BY cff.score DESC, f.name ASC"""
res = run_sql(query)
for code, name in res:
sort_formats.append({
'value' : code,
'text' : name,
})
## ranking methods
ranks = [{
'value' : '',
'text' : "- %s %s -" % (_("OR").lower (), _("rank by")),
}]
for (code,name) in get_bibrank_methods(get_colID(cc), ln):
# propose found rank methods:
ranks.append({
'value' : code,
'text' : name,
})
formats = []
query = """SELECT code,name FROM format ORDER BY name ASC"""
res = run_sql(query)
if res:
# propose found formats:
for code, name in res:
formats.append({ 'value' : code,
'text' : name
})
else:
formats.append({'value' : 'hb',
'text' : _("HTML brief")
})
return websearch_templates.tmpl_search_box(
ln = ln,
weburl = weburl,
as = as,
cc_intl = cc_intl,
cc = cc,
ot = ot,
sp = sp,
action = action,
fieldslist = get_searchwithin_fields(ln = ln),
f1 = f1,
f2 = f2,
f3 = f3,
m1 = m1,
m2 = m2,
m3 = m3,
p1 = p1,
p2 = p2,
p3 = p3,
op1 = op1,
op2 = op2,
rm = rm,
p = p,
f = f,
coll_selects = coll_selects,
d1y = d1y, d2y = d2y, d1m = d1m, d2m = d2m, d1d = d1d, d2d = d2d,
sort_formats = sort_formats,
sf = sf,
so = so,
ranks = ranks,
sc = sc,
rg = rg,
formats = formats,
of = of,
pl = pl
)
def create_navtrail_links(cc=cdsname,
as=0,
ln=cdslang,
self_p=1,
separator=" &gt; "):
"""Creates navigation trail links, i.e. links to collection ancestors (except Home collection).
If as==1, then links to Advanced Search interfaces; otherwise Simple Search.
"""
dads = []
for dad in get_coll_ancestors(cc):
if dad != cdsname: # exclude Home collection
dads.append ((dad, get_coll_i18nname (dad, ln)))
if self_p and cc != cdsname:
dads.append ((cc, get_coll_i18nname(cc, ln)))
return websearch_templates.tmpl_navtrail_links (as = as,
ln = ln,
weburl = weburl,
separator = separator,
dads = dads)
def create_searchwithin_selection_box(fieldname='f', value='', ln='en'):
"Produces 'search within' selection box for the current collection."
out = ""
out += """<select name="%s">""" % fieldname
out += """<option value="">%s""" % get_field_i18nname("any field", ln)
query = "SELECT code,name FROM field ORDER BY name ASC"
res = run_sql(query)
for field_code, field_name in res:
if field_code and field_code != "anyfield":
out += """<option value="%s"%s>%s""" % (field_code, is_selected(field_code,value),
get_field_i18nname(field_name, ln))
if value and str(value[0]).isdigit():
out += """<option value="%s" selected>%s MARC tag""" % (value, value)
out += """</select>"""
return out
def get_searchwithin_fields(ln='en'):
"Retrieves the fields name used in the 'search within' selection box for the current collection."
query = "SELECT code,name FROM field ORDER BY name ASC"
res = run_sql(query)
fields = [{
'value' : '',
'text' : get_field_i18nname("any field", ln)
}]
for field_code, field_name in res:
if field_code and field_code != "anyfield":
fields.append({ 'value' : field_code,
'text' : get_field_i18nname(field_name, ln)
})
return fields
def create_andornot_box(name='op', value='', ln='en'):
"Returns HTML code for the AND/OR/NOT selection box."
_ = gettext_set_language(ln)
out = """
<select name="%s">
<option value="a"%s>%s
<option value="o"%s>%s
<option value="n"%s>%s
</select>
""" % (name,
is_selected('a', value), _("AND"),
is_selected('o', value), _("OR"),
is_selected('n', value), _("AND NOT"))
return out
def create_matchtype_box(name='m', value='', ln='en'):
"Returns HTML code for the 'match type' selection box."
_ = gettext_set_language(ln)
out = """
<select name="%s">
<option value="a"%s>%s
<option value="o"%s>%s
<option value="e"%s>%s
<option value="p"%s>%s
<option value="r"%s>%s
</select>
""" % (name,
is_selected('a', value), _("All of the words:"),
is_selected('o', value), _("Any of the words:"),
is_selected('e', value), _("Exact phrase:"),
is_selected('p', value), _("Partial phrase:"),
is_selected('r', value), _("Regular expression:"))
return out
def nice_number(num, ln=cdslang):
"Returns nicely printed number NUM in language LN using thousands separator char defined in the I18N messages file."
if num is None: return None
_ = gettext_set_language(ln)
separator = _(",")
chars_in = list(str(num))
num = len(chars_in)
chars_out = []
for i in range(0,num):
if i % 3 == 0 and i != 0:
chars_out.append(separator)
chars_out.append(chars_in[num-i-1])
chars_out.reverse()
return ''.join(chars_out)
def is_selected(var, fld):
"Checks if the two are equal, and if yes, returns ' selected'. Useful for select boxes."
if type(var) is int and type(fld) is int:
if var == fld:
return " selected"
elif str(var) == str(fld):
return " selected"
elif fld and len(fld)==3 and fld[0] == "w" and var == fld[1:]:
return " selected"
return ""
def urlargs_replace_text_in_arg(urlargs, regexp_argname, text_old, text_new):
"""Analyze `urlargs' (URL CGI GET query arguments) and for each
occurrence of argument matching `regexp_argname' replace every
substring `text_old' by `text_new'. Return the resulting URL.
Useful for create_nearest_terms_box."""
out = ""
# parse URL arguments into a dictionary:
urlargsdict = cgi.parse_qs(urlargs)
## construct new URL arguments:
urlargsdictnew = {}
for key in urlargsdict.keys():
if sre.match(regexp_argname, key): # replace `arg' by new values
urlargsdictnew[key] = []
for parg in urlargsdict[key]:
urlargsdictnew[key].append(string.replace(parg, text_old, text_new))
else: # keep old values
urlargsdictnew[key] = urlargsdict[key]
# build new URL for this word:
for key in urlargsdictnew.keys():
for val in urlargsdictnew[key]:
out += "&" + key + "=" + urllib.quote_plus(val, '')
if out.startswith("&"):
out = out[1:]
return out
class HitSet:
"""Class describing set of records, implemented as bit vectors of recIDs.
Using Numeric arrays for speed (1 value = 8 bits), can use later "real"
bit vectors to save space."""
def __init__(self, init_set=None):
self._nbhits = -1
if init_set:
self._set = init_set
else:
self._set = Numeric.zeros(cfg_max_recID+1, Numeric.Int0)
def __repr__(self, join=string.join):
return "%s(%s)" % (self.__class__.__name__, join(map(repr, self._set), ', '))
def add(self, recID):
"Adds a record to the set."
self._set[recID] = 1
def addmany(self, recIDs):
"Adds several recIDs to the set."
for recID in recIDs: self._set[recID] = 1
def addlist(self, arr):
"Adds an array of recIDs to the set."
Numeric.put(self._set, arr, 1)
def remove(self, recID):
"Removes a record from the set."
self._set[recID] = 0
def removemany(self, recIDs):
"Removes several records from the set."
for recID in recIDs:
self.remove(recID)
def intersect(self, other):
"Does a set intersection with other. Keep result in self."
self._set = Numeric.bitwise_and(self._set, other._set)
def union(self, other):
"Does a set union with other. Keep result in self."
self._set = Numeric.bitwise_or(self._set, other._set)
def difference(self, other):
"Does a set difference with other. Keep result in self."
#self._set = Numeric.bitwise_not(self._set, other._set)
for recID in Numeric.nonzero(other._set):
self.remove(recID)
def contains(self, recID):
"Checks whether the set contains recID."
return self._set[recID]
__contains__ = contains # Higher performance member-test for python 2.0 and above
def __getitem__(self, index):
"Support for the 'for item in set:' protocol."
return Numeric.nonzero(self._set)[index]
def calculate_nbhits(self):
"Calculates the number of records set in the hitset."
self._nbhits = Numeric.sum(self._set.copy().astype(Numeric.Int))
def items(self):
"Return an array containing all recID."
return Numeric.nonzero(self._set)
def tolist(self):
"Return an array containing all recID."
return Numeric.nonzero(self._set).tolist()
# speed up HitSet operations by ~20% if Psyco is installed:
try:
import psyco
psyco.bind(HitSet)
except:
pass
def escape_string(s):
"Escapes special chars in string. For MySQL queries."
s = MySQLdb.escape_string(s)
return s
def wash_colls(cc, c, split_colls=0):
"""Wash collection list by checking whether user has deselected
anything under 'Narrow search'. Checks also if cc is a list or not.
Return list of cc, colls_to_display, colls_to_search since the list
of collections to display is different from that to search in.
This is because users might have chosen 'split by collection'
functionality.
The behaviour of "collections to display" depends solely whether
user has deselected a particular collection: e.g. if it started
from 'Articles and Preprints' page, and deselected 'Preprints',
then collection to display is 'Articles'. If he did not deselect
anything, then collection to display is 'Articles & Preprints'.
The behaviour of "collections to search in" depends on the
'split_colls' parameter:
* if is equal to 1, then we can wash the colls list down
and search solely in the collection the user started from;
* if is equal to 0, then we are splitting to the first level
of collections, i.e. collections as they appear on the page
we started to search from;
"""
colls_out = []
colls_out_for_display = []
# check what type is 'cc':
if type(cc) is list:
for ci in cc:
if collection_reclist_cache.has_key(ci):
# yes this collection is real, so use it:
cc = ci
break
else:
# check once if cc is real:
if not collection_reclist_cache.has_key(cc):
cc = cdsname # cc is not real, so replace it with Home collection
# check type of 'c' argument:
if type(c) is list:
colls = c
else:
colls = [c]
# remove all 'unreal' collections:
colls_real = []
for coll in colls:
if collection_reclist_cache.has_key(coll):
colls_real.append(coll)
colls = colls_real
# check if some real collections remain:
if len(colls)==0:
colls = [cc]
# then let us check the list of non-restricted "real" sons of 'cc' and compare it to 'coll':
query = "SELECT c.name FROM collection AS c, collection_collection AS cc, collection AS ccc WHERE c.id=cc.id_son AND cc.id_dad=ccc.id AND ccc.name='%s' AND cc.type='r' AND c.restricted IS NULL" % MySQLdb.escape_string(cc)
res = run_sql(query)
l_cc_nonrestricted_sons = []
l_c = colls
for row in res:
l_cc_nonrestricted_sons.append(row[0])
l_c.sort()
l_cc_nonrestricted_sons.sort()
if l_cc_nonrestricted_sons == l_c:
colls_out_for_display = [cc] # yep, washing permitted, it is sufficient to display 'cc'
else:
colls_out_for_display = colls # nope, we need to display all 'colls' successively
# remove duplicates:
colls_out_for_display_nondups=filter(lambda x, colls_out_for_display=colls_out_for_display: colls_out_for_display[x-1] not in colls_out_for_display[x:], range(1, len(colls_out_for_display)+1))
colls_out_for_display = map(lambda x, colls_out_for_display=colls_out_for_display:colls_out_for_display[x-1], colls_out_for_display_nondups)
# second, let us decide on collection splitting:
if split_colls == 0:
# type A - no sons are wanted
colls_out = colls_out_for_display
# elif split_colls == 1:
else:
# type B - sons (first-level descendants) are wanted
for coll in colls_out_for_display:
coll_sons = get_coll_sons(coll)
if coll_sons == []:
colls_out.append(coll)
else:
colls_out = colls_out + coll_sons
# remove duplicates:
colls_out_nondups=filter(lambda x, colls_out=colls_out: colls_out[x-1] not in colls_out[x:], range(1, len(colls_out)+1))
colls_out = map(lambda x, colls_out=colls_out:colls_out[x-1], colls_out_nondups)
return (cc, colls_out_for_display, colls_out)
def strip_accents(x):
"""Strip accents in the input phrase X (assumed in UTF-8) by replacing
accented characters with their unaccented cousins (e.g. é by e).
Return such a stripped X."""
# convert input into Unicode string:
try:
y = unicode(x, "utf-8")
except:
return x # something went wrong, probably the input wasn't UTF-8
# asciify Latin-1 lowercase characters:
y = sre_unicode_lowercase_a.sub("a", y)
y = sre_unicode_lowercase_ae.sub("ae", y)
y = sre_unicode_lowercase_e.sub("e", y)
y = sre_unicode_lowercase_i.sub("i", y)
y = sre_unicode_lowercase_o.sub("o", y)
y = sre_unicode_lowercase_u.sub("u", y)
y = sre_unicode_lowercase_y.sub("y", y)
y = sre_unicode_lowercase_c.sub("c", y)
y = sre_unicode_lowercase_n.sub("n", y)
# asciify Latin-1 uppercase characters:
y = sre_unicode_uppercase_a.sub("A", y)
y = sre_unicode_uppercase_ae.sub("AE", y)
y = sre_unicode_uppercase_e.sub("E", y)
y = sre_unicode_uppercase_i.sub("I", y)
y = sre_unicode_uppercase_o.sub("O", y)
y = sre_unicode_uppercase_u.sub("U", y)
y = sre_unicode_uppercase_y.sub("Y", y)
y = sre_unicode_uppercase_c.sub("C", y)
y = sre_unicode_uppercase_n.sub("N", y)
# return UTF-8 representation of the Unicode string:
return y.encode("utf-8")
def wash_pattern(p):
"""Wash pattern passed by URL. Check for sanity of the wildcard by
removing wildcards if they are appended to extremely short words
(1-3 letters). TODO: instead of this approximative treatment, it
will be much better to introduce a temporal limit, e.g. to kill a
query if it does not finish in 10 seconds."""
# strip accents:
# p = strip_accents(p) # FIXME: when available, strip accents all the time
# add leading/trailing whitespace for the two following wildcard-sanity checking regexps:
p = " " + p + " "
# get rid of wildcards at the beginning of words:
p = sre_pattern_wildcards_at_beginning.sub("\\1", p)
# replace spaces within quotes by __SPACE__ temporarily:
p = sre_pattern_single_quotes.sub(lambda x: "'"+string.replace(x.group(1), ' ', '__SPACE__')+"'", p)
p = sre_pattern_double_quotes.sub(lambda x: "\""+string.replace(x.group(1), ' ', '__SPACE__')+"\"", p)
p = sre_pattern_regexp_quotes.sub(lambda x: "/"+string.replace(x.group(1), ' ', '__SPACE__')+"/", p)
# get rid of extremely short words (1-3 letters with wildcards):
p = sre_pattern_short_words.sub("\\1", p)
# replace back __SPACE__ by spaces:
p = sre_pattern_space.sub(" ", p)
# replace special terms:
p = sre_pattern_today.sub(time.strftime("%Y-%m-%d", time.localtime()), p)
# remove unnecessary whitespace:
p = string.strip(p)
return p
def wash_field(f):
"""Wash field passed by URL."""
# get rid of unnecessary whitespace:
f = string.strip(f)
# wash old-style CDSware/ALEPH 'f' field argument, e.g. replaces 'wau' and 'au' by 'author'
if cfg_fields_convert.has_key(string.lower(f)):
f = cfg_fields_convert[f]
return f
def wash_dates(d1y, d1m, d1d, d2y, d2m, d2d):
"""Take user-submitted dates (day, month, year) of the web form and return (day1, day2) in YYYY-MM-DD format
suitable for time restricted searching. I.e. pay attention when months are not there to put 01 or 12
according to if it's the starting or the ending date, etc."""
day1, day2 = "", ""
# sanity checking:
if d1y==0 and d1m==0 and d1d==0 and d2y==0 and d2m==0 and d2d==0:
return ("", "") # nothing selected, so return empty values
# construct day1 (from):
if d1y:
day1 += "%04d" % d1y
else:
day1 += "0000"
if d1m:
day1 += "-%02d" % d1m
else:
day1 += "-01"
if d1d:
day1 += "-%02d" % d1d
else:
day1 += "-01"
# construct day2 (until):
if d2y:
day2 += "%04d" % d2y
else:
day2 += "9999"
if d2m:
day2 += "-%02d" % d2m
else:
day2 += "-12"
if d2d:
day2 += "-%02d" % d2d
else:
day2 += "-31" # NOTE: perhaps we should add max(datenumber) in
# given month, but for our quering it's not
# needed, 31 will always do
# okay, return constructed YYYY-MM-DD dates
return (day1, day2)
def get_colID(c):
"Return collection ID for collection name C. Return None if no match found."
colID = None
res = run_sql("SELECT id FROM collection WHERE name=%s", (c,), 1)
if res:
colID = res[0][0]
return colID
def get_coll_i18nname(c, ln=cdslang):
"""Return nicely formatted collection name (of name type 'ln',
'long name') for collection C in language LN."""
global collection_i18nname_cache
global collection_i18nname_cache_timestamp
# firstly, check whether the collectionname table was modified:
res = run_sql("SHOW TABLE STATUS LIKE 'collectionname'")
if res and str(res[0][11])>collection_i18nname_cache_timestamp:
# yes it was, cache clear-up needed:
collection_i18nname_cache = create_collection_i18nname_cache()
# secondly, read i18n name from either the cache or return common name:
out = c
try:
out = collection_i18nname_cache[c][ln]
except KeyError:
pass # translation in LN does not exist
return out
def get_field_i18nname(f, ln=cdslang):
"""Return nicely formatted field name (of type 'ln', 'long name')
for field F in language LN."""
global field_i18nname_cache
global field_i18nname_cache_timestamp
# firstly, check whether the fieldname table was modified:
res = run_sql("SHOW TABLE STATUS LIKE 'fieldname'")
if res and str(res[0][11])>field_i18nname_cache_timestamp:
# yes it was, cache clear-up needed:
field_i18nname_cache = create_field_i18nname_cache()
# secondly, read i18n name from either the cache or return common name:
out = f
try:
out = field_i18nname_cache[f][ln]
except KeyError:
pass # translation in LN does not exist
return out
def get_coll_ancestors(coll):
"Returns a list of ancestors for collection 'coll'."
coll_ancestors = []
coll_ancestor = coll
while 1:
query = "SELECT c.name FROM collection AS c "\
"LEFT JOIN collection_collection AS cc ON c.id=cc.id_dad "\
"LEFT JOIN collection AS ccc ON ccc.id=cc.id_son "\
"WHERE ccc.name='%s' ORDER BY cc.id_dad ASC LIMIT 1" \
% escape_string(coll_ancestor)
res = run_sql(query, None, 1)
if res:
coll_name = res[0][0]
coll_ancestors.append(coll_name)
coll_ancestor = coll_name
else:
break
# ancestors found, return reversed list:
coll_ancestors.reverse()
return coll_ancestors
def get_coll_sons(coll, type='r', public_only=1):
"""Return a list of sons (first-level descendants) of type 'type' for collection 'coll'.
If public_only, then return only non-restricted son collections.
"""
coll_sons = []
query = "SELECT c.name FROM collection AS c "\
"LEFT JOIN collection_collection AS cc ON c.id=cc.id_son "\
"LEFT JOIN collection AS ccc ON ccc.id=cc.id_dad "\
"WHERE cc.type='%s' AND ccc.name='%s'" \
% (escape_string(type), escape_string(coll))
if public_only:
query += " AND c.restricted IS NULL "
query += " ORDER BY cc.score DESC"
res = run_sql(query)
for name in res:
coll_sons.append(name[0])
return coll_sons
def get_coll_real_descendants(coll):
"""Return a list of all descendants of collection 'coll' that are defined by a 'dbquery'.
IOW, we need to decompose compound collections like "A & B" into "A" and "B" provided
that "A & B" has no associated database query defined.
"""
coll_sons = []
query = "SELECT c.name,c.dbquery FROM collection AS c "\
"LEFT JOIN collection_collection AS cc ON c.id=cc.id_son "\
"LEFT JOIN collection AS ccc ON ccc.id=cc.id_dad "\
"WHERE ccc.name='%s' ORDER BY cc.score DESC" \
% escape_string(coll)
res = run_sql(query)
for name, dbquery in res:
if dbquery: # this is 'real' collection, so return it:
coll_sons.append(name)
else: # this is 'composed' collection, so recurse:
coll_sons.extend(get_coll_real_descendants(name))
return coll_sons
def get_collection_reclist(coll):
"""Return hitset of recIDs that belong to the collection 'coll'.
But firstly check the last updated date of the collection table.
If it's newer than the cache timestamp, then empty the cache,
since new records could have been added."""
global collection_reclist_cache
global collection_reclist_cache_timestamp
# firstly, check whether the collection table was modified:
res = run_sql("SHOW TABLE STATUS LIKE 'collection'")
if res and str(res[0][11])>collection_reclist_cache_timestamp:
# yes it was, cache clear-up needed:
collection_reclist_cache = create_collection_reclist_cache()
# secondly, read reclist from either the cache or the database:
if not collection_reclist_cache[coll]:
# not yet it the cache, so calculate it and fill the cache:
set = HitSet()
query = "SELECT nbrecs,reclist FROM collection WHERE name='%s'" % coll
res = run_sql(query, None, 1)
if res:
try:
set._nbhits, set._set = res[0][0], Numeric.loads(zlib.decompress(res[0][1]))
except:
set._nbhits = 0
collection_reclist_cache[coll] = set
# finally, return reclist:
return collection_reclist_cache[coll]
def coll_restricted_p(coll):
"Predicate to test if the collection coll is restricted or not."
if not coll:
return 0
query = "SELECT restricted FROM collection WHERE name='%s'" % MySQLdb.escape_string(coll)
res = run_sql(query, None, 1)
if res and res[0][0] != None:
return 1
else:
return 0
def coll_restricted_group(coll):
"Return Apache group to which the collection is restricted. Return None if it's public."
if not coll:
return None
query = "SELECT restricted FROM collection WHERE name='%s'" % MySQLdb.escape_string(coll)
res = run_sql(query, None, 1)
if res:
return res[0][0]
else:
return None
def create_collection_reclist_cache():
"""Creates list of records belonging to collections. Called on startup
and used later for intersecting search results with collection universe."""
global collection_reclist_cache_timestamp
collrecs = {}
res = run_sql("SELECT name,reclist FROM collection")
for name,reclist in res:
collrecs[name] = None # this will be filled later during runtime by calling get_collection_reclist(coll)
# update timestamp
try:
collection_reclist_cache_timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
except NameError:
collection_reclist_cache_timestamp = 0
return collrecs
try:
collection_reclist_cache.has_key(cdsname)
except:
try:
collection_reclist_cache = create_collection_reclist_cache()
except:
collection_reclist_cache = {}
def create_collection_i18nname_cache():
"""Create cache of I18N collection names of type 'ln' (=long name).
Called on startup and used later during the search time."""
global collection_i18nname_cache_timestamp
names = {}
res = run_sql("SELECT c.name,cn.ln,cn.value FROM collectionname AS cn, collection AS c WHERE cn.id_collection=c.id AND cn.type='ln'") # ln=long name
for c,ln,i18nname in res:
if i18nname:
try:
names[c]
except KeyError:
names[c] = {}
names[c][ln] = i18nname
# update timestamp
try:
collection_i18nname_cache_timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
except NameError:
collection_i18nname_cache_timestamp = 0
return names
try:
collection_i18nname_cache.has_key(cdsname)
except:
try:
collection_i18nname_cache = create_collection_i18nname_cache()
except:
collection_i18nname_cache = {}
def create_field_i18nname_cache():
"""Create cache of I18N field names of type 'ln' (=long name).
Called on startup and used later during the search time."""
global field_i18nname_cache_timestamp
names = {}
res = run_sql("SELECT f.name,fn.ln,fn.value FROM fieldname AS fn, field AS f WHERE fn.id_field=f.id AND fn.type='ln'") # ln=long name
for f,ln,i18nname in res:
if i18nname:
try:
names[f]
except KeyError:
names[f] = {}
names[f][ln] = i18nname
# update timestamp
try:
field_i18nname_cache_timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
except NameError:
field_i18nname_cache_timestamp = 0
return names
try:
field_i18nname_cache.has_key(cdsname)
except:
try:
field_i18nname_cache = create_field_i18nname_cache()
except:
field_i18nname_cache = {}
def browse_pattern(req, colls, p, f, rg, ln=cdslang):
"""Browse either biliographic phrases or words indexes, and display it."""
# load the right message language
_ = gettext_set_language(ln)
## do we search in words indexes?
if not f:
return browse_in_bibwords(req, p, f)
## prepare collection urlargument for later printing:
p_orig = p
urlarg_colls = ""
for coll in colls:
urlarg_colls += "&c=%s" % urllib.quote(coll)
## okay, "real browse" follows:
browsed_phrases = get_nearest_terms_in_bibxxx(p, f, rg, 1)
while not browsed_phrases:
# try again and again with shorter and shorter pattern:
try:
p = p[:-1]
browsed_phrases = get_nearest_terms_in_bibxxx(p, f, rg, 1)
except:
# probably there are no hits at all:
req.write(_("No values found."))
return
## try to check hits in these particular collection selection:
browsed_phrases_in_colls = []
if 0:
for phrase in browsed_phrases:
phrase_hitset = HitSet()
phrase_hitsets = search_pattern("", phrase, f, 'e')
for coll in colls:
phrase_hitset.union(phrase_hitsets[coll])
phrase_hitset.calculate_nbhits()
if phrase_hitset._nbhits > 0:
# okay, this phrase has some hits in colls, so add it:
browsed_phrases_in_colls.append([phrase, phrase_hitset._nbhits])
## were there hits in collections?
if browsed_phrases_in_colls == []:
if browsed_phrases != []:
#print_warning(req, """<p>No match close to <em>%s</em> found in given collections.
#Please try different term.<p>Displaying matches in any collection...""" % p_orig)
## try to get nbhits for these phrases in any collection:
for phrase in browsed_phrases:
browsed_phrases_in_colls.append([phrase, get_nbhits_in_bibxxx(phrase, f)])
## display results now:
out = websearch_templates.tmpl_browse_pattern(
f = get_field_i18nname(f, ln),
ln = ln,
browsed_phrases_in_colls = browsed_phrases_in_colls,
weburl = weburl,
urlarg_colls = urlarg_colls,
)
req.write(out)
return
def browse_in_bibwords(req, p, f, ln=cdslang):
"""Browse inside words indexes."""
if not p:
return
_ = gettext_set_language(ln)
urlargs = string.replace(req.args, "action=%s" % _("Browse"), "action=%s" % _("Search"))
nearest_box = create_nearest_terms_box(urlargs, p, f, 'w', ln=ln, intro_text_p=0)
req.write(websearch_templates.tmpl_search_in_bibwords(
p = p,
f = f,
ln = ln,
nearest_box = nearest_box
))
return
def search_pattern(req=None, p=None, f=None, m=None, ap=0, of="id", verbose=0, ln=cdslang):
"""Search for complex pattern 'p' within field 'f' according to
matching type 'm'. Return hitset of recIDs.
The function uses multi-stage searching algorithm in case of no
exact match found. See the Search Internals document for
detailed description.
The 'ap' argument governs whether an alternative patterns are to
be used in case there is no direct hit for (p,f,m). For
example, whether to replace non-alphanumeric characters by
spaces if it would give some hits. See the Search Internals
document for detailed description. (ap=0 forbits the
alternative pattern usage, ap=1 permits it.)
The 'of' argument governs whether to print or not some
information to the user in case of no match found. (Usually it
prints the information in case of HTML formats, otherwise it's
silent).
The 'verbose' argument controls the level of debugging information
to be printed (0=least, 9=most).
All the parameters are assumed to have been previously washed.
This function is suitable as a mid-level API.
"""
_ = gettext_set_language(ln)
hitset_empty = HitSet()
hitset_empty._nbhits = 0
# sanity check:
if not p:
hitset_full = HitSet(Numeric.ones(cfg_max_recID+1, Numeric.Int0))
hitset_full._nbhits = cfg_max_recID
# no pattern, so return all universe
return hitset_full
# search stage 1: break up arguments into basic search units:
if verbose and of.startswith("h"):
t1 = os.times()[4]
basic_search_units = create_basic_search_units(req, p, f, m, of)
if verbose and of.startswith("h"):
t2 = os.times()[4]
print_warning(req, "Search stage 1: basic search units are: %s" % basic_search_units)
print_warning(req, "Search stage 1: execution took %.2f seconds." % (t2 - t1))
# search stage 2: do search for each search unit and verify hit presence:
if verbose and of.startswith("h"):
t1 = os.times()[4]
basic_search_units_hitsets = []
for idx_unit in range(0,len(basic_search_units)):
bsu_o, bsu_p, bsu_f, bsu_m = basic_search_units[idx_unit]
basic_search_unit_hitset = search_unit(bsu_p, bsu_f, bsu_m)
if verbose >= 9 and of.startswith("h"):
print_warning(req, "Search stage 1: pattern %s gave hitlist %s" % (bsu_p, Numeric.nonzero(basic_search_unit_hitset._set)))
if basic_search_unit_hitset._nbhits>0 or \
ap==0 or \
bsu_o=="|" or \
((idx_unit+1)<len(basic_search_units) and basic_search_units[idx_unit+1][0]=="|"):
# stage 2-1: this basic search unit is retained, since
# either the hitset is non-empty, or the approximate
# pattern treatment is switched off, or the search unit
# was joined by an OR operator to preceding/following
# units so we do not require that it exists
basic_search_units_hitsets.append(basic_search_unit_hitset)
else:
# stage 2-2: no hits found for this search unit, try to replace non-alphanumeric chars inside pattern:
if sre.search(r'[^a-zA-Z0-9\s\:]', bsu_p):
if bsu_p.startswith('"') and bsu_p.endswith('"'): # is it ACC query?
bsu_pn = sre.sub(r'[^a-zA-Z0-9\s\:]+', "*", bsu_p)
else: # it is WRD query
bsu_pn = sre.sub(r'[^a-zA-Z0-9\s\:]+', " ", bsu_p)
if verbose and of.startswith('h') and req:
print_warning(req, "trying (%s,%s,%s)" % (bsu_pn,bsu_f,bsu_m))
basic_search_unit_hitset = search_pattern(req=None, p=bsu_pn, f=bsu_f, m=bsu_m, of="id", ln=ln)
if basic_search_unit_hitset._nbhits > 0:
# we retain the new unit instead
if of.startswith('h'):
print_warning(req, _("No exact match found for <em>%s</em>, using <em>%s</em> instead...") % (bsu_p,bsu_pn))
basic_search_units[idx_unit][1] = bsu_pn
basic_search_units_hitsets.append(basic_search_unit_hitset)
else:
# stage 2-3: no hits found either, propose nearest indexed terms:
if of.startswith('h'):
if req:
if bsu_f == "recid":
print_warning(req, "Requested record does not seem to exist.")
else:
print_warning(req, create_nearest_terms_box(req.args, bsu_p, bsu_f, bsu_m, ln=ln))
return hitset_empty
else:
# stage 2-3: no hits found either, propose nearest indexed terms:
if of.startswith('h'):
if req:
if bsu_f == "recid":
print_warning(req, "Requested record does not seem to exist.")
else:
print_warning(req, create_nearest_terms_box(req.args, bsu_p, bsu_f, bsu_m, ln=ln))
return hitset_empty
if verbose and of.startswith("h"):
t2 = os.times()[4]
for idx_unit in range(0,len(basic_search_units)):
print_warning(req, "Search stage 2: basic search unit %s gave %d hits." %
(basic_search_units[idx_unit][1:], basic_search_units_hitsets[idx_unit]._nbhits))
print_warning(req, "Search stage 2: execution took %.2f seconds." % (t2 - t1))
# search stage 3: apply boolean query for each search unit:
if verbose and of.startswith("h"):
t1 = os.times()[4]
# let the initial set be the complete universe:
hitset_in_any_collection = HitSet(Numeric.ones(cfg_max_recID+1, Numeric.Int0))
for idx_unit in range(0,len(basic_search_units)):
this_unit_operation = basic_search_units[idx_unit][0]
this_unit_hitset = basic_search_units_hitsets[idx_unit]
if this_unit_operation == '+':
hitset_in_any_collection.intersect(this_unit_hitset)
elif this_unit_operation == '-':
hitset_in_any_collection.difference(this_unit_hitset)
elif this_unit_operation == '|':
hitset_in_any_collection.union(this_unit_hitset)
else:
if of.startswith("h"):
print_warning(req, "Invalid set operation %s." % this_unit_operation, "Error")
hitset_in_any_collection.calculate_nbhits()
if hitset_in_any_collection._nbhits == 0:
# no hits found, propose alternative boolean query:
if of.startswith('h'):
nearestterms = []
for idx_unit in range(0,len(basic_search_units)):
bsu_o, bsu_p, bsu_f, bsu_m = basic_search_units[idx_unit]
if bsu_p.startswith("%") and bsu_p.endswith("%"):
bsu_p = "'" + bsu_p[1:-1] + "'"
bsu_nbhits = basic_search_units_hitsets[idx_unit]._nbhits
url_args_new = sre.sub(r'(^|\&)p=.*?(\&|$)', r'\1p='+urllib.quote(bsu_p)+r'\2', req.args)
url_args_new = sre.sub(r'(^|\&)f=.*?(\&|$)', r'\1f='+urllib.quote(bsu_f)+r'\2', url_args_new)
nearestterms.append({
'nbhits' : bsu_nbhits,
'url_args' : url_args_new,
'p' : bsu_p,
})
text = websearch_templates.tmpl_search_no_boolean_hits(
ln = ln,
weburl = weburl,
nearestterms = nearestterms,
)
print_warning(req, text)
if verbose and of.startswith("h"):
t2 = os.times()[4]
print_warning(req, "Search stage 3: boolean query gave %d hits." % hitset_in_any_collection._nbhits)
print_warning(req, "Search stage 3: execution took %.2f seconds." % (t2 - t1))
return hitset_in_any_collection
def search_unit(p, f=None, m=None):
"""Search for basic search unit defined by pattern 'p' and field
'f' and matching type 'm'. Return hitset of recIDs.
All the parameters are assumed to have been previously washed.
'p' is assumed to be already a ``basic search unit'' so that it
is searched as such and is not broken up in any way. Only
wildcard and span queries are being detected inside 'p'.
This function is suitable as a low-level API.
"""
## create empty output results set:
set = HitSet()
if not p: # sanity checking
return set
if m == 'a' or m == 'r':
# we are doing either direct bibxxx search or phrase search or regexp search
set = search_unit_in_bibxxx(p, f, m)
else:
# we are doing bibwords search by default
set = search_unit_in_bibwords(p, f)
set.calculate_nbhits()
return set
def search_unit_in_bibwords(word, f, decompress=zlib.decompress):
"""Searches for 'word' inside bibwordsX table for field 'f' and returns hitset of recIDs."""
set = HitSet() # will hold output result set
set_used = 0 # not-yet-used flag, to be able to circumvent set operations
# deduce into which bibwordsX table we will search:
bibwordsX = "idxWORD%02dF" % get_index_id("anyfield")
if f:
index_id = get_index_id(f)
if index_id:
bibwordsX = "idxWORD%02dF" % index_id
else:
return HitSet() # word index f does not exist
# wash 'word' argument and construct query:
word = string.replace(word, '*', '%') # we now use '*' as the truncation character
words = string.split(word, "->", 1) # check for span query
if len(words) == 2:
word0 = sre_word.sub('', words[0])
word1 = sre_word.sub('', words[1])
query = "SELECT term,hitlist FROM %s WHERE term BETWEEN '%s' AND '%s'" % (bibwordsX, escape_string(word0[:50]), escape_string(word1[:50]))
else:
word = sre_word.sub('', word)
if string.find(word, '%') >= 0: # do we have wildcard in the word?
query = "SELECT term,hitlist FROM %s WHERE term LIKE '%s'" % (bibwordsX, escape_string(word[:50]))
else:
query = "SELECT term,hitlist FROM %s WHERE term='%s'" % (bibwordsX, escape_string(word[:50]))
# launch the query:
res = run_sql(query)
# fill the result set:
for word,hitlist in res:
hitset_bibwrd = HitSet(Numeric.loads(decompress(hitlist)))
# add the results:
if set_used:
set.union(hitset_bibwrd)
else:
set = hitset_bibwrd
set_used = 1
# okay, return result set:
return set
def search_unit_in_bibxxx(p, f, type):
"""Searches for pattern 'p' inside bibxxx tables for field 'f' and returns hitset of recIDs found.
The search type is defined by 'type' (e.g. equals to 'r' for a regexp search)."""
p_orig = p # saving for eventual future 'no match' reporting
# wash arguments:
f = string.replace(f, '*', '%') # replace truncation char '*' in field definition
if type == 'r':
pattern = "REGEXP '%s'" % MySQLdb.escape_string(p)
else:
p = string.replace(p, '*', '%') # we now use '*' as the truncation character
ps = string.split(p, "->", 1) # check for span query:
if len(ps) == 2:
pattern = "BETWEEN '%s' AND '%s'" % (MySQLdb.escape_string(ps[0]), MySQLdb.escape_string(ps[1]))
else:
if string.find(p, '%') > -1:
pattern = "LIKE '%s'" % MySQLdb.escape_string(ps[0])
else:
pattern = "='%s'" % MySQLdb.escape_string(ps[0])
# construct 'tl' which defines the tag list (MARC tags) to search in:
tl = []
if str(f[0]).isdigit() and str(f[1]).isdigit():
tl.append(f) # 'f' seems to be okay as it starts by two digits
else:
# convert old ALEPH tag names, if appropriate: (TODO: get rid of this before entering this function)
if cfg_fields_convert.has_key(string.lower(f)):
f = cfg_fields_convert[string.lower(f)]
# deduce desired MARC tags on the basis of chosen 'f'
tl = get_field_tags(f)
if not tl:
# f index does not exist, nevermind
pass
# okay, start search:
l = [] # will hold list of recID that matched
for t in tl:
# deduce into which bibxxx table we will search:
digit1, digit2 = int(t[0]), int(t[1])
bx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
# construct query:
if t == "001":
query = "SELECT id FROM bibrec WHERE id %s" % pattern
else:
if len(t) != 6 or t[-1:]=='%': # only the beginning of field 't' is defined, so add wildcard character:
query = "SELECT bibx.id_bibrec FROM %s AS bx LEFT JOIN %s AS bibx ON bx.id=bibx.id_bibxxx WHERE bx.value %s AND bx.tag LIKE '%s%%'" %\
(bx, bibx, pattern, t)
else:
query = "SELECT bibx.id_bibrec FROM %s AS bx LEFT JOIN %s AS bibx ON bx.id=bibx.id_bibxxx WHERE bx.value %s AND bx.tag='%s'" %\
(bx, bibx, pattern, t)
# launch the query:
res = run_sql(query)
# fill the result set:
for id_bibrec in res:
if id_bibrec[0]:
l.append(id_bibrec[0])
# check no of hits found:
nb_hits = len(l)
# okay, return result set:
set = HitSet()
set.addlist(Numeric.array(l))
return set
def search_unit_in_bibrec(day1, day2, type='creation_date'):
"""Return hitset of recIDs found that were either created or modified (see 'type' arg)
from day1 until day2, inclusive. Does not pay attention to pattern, collection, anything.
Useful to intersect later on with the 'real' query."""
set = HitSet()
if type != "creation_date" and type != "modification_date":
# type argument is invalid, so search for creation dates by default
type = "creation_date"
res = run_sql("SELECT id FROM bibrec WHERE %s>=%s AND %s<=%s" % (type, "%s", type, "%s"),
(day1, day2))
l = []
for row in res:
l.append(row[0])
set.addlist(Numeric.array(l))
return set
def intersect_results_with_collrecs(req, hitset_in_any_collection, colls, ap=0, of="hb", verbose=0, ln=cdslang):
"""Return dict of hitsets given by intersection of hitset with the collection universes."""
_ = gettext_set_language(ln)
# search stage 4: intersect with the collection universe:
if verbose and of.startswith("h"):
t1 = os.times()[4]
results = {}
results_nbhits = 0
for coll in colls:
results[coll] = HitSet()
results[coll]._set = Numeric.bitwise_and(hitset_in_any_collection._set, get_collection_reclist(coll)._set)
results[coll].calculate_nbhits()
results_nbhits += results[coll]._nbhits
if results_nbhits == 0:
# no hits found, try to search in Home:
results_in_Home = HitSet()
results_in_Home._set = Numeric.bitwise_and(hitset_in_any_collection._set, get_collection_reclist(cdsname)._set)
results_in_Home.calculate_nbhits()
if results_in_Home._nbhits > 0:
# some hits found in Home, so propose this search:
url_args = req.args
url_args = sre.sub(r'(^|\&)cc=.*?(\&|$)', r'\2', url_args)
url_args = sre.sub(r'(^|\&)c=.*?(\&[^c]+=|$)', r'\2', url_args)
url_args = sre.sub(r'^\&+', '', url_args)
url_args = sre.sub(r'\&+$', '', url_args)
if of.startswith("h"):
print_warning(req, _("No match found in collection %s. Other public collections gave "
"<a class=\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>.") %
(string.join(colls, ","), weburl, url_args, results_in_Home._nbhits))
results = {}
else:
# no hits found in Home, recommend different search terms:
if of.startswith("h"):
print_warning(req, _("No public collection matched your query. "
"If you were looking for a non-public document, please choose "
"the desired restricted collection first."))
results = {}
if verbose and of.startswith("h"):
t2 = os.times()[4]
print_warning(req, "Search stage 4: intersecting with collection universe gave %d hits." % results_nbhits)
print_warning(req, "Search stage 4: execution took %.2f seconds." % (t2 - t1))
return results
def intersect_results_with_hitset(req, results, hitset, ap=0, aptext="", of="hb"):
"""Return intersection of search 'results' (a dict of hitsets
with collection as key) with the 'hitset', i.e. apply
'hitset' intersection to each collection within search
'results'.
If the final 'results' set is to be empty, and 'ap'
(approximate pattern) is true, and then print the `warningtext'
and return the original 'results' set unchanged. If 'ap' is
false, then return empty results set.
"""
if ap:
results_ap = copy.deepcopy(results)
else:
results_ap = {} # will return empty dict in case of no hits found
nb_total = 0
for coll in results.keys():
results[coll].intersect(hitset)
results[coll].calculate_nbhits()
nb_total += results[coll]._nbhits
if nb_total == 0:
if of.startswith("h"):
print_warning(req, aptext)
results = results_ap
return results
def create_similarly_named_authors_link_box(author_name, ln=cdslang):
"""Return a box similar to ``Not satisfied...'' one by proposing
author searches for similar names. Namely, take AUTHOR_NAME
and the first initial of the firstame (after comma) and look
into author index whether authors with e.g. middle names exist.
Useful mainly for CERN Library that sometimes contains name
forms like Ellis-N, Ellis-Nick, Ellis-Nicolas all denoting the
same person. The box isn't proposed if no similarly named
authors are found to exist.
"""
# return nothing if not configured:
if cfg_create_similarly_named_authors_link_box == 0:
return ""
# return empty box if there is no initial:
if sre.match(r'[^ ,]+, [^ ]', author_name) is None:
return ""
# firstly find name comma initial:
author_name_to_search = sre.sub(r'^([^ ,]+, +[^ ,]).*$', '\\1', author_name)
# secondly search for similar name forms:
similar_author_names = {}
for name in author_name_to_search, strip_accents(author_name_to_search):
for tag in get_field_tags("author"):
# deduce into which bibxxx table we will search:
digit1, digit2 = int(tag[0]), int(tag[1])
bx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
if len(tag) != 6 or tag[-1:]=='%':
# only the beginning of field 't' is defined, so add wildcard character:
query = "SELECT bx.value FROM %s AS bx WHERE bx.value LIKE '%s%%' AND bx.tag LIKE '%s%%'" \
% (bx, escape_string(name), tag)
else:
query = "SELECT bx.value FROM %s AS bx WHERE bx.value LIKE '%s%%' AND bx.tag='%s'" \
% (bx, escape_string(name), tag)
res = run_sql(query)
for row in res:
similar_author_names[row[0]] = 1
# remove the original name and sort the list:
try:
del similar_author_names[author_name]
except KeyError:
pass
# thirdly print the box:
out = ""
if similar_author_names:
out_authors = similar_author_names.keys()
out_authors.sort()
tmp_authors = []
for out_author in out_authors:
nbhits = get_nbhits_in_bibxxx(out_author, "author")
if nbhits:
tmp_authors.append({'nb': nbhits,
'name': out_author})
out += websearch_templates.tmpl_similar_author_names(
ln = ln,
weburl = weburl,
authors = tmp_authors,
)
return out
def create_nearest_terms_box(urlargs, p, f, t='w', n=5, ln=cdslang, intro_text_p=1):
"""Return text box containing list of 'n' nearest terms above/below 'p'
for the field 'f' for matching type 't' (words/phrases) in
language 'ln'.
Propose new searches according to `urlargs' with the new words.
If `intro_text_p' is true, then display the introductory message,
otherwise print only the nearest terms in the box content.
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
nearest_terms = []
if not p: # sanity check
p = "."
# look for nearest terms:
if t == 'w':
nearest_terms = get_nearest_terms_in_bibwords(p, f, n, n)
if not nearest_terms:
return "%s %s." % (_("No words index available for"), get_field_i18nname(f, ln))
else:
nearest_terms = get_nearest_terms_in_bibxxx(p, f, n, n)
if not nearest_terms:
return "%s %s." % (_("No phrase index available for"), get_field_i18nname(f, ln))
termargs = []
termhits = []
for term in nearest_terms:
if t == 'w':
termhits.append(get_nbhits_in_bibwords(term, f))
else:
termhits.append(get_nbhits_in_bibxxx(term, f))
termargs.append(urlargs_replace_text_in_arg(urlargs, r'^p\d?$', p, term))
intro = ""
if intro_text_p: # add full leading introductory text
intro = _("Search term <em>%s</em>") % (p.startswith("%") and p.endswith("%") and p[1:-1] or p)
if f:
intro += " " + _("inside <em>%s</em> index") % get_field_i18nname(f, ln)
intro += " " + _("did not match any record. Nearest terms in any collection are:")
return websearch_templates.tmpl_nearest_term_box(
p = p,
ln = ln,
f = f,
weburl = weburl,
terms = nearest_terms,
termargs = termargs,
termhits = termhits,
intro = intro,
)
def get_nearest_terms_in_bibwords(p, f, n_below, n_above):
"""Return list of +n -n nearest terms to word `p' in index for field `f'."""
nearest_words = [] # will hold the (sorted) list of nearest words to return
# deduce into which bibwordsX table we will search:
bibwordsX = "idxWORD%02dF" % get_index_id("anyfield")
if f:
index_id = get_index_id(f)
if index_id:
bibwordsX = "idxWORD%02dF" % index_id
else:
return nearest_words
# firstly try to get `n' closest words above `p':
query = "SELECT term FROM %s WHERE term<'%s' ORDER BY term DESC LIMIT %d" % (bibwordsX, escape_string(p), n_above)
res = run_sql(query)
for row in res:
nearest_words.append(row[0])
nearest_words.reverse()
# secondly insert given word `p':
nearest_words.append(p)
# finally try to get `n' closest words below `p':
query = "SELECT term FROM %s WHERE term>'%s' ORDER BY term ASC LIMIT %d" % (bibwordsX, escape_string(p), n_below)
res = run_sql(query)
for row in res:
nearest_words.append(row[0])
return nearest_words
def get_nearest_terms_in_bibxxx(p, f, n_below, n_above):
"""Browse (-n_above, +n_below) closest bibliographic phrases
for the given pattern p in the given field f, regardless
of collection.
Return list of [phrase1, phrase2, ... , phrase_n]."""
## determine browse field:
if not f and string.find(p, ":") > 0: # does 'p' contain ':'?
f, p = split(p, ":", 1)
## We are going to take max(n_below, n_above) as the number of
## values to ferch from bibXXx. This is needed to work around
## MySQL UTF-8 sorting troubles in 4.0.x. Proper solution is to
## use MySQL 4.1.x or our own idxPHRASE in the future.
n_fetch = 2*max(n_below,n_above)
## construct 'tl' which defines the tag list (MARC tags) to search in:
tl = []
if str(f[0]).isdigit() and str(f[1]).isdigit():
tl.append(f) # 'f' seems to be okay as it starts by two digits
else:
# deduce desired MARC tags on the basis of chosen 'f'
tl = get_field_tags(f)
## start browsing to fetch list of hits:
browsed_phrases = {} # will hold {phrase1: 1, phrase2: 1, ..., phraseN: 1} dict of browsed phrases (to make them unique)
# always add self to the results set:
browsed_phrases[p.startswith("%") and p.endswith("%") and p[1:-1] or p] = 1
for t in tl:
# deduce into which bibxxx table we will search:
digit1, digit2 = int(t[0]), int(t[1])
bx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
# firstly try to get `n' closest phrases above `p':
if len(t) != 6 or t[-1:]=='%': # only the beginning of field 't' is defined, so add wildcard character:
query = "SELECT bx.value FROM %s AS bx WHERE bx.value<'%s' AND bx.tag LIKE '%s%%' ORDER BY bx.value DESC LIMIT %d" \
% (bx, escape_string(p), t, n_fetch)
else:
query = "SELECT bx.value FROM %s AS bx WHERE bx.value<'%s' AND bx.tag='%s' ORDER BY bx.value DESC LIMIT %d" \
% (bx, escape_string(p), t, n_fetch)
res = run_sql(query)
for row in res:
browsed_phrases[row[0]] = 1
# secondly try to get `n' closest phrases equal to or below `p':
if len(t) != 6 or t[-1:]=='%': # only the beginning of field 't' is defined, so add wildcard character:
query = "SELECT bx.value FROM %s AS bx WHERE bx.value>='%s' AND bx.tag LIKE '%s%%' ORDER BY bx.value ASC LIMIT %d" \
% (bx, escape_string(p), t, n_fetch)
else:
query = "SELECT bx.value FROM %s AS bx WHERE bx.value>='%s' AND bx.tag='%s' ORDER BY bx.value ASC LIMIT %d" \
% (bx, escape_string(p), t, n_fetch)
res = run_sql(query)
for row in res:
browsed_phrases[row[0]] = 1
# select first n words only: (this is needed as we were searching
# in many different tables and so aren't sure we have more than n
# words right; this of course won't be needed when we shall have
# one ACC table only for given field):
phrases_out = browsed_phrases.keys()
phrases_out.sort(lambda x, y: cmp(string.lower(strip_accents(x)),
string.lower(strip_accents(y))))
# find position of self:
try:
idx_p = phrases_out.index(p)
except:
idx_p = len(phrases_out)/2
# return n_above and n_below:
return phrases_out[max(0,idx_p-n_above):idx_p+n_below]
def get_nbhits_in_bibwords(word, f):
"""Return number of hits for word 'word' inside words index for field 'f'."""
out = 0
# deduce into which bibwordsX table we will search:
bibwordsX = "idxWORD%02dF" % get_index_id("anyfield")
if f:
index_id = get_index_id(f)
if index_id:
bibwordsX = "idxWORD%02dF" % index_id
else:
return 0
if word:
query = "SELECT hitlist FROM %s WHERE term='%s'" % (bibwordsX, escape_string(word))
res = run_sql(query)
for hitlist in res:
out += Numeric.sum(Numeric.loads(zlib.decompress(hitlist[0])).copy().astype(Numeric.Int))
return out
def get_nbhits_in_bibxxx(p, f):
"""Return number of hits for word 'word' inside words index for field 'f'."""
## determine browse field:
if not f and string.find(p, ":") > 0: # does 'p' contain ':'?
f, p = split(p, ":", 1)
## construct 'tl' which defines the tag list (MARC tags) to search in:
tl = []
if str(f[0]).isdigit() and str(f[1]).isdigit():
tl.append(f) # 'f' seems to be okay as it starts by two digits
else:
# deduce desired MARC tags on the basis of chosen 'f'
tl = get_field_tags(f)
# start searching:
recIDs = {} # will hold dict of {recID1: 1, recID2: 1, ..., } (unique recIDs, therefore)
for t in tl:
# deduce into which bibxxx table we will search:
digit1, digit2 = int(t[0]), int(t[1])
bx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
if len(t) != 6 or t[-1:]=='%': # only the beginning of field 't' is defined, so add wildcard character:
query = """SELECT bibx.id_bibrec FROM %s AS bibx, %s AS bx
WHERE bx.value='%s' AND bx.tag LIKE '%s%%' AND bibx.id_bibxxx=bx.id""" \
% (bibx, bx, escape_string(p), t)
else:
query = """SELECT bibx.id_bibrec FROM %s AS bibx, %s AS bx
WHERE bx.value='%s' AND bx.tag='%s' AND bibx.id_bibxxx=bx.id""" \
% (bibx, bx, escape_string(p), t)
res = run_sql(query)
for row in res:
recIDs[row[0]] = 1
return len(recIDs)
def get_mysql_recid_from_aleph_sysno(sysno):
"""Returns MySQL's recID for ALEPH sysno passed in the argument (e.g. "002379334CER").
Returns None in case of failure."""
out = None
query = "SELECT bb.id_bibrec FROM bibrec_bib97x AS bb, bib97x AS b WHERE b.value='%s' AND b.tag='970__a' AND bb.id_bibxxx=b.id" %\
(escape_string(sysno))
res = run_sql(query, None, 1)
if res:
out = res[0][0]
return out
def guess_primary_collection_of_a_record(recID):
"""Return primary collection name a record recid belongs to, by testing 980 identifier.
May lead to bad guesses when a collection is defined dynamically bia dbquery.
In that case, return 'cdsname'."""
out = cdsname
dbcollids = get_fieldvalues(recID, "980__a")
if dbcollids:
dbquery = "collection:" + dbcollids[0]
res = run_sql("SELECT name FROM collection WHERE dbquery=%s", (dbquery,))
if res:
out = res[0][0]
return out
def get_tag_name(tag_value, prolog="", epilog=""):
"""Return tag name from the known tag value, by looking up the 'tag' table.
Return empty string in case of failure.
Example: input='100__%', output=first author'."""
out = ""
res = run_sql("SELECT name FROM tag WHERE value=%s", (tag_value,))
if res:
out = prolog + res[0][0] + epilog
return out
def get_fieldcodes():
"""Returns a list of field codes that may have been passed as 'search options' in URL.
Example: output=['subject','division']."""
out = []
res = run_sql("SELECT DISTINCT(code) FROM field")
for row in res:
out.append(row[0])
return out
def get_field_tags(field):
"""Returns a list of MARC tags for the field code 'field'.
Returns empty list in case of error.
Example: field='author', output=['100__%','700__%']."""
out = []
query = """SELECT t.value FROM tag AS t, field_tag AS ft, field AS f
WHERE f.code='%s' AND ft.id_field=f.id AND t.id=ft.id_tag
ORDER BY ft.score DESC""" % field
res = run_sql(query)
for val in res:
out.append(val[0])
return out
def get_fieldvalues(recID, tag):
"""Return list of field values for field TAG inside record RECID."""
out = []
if tag == "001___":
# we have asked for recID that is not stored in bibXXx tables
out.append(str(recID))
else:
# we are going to look inside bibXXx tables
digit = tag[0:2]
bx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag LIKE '%s'" \
"ORDER BY bibx.field_number, bx.tag ASC" % (bx, bibx, recID, tag)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
def get_fieldvalues_alephseq_like(recID, tags):
"""Return textual lines in ALEPH sequential like format for field 'tag' inside record 'recID'."""
out = ""
# clean passed 'tag':
tags_in = string.split(tags, ",")
if len(tags_in) == 1 and len(tags_in[0]) == 6:
## case A: one concrete subfield asked, so print its value if found
## (use with care: can false you if field has multiple occurrences)
out += string.join(get_fieldvalues(recID, tags_in[0]),"\n")
else:
## case B: print our "text MARC" format; works safely all the time
# find out which tags to output:
dict_of_tags_out = {}
for tag in tags_in:
if len(tag) == 0:
for i in range(0,10):
for j in range(0,10):
dict_of_tags_out["%d%d%%" % (i, j)] = 1
elif len(tag) == 1:
for j in range(0,10):
dict_of_tags_out["%s%d%%" % (tag, j)] = 1
elif len(tag) < 5:
dict_of_tags_out["%s%%" % tag] = 1
elif tag >= 6:
dict_of_tags_out[tag[0:5]] = 1
tags_out = dict_of_tags_out.keys()
tags_out.sort()
# search all bibXXx tables as needed:
for tag in tags_out:
digits = tag[0:2]
if tag.startswith("001") or tag.startswith("00%"):
if out:
out += "\n"
out += "%09d %s %d" % (recID, "001__", recID)
bx = "bib%sx" % digits
bibx = "bibrec_bib%sx" % digits
query = "SELECT b.tag,b.value,bb.field_number FROM %s AS b, %s AS bb "\
"WHERE bb.id_bibrec='%s' AND b.id=bb.id_bibxxx AND b.tag LIKE '%s%%' "\
"ORDER BY bb.field_number, b.tag ASC" % (bx, bibx, recID, tag)
res = run_sql(query)
# go through fields:
field_number_old = -999
field_old = ""
for row in res:
field, value, field_number = row[0], row[1], row[2]
ind1, ind2 = field[3], field[4]
if ind1 == "_":
ind1 = ""
if ind2 == "_":
ind2 = ""
# print field tag
if field_number != field_number_old or field[:-1] != field_old[:-1]:
if out:
out += "\n"
out += "%09d %s " % (recID, field[:5])
field_number_old = field_number
field_old = field
# print subfield value
out += "$$%s%s" % (field[-1:], value)
return out
def record_exists(recID):
"""Return 1 if record RECID exists.
Return 0 if it doesn't exist.
Return -1 if it exists but is marked as deleted."""
out = 0
query = "SELECT id FROM bibrec WHERE id='%s'" % recID
res = run_sql(query, None, 1)
if res:
# record exists; now check whether it isn't marked as deleted:
dbcollids = get_fieldvalues(recID, "980__%")
if ("DELETED" in dbcollids) or (cfg_cern_site and "DUMMY" in dbcollids):
out = -1 # exists, but marked as deleted
else:
out = 1 # exists fine
return out
def record_public_p(recID):
"""Return 1 if the record is public, i.e. if it can be found in the Home collection.
Return 0 otherwise.
"""
return get_collection_reclist(cdsname).contains(recID)
def get_creation_date(recID, fmt="%Y-%m-%d"):
"Returns the creation date of the record 'recID'."
out = ""
res = run_sql("SELECT DATE_FORMAT(creation_date,%s) FROM bibrec WHERE id=%s", (fmt, recID), 1)
if res:
out = res[0][0]
return out
def get_modification_date(recID, fmt="%Y-%m-%d"):
"Returns the date of last modification for the record 'recID'."
out = ""
res = run_sql("SELECT DATE_FORMAT(modification_date,%s) FROM bibrec WHERE id=%s", (fmt, recID), 1)
if res:
out = res[0][0]
return out
def print_warning(req, msg, type='', prologue='<br>', epilogue='<br>'):
"Prints warning message and flushes output."
if req and msg:
req.write(websearch_templates.tmpl_print_warning(
msg = msg,
type = type,
prologue = prologue,
epilogue = epilogue,
))
return
def print_search_info(p, f, sf, so, sp, rm, of, ot, collection=cdsname, nb_found=-1, jrec=1, rg=10,
as=0, ln=cdslang, p1="", p2="", p3="", f1="", f2="", f3="", m1="", m2="", m3="", op1="", op2="",
sc=1, pl_in_url="",
d1y=0, d1m=0, d1d=0, d2y=0, d2m=0, d2d=0,
cpu_time=-1, middle_only=0):
"""Prints stripe with the information on 'collection' and 'nb_found' results and CPU time.
Also, prints navigation links (beg/next/prev/end) inside the results set.
If middle_only is set to 1, it will only print the middle box information (beg/netx/prev/end/etc) links.
This is suitable for displaying navigation links at the bottom of the search results page."""
out = ""
# sanity check:
if jrec < 1:
jrec = 1
if jrec > nb_found:
jrec = max(nb_found-rg+1, 1)
return websearch_templates.tmpl_print_search_info(
ln = ln,
weburl = weburl,
collection = collection,
as = as,
collection_name = get_coll_i18nname(collection, ln),
middle_only = middle_only,
rg = rg,
nb_found = nb_found,
sf = sf,
so = so,
rm = rm,
of = of,
ot = ot,
p = p,
f = f,
p1 = p1,
p2 = p2,
p3 = p3,
f1 = f1,
f2 = f2,
f3 = f3,
m1 = m1,
m2 = m2,
m3 = m3,
op1 = op1,
op2 = op2,
pl_in_url = pl_in_url,
d1y = d1y,
d1m = d1m,
d1d = d1d,
d2y = d2y,
d2m = d2m,
d2d = d2d,
jrec = jrec,
sc = sc,
sp = sp,
all_fieldcodes = get_fieldcodes(),
cpu_time = cpu_time,
)
def print_results_overview(req, colls, results_final_nb_total, results_final_nb, cpu_time, ln=cdslang):
"Prints results overview box with links to particular collections below."
out = ""
new_colls = []
for coll in colls:
new_colls.append({
'code' : coll,
'name' : get_coll_i18nname(coll, ln),
})
# deduce url without 'of' argument:
args = req.args or ''
url_args = sre.sub(r'(^|\&)of=.*?(\&|$)',r'\1',args)
url_args = sre.sub(r'^\&+', '', url_args)
url_args = sre.sub(r'\&+$', '', url_args)
return websearch_templates.tmpl_print_results_overview(
ln = ln,
weburl = weburl,
results_final_nb_total = results_final_nb_total,
results_final_nb = results_final_nb,
cpu_time = cpu_time,
colls = new_colls,
url_args = url_args,
)
def sort_records(req, recIDs, sort_field='', sort_order='d', sort_pattern='', verbose=0, of='hb', ln=cdslang):
"""Sort records in 'recIDs' list according sort field 'sort_field' in order 'sort_order'.
If more than one instance of 'sort_field' is found for a given record, try to choose that that is given by
'sort pattern', for example "sort by report number that starts by CERN-PS".
Note that 'sort_field' can be field code like 'author' or MARC tag like '100__a' directly."""
_ = gettext_set_language(ln)
## check arguments:
if not sort_field:
return recIDs
if len(recIDs) > cfg_nb_records_to_sort:
if of.startswith('h'):
print_warning(req, _("Sorry, sorting is allowed on sets of up to %d records only. Using default sort order (\"latest first\").") % cfg_nb_records_to_sort, "Warning")
return recIDs
sort_fields = string.split(sort_field, ",")
recIDs_dict = {}
recIDs_out = []
## first deduce sorting MARC tag out of the 'sort_field' argument:
tags = []
for sort_field in sort_fields:
if sort_field and str(sort_field[0:2]).isdigit():
# sort_field starts by two digits, so this is probably a MARC tag already
tags.append(sort_field)
else:
# let us check the 'field' table
query = """SELECT DISTINCT(t.value) FROM tag AS t, field_tag AS ft, field AS f
WHERE f.code='%s' AND ft.id_field=f.id AND t.id=ft.id_tag
ORDER BY ft.score DESC""" % sort_field
res = run_sql(query)
if res:
for row in res:
tags.append(row[0])
else:
if of.startswith('h'):
print_warning(req, _("Sorry, '%s' does not seem to be a valid sort option. Choosing title sort instead.") % sort_field, "Error")
tags.append("245__a")
if verbose >= 3:
print_warning(req, "Sorting by tags %s." % tags)
if sort_pattern:
print_warning(req, "Sorting preferentially by %s." % sort_pattern)
## check if we have sorting tag defined:
if tags:
# fetch the necessary field values:
for recID in recIDs:
val = "" # will hold value for recID according to which sort
vals = [] # will hold all values found in sorting tag for recID
for tag in tags:
vals.extend(get_fieldvalues(recID, tag))
if sort_pattern:
# try to pick that tag value that corresponds to sort pattern
bingo = 0
for v in vals:
if v.startswith(sort_pattern): # bingo!
bingo = 1
val = v
break
if not bingo: # sort_pattern not present, so add other vals after spaces
val = sort_pattern + " " + string.join(vals)
else:
# no sort pattern defined, so join them all together
val = string.join(vals)
val = val.lower()
if recIDs_dict.has_key(val):
recIDs_dict[val].append(recID)
else:
recIDs_dict[val] = [recID]
# sort them:
recIDs_dict_keys = recIDs_dict.keys()
recIDs_dict_keys.sort()
# now that keys are sorted, create output array:
for k in recIDs_dict_keys:
for s in recIDs_dict[k]:
recIDs_out.append(s)
# ascending or descending?
if sort_order == 'a':
recIDs_out.reverse()
# okay, we are done
return recIDs_out
else:
# good, no sort needed
return recIDs
def print_record_list_for_similarity_boxen(req, title, recID_score_list, ln=cdslang):
"""Print list of records in the "hs" (HTML Similarity) format for similarity boxes.
FIXME: templatize.
"""
recID_score_list_to_be_printed = []
# firstly find 5 first public records to print:
nb_records_to_be_printed = 0
nb_records_seen = 0
while nb_records_to_be_printed < 5 and nb_records_seen < len(recID_score_list) and nb_records_seen < 50:
# looking through first 50 records only, picking first 5 public ones
(recID, score) = recID_score_list[nb_records_seen]
nb_records_seen += 1
if record_public_p(recID):
nb_records_to_be_printed += 1
recID_score_list_to_be_printed.append([recID,score])
# secondly print them:
if nb_records_to_be_printed > 0:
req.write("""<table><tr><td>""")
req.write("""<table><tr><td class="blocknote">%s</td></tr></table>""" % title)
req.write("""<td><tr><td><table>""")
for (recID, score) in recID_score_list_to_be_printed:
req.write("""<tr><td><font class="rankscoreinfo"><a>(%s)&nbsp;</a></font><small>&nbsp;%s</small></td></tr>""" % \
(score,print_record(recID, format="hs", ln=ln)))
req.write("""</table></small></td></tr></table> """)
return
def print_records(req, recIDs, jrec=1, rg=10, format='hb', ot='', ln=cdslang, relevances=[], relevances_prologue="(", relevances_epilogue="%%)", decompress=zlib.decompress):
"""Prints list of records 'recIDs' formatted accoding to 'format' in groups of 'rg' starting from 'jrec'.
Assumes that the input list 'recIDs' is sorted in reverse order, so it counts records from tail to head.
A value of 'rg=-9999' means to print all records: to be used with care.
Print also list of RELEVANCES for each record (if defined), in between RELEVANCE_PROLOGUE and RELEVANCE_EPILOGUE.
"""
# load the right message language
_ = gettext_set_language(ln)
# sanity checking:
if req == None:
return
if len(recIDs):
nb_found = len(recIDs)
if rg == -9999: # print all records
rg = nb_found
else:
rg = abs(rg)
if jrec < 1: # sanity checks
jrec = 1
if jrec > nb_found:
jrec = max(nb_found-rg+1, 1)
# will print records from irec_max to irec_min excluded:
irec_max = nb_found - jrec
irec_min = nb_found - jrec - rg
if irec_min < 0:
irec_min = -1
if irec_max >= nb_found:
irec_max = nb_found - 1
#req.write("%s:%d-%d" % (recIDs, irec_min, irec_max))
if format.startswith('x'):
# we are doing XML output:
for irec in range(irec_max,irec_min,-1):
req.write(print_record(recIDs[irec], format, ot, ln))
elif format.startswith('t') or str(format[0:3]).isdigit():
# we are doing plain text output:
for irec in range(irec_max,irec_min,-1):
x = print_record(recIDs[irec], format, ot, ln)
req.write(x)
if x:
req.write('\n')
else:
# we are doing HTML output:
if format == 'hp' or format.startswith("hb_") or format.startswith("hd_"):
# portfolio and on-the-fly formats:
for irec in range(irec_max,irec_min,-1):
req.write(print_record(recIDs[irec], format, ot, ln))
elif format.startswith("hb"):
# HTML brief format:
rows = []
for irec in range(irec_max,irec_min,-1):
temp = {
'number' : jrec+irec_max-irec,
'recid' : recIDs[irec],
}
if relevances and relevances[irec]:
temp['relevance'] = relevances[irec]
else:
temp['relevance'] = ''
temp['record'] = print_record(recIDs[irec], format, ot, ln)
rows.append(temp)
req.write(websearch_templates.tmpl_records_format_htmlbrief(
ln = ln,
weburl = weburl,
rows = rows,
relevances_prologue = relevances_prologue,
relevances_epilogue = relevances_epilogue,
))
else:
# HTML detailed format:
# deduce url without 'of' argument:
url_args = sre.sub(r'(^|\&)of=.*?(\&|$)',r'\1',req.args)
url_args = sre.sub(r'^\&+', '', url_args)
url_args = sre.sub(r'\&+$', '', url_args)
# print other formatting choices:
rows = []
for irec in range(irec_max,irec_min,-1):
temp = {
'record' : print_record(recIDs[irec], format, ot, ln),
'recid' : recIDs[irec],
'creationdate': '',
'modifydate' : '',
}
if record_exists(recIDs[irec])==1:
temp['creationdate'] = get_creation_date(recIDs[irec])
temp['modifydate'] = get_modification_date(recIDs[irec])
if cfg_experimental_features:
r = calculate_cited_by_list(recIDs[irec])
if r:
temp ['citinglist'] = r
temp ['citationhistory'] = create_citation_history_graph_and_box(recIDs[irec], ln)
r = calculate_co_cited_with_list(recIDs[irec])
if r: temp ['cociting'] = r
r = calculate_reading_similarity_list(recIDs[irec], "downloads")
if r:
temp ['downloadsimilarity'] = r
temp ['downloadhistory'] = create_download_history_graph_and_box(recIDs[irec], ln)
# Get comments and reviews for this record if exist
# FIXME: templatize me
if cfg_webcomment_allow_comments or cfg_webcomment_allow_reviews:
from webcomment import get_first_comments_or_remarks
(comments, reviews) = get_first_comments_or_remarks(recID=recIDs[irec], ln=ln,
nb_comments=cfg_webcomment_nb_comments_in_detailed_view,
nb_reviews=cfg_webcomment_nb_reviews_in_detailed_view)
temp['comments'] = comments
temp['reviews'] = reviews
r = calculate_reading_similarity_list(recIDs[irec], "pageviews")
if r: temp ['viewsimilarity'] = r
rows.append(temp)
req.write(websearch_templates.tmpl_records_format_other(
ln = ln,
weburl = weburl,
url_args = url_args,
rows = rows,
format = format,
))
else:
print_warning(req, _("Use different search terms."))
def print_record(recID, format='hb', ot='', ln=cdslang, decompress=zlib.decompress):
"Prints record 'recID' formatted accoding to 'format'."
_ = gettext_set_language(ln)
out = ""
# sanity check:
record_exist_p = record_exists(recID)
if record_exist_p == 0: # doesn't exist
return out
# print record opening tags, if needed:
if format == "marcxml" or format == "oai_dc":
out += " <record>\n"
out += " <header>\n"
for id in get_fieldvalues(recID,oaiidfield):
out += " <identifier>%s</identifier>\n" % id
out += " <datestamp>%s</datestamp>\n" % get_modification_date(recID)
out += " </header>\n"
out += " <metadata>\n"
if format.startswith("xm") or format == "marcxml":
# look for detailed format existence:
query = "SELECT value FROM bibfmt WHERE id_bibrec='%s' AND format='%s'" % (recID, format)
res = run_sql(query, None, 1)
if res and record_exist_p==1:
# record 'recID' is formatted in 'format', so print it
out += "%s" % decompress(res[0][0])
else:
# record 'recID' is not formatted in 'format' -- they are not in "bibfmt" table; so fetch all the data from "bibXXx" tables:
if format == "marcxml":
out += """ <record xmlns="http://www.loc.gov/MARC21/slim">\n"""
out += " <controlfield tag=\"001\">%d</controlfield>\n" % int(recID)
elif format.startswith("xm"):
out += """ <record>\n"""
out += " <controlfield tag=\"001\">%d</controlfield>\n" % int(recID)
if record_exist_p == -1:
# deleted record, so display only OAI ID and 980:
oai_ids = get_fieldvalues(recID, cfg_oaiidtag)
if oai_ids:
out += "<datafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\"><subfield code=\"%s\">%s</subfield></datafield>\n" % \
(cfg_oaiidtag[0:3], cfg_oaiidtag[3:4], cfg_oaiidtag[4:5], cfg_oaiidtag[5:6], oai_ids[0])
out += "<datafield tag=\"980\" ind1=\"\" ind2=\"\"><subfield code=\"c\">DELETED</subfield></datafield>\n"
else:
for digit1 in range(0,10):
for digit2 in range(0,10):
bx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
query = "SELECT b.tag,b.value,bb.field_number FROM %s AS b, %s AS bb "\
"WHERE bb.id_bibrec='%s' AND b.id=bb.id_bibxxx AND b.tag LIKE '%s%%' "\
"ORDER BY bb.field_number, b.tag ASC" % (bx, bibx, recID, str(digit1)+str(digit2))
res = run_sql(query)
field_number_old = -999
field_old = ""
for row in res:
field, value, field_number = row[0], row[1], row[2]
ind1, ind2 = field[3], field[4]
if ind1 == "_":
ind1 = ""
if ind2 == "_":
ind2 = ""
# print field tag
if field_number != field_number_old or field[:-1] != field_old[:-1]:
if format.startswith("xm") or format == "marcxml":
fieldid = encode_for_xml(field[0:3])
if field_number_old != -999:
out += """ </datafield>\n"""
out += """ <datafield tag="%s" ind1="%s" ind2="%s">\n""" % \
(encode_for_xml(field[0:3]), encode_for_xml(ind1), encode_for_xml(ind2))
field_number_old = field_number
field_old = field
# print subfield value
if format.startswith("xm") or format == "marcxml":
value = encode_for_xml(value)
out += """ <subfield code="%s">%s</subfield>\n""" % (encode_for_xml(field[-1:]), value)
# all fields/subfields printed in this run, so close the tag:
if (format.startswith("xm") or format == "marcxml") and field_number_old != -999:
out += """ </datafield>\n"""
# we are at the end of printing the record:
if format.startswith("xm") or format == "marcxml":
out += " </record>\n"
elif format == "xd" or format == "oai_dc":
# XML Dublin Core format, possibly OAI -- select only some bibXXx fields:
out += """ <dc xmlns="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://purl.org/dc/elements/1.1/
http://www.openarchives.org/OAI/1.1/dc.xsd">\n"""
if record_exist_p == -1:
out += ""
else:
for f in get_fieldvalues(recID, "041__a"):
out += " <language>%s</language>\n" % f
for f in get_fieldvalues(recID, "100__a"):
out += " <creator>%s</creator>\n" % encode_for_xml(f)
for f in get_fieldvalues(recID, "700__a"):
out += " <creator>%s</creator>\n" % encode_for_xml(f)
for f in get_fieldvalues(recID, "245__a"):
out += " <title>%s</title>\n" % encode_for_xml(f)
for f in get_fieldvalues(recID, "65017a"):
out += " <subject>%s</subject>\n" % encode_for_xml(f)
for f in get_fieldvalues(recID, "8564_u"):
out += " <identifier>%s</identifier>\n" % encode_for_xml(f)
for f in get_fieldvalues(recID, "520__a"):
out += " <description>%s</description>\n" % encode_for_xml(f)
out += " <date>%s</date>\n" % get_creation_date(recID)
out += " </dc>\n"
elif format.startswith("x_"):
# underscore means that XML formats should be called on-the-fly; suitable for testing formats
out += call_bibformat(recID, format)
elif str(format[0:3]).isdigit():
# user has asked to print some fields only
if format == "001":
out += "<!--%s-begin-->%s<!--%s-end-->\n" % (format, recID, format)
else:
vals = get_fieldvalues(recID, format)
for val in vals:
out += "<!--%s-begin-->%s<!--%s-end-->\n" % (format, val, format)
elif format.startswith('t'):
## user directly asked for some tags to be displayed only
if record_exist_p == -1:
out += get_fieldvalues_alephseq_like(recID, "001,%s,980" % cfg_oaiidtag)
else:
out += get_fieldvalues_alephseq_like(recID, ot)
elif format == "hm":
if record_exist_p == -1:
out += "<pre>" + cgi.escape(get_fieldvalues_alephseq_like(recID, "001,%s,980" % cfg_oaiidtag)) + "</pre>"
else:
out += "<pre>" + cgi.escape(get_fieldvalues_alephseq_like(recID, ot)) + "</pre>"
elif format.startswith("h") and ot:
## user directly asked for some tags to be displayed only
if record_exist_p == -1:
out += "<pre>" + get_fieldvalues_alephseq_like(recID, "001,%s,980" % cfg_oaiidtag) + "</pre>"
else:
out += "<pre>" + get_fieldvalues_alephseq_like(recID, ot) + "</pre>"
elif format == "hd":
# HTML detailed format
if record_exist_p == -1:
out += _("The record has been deleted.")
else:
# look for detailed format existence:
query = "SELECT value FROM bibfmt WHERE id_bibrec='%s' AND format='%s'" % (recID, format)
res = run_sql(query, None, 1)
if res:
# record 'recID' is formatted in 'format', so print it
out += "%s" % decompress(res[0][0])
else:
# record 'recID' is not formatted in 'format', so either call BibFormat on the fly or use default format
# second, see if we are calling BibFormat on the fly:
if cfg_call_bibformat:
xfm = call_bibformat(recID, format)
dom = minidom.parseString(xfm)
for e in dom.getElementsByTagName('subfield'):
if e.getAttribute('code') == 'g':
for t in e.childNodes:
out += t.data.encode('utf-8')
else:
out += websearch_templates.tmpl_print_record_detailed(
ln = ln,
recID = recID,
weburl = weburl,
)
elif format.startswith("hb_") or format.startswith("hd_"):
# underscore means that HTML brief/detailed formats should be called on-the-fly; suitable for testing formats
if record_exist_p == -1:
out += _("The record has been deleted.")
else:
out += call_bibformat(recID, format)
elif format.startswith("hx"):
# BibTeX format, called on the fly:
if record_exist_p == -1:
out += _("The record has been deleted.")
else:
out += call_bibformat(recID, format)
elif format.startswith("hs"):
# for citation/download similarity navigation links:
if record_exist_p == -1:
out += _("The record has been deleted.")
else:
out += """<a href="%s/search.py?recid=%s&ln=%s">""" % (weburl, recID, ln)
# firstly, title:
titles = get_fieldvalues(recID, "245__a")
if titles:
for title in titles:
out += "<strong>%s</strong>" % title
else:
# usual title not found, try conference title:
titles = get_fieldvalues(recID, "111__a")
if titles:
for title in titles:
out += "<strong>%s</strong>" % title
else:
# just print record ID:
out += "<strong>%s %d</strong>" % (get_field_i18nname("record ID", ln), recID)
out += "</a>"
# secondly, authors:
authors = get_fieldvalues(recID, "100__a") + get_fieldvalues(recID, "700__a")
if authors:
out += " - %s" % authors[0]
if len(authors) > 1:
out += " <em>et al</em>"
# thirdly publication info:
publinfos = get_fieldvalues(recID, "773__s")
if not publinfos:
publinfos = get_fieldvalues(recID, "909C4s")
if not publinfos:
publinfos = get_fieldvalues(recID, "037__a")
if not publinfos:
publinfos = get_fieldvalues(recID, "088__a")
if publinfos:
out += " - %s" % publinfos[0]
else:
# fourthly publication year (if not publication info):
years = get_fieldvalues(recID, "773__y")
if not years:
years = get_fieldvalues(recID, "909C4y")
if not years:
years = get_fieldvalues(recID, "260__c")
if years:
out += " (%s)" % years[0]
else:
# HTML brief format by default
if record_exist_p == -1:
out += _("The record has been deleted.")
else:
query = "SELECT value FROM bibfmt WHERE id_bibrec='%s' AND format='%s'" % (recID, format)
res = run_sql(query)
if res:
# record 'recID' is formatted in 'format', so print it
out += "%s" % decompress(res[0][0])
else:
out += websearch_templates.tmpl_print_record_brief(
ln = ln,
recID = recID,
weburl = weburl,
)
# at the end of HTML brief mode, print the "Detailed record" functionality:
if format == 'hp' or format.startswith("hb_") or format.startswith("hd_"):
pass # do nothing for portfolio and on-the-fly formats
else:
out += websearch_templates.tmpl_print_record_brief_links(
ln = ln,
recID = recID,
weburl = weburl,
)
# print record closing tags, if needed:
if format == "marcxml" or format == "oai_dc":
out += " </metadata>\n"
out += " </record>\n"
return out
def encode_for_xml(s):
"Encode special chars in string so that it would be XML-compliant."
s = string.replace(s, '&', '&amp;')
s = string.replace(s, '<', '&lt;')
return s
def call_bibformat(id, otype="HD"):
"""Calls BibFormat for the record 'id'. Desired BibFormat output type is passed in 'otype' argument.
This function is mainly used to display full format, if they are not stored in the 'bibfmt' table."""
pipe_input, pipe_output, pipe_error = os.popen3(["%s/bibformat" % bindir, "otype=%s" % otype], 'rw')
pipe_input.write(print_record(id, "xm"))
pipe_input.close()
out = pipe_output.read()
pipe_output.close()
pipe_error.close()
return out
def log_query(hostname, query_args, uid=-1):
"""Log query into the query and user_query tables."""
if uid > 0:
# log the query only if uid is reasonable
res = run_sql("SELECT id FROM query WHERE urlargs=%s", (query_args,), 1)
try:
id_query = res[0][0]
except:
id_query = run_sql("INSERT INTO query (type, urlargs) VALUES ('r', %s)", (query_args,))
if id_query:
run_sql("INSERT INTO user_query (id_user, id_query, hostname, date) VALUES (%s, %s, %s, %s)",
(uid, id_query, hostname,
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
return
def log_query_info(action, p, f, colls, nb_records_found_total=-1):
"""Write some info to the log file for later analysis."""
try:
log = open(logdir + "/search.log", "a")
log.write(time.strftime("%Y%m%d%H%M%S#", time.localtime()))
log.write(action+"#")
log.write(p+"#")
log.write(f+"#")
for coll in colls[:-1]:
log.write("%s," % coll)
log.write("%s#" % colls[-1])
log.write("%d" % nb_records_found_total)
log.write("\n")
log.close()
except:
pass
return
def wash_url_argument(var, new_type):
"""Wash list argument into 'new_type', that can be 'list',
'str', or 'int'. Useful for washing mod_python passed
arguments, that are all lists of strings (URL args may be
multiple), but we sometimes want only to take the first value,
and sometimes to represent it as string or numerical value."""
out = []
if new_type == 'list': # return lst
if type(var) is list:
out = var
else:
out = [var]
elif new_type == 'str': # return str
if type(var) is list:
try:
out = "%s" % var[0]
except:
out = ""
elif type(var) is str:
out = var
else:
out = "%s" % var
elif new_type == 'int': # return int
if type(var) is list:
try:
out = string.atoi(var[0])
except:
out = 0
elif type(var) is int:
out = var
elif type(var) is str:
try:
out = string.atoi(var)
except:
out = 0
else:
out = 0
return out
### CALLABLES
def perform_request_search(req=None, cc=cdsname, c=None, p="", f="", rg="10", sf="", so="d", sp="", rm="", of="id", ot="", as="0",
p1="", f1="", m1="", op1="", p2="", f2="", m2="", op2="", p3="", f3="", m3="", sc="0", jrec="0",
recid="-1", recidb="-1", sysno="", id="-1", idb="-1", sysnb="", action="",
d1y="0", d1m="0", d1d="0", d2y="0", d2m="0", d2d="0", verbose="0", ap="0", ln=cdslang):
"""Perform search or browse request, without checking for
authentication. Return list of recIDs found, if of=id.
Otherwise create web page.
The arguments are as follows:
req - mod_python Request class instance.
cc - current collection (e.g. "ATLAS"). The collection the
user started to search/browse from.
c - collectin list (e.g. ["Theses", "Books"]). The
collections user may have selected/deselected when
starting to search from 'cc'.
p - pattern to search for (e.g. "ellis and muon or kaon").
f - field to search within (e.g. "author").
rg - records in groups of (e.g. "10"). Defines how many hits
per collection in the search results page are
displayed.
sf - sort field (e.g. "title").
so - sort order ("a"=ascending, "d"=descending).
sp - sort pattern (e.g. "CERN-") -- in case there are more
values in a sort field, this argument tells which one
to prefer
rm - ranking method (e.g. "jif"). Defines whether results
should be ranked by some known ranking method.
of - output format (e.g. "hb"). Usually starting "h" means
HTML output (and "hb" for HTML brief, "hd" for HTML
detailed), "x" means XML output, "t" means plain text
output, "id" means no output at all but to return list
of recIDs found. (Suitable for high-level API.)
ot - output only these MARC tags (e.g. "100,700,909C0b").
Useful if only some fields are to be shown in the
output, e.g. for library to control some fields.
as - advanced search ("0" means no, "1" means yes). Whether
search was called from within the advanced search
interface.
p1 - first pattern to search for in the advanced search
interface. Much like 'p'.
f1 - first field to search within in the advanced search
interface. Much like 'f'.
m1 - first matching type in the advanced search interface.
("a" all of the words, "o" any of the words, "e" exact
phrase, "p" partial phrase, "r" regular expression).
op1 - first operator, to join the first and the second unit
in the advanced search interface. ("a" add, "o" or,
"n" not).
p2 - second pattern to search for in the advanced search
interface. Much like 'p'.
f2 - second field to search within in the advanced search
interface. Much like 'f'.
m2 - second matching type in the advanced search interface.
("a" all of the words, "o" any of the words, "e" exact
phrase, "p" partial phrase, "r" regular expression).
op2 - second operator, to join the second and the third unit
in the advanced search interface. ("a" add, "o" or,
"n" not).
p3 - third pattern to search for in the advanced search
interface. Much like 'p'.
f3 - third field to search within in the advanced search
interface. Much like 'f'.
m3 - third matching type in the advanced search interface.
("a" all of the words, "o" any of the words, "e" exact
phrase, "p" partial phrase, "r" regular expression).
sc - split by collection ("0" no, "1" yes). Governs whether
we want to present the results in a single huge list,
or splitted by collection.
jrec - jump to record (e.g. "234"). Used for navigation
inside the search results.
recid - display record ID (e.g. "20000"). Do not
search/browse but go straight away to the Detailed
record page for the given recID.
recidb - display record ID bis (e.g. "20010"). If greater than
'recid', then display records from recid to recidb.
Useful for example for dumping records from the
database for reformatting.
sysno - display old system SYS number (e.g. ""). If you
migrate to CDSware from another system, and store your
old SYS call numbers, you can use them instead of recid
if you wish so.
id - the same as recid, in case recid is not set. For
backwards compatibility.
idb - the same as recid, in case recidb is not set. For
backwards compatibility.
sysnb - the same as sysno, in case sysno is not set. For
backwards compatibility.
action - action to do. "SEARCH" for searching, "Browse" for
browsing. Default is to search.
d1y - first date year (e.g. "1998"). Useful for search
limits on creation date.
d1m - first date month (e.g. "08"). Useful for search
limits on creation date.
d1d - first date day (e.g. "23"). Useful for search
limits on creation date.
d2y - second date year (e.g. "1998"). Useful for search
limits on creation date.
d2m - second date month (e.g. "09"). Useful for search
limits on creation date.
d2d - second date day (e.g. "02"). Useful for search limits
on creation date.
verbose - verbose level (0=min, 9=max). Useful to print some
internal information on the searching process in case
something goes wrong.
ap - alternative patterns (0=no, 1=yes). In case no exact
match is found, the search engine can try alternative
patterns e.g. to replace non-alphanumeric characters by
a boolean query. ap defines if this is wanted.
ln - language of the search interface (e.g. "en"). Useful
for internationalization.
"""
# wash all passed arguments:
cc = wash_url_argument(cc, 'str')
sc = wash_url_argument(sc, 'int')
(cc, colls_to_display, colls_to_search) = wash_colls(cc, c, sc) # which colls to search and to display?
p = wash_pattern(wash_url_argument(p, 'str'))
f = wash_field(wash_url_argument(f, 'str'))
rg = wash_url_argument(rg, 'int')
sf = wash_url_argument(sf, 'str')
so = wash_url_argument(so, 'str')
sp = wash_url_argument(sp, 'str')
rm = wash_url_argument(rm, 'str')
of = wash_url_argument(of, 'str')
if type(ot) is list:
ot = string.join(ot,",")
ot = wash_url_argument(ot, 'str')
as = wash_url_argument(as, 'int')
p1 = wash_pattern(wash_url_argument(p1, 'str'))
f1 = wash_field(wash_url_argument(f1, 'str'))
m1 = wash_url_argument(m1, 'str')
op1 = wash_url_argument(op1, 'str')
p2 = wash_pattern(wash_url_argument(p2, 'str'))
f2 = wash_field(wash_url_argument(f2, 'str'))
m2 = wash_url_argument(m2, 'str')
op2 = wash_url_argument(op2, 'str')
p3 = wash_pattern(wash_url_argument(p3, 'str'))
f3 = wash_field(wash_url_argument(f3, 'str'))
m3 = wash_url_argument(m3, 'str')
jrec = wash_url_argument(jrec, 'int')
recid = wash_url_argument(recid, 'int')
recidb = wash_url_argument(recidb, 'int')
sysno = wash_url_argument(sysno, 'str')
id = wash_url_argument(id, 'int')
idb = wash_url_argument(idb, 'int')
sysnb = wash_url_argument(sysnb, 'str')
action = wash_url_argument(action, 'str')
d1y = wash_url_argument(d1y, 'int')
d1m = wash_url_argument(d1m, 'int')
d1d = wash_url_argument(d1d, 'int')
d2y = wash_url_argument(d2y, 'int')
d2m = wash_url_argument(d2m, 'int')
d2d = wash_url_argument(d2d, 'int')
day1, day2 = wash_dates(d1y, d1m, d1d, d2y, d2m, d2d)
verbose = wash_url_argument(verbose, 'int')
ap = wash_url_argument(ap, 'int')
ln = wash_language(ln)
_ = gettext_set_language(ln)
# backwards compatibility: id, idb, sysnb -> recid, recidb, sysno (if applicable)
if sysnb != "" and sysno == "":
sysno = sysnb
if id > 0 and recid == -1:
recid = id
if idb > 0 and recidb == -1:
recidb = idb
# TODO deduce passed search limiting criterias (if applicable)
pl, pl_in_url = "", "" # no limits by default
if action != _("Browse") and req and req.args: # we do not want to add options while browsing or while calling via command-line
fieldargs = cgi.parse_qs(req.args)
for fieldcode in get_fieldcodes():
if fieldargs.has_key(fieldcode):
for val in fieldargs[fieldcode]:
pl += "+%s:\"%s\" " % (fieldcode, val)
pl_in_url += "&amp;%s=%s" % (urllib.quote(fieldcode), urllib.quote(val))
# deduce recid from sysno argument (if applicable):
if sysno: # ALEPH SYS number was passed, so deduce MySQL recID for the record:
recid = get_mysql_recid_from_aleph_sysno(sysno)
# deduce collection we are in (if applicable):
if recid>0:
cc = guess_primary_collection_of_a_record(recid)
# deduce user id (if applicable):
try:
uid = getUid(req)
except:
uid = 0
## 0 - start output
if recid>0:
## 1 - detailed record display
page_start(req, of, cc, as, ln, uid, _("Detailed record") + " #%d" % recid)
if of == "hb":
of = "hd"
if record_exists(recid):
if recidb<=recid: # sanity check
recidb=recid+1
print_records(req, range(recid,recidb), -1, -9999, of, ot, ln)
if req and of.startswith("h"): # register detailed record page view event
client_ip_address = str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
register_page_view_event(recid, uid, client_ip_address)
else: # record does not exist
if of.startswith("h"):
print_warning(req, "Requested record does not seem to exist.")
elif action == _("Browse"):
## 2 - browse needed
page_start(req, of, cc, as, ln, uid, _("Browse"))
if of.startswith("h"):
req.write(create_search_box(cc, colls_to_display, p, f, rg, sf, so, sp, rm, of, ot, as, ln, p1, f1, m1, op1,
p2, f2, m2, op2, p3, f3, m3, sc, pl, d1y, d1m, d1d, d2y, d2m, d2d, action))
try:
if as==1 or (p1 or p2 or p3):
browse_pattern(req, colls_to_search, p1, f1, rg)
browse_pattern(req, colls_to_search, p2, f2, rg)
browse_pattern(req, colls_to_search, p3, f3, rg)
else:
browse_pattern(req, colls_to_search, p, f, rg)
except:
if of.startswith("h"):
req.write(create_error_box(req, verbose=verbose, ln=ln))
return page_end(req, of, ln)
elif rm and p.startswith("recid:"):
## 3-ter - similarity search needed
page_start(req, of, cc, as, ln, uid, _("Search Results"))
if of.startswith("h"):
req.write(create_search_box(cc, colls_to_display, p, f, rg, sf, so, sp, rm, of, ot, as, ln, p1, f1, m1, op1,
p2, f2, m2, op2, p3, f3, m3, sc, pl, d1y, d1m, d1d, d2y, d2m, d2d, action))
if record_exists(p[6:]) != 1:
# record does not exist
if of.startswith("h"):
print_warning(req, "Requested record does not seem to exist.")
if of == "id":
return []
else:
# record well exists, so find similar ones to it
t1 = os.times()[4]
results_similar_recIDs, results_similar_relevances, results_similar_relevances_prologue, results_similar_relevances_epilogue, results_similar_comments = \
rank_records(rm, 0, get_collection_reclist(cdsname), string.split(p), verbose)
if results_similar_recIDs:
t2 = os.times()[4]
cpu_time = t2 - t1
if of.startswith("h"):
req.write(print_search_info(p, f, sf, so, sp, rm, of, ot, cdsname, len(results_similar_recIDs),
jrec, rg, as, ln, p1, p2, p3, f1, f2, f3, m1, m2, m3, op1, op2,
sc, pl_in_url,
d1y, d1m, d1d, d2y, d2m, d2d, cpu_time))
print_warning(req, results_similar_comments)
print_records(req, results_similar_recIDs, jrec, rg, of, ot, ln,
results_similar_relevances, results_similar_relevances_prologue, results_similar_relevances_epilogue)
elif of=="id":
return results_similar_recIDs
else:
# rank_records failed and returned some error message to display:
if of.startswith("h"):
print_warning(req, results_similar_relevances_prologue)
print_warning(req, results_similar_relevances_epilogue)
print_warning(req, results_similar_comments)
if of == "id":
return []
elif cfg_experimental_features and p.startswith("cocitedwith:"):
## 3-terter - cited by search needed
page_start(req, of, cc, as, ln, uid, _("Search Results"))
if of.startswith("h"):
req.write(create_search_box(cc, colls_to_display, p, f, rg, sf, so, sp, rm, of, ot, as, ln, p1, f1, m1, op1,
p2, f2, m2, op2, p3, f3, m3, sc, pl, d1y, d1m, d1d, d2y, d2m, d2d, action))
recID = p[12:]
if record_exists(recID) != 1:
# record does not exist
if of.startswith("h"):
print_warning(req, "Requested record does not seem to exist.")
if of == "id":
return []
else:
# record well exists, so find co-cited ones:
t1 = os.times()[4]
results_cocited_recIDs = map(lambda x: x[0], calculate_co_cited_with_list(int(recID)))
if results_cocited_recIDs:
t2 = os.times()[4]
cpu_time = t2 - t1
if of.startswith("h"):
req.write(print_search_info(p, f, sf, so, sp, rm, of, ot, cdsname, len(results_cocited_recIDs),
jrec, rg, as, ln, p1, p2, p3, f1, f2, f3, m1, m2, m3, op1, op2,
sc, pl_in_url,
d1y, d1m, d1d, d2y, d2m, d2d, cpu_time))
print_records(req, results_cocited_recIDs, jrec, rg, of, ot, ln)
elif of=="id":
return results_cocited_recIDs
else:
# cited rank_records failed and returned some error message to display:
if of.startswith("h"):
print_warning(req, "nothing found")
if of == "id":
return []
else:
## 3 - common search needed
page_start(req, of, cc, as, ln, uid, _("Search Results"))
if of.startswith("h"):
req.write(create_search_box(cc, colls_to_display, p, f, rg, sf, so, sp, rm, of, ot, as, ln, p1, f1, m1, op1,
p2, f2, m2, op2, p3, f3, m3, sc, pl, d1y, d1m, d1d, d2y, d2m, d2d, action))
t1 = os.times()[4]
results_in_any_collection = HitSet()
if as == 1 or (p1 or p2 or p3):
## 3A - advanced search
try:
results_in_any_collection = search_pattern(req, p1, f1, m1, ap=ap, of=of, verbose=verbose, ln=ln)
if results_in_any_collection._nbhits == 0:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if p2:
results_tmp = search_pattern(req, p2, f2, m2, ap=ap, of=of, verbose=verbose, ln=ln)
if op1 == "a": # add
results_in_any_collection.intersect(results_tmp)
elif op1 == "o": # or
results_in_any_collection.union(results_tmp)
elif op1 == "n": # not
results_in_any_collection.difference(results_tmp)
else:
if of.startswith("h"):
print_warning(req, "Invalid set operation %s." % op1, "Error")
results_in_any_collection.calculate_nbhits()
if results_in_any_collection._nbhits == 0:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if p3:
results_tmp = search_pattern(req, p3, f3, m3, ap=ap, of=of, verbose=verbose, ln=ln)
if op2 == "a": # add
results_in_any_collection.intersect(results_tmp)
elif op2 == "o": # or
results_in_any_collection.union(results_tmp)
elif op2 == "n": # not
results_in_any_collection.difference(results_tmp)
else:
if of.startswith("h"):
print_warning(req, "Invalid set operation %s." % op2, "Error")
results_in_any_collection.calculate_nbhits()
except:
if of.startswith("h"):
req.write(create_error_box(req, verbose=verbose, ln=ln))
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
else:
## 3B - simple search
try:
results_in_any_collection = search_pattern(req, p, f, ap=ap, of=of, verbose=verbose, ln=ln)
except:
if of.startswith("h"):
req.write(create_error_box(req, verbose=verbose, ln=ln))
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if results_in_any_collection._nbhits == 0:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
# search_cache_key = p+"@"+f+"@"+string.join(colls_to_search,",")
# if search_cache.has_key(search_cache_key): # is the result in search cache?
# results_final = search_cache[search_cache_key]
# else:
# results_final = search_pattern(req, p, f, colls_to_search)
# search_cache[search_cache_key] = results_final
# if len(search_cache) > cfg_search_cache_size: # is the cache full? (sanity cleaning)
# search_cache.clear()
# search stage 4: intersection with collection universe:
try:
results_final = intersect_results_with_collrecs(req, results_in_any_collection, colls_to_search, ap, of, verbose, ln)
except:
if of.startswith("h"):
req.write(create_error_box(req, verbose=verbose, ln=ln))
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if results_final == {}:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
# search stage 5: apply search option limits and restrictions:
if day1 != "":
try:
results_final = intersect_results_with_hitset(req,
results_final,
search_unit_in_bibrec(day1, day2),
ap,
aptext= _("No match within your time limits, "
"discarding this condition..."),
of=of)
except:
if of.startswith("h"):
req.write(create_error_box(req, verbose=verbose, ln=ln))
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if results_final == {}:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if pl:
try:
results_final = intersect_results_with_hitset(req,
results_final,
search_pattern(req, pl, ap=0, ln=ln),
ap,
aptext=_("No match within your search limits, "
"discarding this condition..."),
of=of)
except:
if of.startswith("h"):
req.write(create_error_box(req, verbose=verbose, ln=ln))
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
if results_final == {}:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
t2 = os.times()[4]
cpu_time = t2 - t1
## search stage 6: display results:
results_final_nb_total = 0
results_final_nb = {} # will hold number of records found in each collection
# (in simple dict to display overview more easily; may refactor later)
for coll in results_final.keys():
results_final_nb[coll] = results_final[coll]._nbhits
results_final_nb_total += results_final_nb[coll]
if results_final_nb_total == 0:
if of.startswith('h'):
print_warning(req, "No match found, please enter different search terms.")
else:
# yes, some hits found: good!
# collection list may have changed due to not-exact-match-found policy so check it out:
for coll in results_final.keys():
if coll not in colls_to_search:
colls_to_search.append(coll)
# print results overview:
if of == "id":
# we have been asked to return list of recIDs
results_final_for_all_colls = HitSet()
for coll in results_final.keys():
results_final_for_all_colls.union(results_final[coll])
recIDs = results_final_for_all_colls.items().tolist()
if sf: # do we have to sort?
recIDs = sort_records(req, recIDs, sf, so, sp, verbose, of)
elif rm: # do we have to rank?
results_final_for_all_colls_rank_records_output = rank_records(rm, 0, results_final_for_all_colls,
string.split(p) + string.split(p1) +
string.split(p2) + string.split(p3), verbose)
if results_final_for_all_colls_rank_records_output[0]:
recIDs = results_final_for_all_colls_rank_records_output[0]
return recIDs
elif of.startswith("h"):
req.write(print_results_overview(req, colls_to_search, results_final_nb_total, results_final_nb, cpu_time, ln))
# print records:
if len(colls_to_search)>1:
cpu_time = -1 # we do not want to have search time printed on each collection
for coll in colls_to_search:
if results_final.has_key(coll) and results_final[coll]._nbhits:
if of.startswith("h"):
req.write(print_search_info(p, f, sf, so, sp, rm, of, ot, coll, results_final_nb[coll],
jrec, rg, as, ln, p1, p2, p3, f1, f2, f3, m1, m2, m3, op1, op2,
sc, pl_in_url,
d1y, d1m, d1d, d2y, d2m, d2d, cpu_time))
results_final_recIDs = results_final[coll].items()
results_final_relevances = []
results_final_relevances_prologue = ""
results_final_relevances_epilogue = ""
if sf: # do we have to sort?
results_final_recIDs = sort_records(req, results_final_recIDs, sf, so, sp, verbose, of)
elif rm: # do we have to rank?
results_final_recIDs_ranked, results_final_relevances, results_final_relevances_prologue, results_final_relevances_epilogue, results_final_comments = \
rank_records(rm, 0, results_final[coll],
string.split(p) + string.split(p1) +
string.split(p2) + string.split(p3), verbose)
if of.startswith("h"):
print_warning(req, results_final_comments)
if results_final_recIDs_ranked:
results_final_recIDs = results_final_recIDs_ranked
else:
# rank_records failed and returned some error message to display:
print_warning(req, results_final_relevances_prologue)
print_warning(req, results_final_relevances_epilogue)
print_records(req, results_final_recIDs, jrec, rg, of, ot, ln,
results_final_relevances, results_final_relevances_prologue, results_final_relevances_epilogue)
if of.startswith("h"):
req.write(print_search_info(p, f, sf, so, sp, rm, of, ot, coll, results_final_nb[coll],
jrec, rg, as, ln, p1, p2, p3, f1, f2, f3, m1, m2, m3, op1, op2,
sc, pl_in_url,
d1y, d1m, d1d, d2y, d2m, d2d, cpu_time, 1))
if f == "author" and of.startswith("h"):
req.write(create_similarly_named_authors_link_box(p, ln))
# log query:
try:
log_query(req.get_remote_host(), req.args, uid)
except:
# do not log query if req is None (used by CLI interface)
pass
log_query_info("ss", p, f, colls_to_search, results_final_nb_total)
## 4 - write footer:
if of.startswith("h"):
req.write(create_google_box(cc, p, f, p1, p2, p3, ln))
return page_end(req, of, ln)
def perform_request_cache(req, action="show"):
"""Manipulates the search engine cache."""
global search_cache
global collection_reclist_cache
global collection_reclist_cache_timestamp
global field_i18nname_cache
global field_i18nname_cache_timestamp
global collection_i18nname_cache
global collection_i18nname_cache_timestamp
req.content_type = "text/html"
req.send_http_header()
out = ""
out += "<h1>Search Cache</h1>"
# clear cache if requested:
if action == "clear":
search_cache = {}
collection_reclist_cache = create_collection_reclist_cache()
# show collection reclist cache:
out += "<h3>Collection reclist cache</h3>"
res = run_sql("SHOW TABLE STATUS LIKE 'collection'")
out += "- collection table last updated: %s" % str(res[0][11])
out += "<br>- reclist cache timestamp: %s" % collection_reclist_cache_timestamp
out += "<br>- reclist cache contents:"
out += "<blockquote>"
for coll in collection_reclist_cache.keys():
if collection_reclist_cache[coll]:
out += "%s (%d)<br>" % (coll, get_collection_reclist(coll)._nbhits)
out += "</blockquote>"
# show search cache:
out += "<h3>Search Cache</h3>"
out += "<blockquote>"
if len(search_cache):
out += """<table border="=">"""
out += "<tr><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td></tr>" % ("Pattern","Field","Collection","Number of Hits")
for search_cache_key in search_cache.keys():
p, f, c = string.split(search_cache_key, "@", 2)
# find out about length of cached data:
l = 0
for coll in search_cache[search_cache_key]:
l += search_cache[search_cache_key][coll]._nbhits
out += "<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td></tr>" % (p, f, c, l)
out += "</table>"
else:
out += "<p>Search cache is empty."
out += "</blockquote>"
out += """<p><a href="%s/search.py/cache?action=clear">clear cache</a>""" % weburl
# show field i18nname cache:
out += "<h3>Field I18N names cache</h3>"
res = run_sql("SHOW TABLE STATUS LIKE 'fieldname'")
out += "- fieldname table last updated: %s" % str(res[0][11])
out += "<br>- i18nname cache timestamp: %s" % field_i18nname_cache_timestamp
out += "<br>- i18nname cache contents:"
out += "<blockquote>"
for field in field_i18nname_cache.keys():
for ln in field_i18nname_cache[field].keys():
out += "%s, %s = %s<br>" % (field, ln, field_i18nname_cache[field][ln])
out += "</blockquote>"
# show collection i18nname cache:
out += "<h3>Collection I18N names cache</h3>"
res = run_sql("SHOW TABLE STATUS LIKE 'collectionname'")
out += "- collectionname table last updated: %s" % str(res[0][11])
out += "<br>- i18nname cache timestamp: %s" % collection_i18nname_cache_timestamp
out += "<br>- i18nname cache contents:"
out += "<blockquote>"
for coll in collection_i18nname_cache.keys():
for ln in collection_i18nname_cache[coll].keys():
out += "%s, %s = %s<br>" % (coll, ln, collection_i18nname_cache[coll][ln])
out += "</blockquote>"
req.write(out)
return "\n"
def perform_request_log(req, date=""):
"""Display search log information for given date."""
req.content_type = "text/html"
req.send_http_header()
req.write("<h1>Search Log</h1>")
if date: # case A: display stats for a day
yyyymmdd = string.atoi(date)
req.write("<p><big><strong>Date: %d</strong></big><p>" % yyyymmdd)
req.write("""<table border="1">""")
req.write("<tr><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td><td><strong>%s</strong></td></tr>" % ("No.","Time", "Pattern","Field","Collection","Number of Hits"))
# read file:
p = os.popen("grep ^%d %s/search.log" % (yyyymmdd,logdir), 'r')
lines = p.readlines()
p.close()
# process lines:
i = 0
for line in lines:
try:
datetime, as, p, f, c, nbhits = string.split(line,"#")
i += 1
req.write("<tr><td align=\"right\">#%d</td><td>%s:%s:%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" \
% (i, datetime[8:10], datetime[10:12], datetime[12:], p, f, c, nbhits))
except:
pass # ignore eventual wrong log lines
req.write("</table>")
else: # case B: display summary stats per day
yyyymm01 = int(time.strftime("%Y%m01", time.localtime()))
yyyymmdd = int(time.strftime("%Y%m%d", time.localtime()))
req.write("""<table border="1">""")
req.write("<tr><td><strong>%s</strong></td><td><strong>%s</strong></tr>" % ("Day", "Number of Queries"))
for day in range(yyyymm01,yyyymmdd+1):
p = os.popen("grep -c ^%d %s/search.log" % (day,logdir), 'r')
for line in p.readlines():
req.write("""<tr><td>%s</td><td align="right"><a href="%s/search.py/log?date=%d">%s</a></td></tr>""" % (day, weburl,day,line))
p.close()
req.write("</table>")
return "\n"
def profile(p="", f="", c=cdsname):
"""Profile search time."""
import profile
import pstats
profile.run("perform_request_search(p='%s',f='%s', c='%s')" % (p, f, c), "perform_request_search_profile")
p = pstats.Stats("perform_request_search_profile")
p.strip_dirs().sort_stats("cumulative").print_stats()
return 0
## test cases:
#print wash_colls(cdsname,"Library Catalogue", 0)
#print wash_colls("Periodicals & Progress Reports",["Periodicals","Progress Reports"], 0)
#print wash_field("wau")
#print print_record(20,"tm","001,245")
#print create_opft_search_units(None, "PHE-87-13","reportnumber")
#print ":"+wash_pattern("* and % doo * %")+":\n"
#print ":"+wash_pattern("*")+":\n"
#print ":"+wash_pattern("ellis* ell* e*%")+":\n"
#print run_sql("SELECT name,dbquery from collection")
#print get_index_id("author")
#print get_coll_ancestors("Theses")
#print get_coll_sons("Articles & Preprints")
#print get_coll_real_descendants("Articles & Preprints")
#print get_collection_reclist("Theses")
#print log(sys.stdin)
#print search_unit_in_bibrec('2002-12-01','2002-12-12')
#print wash_dates('1980', '', '28', '2003','02','')
#print type(wash_url_argument("-1",'int'))
#print get_nearest_terms_in_bibxxx("ellis", "author", 5, 5)
#print call_bibformat(68, "HB_FLY")
#print create_collection_i18nname_cache()
#print get_fieldvalues_alephseq_like(11,"980__a")
## profiling:
#profile("of the this")
#print perform_request_search(p="ellis")
diff --git a/modules/websearch/lib/search_engine_config.py b/modules/websearch/lib/search_engine_config.py
index 16c0d8e19..b946e3479 100644
--- a/modules/websearch/lib/search_engine_config.py
+++ b/modules/websearch/lib/search_engine_config.py
@@ -1,40 +1,40 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Search Engine config parameters."""
## import config variables defined from config.wml:
from cdsware.config import cfg_max_recID, \
cfg_instant_browse, \
cfg_author_et_al_threshold, \
cfg_search_cache_size, \
cfg_nb_records_to_sort, \
cfg_call_bibformat, \
cfg_use_aleph_sysnos, \
cfg_fields_convert, \
cfg_simplesearch_pattern_box_width, \
cfg_advancedsearch_pattern_box_width, \
cfg_narrow_search_show_grandsons, \
cfg_oaiidtag, \
cfg_create_similarly_named_authors_link_box, \
cfg_google_box, \
cfg_google_box_servers
## do we want experimental features? (0=no, 1=yes)
cfg_experimental_features = 0
diff --git a/modules/websearch/lib/search_engine_tests.py b/modules/websearch/lib/search_engine_tests.py
index cb5939355..17c132774 100644
--- a/modules/websearch/lib/search_engine_tests.py
+++ b/modules/websearch/lib/search_engine_tests.py
@@ -1,185 +1,185 @@
# -*- coding: utf-8 -*-
## $Id$
## CDSware Search Engine unit tests.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""Unit tests for the search engine."""
__version__ = "$Id$"
import unittest
from cdsware import search_engine
class TestWashQueryParameters(unittest.TestCase):
"""Test for washing of search query parameters."""
def test_wash_url_argument(self):
"""search engine - washing of URL arguments"""
self.assertEqual(1, search_engine.wash_url_argument(['1'],'int'))
self.assertEqual("1", search_engine.wash_url_argument(['1'],'str'))
self.assertEqual(['1'], search_engine.wash_url_argument(['1'],'list'))
self.assertEqual(0, search_engine.wash_url_argument('ellis','int'))
self.assertEqual("ellis", search_engine.wash_url_argument('ellis','str'))
self.assertEqual(["ellis"], search_engine.wash_url_argument('ellis','list'))
self.assertEqual(0, search_engine.wash_url_argument(['ellis'],'int'))
self.assertEqual("ellis", search_engine.wash_url_argument(['ellis'],'str'))
self.assertEqual(["ellis"], search_engine.wash_url_argument(['ellis'],'list'))
def test_wash_pattern(self):
"""search engine - washing of query patterns"""
self.assertEqual("Ellis, J", search_engine.wash_pattern('Ellis, J'))
self.assertEqual("ell", search_engine.wash_pattern('ell*'))
class TestStripAccents(unittest.TestCase):
"""Test for handling of UTF-8 accents."""
def test_strip_accents(self):
"""search engine - stripping of accented letters"""
self.assertEqual("memememe", search_engine.strip_accents('mémêmëmè'))
self.assertEqual("MEMEMEME", search_engine.strip_accents('MÉMÊMËMÈ'))
class TestQueryParser(unittest.TestCase):
"""Test of search pattern (or query) parser."""
def _check(self, p, f, m, result_wanted):
"Internal checking function calling create_basic_search_units."
result_obtained = search_engine.create_basic_search_units(None, p, f, m)
assert result_obtained == result_wanted, \
'obtained %s instead of %s' % (repr(result_obtained), repr(result_wanted))
return
def test_parsing_single_word_query(self):
"search engine - parsing single word queries"
self._check('word', '', None, [['+', 'word', '', 'w']])
def test_parsing_single_word_with_boolean_operators(self):
"search engine - parsing single word queries"
self._check('+word', '', None, [['+', 'word', '', 'w']])
self._check('-word', '', None, [['-', 'word', '', 'w']])
self._check('|word', '', None, [['|', 'word', '', 'w']])
def test_parsing_single_word_in_field(self):
"search engine - parsing single word queries in a logical field"
self._check('word', 'title', None, [['+', 'word', 'title', 'w']])
def test_parsing_single_word_in_tag(self):
"search engine - parsing single word queries in a physical tag"
self._check('word', '500', None, [['+', 'word', '500', 'a']])
def test_parsing_query_with_commas(self):
"search engine - parsing queries with commas"
self._check('word,word', 'title', None, [['+', 'word,word', 'title', 'a']])
def test_parsing_exact_phrase_query(self):
"search engine - parsing exact phrase"
self._check('"the word"', 'title', None, [['+', 'the word', 'title', 'a']])
def test_parsing_exact_phrase_query_unbalanced(self):
"search engine - parsing unbalanced exact phrase"
self._check('"the word', 'title', None, [['+', '"the', 'title', 'w'],
['+', 'word', 'title', 'w']])
def test_parsing_exact_phrase_query_in_any_field(self):
"search engine - parsing exact phrase in any field"
self._check('"the word"', '', None, [['+', 'the word', 'anyfield', 'a']])
def test_parsing_partial_phrase_query(self):
"search engine - parsing partial phrase"
self._check("'the word'", 'title', None, [['+', '%the word%', 'title', 'a']])
def test_parsing_partial_phrase_query_unbalanced(self):
"search engine - parsing unbalanced partial phrase"
self._check("'the word", 'title', None, [['+', "'the", 'title', 'w'],
['+', "word", 'title', 'w']])
def test_parsing_partial_phrase_query_in_any_field(self):
"search engine - parsing partial phrase in any field"
self._check("'the word'", '', None, [['+', "'the", '', 'w'],
['+', "word'", '', 'w']])
def test_parsing_regexp_query(self):
"search engine - parsing regex matches"
self._check("/the word/", 'title', None, [['+', 'the word', 'title', 'r']])
def test_parsing_regexp_query_unbalanced(self):
"search engine - parsing unbalanced regexp"
self._check("/the word", 'title', None, [['+', '/the', 'title', 'w'],
['+', 'word', 'title', 'w']])
def test_parsing_regexp_query_in_any_field(self):
"search engine - parsing regexp searches in any field"
self._check("/the word/", '', None, [['+', "/the", '', 'w'],
['+', "word/", '', 'w']])
def test_parsing_boolean_query(self):
"search engine - parsing boolean query with several words"
self._check("muon kaon ellis cern", '', None, [['+', 'muon', '', 'w'],
['+', 'kaon', '', 'w'],
['+', 'ellis', '', 'w'],
['+', 'cern', '', 'w']])
def test_parsing_boolean_query_with_word_operators(self):
"search engine - parsing boolean query with word operators"
self._check("muon and kaon or ellis not cern", '', None, [['+', 'muon', '', 'w'],
['+', 'kaon', '', 'w'],
['|', 'ellis', '', 'w'],
['-', 'cern', '', 'w']])
def test_parsing_boolean_query_with_symbol_operators(self):
"search engine - parsing boolean query with symbol operators"
self._check("muon +kaon |ellis -cern", '', None, [['+', 'muon', '', 'w'],
['+', 'kaon', '', 'w'],
['|', 'ellis', '', 'w'],
['-', 'cern', '', 'w']])
def test_parsing_boolean_query_with_symbol_operators_and_spaces(self):
"search engine - parsing boolean query with symbol operators and spaces"
self._check("muon + kaon | ellis - cern", '', None, [['+', 'muon', '', 'w'],
['+', 'kaon', '', 'w'],
['|', 'ellis', '', 'w'],
['-', 'cern', '', 'w']])
def test_parsing_boolean_query_with_symbol_operators_and_no_spaces(self):
"search engine - parsing boolean query with symbol operators and no spaces"
self._check("muon+kaon|ellis-cern", '', None, [['+', 'muon+kaon|ellis-cern', '', 'w']])
def test_parsing_combined_structured_query(self):
"search engine - parsing combined structured query"
self._check("title:muon author:ellis", '', None, [['+', 'muon', 'title', 'w'],
['+', 'ellis', 'author', 'w']])
def test_parsing_structured_regexp_query(self):
"search engine - parsing structured regexp query"
self._check("title:/(one|two)/", '', None, [['+', '(one|two)', 'title', 'r']]),
def test_parsing_combined_structured_query_in_a_field(self):
"search engine - parsing structured query in a field"
self._check("title:muon author:ellis", 'abstract', None, [['+', 'muon', 'title', 'w'],
['+', 'ellis', 'author', 'w']])
def create_test_suite():
"""Return test suite for the search engine."""
return unittest.TestSuite((unittest.makeSuite(TestWashQueryParameters,'test'),
unittest.makeSuite(TestStripAccents,'test'),
unittest.makeSuite(TestQueryParser,'test')))
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(create_test_suite())
diff --git a/modules/websearch/lib/websearch_templates.py b/modules/websearch/lib/websearch_templates.py
index 0d48a468e..b6a60d4dc 100644
--- a/modules/websearch/lib/websearch_templates.py
+++ b/modules/websearch/lib/websearch_templates.py
@@ -1,2367 +1,2367 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import urllib
import time
import cgi
import gettext
import string
import locale
import sre
from cdsware.config import *
from cdsware.dbquery import run_sql
from cdsware.messages import gettext_set_language
from cdsware.search_engine_config import *
def get_fieldvalues(recID, tag):
"""Return list of field values for field TAG inside record RECID.
FIXME: should be imported commonly for search_engine too."""
out = []
if tag == "001___":
# we have asked for recID that is not stored in bibXXx tables
out.append(str(recID))
else:
# we are going to look inside bibXXx tables
digit = tag[0:2]
bx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag LIKE '%s'" \
"ORDER BY bibx.field_number, bx.tag ASC" % (bx, bibx, recID, tag)
res = run_sql(query)
for row in res:
out.append(row[0])
return out
class Template:
# This dictionary maps CDSware language code to locale codes (ISO 639)
tmpl_localemap = {
'ca': 'ca_ES',
'de': 'de_DE',
'el': 'el_GR',
'en': 'en_US',
'es': 'es_ES',
'pt': 'pt_BR',
'fr': 'fr_FR',
'it': 'it_IT',
'ru': 'ru_RU',
'sk': 'sk_SK',
'cs': 'cs_CZ',
'no': 'no_NO',
'sv': 'sv_SE',
'uk': 'uk_UA',
'ja': 'ja_JA',
'pl': 'pl_PL'
}
tmpl_default_locale = "en_US" # which locale to use by default, useful in case of failure
def tmpl_navtrail_links(self, as, ln, weburl, separator, dads):
"""
Creates the navigation bar at top of each search page (*Home > Root collection > subcollection > ...*)
Parameters:
- 'as' *bool* - Should we display an advanced search box?
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'separator' *string* - The separator between two consecutive collections
- 'dads' *list* - A list of parent links, eachone being a dictionary of ('name', 'longname')
"""
out = ""
for url, name in dads:
if out:
out += separator
out += '''<a class="navtrail" href="%(weburl)s/?c=%(qname)s&amp;as=%(as)d&amp;ln=%(ln)s">%(longname)s</a>''' % {
'weburl' : weburl,
'qname' : urllib.quote_plus (url),
'as' : as,
'ln' : ln,
'longname' : name }
return out
def tmpl_webcoll_body(self, weburl, te_portalbox, searchfor, np_portalbox, narrowsearch, focuson, ne_portalbox):
"""
Creates the body of the main search page.
Parameters:
- 'weburl' *string* - The base URL for the site
- 'te_portalbox' *string* - The HTML code for the portalbox on top of search
- 'searchfor' *string* - The HTML code for the search options
- 'np_portalbox' *string* - The HTML code for the portalbox on bottom of search
- 'searchfor' *string* - The HTML code for the search categories (left bottom of page)
- 'focuson' *string* - The HTML code for the "focuson" categories (right bottom of page)
- 'ne_portalbox' *string* - The HTML code for the bottom of the page
"""
body = """
<form action="%(weburl)s/search.py" method="get">
%(searchfor)s
%(np_portalbox)s
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td valign="top">%(narrowsearch)s</td>
""" % {
'weburl' : weburl,
'searchfor' : searchfor,
'np_portalbox' : np_portalbox,
'narrowsearch' : narrowsearch
}
if focuson:
body += """<td valign="top">""" + focuson + """</td>"""
body += """</tr></table>
%(ne_portalbox)s
</form>""" % {'ne_portalbox' : ne_portalbox}
return body
def tmpl_portalbox(self, title, body):
"""Creates portalboxes based on the parameters
Parameters:
- 'title' *string* - The title of the box
- 'body' *string* - The HTML code for the body of the box
"""
out = """<div class="portalbox">
<div class="portalboxheader">%(title)s</div>
<div class="portalboxbody">%(body)s</div>
</div>""" % {'title' : title, 'body' : body}
return out
def tmpl_searchfor_simple(self, ln,weburl,asearchurl, header, middle_option):
"""Produces simple *Search for* box for the current collection.
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'asearchurl' *string* - The URL to advanced search form
- 'header' *string* - header of search form
- 'middle_option' *string* - HTML code for the options (any field, specific fields ...)
"""
# load the right message language
_ = gettext_set_language(ln)
# print commentary start:
out = """<!--create_searchfor_simple()-->
<input type="hidden" name="sc" value="1">
<input type="hidden" name="ln" value="%(ln)s">
<table class="searchbox">
<thead>
<tr align="left">
<th colspan="3" class="searchboxheader">%(header)s</th>
</tr>
</thead>
<tbody>
<tr valign="baseline">
<td class="searchboxbody" align="left"><input type="text" name="p" size="40" value=""></td>
<td class="searchboxbody" align="left">%(middle_option)s</td>
<td class="searchboxbody" align="left"><input class="formbutton" type="submit" name="action" value="%(msg_search)s"><input class="formbutton" type="submit" name="action" value="%(msg_browse)s"></td>
</tr>
<tr valign="baseline">
<td class="searchboxbody" colspan="3" align="right"
<small><a href="%(weburl)s/help/search/tips.%(ln)s.html">%(msg_search_tips)s</a> :: <a href="%(asearchurl)s">%(msg_advanced_search)s</a></small>
</td>
</tr>
</tbody>
</table>
<!--/create_searchfor_simple()-->
""" % {
'ln' : ln,
'weburl' : weburl,
'asearchurl' : asearchurl,
'header' : header,
'middle_option' : middle_option,
'msg_search' : _('Search'),
'msg_browse' : _('Browse'),
'msg_search_tips' : _('Search Tips'),
'msg_advanced_search' : _('Advanced Search'),
}
return out
def tmpl_searchfor_advanced(self,
ln, # current language
weburl, # base url
ssearchurl, # url to simple search form
header, # header of search form
middle_option_1, middle_option_2, middle_option_3,
searchoptions,
sortoptions,
rankoptions,
displayoptions,
formatoptions
):
"""
Produces advanced *Search for* box for the current collection.
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'ssearchurl' *string* - The URL to simple search form
- 'header' *string* - header of search form
- 'middle_option_1' *string* - HTML code for the first row of options (any field, specific fields ...)
- 'middle_option_2' *string* - HTML code for the second row of options (any field, specific fields ...)
- 'middle_option_3' *string* - HTML code for the third row of options (any field, specific fields ...)
- 'searchoptions' *string* - HTML code for the search options
- 'sortoptions' *string* - HTML code for the sort options
- 'rankoptions' *string* - HTML code for the rank options
- 'displayoptions' *string* - HTML code for the display options
- 'formatoptions' *string* - HTML code for the format options
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<!--create_searchfor_advanced()-->
<input type="hidden" name="as" value="1">
<input type="hidden" name="ln" value="%(ln)s">
<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader" colspan="3">%(header)s</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td class="searchboxbody" nowrap>%(matchbox_m1)s<input type="text" name="p1" size="40" value=""></td>
<td class="searchboxbody">%(middle_option_1)s</td>
<td class="searchboxbody">%(andornot_op1)s</td>
</tr>
<tr valign="bottom">
<td class="searchboxbody" nowrap>%(matchbox_m2)s<input type="text" name="p2" size="40" value=""></td>
<td class="searchboxbody">%(middle_option_2)s</td>
<td class="searchboxbody">%(andornot_op2)s</td>
</tr>
<tr valign="bottom">
<td class="searchboxbody" nowrap>%(matchbox_m3)s<input type="text" name="p3" size="40" value=""></td>
<td class="searchboxbody">%(middle_option_3)s</td>
<td class="searchboxbody" nowrap><input class="formbutton" type="submit" name="action" value="%(msg_search)s"><input class="formbutton" type="submit" name="action" value="%(msg_browse)s"></td>
</tr>
<tr valign="bottom">
<td colspan="3" class="searchboxbody" align="right">
<small><a href="%(weburl)s/help/search/tips.%(ln)s.html">%(msg_search_tips)s</a> :: <a href="%(ssearchurl)s">%(msg_simple_search)s</a></small>
</td>
</tr>
</tbody>
</table>
<!-- @todo - more imports -->
""" % {
'ln' : ln,
'weburl' : weburl,
'ssearchurl' : ssearchurl,
'header' : header,
'matchbox_m1' : self.tmpl_matchtype_box('m1', ln=ln),
'middle_option_1' : middle_option_1,
'andornot_op1' : self.tmpl_andornot_box('op1', ln=ln),
'matchbox_m2' : self.tmpl_matchtype_box('m2', ln=ln),
'middle_option_2' : middle_option_2,
'andornot_op2' : self.tmpl_andornot_box('op2', ln=ln),
'matchbox_m3' : self.tmpl_matchtype_box('m3', ln=ln),
'middle_option_3' : middle_option_3,
'msg_search' : _("Search"),
'msg_browse' : _("Browse"),
'msg_search_tips' : _("Search Tips"),
'msg_simple_search' : _("Simple Search")
}
if (searchoptions):
out += """<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader">
%(searchheader)s
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td class="searchboxbody">%(searchoptions)s</td>
</tr>
<tbody>
</table>""" % {
'searchheader' : _("Search options:"),
'searchoptions' : searchoptions
}
out += """<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader">
%(added)s
</th>
<th class="searchboxheader">
%(until)s
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td class="searchboxbody">%(date_added)s</td>
<td class="searchboxbody">%(date_until)s</td>
</tr>
</tbody>
</table>
<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader">
%(msg_sort)s
</th>
<th class="searchboxheader">
%(msg_display)s
</th>
<th class="searchboxheader">
%(msg_format)s
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td class="searchboxbody">%(sortoptions)s %(rankoptions)s</td>
<td class="searchboxbody">%(displayoptions)s</td>
<td class="searchboxbody">%(formatoptions)s</td>
</tr>
</tbody>
</table>
<!--/create_searchfor_advanced()-->
""" % {
'added' : _("Added since:"),
'until' : _("until:"),
'date_added' : self.tmpl_inputdate("d1", ln=ln),
'date_until' : self.tmpl_inputdate("d2", ln=ln),
'msg_sort' : _("Sort by:"),
'msg_display' : _("Display results:"),
'msg_format' : _("Output format:"),
'sortoptions' : sortoptions,
'rankoptions' : rankoptions,
'displayoptions' : displayoptions,
'formatoptions' : formatoptions
}
return out
def tmpl_matchtype_box(self, name='m', value='', ln='en'):
"""Returns HTML code for the 'match type' selection box.
Parameters:
- 'name' *string* - The name of the produced select
- 'value' *string* - The selected value (if any value is already selected)
- 'ln' *string* - the language to display
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<select name="%(name)s">
<option value="a"%(sela)s>%(opta)s
<option value="o"%(selo)s>%(opto)s
<option value="e"%(sele)s>%(opte)s
<option value="p"%(selp)s>%(optp)s
<option value="r"%(selr)s>%(optr)s
</select>
""" % {'name' : name,
'sela' : self.tmpl_is_selected('a', value),
'opta' : _("All of the words:"),
'selo' : self.tmpl_is_selected('o', value),
'opto' : _("Any of the words:"),
'sele' : self.tmpl_is_selected('e', value),
'opte' : _("Exact phrase:"),
'selp' : self.tmpl_is_selected('p', value),
'optp' : _("Partial phrase:"),
'selr' : self.tmpl_is_selected('r', value),
'optr' : _("Regular expression:")
}
return out
def tmpl_is_selected(self, var, fld):
"""
Checks if *var* and *fld* are equal, and if yes, returns ' selected'. Useful for select boxes.
Parameters:
- 'var' *string* - First value to compare
- 'fld' *string* - Second value to compare
"""
if var == fld:
return " selected"
else:
return ""
def tmpl_andornot_box(self, name='op', value='', ln='en'):
"""
Returns HTML code for the AND/OR/NOT selection box.
Parameters:
- 'name' *string* - The name of the produced select
- 'value' *string* - The selected value (if any value is already selected)
- 'ln' *string* - the language to display
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<select name="%(name)s">
<option value="a"%(sela)s>%(opta)s
<option value="o"%(selo)s>%(opto)s
<option value="n"%(seln)s>%(optn)s
</select>
""" % {'name' : name,
'sela' : self.tmpl_is_selected('a', value), 'opta' : _("AND"),
'selo' : self.tmpl_is_selected('o', value), 'opto' : _("OR"),
'seln' : self.tmpl_is_selected('n', value), 'optn' : _("AND NOT")
}
return out
def tmpl_inputdate(self, name, ln, sy = 0, sm = 0, sd = 0):
"""
Produces *From Date*, *Until Date* kind of selection box. Suitable for search options.
Parameters:
- 'name' *string* - The base name of the produced selects
- 'ln' *string* - the language to display
"""
# load the right message language
_ = gettext_set_language(ln)
box = """
<select name="%(name)sd">
<option value=""%(sel)s>%(any)s
""" % {
'name' : name,
'any' : _("any day"),
'sel' : self.tmpl_is_selected(sd, 0)
}
for day in range(1,32):
box += """<option value="%02d"%s>%02d""" % (day, self.tmpl_is_selected(sd, day), day)
box += """</select>"""
# month
box += """
<select name="%(name)sm">
<option value=""%(sel)s>%(any)s
""" % {
'name' : name,
'any' : _("any month"),
'sel' : self.tmpl_is_selected(sm, 0)
}
for mm, month in [(1,_("January")), (2,_("February")), (3,_("March")), (4,_("April")), \
(5,_("May")), (6,_("June")), (7,_("July")), (8,_("August")), \
(9,_("September")), (10,_("October")), (11,_("November")), (12,_("December"))]:
box += """<option value="%02d"%s>%s""" % (mm, self.tmpl_is_selected(sm, mm), month)
box += """</select>"""
# year
box += """
<select name="%(name)sy">
<option value=""%(sel)s>%(any)s
""" % {
'name' : name,
'any' : _("any year"),
'sel' : self.tmpl_is_selected(sy, 0)
}
this_year = int(time.strftime("%Y", time.localtime()))
for year in range(this_year-20, this_year+1):
box += """<option value="%d"%s>%d""" % (year, self.tmpl_is_selected(sy, year), year)
box += """</select>"""
return box
def tmpl_narrowsearch(self, as, ln, weburl, title, type, father, has_grandchildren, instant_browse, sons, display_grandsons, grandsons):
"""
Creates list of collection descendants of type *type* under title *title*.
If as==1, then links to Advanced Search interfaces; otherwise Simple Search.
Suitable for 'Narrow search' and 'Focus on' boxes.
Parameters:
- 'as' *bool* - Should we display an advanced search box?
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'title' *string* - The title of the produced box
- 'type' *string* - The type of the produced box (virtual collections or normal collections)
- 'father' *collection* - The current collection
- 'has_grandchildren' *bool* - If the current collection has grand children
- 'sons' *list* - The list of the sub-collections (first level)
- 'display_grandsons' *bool* - If the grand children collections should be displayed (2 level deep display)
- 'grandsons' *list* - The list of sub-collections (second level)
"""
# load the right message language
_ = gettext_set_language(ln)
if has_grandchildren:
style_prolog = "<strong>"
style_epilog = "</strong>"
else:
style_prolog = ""
style_epilog = ""
out = ''
if type == 'r':
out += """<input type="hidden" name="cc" value="%(name)s">""" % {
'name' : cgi.escape(father.name, 1),
}
if len(sons):
out += """<table class="narrowsearchbox">
<thead>
<tr>
<th colspan="2" align="left" class="narrowsearchboxheader">
%(title)s
</th>
</tr>
</thead>
<tbody>""" % {'title' : title}
# iterate through sons:
i = 0
for son in sons:
out += """<tr><td class="narrowsearchboxbody" valign="top">"""
if type=='r':
if son.restricted_p() and son.restricted_p() != father.restricted_p():
out += """<input type=checkbox name="c" value="%(name)s">&nbsp;</td>""" % {'name' : son.name }
else:
out += """<input type=checkbox name="c" value="%(name)s" checked>&nbsp;</td>""" % {'name' : son.name }
out += """<td valign="top"><a href="%(url)s/?c=%(name)s&amp;as=%(as)d&amp;ln=%(ln)s">%(prolog)s%(longname)s%(epilog)s</a>%(recs)s """ % {
'url' : weburl,
'name' : urllib.quote_plus(son.name),
'as' : as,
'ln' : ln,
'prolog' : style_prolog,
'longname' : son.get_name(ln),
'epilog' : style_epilog,
'recs' : son.create_nbrecs_info(ln)
}
if son.restricted_p():
out += """ <small class="warning">[%(msg)s]</small>""" % { 'msg' : _("restricted") }
if display_grandsons and len(grandsons[i]):
# iterate trough grandsons:
out += """<br>"""
for grandson in grandsons[i]:
out += """
<a href="%(weburl)s/?c=%(name)s&amp;as=%(as)d&amp;ln=%(ln)s">%(longname)s</a>%(nbrec)s
""" % {
'weburl' : weburl,
'name' : urllib.quote_plus(grandson.name),
'as' : as,
'ln' : ln,
'longname' : grandson.get_name(ln),
'nbrec' : grandson.create_nbrecs_info(ln)
}
out += """</td></tr>"""
i += 1
out += "</tbody></table>"
else:
if type == 'r':
# no sons, and type 'r', so print info on collection content:
out += """<table class="narrowsearchbox">
<thead>
<tr>
<th class="narrowsearchboxheader">
%(header)s
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="narrowsearchboxbody">%(body)s</td>
</tr>
<tbody>
</table>""" % {
'header' : _("Latest additions:"),
'body' : instant_browse
}
return out
def tmpl_nbrecs_info(self, number, prolog = None, epilog = None):
"""
Return information on the number of records.
Parameters:
- 'number' *string* - The number of records
- 'prolog' *string* (optional) - An HTML code to prefix the number (if **None**, will be
'<small class="nbdoccoll">(')
- 'epilog' *string* (optional) - An HTML code to append to the number (if **None**, will be
')</small>')
"""
if number is None: return ''
if prolog == None: prolog = """&nbsp;<small class="nbdoccoll">("""
if epilog == None: epilog = """)</small>"""
return prolog + number + epilog
def tmpl_box_restricted_content(self, ln):
"""
Displays a box containing a *restricted content* message
Parameters:
- 'ln' *string* - The language to display
"""
# load the right message language
_ = gettext_set_language(ln)
return _("The contents of this collection is restricted.")
def tmpl_box_no_records(self, ln):
"""
Displays a box containing a *no content* message
Parameters:
- 'ln' *string* - The language to display
"""
# load the right message language
_ = gettext_set_language(ln)
return _("This collection does not contain any document yet.")
def tmpl_instant_browse(self, ln, recids, more_link = None):
"""
Formats a list of records (given in the recids list) from the database.
Parameters:
- 'ln' *string* - The language to display
- 'recids' *list* - the list of records from the database
- 'more_link' *string* - the "More..." link for the record. If not given, will not be displayed
"""
# load the right message language
_ = gettext_set_language(ln)
if not len(recids): return ""
out = """<table class="latestadditionsbox">"""
for recid in recids:
out += """<tr>
<td class="latestadditionsboxtimebody">%(date)s</td>
<td class="latestadditionsboxrecordbody">%(body)s</td>
</tr>""" % {
'date': recid['date'],
'body': recid['body']
}
out += "</table>"
if more_link:
out += """<div align="right"><small><a href="%(url)s&amp;ln=%(ln)s">[&gt;&gt; %(text)s]</a></small></div>""" % {
'url' : more_link,
'ln' : ln,
'text' : _("more")}
return out
def tmpl_searchwithin_select(self, ln, fieldname, selected, values):
"""
Produces 'search within' selection box for the current collection.
Parameters:
- 'ln' *string* - The language to display
- 'fieldname' *string* - the name of the select box produced
- 'selected' *string* - which of the values is selected
- 'values' *list* - the list of values in the select
"""
out = """<select name="%(fieldname)s">""" % {
'fieldname' : fieldname,
}
if values:
for pair in values:
out += """<option value="%(value)s"%(selected)s>%(text)s""" % {
'value' : pair['value'],
'selected' : self.tmpl_is_selected(pair['value'], selected),
'text' : pair['text']
}
out += """</select>"""
return out
def tmpl_select(self, fieldname, values, selected = None, css_class = ''):
"""
Produces a generic select box
Parameters:
- 'css_class' *string* - optional, a css class to display this select with
- 'fieldname' *list* - the name of the select box produced
- 'selected' *string* - which of the values is selected
- 'values' *list* - the list of values in the select
"""
if css_class != '':
class_field = ' class="%s"' % css_class
else:
class_field = ''
out = """<select name="%(fieldname)s"%(class)s>""" % {
'fieldname' : fieldname,
'class' : class_field
}
for pair in values:
out += """<option value="%(value)s"%(selected)s>%(text)s""" % {
'value' : pair['value'],
'selected' : self.tmpl_is_selected(pair['value'], selected) or
(pair.has_key('selected') and self.tmpl_is_selected(pair['selected'], True)),
'text' : pair['text']
}
out += """</select>"""
return out
def tmpl_record_links(self, weburl, recid, ln):
"""
Displays the *More info* and *Find similar* links for a record
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'recid' *string* - the id of the displayed record
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<br><span class="moreinfo"><a class="moreinfo" href="%(weburl)s/search.py?recid=%(recid)s&amp;ln=%(ln)s">%(msgdetail)s</a>
- <a class="moreinfo" href="%(weburl)s/search.py?p=recid:%(recid)d&amp;rm=wrd&amp;ln=%(ln)s">%(msgsimilar)s</a></span>
""" % {
'weburl' : weburl,
'recid' : recid,
'ln' : ln,
'msgdetail' : _("Detailed record"),
'msgsimilar' : _("Similar records")
}
if cfg_experimental_features:
out += """<span class="moreinfo"> - <a class="moreinfo" href="%s/search.py?p=recid:%d&amp;rm=cit&amp;ln=%s">%s</a></span>\n""" % (
weburl, recid, ln, _("Cited by"))
return out
def tmpl_record_body(self, weburl, titles, authors, dates, rns, abstracts, urls_u, urls_z):
"""
Displays the "HTML basic" format of a record
Parameters:
- 'weburl' *string* - The base URL for the site
- 'authors' *list* - the authors (as strings)
- 'dates' *list* - the dates of publication
- 'rns' *list* - the quicknotes for the record
- 'abstracts' *list* - the abstracts for the record
- 'urls_u' *list* - URLs to the original versions of the notice
- 'urls_z' *list* - Not used
"""
out = ""
for title in titles:
out += "<strong>%(title)s</strong> " % {
'title' : cgi.escape(title)
}
if authors:
out += " / "
for i in range (0,cfg_author_et_al_threshold):
if i < len(authors):
out += """<a href="%(weburl)s/search.py?p=%(name_url)s&f=author">%(name)s</a> ;""" % {
'weburl' : weburl,
'name_url' : urllib.quote(authors[i]),
'name' : cgi.escape(authors[i])
}
if len(authors) > cfg_author_et_al_threshold:
out += " <em>et al</em>"
for date in dates:
out += " %s." % cgi.escape(date)
for rn in rns:
out += """ <small class="quicknote">[%(rn)s]</small>""" % {'rn' : cgi.escape(rn)}
for abstract in abstracts:
out += "<br><small>%(abstract)s [...]</small>" % {'abstract' : cgi.escape(abstract[:1+string.find(abstract, '.')]) }
for idx in range(0,len(urls_u)):
out += """<br><small class="note"><a class="note" href="%(url)s">%(name)s</a></small>""" % {
'url' : urls_u[idx],
'name' : urls_u[idx]
}
return out
def tmpl_search_in_bibwords(self, p, f, ln, nearest_box):
"""
Displays the *Words like current ones* links for a search
Parameters:
- 'p' *string* - Current search words
- 'f' *string* - the fields in which the search was done
- 'nearest_box' *string* - the HTML code for the "nearest_terms" box - most probably from a create_nearest_terms_box call
"""
# load the right message language
_ = gettext_set_language(ln)
out = "<p>%(words)s <em>%(p)s</em> " % {
'words' : _("Words nearest to"),
'p' : p,
}
if f:
out += "%(inside)s <em>%(f)s</em> " %{
'inside' : _("inside"),
'f' : f,
}
out += _("in any collection are:") + "<br>"
out += nearest_box
return out
def tmpl_nearest_term_box(self, p, ln, f, weburl, terms, termargs, termhits, intro):
"""
Displays the *Nearest search terms* box
Parameters:
- 'p' *string* - Current search words
- 'f' *string* - a collection description (if the search has been completed in a collection)
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'terms' *array* - the broken down related terms
- 'termargs' *array* - the URL parameters to compose the search queries for the terms
- 'termhits' *array* - the number of hits in each query
- 'intro' *string* - the intro HTML to prefix the box with
"""
out = """<table class="nearesttermsbox" cellpadding="0" cellspacing="0" border="0">"""
for i in range(0, len(terms)):
if terms[i] == p: # print search word for orientation:
if termhits[i] > 0:
out += """<tr>
<td class="nearesttermsboxbodyselected" align="right">%(hits)d</td>
<td class="nearesttermsboxbodyselected" width="15">&nbsp;</td>
<td class="nearesttermsboxbodyselected" align="left">
<a class="nearesttermsselected" href="%(weburl)s/search.py?%(urlargs)s">%(term)s</a>
</td>
</tr>""" % {
'hits' : termhits[i],
'weburl' : weburl,
'urlargs' : termargs[i],
'term' : terms[i]
}
else:
out += """<tr>
<td class="nearesttermsboxbodyselected" align="right">-</td>
<td class="nearesttermsboxbodyselected" width="15">&nbsp;</td>
<td class="nearesttermsboxbodyselected" align="left">%(term)s</td>
</tr>""" % {
'term' : terms[i]
}
else:
out += """<tr>
<td class="nearesttermsboxbody" align="right">%(hits)s</td>
<td class="nearesttermsboxbody" width="15">&nbsp;</td>
<td class="nearesttermsboxbody" align="left">
<a class="nearestterms" href="%(weburl)s/search.py?%(urlargs)s">%(term)s</a>
</td>
</tr>""" % {
'hits' : termhits[i],
'weburl' : weburl,
'urlargs' : termargs[i],
'term' : terms[i]
}
out += "</table>"
return intro + "<blockquote>" + out + "</blockquote>"
def tmpl_browse_pattern(self, f, ln, weburl, browsed_phrases_in_colls, urlarg_colls):
"""
Displays the *Nearest search terms* box
Parameters:
- 'f' *string* - a field name (i18nized)
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'browsed_phrases_in_colls' *array* - the phrases to display
- 'urlargs_colls' *string* - the url parameters for the search
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<table class="searchresultsbox">
<thead>
<tr>
<th class="searchresultsboxheader" align="left">
%(hits)s
</th>
<th class="searchresultsboxheader" width="15">
&nbsp;
</th>
<th class="searchresultsboxheader" align="left">
%(f)s
</th>
</tr>
</thead>
<tbody>""" % {
'hits' : _("Hits"),
'f' : f
}
if len(browsed_phrases_in_colls) == 1:
# one hit only found:
phrase, nbhits = browsed_phrases_in_colls[0][0], browsed_phrases_in_colls[0][1]
out += """<tr>
<td class="searchresultsboxbody" align="right">
%(nbhits)s
</td>
<td class="searchresultsboxbody" width="15">
&nbsp;
</td>
<td class="searchresultsboxbody" align="left">
<a href="%(weburl)s/search.py?p=%%22%(phrase_qt)s%%22&f=%(f)s%(urlargs)s">%(phrase)s</a>
</td>
</tr>""" % {
'nbhits' : nbhits,
'weburl' : weburl,
'phrase_qt' : urllib.quote(phrase),
'phrase' : phrase,
'f' : urllib.quote(f),
'urlargs' : urlarg_colls,
}
elif len(browsed_phrases_in_colls) > 1:
# first display what was found but the last one:
for phrase, nbhits in browsed_phrases_in_colls[:-1]:
out += """<tr>
<td class="searchresultsboxbody" align="right">
%(nbhits)s
</td>
<td class="searchresultsboxbody" width="15">
&nbsp;
</td>
<td class="searchresultsboxbody" align="left">
<a href="%(weburl)s/search.py?p=%%22%(phrase_qt)s%%22&f=%(f)s%(urlargs)s">%(phrase)s</a>
</td>
</tr>""" % {
'nbhits' : nbhits,
'weburl' : weburl,
'phrase_qt' : urllib.quote(phrase),
'phrase' : phrase,
'f' : urllib.quote(f),
'urlargs' : urlarg_colls,
}
# now display last hit as "next term":
phrase, nbhits = browsed_phrases_in_colls[-1]
out += """<tr><td colspan="2" class="normal">
&nbsp;
</td>
<td class="normal">
<img src="%(weburl)s/img/sn.gif" alt="" border="0">
<a href="%(weburl)s/search.py?action=%(browse)s&p=%(phrase_qt)s&f=%(f)s%(urlargs)s">%(next)s</a>
</td>
</tr>""" % {
'weburl' : weburl,
'phrase_qt' : urllib.quote(phrase),
'browse' : _("Browse"),
'next' : _("next"),
'f' : urllib.quote(f),
'urlargs' : urlarg_colls,
}
out += """</tbody>
</table>"""
return out
def tmpl_search_box(self, ln, weburl, as, cc, cc_intl, ot, sp, action, fieldslist, f1, f2, f3, m1, m2, m3, p1, p2, p3, op1, op2, rm, p, f, coll_selects, d1y, d2y, d1m, d2m, d1d, d2d, sort_formats, sf, so, ranks, sc, rg, formats, of, pl):
"""
Displays the *Nearest search terms* box
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'as' *bool* - Should we display an advanced search box?
- 'cc_intl' *string* - the i18nized current collection name
- 'cc' *string* - the internal current collection name
- 'ot', 'sp' *string* - hidden values
- 'action' *string* - the action demanded by the user
- 'fieldlist' *list* - the list of all fields available in CDSWare, for use in select within boxes in advanced search
- 'p, f, f1, f2, f3, m1, m2, m3, p1, p2, p3, op1, op2, op3, rm' *strings* - the search parameters
- 'coll_selects' *array* - a list of lists, each containing the collections selects to display
- 'd1y, d2y, d1m, d2m, d1d, d2d' *int* - the search between dates
- 'sort_formats' *array* - the select information for the sorting format
- 'sf' *string* - the currently selected sort format
- 'so' *string* - the currently selected sort order ("a" or "d")
- 'ranks' *array* - ranking methods
- 'rm' *string* - selected ranking method
- 'sc' *string* - split by collection or not
- 'rg' *string* - selected results/page
- 'formats' *array* - available output formats
- 'of' *string* - the selected output format
- 'pl' *string* - `limit to' search pattern
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
# print search box prolog:
out += """
<h1 class="headline">%(ccname)s</h1>
<form action="%(weburl)s/search.py" method="get">
<input type="hidden" name="cc" value="%(cc)s">
<input type="hidden" name="as" value="%(as)s">
<input type="hidden" name="ln" value="%(ln)s">
""" % {
'ccname' : cc_intl,
'weburl' : weburl,
'cc' : cgi.escape(cc, 1),
'as' : as,
'ln' : ln
}
if ot: out += self.tmpl_input_hidden('ot', ot)
if sp: out += self.tmpl_input_hidden('sp', sp)
leadingtext = _("Search")
if action == _("Browse") :
leadingtext = _("Browse")
if as == 1:
# print Advanced Search form:
google = ''
if cfg_google_box and (p1 or p2 or p3):
google = """<small> :: <a href="#googlebox">%(search_smwhere)s</a></small>""" % {
'search_smwhere' : _("Try your search on...")
}
# define search box elements:
out += """
<table class="searchbox">
<thead>
<tr>
<th colspan="3" class="searchboxheader">
%(leading)s:
</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td class="searchboxbody">%(matchbox1)s
<input type="text" name="p1" size="%(sizepattern)d" value="%(p1)s">
</td>
<td class="searchboxbody">%(searchwithin1)s</td>
<td class="searchboxbody">%(andornot1)s</td>
</tr>
<tr valign="top">
<td class="searchboxbody">%(matchbox2)s
<input type="text" name="p2" size="%(sizepattern)d" value="%(p2)s">
</td>
<td class="searchboxbody">%(searchwithin2)s</td>
<td class="searchboxbody">%(andornot2)s</td>
</tr>
<tr valign="top">
<td class="searchboxbody">%(matchbox3)s
<input type="text" name="p3" size="%(sizepattern)d" value="%(p3)s">
</td>
<td class="searchboxbody">%(searchwithin3)s</td>
<td class="searchboxbody">
<input class="formbutton" type="submit" name="action" value="%(search)s"><input class="formbutton" type="submit" name="action" value="%(browse)s">&nbsp;
</td>
</tr>
<tr valign="bottom">
<td colspan="3" align="right" class="searchboxbody">
<small><a href="%(weburl)s/help/search/tips.%(ln)s.html">%(search_tips)s</a> ::
<a href="%(weburl)s/search.py?p=%(p1_qt)s&amp;f=%(f1_qt)s&amp;rm=%(rm)s&amp;cc=%(cc)s&amp;ln=%(ln)s">%(simple_search)s</a>
</small>
%(google)s
</td>
</tr>
</tbody>
</table>
""" % {
'leading' : leadingtext,
'sizepattern' : cfg_advancedsearch_pattern_box_width,
'matchbox1' : self.tmpl_matchtype_box('m1', m1, ln=ln),
'p1' : cgi.escape(p1,1),
'searchwithin1' : self.tmpl_searchwithin_select(
ln = ln,
fieldname = 'f1',
selected = f1,
values = self._add_mark_to_field(value = f1, fields = fieldslist, ln = ln)
),
'andornot1' : self.tmpl_andornot_box(
name = 'op1',
value = op1,
ln = ln
),
'matchbox2' : self.tmpl_matchtype_box('m2', m2, ln=ln),
'p2' : cgi.escape(p2,1),
'searchwithin2' : self.tmpl_searchwithin_select(
ln = ln,
fieldname = 'f2',
selected = f2,
values = self._add_mark_to_field(value = f2, fields = fieldslist, ln = ln)
),
'andornot2' : self.tmpl_andornot_box(
name = 'op2',
value = op2,
ln = ln
),
'matchbox3' : self.tmpl_matchtype_box('m3', m3, ln=ln),
'p3' : cgi.escape(p3,1),
'searchwithin3' : self.tmpl_searchwithin_select(
ln = ln,
fieldname = 'f3',
selected = f3,
values = self._add_mark_to_field(value = f3, fields = fieldslist, ln = ln)
),
'search' : _("Search"),
'browse' : _("Browse"),
'weburl' : weburl,
'ln' : ln,
'search_tips': _("Search Tips"),
'p1_qt' : urllib.quote(p1),
'f1_qt' : urllib.quote(f1),
'rm' : urllib.quote(rm),
'cc' : urllib.quote(cc),
'simple_search' : _("Simple Search"),
'google' : google,
}
else:
# print Simple Search form:
google = ''
if cfg_google_box and (p1 or p2 or p3):
google = """<small> :: <a href="#googlebox">%(search_smwhere)s</a></small>""" % {
'search_smwhere' : _("Try your search on...")
}
out += """
<table class="searchbox">
<thead>
<tr>
<th colspan="3" class="searchboxheader">
%(leading)s:
</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td class="searchboxbody"><input type="text" name="p" size="%(sizepattern)d" value="%(p)s"></td>
<td class="searchboxbody">%(searchwithin)s</td>
<td class="searchboxbody">
<input class="formbutton" type="submit" name="action" value="%(search)s">
<input class="formbutton" type="submit" name="action" value="%(browse)s">&nbsp;
</td>
</tr>
<tr valign="bottom">
<td colspan="3" align="right" class="searchboxbody">
<small><a href="%(weburl)s/help/search/tips.%(ln)s.html">%(search_tips)s</a> ::
<a href="%(weburl)s/search.py?p1=%(p_qt)s&amp;f1=%(f_qt)s&amp;rm=%(rm)s&amp;as=1&amp;cc=%(cc)s&amp;ln=%(ln)s">%(advanced_search)s</a>
</small>
%(google)s
</td>
</tr>
</tbody>
</table>
""" % {
'leading' : leadingtext,
'sizepattern' : cfg_advancedsearch_pattern_box_width,
'p' : cgi.escape(p, 1),
'searchwithin' : self.tmpl_searchwithin_select(
ln = ln,
fieldname = 'f',
selected = f,
values = self._add_mark_to_field(value = f, fields = fieldslist, ln = ln)
),
'search' : _("Search"),
'browse' : _("Browse"),
'weburl' : weburl,
'ln' : ln,
'search_tips': _("Search Tips"),
'p_qt' : urllib.quote(p),
'f_qt' : urllib.quote(f),
'rm' : urllib.quote(rm),
'cc' : urllib.quote(cc),
'advanced_search' : _("Advanced Search"),
'google' : google,
}
## secondly, print Collection(s) box:
selects = ''
for sel in coll_selects:
selects += self.tmpl_select(fieldname = 'c', values = sel)
out += """
<table class="searchbox">
<thead>
<tr>
<th colspan="3" class="searchboxheader">
%(leading)s %(msg_coll)s:
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td valign="top" class="searchboxbody">
%(colls)s
</td>
</tr>
</tbody>
</table>
""" % {
'leading' : leadingtext,
'msg_coll' : _("collections"),
'colls' : selects,
}
## thirdly, print search limits, if applicable:
if action != _("Browse") and pl:
out += """<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader">
%(limitto)s:
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td class="searchboxbody">
<input type="text" name="pl" size="%(sizepattern)d" value="%(pl)s">
</td>
</tr>
</tbody>
</table>""" % {
'limitto' : _("Limit to"),
'sizepattern' : cfg_advancedsearch_pattern_box_width,
'pl' : cgi.escape(pl, 1),
}
## fourthly, print from/until date boxen, if applicable:
if action == _("Browse") or (d1y==0 and d1m==0 and d1d==0 and d2y==0 and d2m==0 and d2d==0):
pass # do not need it
else:
cell_6_a = self.tmpl_inputdate("d1", ln, d1y, d1m, d1d)
cell_6_b = self.tmpl_inputdate("d2", ln, d2y, d2m, d2d)
out += """<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader">
%(added)s
</th>
<th class="searchboxheader">
%(until)s
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td class="searchboxbody">%(date1)s</td>
<td class="searchboxbody">%(date2)s</td>
</tr>
</tbody>
</table>""" % {
'added' : _("Added since:"),
'until' : _("until:"),
'date1' : self.tmpl_inputdate("d1", ln, d1y, d1m, d1d),
'date2' : self.tmpl_inputdate("d2", ln, d2y, d2m, d2d),
}
## fifthly, print Display results box, including sort/rank, formats, etc:
if action != _("Browse"):
rgs = []
for i in [10, 25, 50, 100, 250, 500]:
rgs.append({ 'value' : i, 'text' : "%d %s" % (i, _("results"))})
# sort by:
out += """<table class="searchbox">
<thead>
<tr>
<th class="searchboxheader">
%(sort_by)s
</th>
<th class="searchboxheader">
%(display_res)s
</th>
<th class="searchboxheader">
%(out_format)s
</th>
</tr>
</thead>
<tbody>
<tr valign="bottom">
<td valign="top" class="searchboxbody">
%(select_sf)s %(select_so)s %(select_rm)s
</td>
<td valign="top" class="searchboxbody">
%(select_rg)s %(select_sc)s
</td>
<td valign="top" class="searchboxbody">%(select_of)s</td>
</tr>
</tbody>
</table>""" % {
'sort_by' : _("Sort by:"),
'display_res' : _("Display results:"),
'out_format' : _("Output format:"),
'select_sf' : self.tmpl_select(fieldname = 'sf', values = sort_formats, selected = sf, css_class = 'address'),
'select_so' : self.tmpl_select(fieldname = 'so', values = [{
'value' : 'a',
'text' : _("asc.")
}, {
'value' : 'd',
'text' : _("desc.")
}], selected = so, css_class = 'address'),
'select_rm' : self.tmpl_select(fieldname = 'rm', values = ranks, selected = rm, css_class = 'address'),
'select_rg' : self.tmpl_select(fieldname = 'rg', values = rgs, selected = rg, css_class = 'address'),
'select_sc' : self.tmpl_select(fieldname = 'sc', values = [{
'value' : '0',
'text' : _("single list")
}, {
'value' : '1',
'text' : _("split by collection")
}], selected = so, css_class = 'address'),
'select_of' : self.tmpl_searchwithin_select(
ln = ln,
fieldname = 'of',
selected = of,
values = self._add_mark_to_field(value = of, fields = formats, chars = 3, ln = ln)
),
}
## last but not least, print end of search box:
out += """</form>"""
return out
def tmpl_input_hidden(self, name, value):
"Produces the HTML code for a hidden field "
return """<input type="hidden" name="%(name)s" value="%(value)s">""" % {
'name' : cgi.escape(str(name), 1),
'value' : cgi.escape(str(value), 1),
}
def _add_mark_to_field(self, value, fields, ln, chars = 1):
"""Adds the current value as a MARC tag in the fields array
Useful for advanced search"""
# load the right message language
_ = gettext_set_language(ln)
out = fields
if value and str(value[0:chars]).isdigit():
out.append({'value' : value,
'text' : str(value) + " " + _("MARC tag")
})
return out
def tmpl_google_box(self, ln, cc, p, f, prolog_start, prolog_end, column_separator, link_separator, epilog):
"""Creates the box that proposes links to other useful search engines like Google.
Parameters:
- 'ln' *string* - The language to display in
- 'cc' *string* - the internal current collection name
- 'p' *string* - the search query
- 'f' *string* - the current field
- 'prolog_start, prolog_end, column_separator, link_separator, epilog' *strings* - default HTML code for the specified position in the box
"""
# load the right message language
_ = gettext_set_language(ln)
out_links = []
p_quoted = urllib.quote(p)
# Amazon
if cfg_google_box_servers.get('Amazon', 0):
if string.find(cc, "Book") >= 0:
if f == "author":
out_links.append("""<a class="google" href="http://www.amazon.com/exec/obidos/external-search/?field-author=%s&tag=cern">%s %s Amazon</a>""" % (p_quoted, p, _('in')))
else:
out_links.append("""<a class="google" href="http://www.amazon.com/exec/obidos/external-search/?keyword=%s&tag=cern">%s %s Amazon</a>""" % (p_quoted, p, _('in')))
# CERN Intranet:
if cfg_google_box_servers.get('CERN Intranet', 0):
out_links.append("""<a class="google" href="http://search.cern.ch/query.html?qt=%s">%s %s CERN&nbsp;Intranet</a>""" % (urllib.quote(string.replace(p, ' ', ' +')), p, _('in')))
# CERN Agenda:
if cfg_google_box_servers.get('CERN Agenda', 0):
if f == "author":
out_links.append("""<a class="google" href="http://agenda.cern.ch/search.php?field=speaker&keywords=%s&search=Search">%s %s CERN&nbsp;Agenda</a>""" % (p_quoted, p, _('in')))
elif f == "title":
out_links.append("""<a class="google" href="http://agenda.cern.ch/search.php?field=title&keywords=%s&search=Search">%s %s CERN&nbsp;Agenda</a>""" % (p_quoted, p, _('in')))
# CERN EDMS:
if cfg_google_box_servers.get('CERN Agenda', 0):
# FIXME: reusing CERN Agenda config variable until we can enter CERN EDMS into config.wml
if f == "author":
out_links.append("""<a class="google" href="https://edms.cern.ch/cedar/plsql/fullsearch.doc_search?p_search_type=ADVANCED&p_author=%s">%s %s CERN&nbsp;EDMS</a>""" % (p_quoted, p, _("in")))
elif f == "title" or f == "abstract" or f == "keyword":
out_links.append("""<a class="google" href="https://edms.cern.ch/cedar/plsql/fullsearch.doc_search?p_search_type=ADVANCED&p_title=%s">%s %s CERN&nbsp;EDMS</a>""" % (p_quoted, p, _("in")))
elif f == "reportnumber":
out_links.append("""<a class="google" href="https://edms.cern.ch/cedar/plsql/fullsearch.doc_search?p_search_type=ADVANCED&p_document_id=%s">%s %s CERN&nbsp;EDMS</a>""" % (p_quoted, p, _("in")))
else:
out_links.append("""<a class="google" href="https://edms.cern.ch/cedar/plsql/fullsearch.doc_search?p_search_type=BASE&p_free_text=%s">%s %s CERN&nbsp;EDMS</a>""" % (p_quoted, p, _("in")))
# CiteSeer:
if cfg_google_box_servers.get('CiteSeer', 0):
out_links.append("""<a class="google" href="http://citeseer.ist.psu.edu/cs?q=%s">%s %s CiteSeer</a>""" % (p_quoted, p, _('in')))
# Google Print:
if cfg_google_box_servers.get('Google Scholar', 0):
# FIXME: reusing Google Scholar config variable until we can enter Google Print into config.wml
if string.find(cc, "Book") >= 0:
out_links.append("""<a class="google" href="http://print.google.com/print?q=%s">%s %s Google Print</a>""" % (p_quoted, p, _("in")))
# Google Scholar:
if cfg_google_box_servers.get('Google Scholar', 0):
if f == "author":
out_links.append("""<a class="google" href="http://scholar.google.com/scholar?q=author%%3A%s">%s %s Google Scholar</a>""" % (p_quoted, p, _('in')))
else:
out_links.append("""<a class="google" href="http://scholar.google.com/scholar?q=%s">%s %s Google Scholar</a>""" % (p_quoted, p, _('in')))
# Google Web:
if cfg_google_box_servers.get('Google Web', 0):
if f == "author":
p_google = p
if string.find(p, ",") >= 0 and (not p.startswith('"')) and (not p.endswith('"')):
p_lastname, p_firstnames = string.split(p, ",", 1)
p_google = '"%s %s" OR "%s %s"' % (p_lastname, p_firstnames, p_firstnames, p_lastname)
out_links.append("""<a class="google" href="http://google.com/search?q=%s">%s %s Google Web</a>""" % (urllib.quote(p_google), p_google, _('in')))
else:
out_links.append("""<a class="google" href="http://google.com/search?q=%s">%s %s Google Web</a>""" % (p_quoted, p, _('in')))
# IEC
if cfg_google_box_servers.get('IEC', 0):
if string.find(cc, "Standard") >= 0:
out_links.append("""<a class="google" href="http://www.iec.ch/cgi-bin/procgi.pl/www/iecwww.p?wwwlang=E&wwwprog=sea22.p&search=text&searchfor=%s">%s %s IEC</a>""" % (p_quoted, p, _('in')))
# IHS
if cfg_google_box_servers.get('IHS', 0):
if string.find(cc, "Standard") >= 0:
out_links.append("""<a class="google" href="http://global.ihs.com/search_res.cfm?&input_doc_title=%s">%s %s IHS</a>""" % (p_quoted, p, _('in')))
# INSPEC
if cfg_google_box_servers.get('INSPEC', 0):
if f == "author":
p_inspec = sre.sub(r'(, )| ', '-', p)
p_inspec = sre.sub(r'(-\w)\w+$', '\\1', p_inspec)
out_links.append("""<a class="google" href="http://www.datastarweb.com/cern/?dblabel=inzz&query=%s.au.">%s %s INSPEC</a>""" % (urllib.quote(p_inspec), p_inspec, _('in')))
elif f == "title":
out_links.append("""<a class="google" href="http://www.datastarweb.com/cern/?dblabel=inzz&query=%s.ti.">%s %s INSPEC</a>""" % (p_quoted, p, _('in')))
elif f == "abstract":
out_links.append("""<a class="google" href="http://www.datastarweb.com/cern/?dblabel=inzz&query=%s.ab.">%s %s INSPEC</a>""" % (p_quoted, p, _('in')))
elif f == "year":
out_links.append("""<a class="google" href="http://www.datastarweb.com/cern/?dblabel=inzz&query=%s.yr.">%s %s INSPEC</a>""" % (p_quoted, p, _('in')))
# ISO
if cfg_google_box_servers.get('ISO', 0):
if string.find(cc, "Standard") >= 0:
out_links.append("""<a class="google" href="http://www.iso.org/iso/en/StandardsQueryFormHandler.StandardsQueryFormHandler?languageCode=en&keyword=%s&lastSearch=false&title=true&isoNumber=&isoPartNumber=&isoDocType=ALL&isoDocElem=ALL&ICS=&stageCode=&stagescope=Current&repost=1&stagedatepredefined=&stageDate=&committee=ALL&subcommittee=&scopecatalogue=CATALOGUE&scopeprogramme=PROGRAMME&scopewithdrawn=WITHDRAWN&scopedeleted=DELETED&sortOrder=ISO">%s %s ISO</a>""" % (p_quoted, p, _('in')))
# KEK
if cfg_google_box_servers.get('KEK', 0):
kek_search_title = "KEK KISS Preprints"
kek_search_baseurl = "http://www-lib.kek.jp/cgi-bin/kiss_prepri?"
if string.find(cc, "Book") >= 0:
kek_search_title = "KEK Library Books"
kek_search_baseurl = "http://www-lib.kek.jp/cgi-bin/kiss_book?DSP=1&"
elif string.find(cc, "Periodical") >= 0:
kek_search_title = "KEK Library Journals"
kek_search_baseurl = "http://www-lib.kek.jp/cgi-bin/kiss_book?DSP=2&"
if f == "author":
out_links.append("""<a class="google" href="%sAU=%s">%s %s %s</a>""" % \
(kek_search_baseurl, p_quoted, p, _('in'), kek_search_title))
elif f == "title":
out_links.append("""<a class="google" href="%sTI=%s">%s %s %s</a>""" % \
(kek_search_baseurl, p_quoted, p, _('in'), kek_search_title))
elif f == "reportnumber":
out_links.append("""<a class="google" href="%sRP=%s">%s %s %s</a>""" % \
(kek_search_baseurl, p_quoted, p, _('in'), kek_search_title))
# NEBIS
if cfg_google_box_servers.get('NEBIS', 0):
if string.find(cc, "Book") >= 0:
if f == "author":
out_links.append("""<a class="google" href="http://opac.nebis.ch/F/?func=find-b&REQUEST=%s&find_code=WAU">%s %s NEBIS</a>""" % (p_quoted, p, _('in')))
elif f == "title":
out_links.append("""<a class="google" href="http://opac.nebis.ch/F/?func=find-b&REQUEST=%s&find_code=WTI">%s %s NEBIS</a>""" % (p_quoted, p, _('in')))
else:
out_links.append("""<a class="google" href="http://opac.nebis.ch/F/?func=find-b&REQUEST=%s&find_code=WRD">%s %s NEBIS</a>""" % (p_quoted, p, _('in')))
# Scirus:
if cfg_google_box_servers.get('Google Scholar', 0):
# FIXME: reusing Google Scholar config variable until we can enter Scirus into config.wml
if f == "author":
out_links.append("""<a class="google" href="http://www.scirus.com/srsapp/search?q=author%%3A%s">%s %s Scirus</a>""" % (p_quoted, p, _("in")))
elif f == "title":
out_links.append("""<a class="google" href="http://www.scirus.com/srsapp/search?q=title%%3A%s">%s %s Scirus</a>""" % (p_quoted, p, _("in")))
elif f == "keyword":
out_links.append("""<a class="google" href="http://www.scirus.com/srsapp/search?q=keywords%%3A%s">%s %s Scirus</a>""" % (p_quoted, p, _("in")))
else:
out_links.append("""<a class="google" href="http://www.scirus.com/srsapp/search?q=%s">%s %s Scirus</a>""" % (p_quoted, p, _("in")))
# SPIRES
if cfg_google_box_servers.get('SPIRES', 0):
spires_search_title = "SLAC SPIRES HEP"
spires_search_baseurl = "http://www.slac.stanford.edu/spires/find/hep/"
if string.find(cc, "Book") >= 0:
spires_search_title = "SLAC Library Books"
spires_search_baseurl = "http://www.slac.stanford.edu/spires/find/books/"
elif string.find(cc, "Periodical") >= 0:
spires_search_title = "SLAC Library Journals"
spires_search_baseurl = "http://www.slac.stanford.edu/spires/find/tserials/"
if f == "author":
out_links.append("""<a class="google" href="%swww?AUTHOR=%s">%s %s %s</a>""" % \
(spires_search_baseurl, p_quoted, p, _('in'), spires_search_title))
elif f == "title":
out_links.append("""<a class="google" href="%swww?TITLE=%s">%s %s %s</a>""" % \
(spires_search_baseurl, p_quoted, p, _('in'), spires_search_title))
elif f == "reportnumber":
out_links.append("""<a class="google" href="%swww?REPORT-NUM=%s">%s %s %s</a>""" % \
(spires_search_baseurl, p_quoted, p, _('in'), spires_search_title))
elif f == "keyword":
out_links.append("""<a class="google" href="%swww?k=%s">%s %s %s</a>""" % \
(spires_search_baseurl, p_quoted, p, _('in'), spires_search_title))
else: # invent a poor man's any field search since SPIRES doesn't support one
out_links.append("""<a class="google" href="%swww?rawcmd=find+t+%s+or+a+%s+or+k+%s+or+s+%s+or+r+%s">%s %s %s</a>""" % \
(spires_search_baseurl, p_quoted, p_quoted, p_quoted, p_quoted, p_quoted, p, _('in'), spires_search_title))
# okay, so print the box now:
out = ""
if out_links:
out += """<a name="googlebox"></a>"""
out += prolog_start + _("Haven't found what you were looking for? Try your search on other servers:") + prolog_end
nb_out_links_in_one_column = len(out_links)/2
out += string.join(out_links[:nb_out_links_in_one_column], link_separator)
out += column_separator
out += string.join(out_links[nb_out_links_in_one_column:], link_separator)
out += epilog
return out
def tmpl_search_pagestart(self, ln) :
"page start for search page. Will display after the page header"
return """<div class="pagebody"><div class="pagebodystripemiddle">"""
def tmpl_search_pageend(self, ln) :
"page end for search page. Will display just before the page footer"
return """</div></div>"""
def tmpl_print_warning(self, msg, type, prologue, epilogue):
"""Prints warning message and flushes output.
Parameters:
- 'msg' *string* - The message string
- 'type' *string* - the warning type
- 'prologue' *string* - HTML code to display before the warning
- 'epilogue' *string* - HTML code to display after the warning
"""
out = '\n%s<span class="quicknote">' % (prologue)
if type:
out += '%s: ' % type
out += '%s</span>%s' % (msg, epilogue)
return out
def tmpl_print_search_info(self, ln, weburl, middle_only, collection, collection_name, as, sf, so, rm, rg, nb_found, of, ot, p, f, f1, f2, f3, m1, m2, m3, op1, op2, p1, p2, p3, d1y, d1m, d1d, d2y, d2m, d2d, all_fieldcodes, cpu_time, pl_in_url, jrec, sc, sp):
"""Prints stripe with the information on 'collection' and 'nb_found' results and CPU time.
Also, prints navigation links (beg/next/prev/end) inside the results set.
If middle_only is set to 1, it will only print the middle box information (beg/netx/prev/end/etc) links.
This is suitable for displaying navigation links at the bottom of the search results page.
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'middle_only' *bool* - Only display parts of the interface
- 'collection' *string* - the collection name
- 'collection_name' *string* - the i18nized current collection name
- 'as' *bool* - if we display the advanced search interface
- 'sf' *string* - the currently selected sort format
- 'so' *string* - the currently selected sort order ("a" or "d")
- 'rm' *string* - selected ranking method
- 'rg' *int* - selected results/page
- 'nb_found' *int* - number of results found
- 'of' *string* - the selected output format
- 'ot' *string* - hidden values
- 'p' *string* - Current search words
- 'f' *string* - the fields in which the search was done
- 'f1, f2, f3, m1, m2, m3, p1, p2, p3, op1, op2' *strings* - the search parameters
- 'jrec' *int* - number of first record on this page
- 'd1y, d2y, d1m, d2m, d1d, d2d' *int* - the search between dates
- 'all_fieldcodes' *array* - all the available fields
- 'cpu_time' *float* - the time of the query in seconds
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
# left table cells: print collection name
if not middle_only:
out += """
<a name="%(collection_qt)s"></a>
<form action="%(weburl)s/search.py" method="get">
<table class="searchresultsbox"><tr><td class="searchresultsboxheader" align="left">
<strong><big>
<a href="%(weburl)s/?c=%(collection_qt_plus)s&amp;as=%(as)d&amp;ln=%(ln)s">%(collection_name)s</a></big></strong></td>
""" % {
'collection_qt' : urllib.quote(collection),
'collection_qt_plus' : urllib.quote_plus(collection),
'as' : as,
'ln' : ln,
'collection_name' : collection_name,
'weburl' : weburl,
}
else:
out += """
<form action="%(weburl)s/search.py" method="get"><div align="center">
""" % { 'weburl' : weburl }
# middle table cell: print beg/next/prev/end arrows:
if not middle_only:
out += """<td class="searchresultsboxheader" align="center">
%(recs_found)s &nbsp;""" % {
'recs_found' : _("<strong>%s</strong> records found") % self.tmpl_nice_number(nb_found, ln)
}
else:
out += "<small>"
if nb_found > rg:
out += "" + collection_name + " : " + _("<strong>%s</strong> records found") % self.tmpl_nice_number(nb_found, ln) + " &nbsp; "
if nb_found > rg: # navig.arrows are needed, since we have many hits
if (pl_in_url):
scbis = 1
else:
scbis = 0
url = """%(weburl)s/search.py?p=%(p_qt)s&amp;cc=%(coll_qt)s&amp;f=%(f)s&amp;sf=%(sf)s&amp;so=%(so)s&amp;sp=%(sp)s&amp;rm=%(rm)s&amp;of=%(of)s&amp;ot=%(ot)s&amp;as=%(as)s&amp;ln=%(ln)s&amp;p1=%(p1)s&amp;p2=%(p2)s&amp;p3=%(p3)s&amp;f1=%(f1)s&amp;f2=%(f2)s&amp;f3=%(f3)s&amp;m1=%(m1)s&amp;m2=%(m2)s&amp;m3=%(m3)s&amp;op1=%(op1)s&amp;op2=%(op2)s&amp;sc=%(sc)d&amp;d1y=%(d1y)d&amp;d1m=%(d1m)d&amp;d1d=%(d1d)d&amp;d2y=%(d2y)d&amp;d2m=%(d2m)d&amp;d2d=%(d2d)d""" % {
'weburl' : weburl,
'p_qt' : urllib.quote(p),
'coll_qt' : urllib.quote(collection),
'f' : f,
'sf' : sf,
'so' : so,
'sp' : sp,
'rm' : rm,
'of' : of,
'ot' : ot,
'as' : as,
'ln' : ln,
'p1' : urllib.quote(p1),
'p2' : urllib.quote(p2),
'p3' : urllib.quote(p3),
'f1' : f1,
'f2' : f2,
'f3' : f3,
'm1' : m1,
'm2' : m2,
'm3' : m3,
'op1' : op1,
'op2' : op2,
'sc' : scbis,
'd1y' : d1y,
'd1m' : d1m,
'd1d' : d1d,
'd2y' : d2y,
'd2m' : d2m,
'd2d' : d2d,
}
# @todo here
if jrec-rg > 1:
out += """<a class="img" href="%(url)s&amp;jrec=1&amp;rg=%(rg)d"><img src="%(weburl)s/img/sb.gif" alt="%(begin)s" border="0"></a>""" % {
'url' : url,
'rg' : rg,
'weburl' : weburl,
'begin' : _("begin"),
}
if jrec > 1:
out += """<a class="img" href="%(url)s&amp;jrec=%(jrec)d&amp;rg=%(rg)d"><img src="%(weburl)s/img/sp.gif" alt="%(previous)s" border="0"></a>""" % {
'url' : url,
'jrec' : max(jrec-rg, 1),
'rg' : rg,
'weburl' : weburl,
'previous' : _("previous")
}
if jrec+rg-1 < nb_found:
out += "%d - %d" % (jrec, jrec+rg-1)
else:
out += "%d - %d" % (jrec, nb_found)
if nb_found >= jrec+rg:
out += """<a class="img" href="%(url)s&amp;jrec=%(jrec)d&amp;rg=%(rg)d"><img src="%(weburl)s/img/sn.gif" alt="%(next)s" border="0"></a>""" % {
'url' : url,
'jrec' : jrec + rg,
'rg' : rg,
'weburl' : weburl,
'next' : _("next")
}
if nb_found >= jrec+rg+rg:
out += """<a class="img" href="%(url)s&amp;jrec=%(jrec)d&amp;rg=%(rg)d"><img src="%(weburl)s/img/se.gif" alt="%(end)s" border="0"></a>""" % {
'url' : url,
'jrec' : nb_found-rg+1,
'rg' : rg,
'weburl' : weburl,
'end' : _("end")
}
# still in the navigation part
cc = collection
sc = 0
for var in ['p', 'cc', 'f', 'sf', 'so', 'of', 'rg', 'as', 'ln', 'p1', 'p2', 'p3', 'f1', 'f2', 'f3', 'm1', 'm2', 'm3', 'op1', 'op2', 'sc', 'd1y', 'd1m', 'd1d', 'd2y', 'd2m', 'd2d']:
out += self.tmpl_input_hidden(name = var, value = vars()[var])
for var in ['ot', 'sp', 'rm']:
if vars()[var]:
out += self.tmpl_input_hidden(name = var, value = vars()[var])
if pl_in_url:
fieldargs = cgi.parse_qs(pl_in_url)
for fieldcode in all_fieldcodes:
# get_fieldcodes():
if fieldargs.has_key(fieldcode):
for val in fieldargs[fieldcode]:
out += self.tmpl_input_hidden(name = fieldcode, value = val)
out += """&nbsp; %(jump)s <input type="text" name="jrec" size="4" value="%(jrec)d">""" % {
'jump' : _("jump to record:"),
'jrec' : jrec,
}
if not middle_only:
out += "</td>"
else:
out += "</small>"
# right table cell: cpu time info
if not middle_only:
if cpu_time > -1:
out += """<td class="searchresultsboxheader" align="right"><small>%(time)s</small>&nbsp;</td>""" % {
'time' : _("Search took %.2f seconds.") % cpu_time,
}
out += "</tr></table>"
else:
out += "</div>"
out += "</form>"
return out
def tmpl_nice_number(self, number, ln):
"Returns nicely printed number NUM in language LN using the locale."
if number is None:
return None
# Temporarily switch the numeric locale to the requeted one, and format the number
# In case the system has no locale definition, use the vanilla form
ol = locale.getlocale(locale.LC_NUMERIC)
try:
locale.setlocale(locale.LC_NUMERIC, self.tmpl_localemap.get(ln, self.tmpl_default_locale))
except locale.Error:
return str(number)
number = locale.format('%d', number, True)
locale.setlocale(locale.LC_NUMERIC, ol)
return number
def tmpl_records_format_htmlbrief(self, ln, weburl, rows, relevances_prologue, relevances_epilogue):
"""Returns the htmlbrief format of the records
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'rows' *array* - Parts of the interface to display, in the format:
- 'rows[number]' *int* - The order number
- 'rows[recid]' *int* - The recID
- 'rows[relevance]' *string* - The relevance of the record
- 'rows[record]' *string* - The formatted record
- 'relevances_prologue' *string* - HTML code to prepend the relevance indicator
- 'relevances_epilogue' *string* - HTML code to append to the relevance indicator (used mostly for formatting)
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<form action="%(weburl)s/yourbaskets.py/add" method="post">
<table>
""" % {
'weburl' : weburl,
}
for row in rows:
out += """
<tr><td valign="top" align="right" nowrap><input name="recid" type="checkbox" value="%(recid)s">
%(number)s.
""" % row
if row['relevance']:
out += """<br><div class="rankscoreinfo"><a title="rank score">%(prologue)s%(relevance)s%(epilogue)s</a></div>""" % {
'prologue' : relevances_prologue,
'epilogue' : relevances_epilogue,
'relevance' : row['relevance']
}
out += """</td><td valign="top">%s</td></tr>""" % row['record']
out += """</table>
<br><input class="formbutton" type="submit" name="action" value="%(basket)s">
</form>""" % {
'basket' : _("ADD TO BASKET")
}
return out
def tmpl_records_format_other(self, ln, weburl, rows, format, url_args):
"""Returns other formats of the records
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'rows' *array* - Parts of the interface to display, in the format:
- 'rows[record]' *string* - The formatted record
- 'rows[number]' *int* - The order number
- 'rows[recid]' *int* - The recID
- 'rows[relevance]' *string* - The relevance of the record
- 'format' *string* - The current format
- 'url_args' *string* - The rest of the search query
"""
# load the right message language
_ = gettext_set_language(ln)
out = """ <p><div align="right"><small>%(format)s: """ % {
'format' : _("Format")
}
if format == "hm":
out += """<a href="%(weburl)s/search.py?%(url_args)s">HTML</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=hx">BibTeX</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=xd">DC</a> | MARC | <a href="%(weburl)s/search.py?%(url_args)s&of=xm">MARCXML</a>""" % vars()
elif format == "hx":
out += """<a href="%(weburl)s/search.py?%(url_args)s">HTML</a> | BibTeX | <a href="%(weburl)s/search.py?%(url_args)s&of=xd">DC</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=hm">MARC</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=xm">MARCXML</a>""" % vars()
else:
out += """HTML | <a href="%(weburl)s/search.py?%(url_args)s&of=hx">BibTeX</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=xd">DC</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=hm">MARC</a> | <a href="%(weburl)s/search.py?%(url_args)s&of=xm">MARCXML</a>""" % vars()
out += "</small></div>"
for row in rows:
out += row ['record']
if format.startswith("hd"):
# do not print further information but for HTML detailed formats
if row ['creationdate']:
out += """<div class="recordlastmodifiedbox">%(dates)s</div>
<p><span class="moreinfo"><a class="moreinfo" href="%(weburl)s/search.py?p=recid:%(recid)d&amp;rm=wrd&amp;ln=%(ln)s">%(similar)s</a></span>
<form action="%(weburl)s/yourbaskets.py/add" method="post">
<input name="recid" type="hidden" value="%(recid)s">
<br><input class="formbutton" type="submit" name="action" value="%(basket)s">
</form>
""" % {
'dates' : _("Record created %s, last modified %s") % (row['creationdate'], row['modifydate']),
'weburl' : weburl,
'recid' : row['recid'],
'ln' : ln,
'similar' : _("Similar records"),
'basket' : _("ADD TO BASKET")
}
out += '<table>'
if row.has_key ('citinglist'):
cs = row ['citinglist']
similar = self.tmpl_print_record_list_for_similarity_boxen (
_("Cited by: %s records") % len (cs), cs, ln)
out += '''
<tr><td>
%(similar)s&nbsp;<a href="%(weburl)s/search.py?p=recid:%(recid)d&amp;rm=cit&amp;ln=%(ln)s">%(more)s</a>
<br><br>
</td></tr>''' % { 'weburl': weburl, 'recid': row ['recid'], 'ln': ln,
'similar': similar, 'more': _("more"),
}
if row.has_key ('cociting'):
cs = row ['cociting']
similar = self.tmpl_print_record_list_for_similarity_boxen (
_("Co-cited with: %s records") % len (cs), cs, ln)
out += '''
<tr><td>
%(similar)s&nbsp;<a href="%(weburl)s/search.py?p=cocitedwith:%(recid)d&amp;ln=%(ln)s">%(more)s</a>
<br>
</td></tr>''' % { 'weburl': weburl, 'recid': row ['recid'], 'ln': ln,
'similar': similar, 'more': _("more"),
}
if row.has_key ('citationhistory'):
out += '<tr><td>%s</td></tr>' % row ['citationhistory']
if row.has_key ('downloadsimilarity'):
cs = row ['downloadsimilarity']
similar = self.tmpl_print_record_list_for_similarity_boxen (
_("People who downloaded this document also downloaded:"), cs, ln)
out += '''
<tr><td>%(graph)s</td></tr>
<tr><td>%(similar)s</td></tr
>''' % { 'weburl': weburl, 'recid': row ['recid'], 'ln': ln,
'similar': similar, 'more': _("more"),
'graph': row ['downloadhistory']
}
out += '</table>'
if row.has_key ('viewsimilarity'):
out += '<p>&nbsp'
out += self.tmpl_print_record_list_for_similarity_boxen (
_("People who viewed this page also viewed:"), row ['viewsimilarity'], ln)
if row.has_key ('reviews'):
out += '<p>&nbsp'
out += row['reviews']
if row.has_key ('comments'):
out += row['comments']
out += "<p>&nbsp;"
return out
def tmpl_print_results_overview(self, ln, weburl, results_final_nb_total, cpu_time, results_final_nb, colls, url_args):
"""Prints results overview box with links to particular collections below.
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'results_final_nb_total' *int* - The total number of hits for the query
- 'colls' *array* - The collections with hits, in the format:
- 'coll[code]' *string* - The code of the collection (canonical name)
- 'coll[name]' *string* - The display name of the collection
- 'results_final_nb' *array* - The number of hits, indexed by the collection codes:
- 'cpu_time' *string* - The time the query took
- 'url_args' *string* - The rest of the search query
"""
if len(colls) == 1:
# if one collection only, print nothing:
return ""
# load the right message language
_ = gettext_set_language(ln)
# first find total number of hits:
out = """<p><table class="searchresultsbox">
<thead><tr><th class="searchresultsboxheader">%(founds)s</th></tr></thead>
<tbody><tr><td class="searchresultsboxbody"> """ % {
'founds' : _("<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f seconds.") % (self.tmpl_nice_number(results_final_nb_total, ln), cpu_time)
}
# then print hits per collection:
for coll in colls:
if results_final_nb.has_key(coll['code']) and results_final_nb[coll['code']] > 0:
out += """<strong><a href="#%(coll)s">%(coll_name)s</a></strong>,
<a href="#%(coll)s">%(number)s</a><br>""" % {
'coll' : urllib.quote(coll['code']),
'coll_name' : coll['name'],
'number' : _("<strong>%s</strong> records found") % self.tmpl_nice_number(results_final_nb[coll['code']], ln)
}
out += "</td></tr></tbody></table>"
return out
def tmpl_search_no_boolean_hits(self, ln, weburl, nearestterms):
"""No hits found, proposes alternative boolean queries
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'nearestterms' *array* - Parts of the interface to display, in the format:
- 'nearestterms[nbhits]' *int* - The resulting number of hits
- 'nearestterms[url_args]' *string* - The search parameters
- 'nearestterms[p]' *string* - The search terms
"""
# load the right message language
_ = gettext_set_language(ln)
out = _("Boolean query returned no hits. Please combine your search terms differently.")
out += """<blockquote><table class="nearesttermsbox" cellpadding="0" cellspacing="0" border="0">"""
for term in nearestterms:
out += """<tr><td class="nearesttermsboxbody" align="right">%(hits)s</td>
<td class="nearesttermsboxbody" width="15">&nbsp;</td>
<td class="nearesttermsboxbody" align="left">
<a class="nearestterms" href="%(weburl)s/search.py?%(url_args)s">%(p)s</a>
</td>
</tr>""" % {
'hits' : term['nbhits'],
'weburl' : weburl,
'url_args' : term['url_args'],
'p' : term['p']
}
out += """</table></blockquote>"""
return out
def tmpl_similar_author_names(self, ln, weburl, authors):
"""No hits found, proposes alternative boolean queries
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'authors' *array* - The authors information, in the format:
- 'authors[nb]' *int* - The resulting number of hits
- 'authors[name]' *string* - The author
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<a name="googlebox"></a>
<table class="googlebox"><tr><th colspan="2" class="googleboxheader">%(similar)s</th></tr>""" % {
'similar' : _("See also: similar author names")
}
for author in authors:
out += """<tr>
<td class="googleboxbody">%(nb)d</td>
<td class="googleboxbody">
<a class="google" href="%(weburl)s/search.py?p=%(auth_qt)s&amp;f=author">%(auth)s</a>
</td></tr>""" % {
'nb' : author['nb'],
'weburl' : weburl,
'auth_qt' : urllib.quote(author['name']),
'auth' : author['name'],
}
out += """</table>"""
return out
def tmpl_print_record_detailed(self, recID, ln, weburl):
"""Displays a detailed on-the-fly record
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'recID' *int* - The record id
"""
# okay, need to construct a simple "Detailed record" format of our own:
out = "<p>&nbsp;"
# secondly, title:
titles = get_fieldvalues(recID, "245__a")
for title in titles:
out += "<p><p><center><big><strong>%s</strong></big></center>" % title
# thirdly, authors:
authors = get_fieldvalues(recID, "100__a") + get_fieldvalues(recID, "700__a")
if authors:
out += "<p><p><center>"
for author in authors:
out += """<a href="%s/search.py?p=%s&f=author">%s</a> ;""" % (weburl, urllib.quote(author), author)
out += "</center>"
# fourthly, date of creation:
dates = get_fieldvalues(recID, "260__c")
for date in dates:
out += "<p><center><small>%s</small></center>" % date
# fifthly, abstract:
abstracts = get_fieldvalues(recID, "520__a")
for abstract in abstracts:
out += """<p style="margin-left: 15%%; width: 70%%">
<small><strong>Abstract:</strong> %s</small></p>""" % abstract
# fifthly bis, keywords:
keywords = get_fieldvalues(recID, "6531_a")
if len(keywords):
out += """<p style="margin-left: 15%%; width: 70%%">
<small><strong>Keyword(s):</strong></small>"""
for keyword in keywords:
out += """<small><a href="%s/search.py?p=%s&f=keyword">%s</a> ;</small> """ % (weburl, urllib.quote(keyword), keyword)
# fifthly bis bis, published in:
prs_p = get_fieldvalues(recID, "909C4p")
prs_v = get_fieldvalues(recID, "909C4v")
prs_y = get_fieldvalues(recID, "909C4y")
prs_n = get_fieldvalues(recID, "909C4n")
prs_c = get_fieldvalues(recID, "909C4c")
for idx in range(0,len(prs_p)):
out += """<p style="margin-left: 15%%; width: 70%%">
<small><strong>Publ. in:</strong> %s""" % prs_p[idx]
if prs_v and prs_v[idx]:
out += """<strong>%s</strong>""" % prs_v[idx]
if prs_y and prs_y[idx]:
out += """(%s)""" % prs_y[idx]
if prs_n and prs_n[idx]:
out += """, no.%s""" % prs_n[idx]
if prs_c and prs_c[idx]:
out += """, p.%s""" % prs_c[idx]
out += """.</small>"""
# sixthly, fulltext link:
urls_z = get_fieldvalues(recID, "8564_z")
urls_u = get_fieldvalues(recID, "8564_u")
for idx in range(0,len(urls_u)):
link_text = "URL"
try:
if urls_z[idx]:
link_text = urls_z[idx]
except IndexError:
pass
out += """<p style="margin-left: 15%%; width: 70%%">
<small><strong>%s:</strong> <a href="%s">%s</a></small>""" % (link_text, urls_u[idx], urls_u[idx])
# print some white space at the end:
out += "<p><p>"
return out
def tmpl_print_record_list_for_similarity_boxen(self, title, score_list, ln=cdslang):
"""Print list of records in the "hs" (HTML Similarity) format for similarity boxes.
FIXME: bad symbol names again, e.g. SCORE_LIST is *not* a list of scores. Humph.
"""
from cdsware.search_engine import print_record
out = '''
<table><tr><td>
<table><tr><td class="blocknote">%(title)s</td></tr></table>
</td>
<tr><td><table>
''' % { 'title': title }
for recid, score in score_list [:5]:
out += '''
<tr><td><font class="rankscoreinfo"><a>(%(score)s)&nbsp;</a></font><small>&nbsp;%(info)s</small></td></tr>''' % {
'score': score,
'info' : print_record (recid, format="hs", ln=ln),
}
out += """</table></small></td></tr></table> """
return out
def tmpl_print_record_brief(self, ln, recID, weburl):
"""Displays a brief record on-the-fly
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'recID' *int* - The record id
"""
out = ""
# record 'recID' does not exist in format 'format', so print some default format:
# firstly, title:
titles = get_fieldvalues(recID, "245__a")
# secondly, authors:
authors = get_fieldvalues(recID, "100__a") + get_fieldvalues(recID, "700__a")
# thirdly, date of creation:
dates = get_fieldvalues(recID, "260__c")
# thirdly bis, report numbers:
rns = get_fieldvalues(recID, "037__a")
rns = get_fieldvalues(recID, "088__a")
# fourthly, beginning of abstract:
abstracts = get_fieldvalues(recID, "520__a")
# fifthly, fulltext link:
urls_z = get_fieldvalues(recID, "8564_z")
urls_u = get_fieldvalues(recID, "8564_u")
return self.tmpl_record_body(
weburl = weburl,
titles = titles,
authors = authors,
dates = dates,
rns = rns,
abstracts = abstracts,
urls_u = urls_u,
urls_z = urls_z,
)
def tmpl_print_record_brief_links(self, ln, recID, weburl):
"""Displays links for brief record on-the-fly
Parameters:
- 'ln' *string* - The language to display
- 'weburl' *string* - The base URL for the site
- 'recID' *int* - The record id
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if cfg_use_aleph_sysnos:
alephsysnos = get_fieldvalues(recID, "970__a")
if len(alephsysnos)>0:
alephsysno = alephsysnos[0]
out += """<br><span class="moreinfo"><a class="moreinfo" href="%s/search.py?sysno=%s&amp;ln=%s">%s</a></span>""" \
% (weburl, alephsysno, ln, _("Detailed record"))
else:
out += """<br><span class="moreinfo"><a class="moreinfo" href="%s/search.py?recid=%s&amp;ln=%s">%s</a></span>""" \
% (weburl, recID, ln, _("Detailed record"))
else:
out += """<br><span class="moreinfo"><a class="moreinfo" href="%s/search.py?recid=%s&amp;ln=%s">%s</a></span>""" \
% (weburl, recID, ln, _("Detailed record"))
out += """<span class="moreinfo"> - <a class="moreinfo" href="%s/search.py?p=recid:%d&amp;rm=wrd&amp;ln=%s">%s</a></span>\n""" % \
(weburl, recID, ln, _("Similar records"))
if cfg_experimental_features:
out += """<span class="moreinfo"> - <a class="moreinfo" href="%s/search.py?p=recid:%d&amp;rm=cit&amp;ln=%s">%s</a></span>\n""" % (
weburl, recID, ln, _("Cited by"))
return out
diff --git a/modules/websearch/lib/websearchadminlib.py b/modules/websearch/lib/websearchadminlib.py
index 4fd2e7edb..7044c8320 100644
--- a/modules/websearch/lib/websearchadminlib.py
+++ b/modules/websearch/lib/websearchadminlib.py
@@ -1,3174 +1,3174 @@
## $Id$
## Administrator interface for WebSearch
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware WebSearch Administrator Interface."""
import cgi
import re
import MySQLdb
import Numeric
import os
import urllib
import random
import marshal
import time
from zlib import compress,decompress
from mod_python import apache
from cdsware.bibrankadminlib import write_outcome,modify_translations,get_def_name,get_i8n_name,get_name,get_rnk_nametypes,get_languages,check_user,is_adminuser,adderrorbox,addadminbox,tupletotable,tupletotable_onlyselected,addcheckboxes,createhiddenform,serialize_via_numeric_array_dumps,serialize_via_numeric_array_compr,serialize_via_numeric_array_escape,serialize_via_numeric_array,deserialize_via_numeric_array,serialize_via_marshal,deserialize_via_marshal
from cdsware.dbquery import run_sql
from cdsware.config import *
from cdsware.webpage import page, pageheaderonly, pagefooteronly
from cdsware.webuser import getUid, get_email
__version__ = "$Id$"
def getnavtrail(previous = ''):
"""Get the navtrail"""
navtrail = """<a class=navtrail href="%s/admin/">Admin Area</a> &gt; <a class=navtrail href="%s/admin/websearch/">WebSearch Admin</a> """ % (weburl, weburl)
navtrail = navtrail + previous
return navtrail
def perform_modifytranslations(colID, ln, sel_type='', trans=[], confirm=-1, callback='yes'):
"""Modify the translations of a collection
sel_type - the nametype to modify
trans - the translations in the same order as the languages from get_languages()"""
output = ''
subtitle = ''
cdslangs = get_languages()
if confirm in ["2", 2] and colID:
finresult = modify_translations(colID, cdslangs, sel_type, trans, "collection")
col_dict = dict(get_def_name('', "collection"))
if colID and col_dict.has_key(int(colID)):
colID = int(colID)
subtitle = """<a name="3">3. Modify translations for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a href="%s/admin/websearch/guide.html#3.3">?</a>]</small>""" % (col_dict[colID], weburl)
if type(trans) is str:
trans = [trans]
if sel_type == '':
sel_type = get_col_nametypes()[0][0]
header = ['Language', 'Translation']
actions = []
types = get_col_nametypes()
if len(types) > 1:
text = """
<span class="adminlabel">Name type</span>
<select name="sel_type" class="admin_w200">
"""
for (key, value) in types:
text += """<option value="%s" %s>%s""" % (key, key == sel_type and 'selected="selected"' or '', value)
trans_names = get_name(colID, ln, key, "collection")
if trans_names and trans_names[0][0]:
text += ": %s" % trans_names[0][0]
text += "</option>"
text += """</select>"""
output += createhiddenform(action="modifytranslations#3",
text=text,
button="Select",
colID=colID,
ln=ln,
confirm=0)
if confirm in [-1, "-1", 0, "0"]:
trans = []
for (key, value) in cdslangs:
try:
trans_names = get_name(colID, key, sel_type, "collection")
trans.append(trans_names[0][0])
except StandardError, e:
trans.append('')
for nr in range(0,len(cdslangs)):
actions.append(["%s %s" % (cdslangs[nr][1], (cdslangs[nr][0]==cdslang and '<small>(def)</small>' or ''))])
actions[-1].append('<input type="text" name="trans" size="30" value="%s"/>' % trans[nr])
text = tupletotable(header=header, tuple=actions)
output += createhiddenform(action="modifytranslations#3",
text=text,
button="Modify",
colID=colID,
sel_type=sel_type,
ln=ln,
confirm=2)
if sel_type and len(trans) and confirm in ["2", 2]:
output += write_outcome(finresult)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_modifytranslations", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyrankmethods(colID, ln, func='', rnkID='', confirm=0, callback='yes'):
"""Modify which rank methods is visible to the collection
func - remove or add rank method
rnkID - the id of the rank method."""
output = ""
subtitle = ""
col_dict = dict(get_def_name('', "collection"))
rnk_dict = dict(get_def_name('', "rnkMETHOD"))
if colID and col_dict.has_key(int(colID)):
colID = int(colID)
if func in ["0", 0] and confirm in ["1", 1]:
finresult = attach_rnk_col(colID, rnkID)
elif func in ["1", 1] and confirm in ["1", 1]:
finresult = detach_rnk_col(colID, rnkID)
subtitle = """<a name="9">9. Modify rank options for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.9">?</a>]</small>""" % (col_dict[colID], weburl)
output = """
<dl>
<dt>The rank methods enabled for the collection '%s' is:</dt>
""" % col_dict[colID]
rnkmethods = get_col_rnk(colID, ln)
output += """<dd>"""
if not rnkmethods:
output += """No rank methods"""
else:
for id, name in rnkmethods:
output += """%s, """ % name
output += """</dd>
</dl>
"""
rnk_list = get_def_name('', "rnkMETHOD")
rnk_dict_in_col = dict(get_col_rnk(colID, ln))
rnk_list = filter(lambda x: not rnk_dict_in_col.has_key(x[0]), rnk_list)
if rnk_list:
text = """
<span class="adminlabel">Enable:</span>
<select name="rnkID" class="admin_w200">
<option value="-1">- select rank method -</option>
"""
for (id, name) in rnk_list:
text += """<option value="%s" %s>%s</option>""" % (id, (func in ["0", 0] and confirm in ["0", 0] and int(rnkID) == int(id)) and 'selected="selected"' or '' , name)
text += """</select>"""
output += createhiddenform(action="modifyrankmethods#9",
text=text,
button="Enable",
colID=colID,
ln=ln,
func=0,
confirm=1)
if confirm in ["1", 1] and func in ["0", 0] and int(rnkID) != -1:
output += write_outcome(finresult)
elif confirm not in ["0", 0] and func in ["0", 0]:
output += """<b><span class="info">Please select a rank method.</span></b>"""
coll_list = get_col_rnk(colID, ln)
if coll_list:
text = """
<span class="adminlabel">Disable:</span>
<select name="rnkID" class="admin_w200">
<option value="-1">- select rank method-</option>
"""
for (id, name) in coll_list:
text += """<option value="%s" %s>%s</option>""" % (id, (func in ["1", 1] and confirm in ["0", 0] and int(rnkID) == int(id)) and 'selected="selected"' or '' , name)
text += """</select>"""
output += createhiddenform(action="modifyrankmethods#9",
text=text,
button="Disable",
colID=colID,
ln=ln,
func=1,
confirm=1)
if confirm in ["1", 1] and func in ["1", 1] and int(rnkID) != -1:
output += write_outcome(finresult)
elif confirm not in ["0", 0] and func in ["1", 1]:
output += """<b><span class="info">Please select a rank method.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_modifyrankmethods", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addcollectiontotree(colID, ln, add_dad='', add_son='', rtype='', mtype='', callback='yes', confirm=-1):
"""Form to add a collection to the tree.
add_dad - the dad to add the collection to
add_son - the collection to add
rtype - add it as a regular or virtual
mtype - add it to the regular or virtual tree."""
output = ""
output2 = ""
subtitle = """Attach collection to tree&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#2.2">?</a>]</small>""" % (weburl)
col_dict = dict(get_def_name('', "collection"))
if confirm not in [-1, "-1"] and not (add_son and add_dad and rtype):
output2 += """<b><span class="info">All fields must be filled.</span></b><br><br>
"""
elif add_son and add_dad and rtype:
add_son = int(add_son)
add_dad = int(add_dad)
if confirm not in [-1, "-1"]:
if add_son == add_dad:
output2 += """<b><span class="info">Cannot add a collection as a pointer to itself.</span></b><br><br>
"""
elif check_col(add_dad, add_son):
res = add_col_dad_son(add_dad, add_son, rtype)
output2 += write_outcome(res)
if res[0] == 1:
output2 += """<b><span class="info"><br> The collection will appear on your website after the next webcoll run. You can either run it manually or wait until bibsched does it for you.</span></b><br><br>
"""
else:
output2 += """<b><span class="info">Cannot add the collection '%s' as a %s subcollection of '%s' since it will either create a loop, or the association already exists.</span></b><br><br>
""" % (col_dict[add_son], (rtype=="r" and 'regular' or 'virtual'), col_dict[add_dad])
add_son = ''
add_dad = ''
rtype = ''
tree = get_col_tree(colID)
col_list = col_dict.items()
col_list.sort(compare_on_val)
output = show_coll_not_in_tree(colID, ln, col_dict)
text = """
<span class="adminlabel">Attach which</span>
<select name="add_son" class="admin_w200">
<option value="">- select collection -</option>
"""
for (id, name) in col_list:
if id != colID:
text += """<option value="%s" %s>%s</option>""" % (id, str(id)==str(add_son) and 'selected="selected"' or '', name)
text += """
</select><br>
<span class="adminlabel">Attach to</span>
<select name="add_dad" class="admin_w200">
<option value="">- select parent collection -</option>
"""
for (id, name) in col_list:
text += """<option value="%s" %s>%s</option>
""" % (id, str(id)==add_dad and 'selected="selected"' or '', name)
text += """</select><br>
"""
text += """
<span class="adminlabel">Relationship</span>
<select name="rtype" class="admin_w200">
<option value="">- select relationship -</option>
<option value="r" %s>Regular (Narrow by...)</option>
<option value="v" %s>Virtual (Focus on...)</option>
</select>
""" % ((rtype=="r" and 'selected="selected"' or ''), (rtype=="v" and 'selected="selected"' or ''))
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/addcollectiontotree" % weburl,
text=text,
button="Add",
colID=colID,
ln=ln,
confirm=1)
output += output2
#output += perform_showtree(colID, ln)
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(colID, ln, mtype="perform_addcollectiontotree", content=addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addcollection(colID, ln, colNAME='', dbquery='', rest='', callback="yes", confirm=-1):
"""form to add a new collection.
colNAME - the name of the new collection
dbquery - the dbquery of the new collection
rest - the group allowed to access the new collection"""
output = ""
subtitle = """Create new collection&nbsp;&nbsp;&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#2.1">?</a>]</small>""" % (weburl)
text = """
<span class="adminlabel">Default name</span>
<input class="admin_w200" type="text" name="colNAME" value="%s" /><br>
""" % colNAME
output = createhiddenform(action="%s/admin/websearch/websearchadmin.py/addcollection" % weburl,
text=text,
colID=colID,
ln=ln,
button="Add collection",
confirm=1)
if colNAME and confirm in ["1", 1]:
res = add_col(colNAME, '', '')
output += write_outcome(res)
if res[0] == 1:
output += perform_addcollectiontotree(colID=colID, ln=ln, add_son=res[1], callback='')
elif confirm not in ["-1", -1]:
output += """<b><span class="info">Please give the collection a name.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(colID, ln=ln, mtype="perform_addcollection", content=addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifydbquery(colID, ln, dbquery='', callback='yes', confirm=-1):
"""form to modify the dbquery of the collection.
dbquery - the dbquery of the collection."""
subtitle = ''
output = ""
col_dict = dict(get_def_name('', "collection"))
if colID and col_dict.has_key(int(colID)):
colID = int(colID)
subtitle = """<a name="1">1. Modify collection query for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.1">?</a>]</small>""" % (col_dict[colID], weburl)
if confirm == -1:
res = run_sql("SELECT dbquery FROM collection WHERE id=%s" % colID)
dbquery = res[0][0]
if not dbquery:
dbquery = ''
reg_sons = len(get_col_tree(colID, 'r'))
vir_sons = len(get_col_tree(colID, 'v'))
if reg_sons > 1:
if dbquery:
output += "Warning: This collection got subcollections, and should because of this not have a collection query, for further explanation, check the WebSearch Guide<br>"
elif reg_sons <= 1:
if not dbquery:
output += "Warning: This collection does not have any subcollections, and should because of this have a collection query, for further explanation, check the WebSearch Guide<br>"
text = """
<span class="adminlabel">Query</span>
<input class="admin_w200" type="text" name="dbquery" value="%s" /><br>
""" % dbquery
output += createhiddenform(action="modifydbquery",
text=text,
button="Modify",
colID=colID,
ln=ln,
confirm=1)
if confirm in ["1", 1]:
res = modify_dbquery(colID, dbquery)
if res:
if dbquery == "":
text = """<b><span class="info">Query removed for this collection.</span></b>"""
else:
text = """<b><span class="info">Query set for this collection.</span></b>"""
else:
text = """<b><span class="info">Sorry, could not change query.</span></b>"""
output += text
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_modifydbquery", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyrestricted(colID, ln, rest='', callback='yes', confirm=-1):
"""modify which apache group is allowed to access the collection.
rest - the groupname"""
subtitle = ''
output = ""
col_dict = dict(get_def_name('', "collection"))
if colID and col_dict.has_key(int(colID)):
colID = int(colID)
subtitle = """<a name="2">2. Modify access restrictions for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.2">?</a>]</small>""" % (col_dict[colID], weburl)
if confirm == -1:
res = run_sql("SELECT restricted FROM collection WHERE id=%s" % colID)
rest = res[0][0]
if not rest:
rest = ''
text = """
<span class="adminlabel">Restricted to:</span>
<input class="admin_w200" type="text" name="rest" value="%s" /><br>
""" % rest
output += createhiddenform(action="modifyrestricted",
text=text,
button="Modify",
colID=colID,
ln=ln,
confirm=1)
if confirm in ["1", 1]:
res = modify_restricted(colID, rest)
if res:
if rest == "":
text = """<b><span class="info">Removed restriction for this collection.</span></b>"""
else:
text = """<b><span class="info">Restriction set for this collection.</span></b>"""
else:
text = """<b><span class="info">Sorry, could not change the access restrictions.</span></b>"""
output += text
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_modifyrestricted", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifycollectiontree(colID, ln, move_up='', move_down='', move_from='', move_to='', delete='', rtype='', callback='yes', confirm=0):
"""to modify the collection tree: move a collection up and down, delete a collection, or change the father of the collection.
colID - the main collection of the tree, the root
move_up - move this collection up (is not the collection id, but the place in the tree)
move_up - move this collection down (is not the collection id, but the place in the tree)
move_from - move this collection from the current positon (is not the collection id, but the place in the tree)
move_to - move the move_from collection and set this as it's father. (is not the collection id, but the place in the tree)
delete - delete this collection from the tree (is not the collection id, but the place in the tree)
rtype - the type of the collection in the tree, regular or virtual"""
colID = int(colID)
tree = get_col_tree(colID, rtype)
col_dict = dict(get_def_name('', "collection"))
subtitle = """Modify collection tree: %s&nbsp;&nbsp;&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#2.3">?</a>]&nbsp;&nbsp;&nbsp;<a href="%s/admin/websearch/websearchadmin.py/showtree?colID=%s&amp;ln=%s">Printer friendly version</a></small>""" % (col_dict[colID], weburl, weburl, colID, ln)
fin_output = ""
output = ""
try:
if move_up:
move_up = int(move_up)
switch = find_last(tree, move_up)
if switch and switch_col_treescore(tree[move_up], tree[switch]):
output += """<b><span class="info">Moved the %s collection '%s' up and '%s' down.</span></b><br><br>
""" % ((rtype=="r" and 'regular' or 'virtual'), col_dict[tree[move_up][0]], col_dict[tree[switch][0]])
else:
output += """<b><span class="info">Could not move the %s collection '%s' up and '%s' down.</span></b><br><br>
""" % ((rtype=="r" and 'regular' or 'virtual'), col_dict[tree[move_up][0]], col_dict[tree[switch][0]])
elif move_down:
move_down = int(move_down)
switch = find_next(tree, move_down)
if switch and switch_col_treescore(tree[move_down], tree[switch]):
output += """<b><span class="info">Moved the %s collection '%s' down and '%s' up.</span></b><br><br>
""" % ((rtype=="r" and 'regular' or 'virtual'), col_dict[tree[move_down][0]], col_dict[tree[switch][0]])
else:
output += """<b><span class="info">Could not move the %s collection '%s' up and '%s' down.</span></b><br><br>
""" % ((rtype=="r" and 'regular' or 'virtual'), col_dict[tree[move_up][0]],col_dict[tree[switch][0]])
elif delete:
delete = int(delete)
if confirm in [0, "0"]:
if col_dict[tree[delete][0]] != col_dict[tree[delete][3]]:
text = """<b>Do you want to remove the %s collection '%s' and its subcollections in the %s collection '%s'.</b>
""" % ((tree[delete][4]=="r" and 'regular' or 'virtual'), col_dict[tree[delete][0]], (rtype=="r" and 'regular' or 'virtual'), col_dict[tree[delete][3]])
else:
text = """<b>Do you want to remove all subcollections of the %s collection '%s'.</b>
""" % ((rtype=="r" and 'regular' or 'virtual'), col_dict[tree[delete][3]])
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/modifycollectiontree#tree" % weburl,
text=text,
button="Confirm",
colID=colID,
delete=delete,
rtype=rtype,
ln=ln,
confirm=1)
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/index?mtype=perform_modifycollectiontree#tree" % weburl,
text="<b>To cancel</b>",
button="Cancel",
colID=colID,
ln=ln)
else:
if remove_col_subcol(tree[delete][0], tree[delete][3], rtype):
if col_dict[tree[delete][0]] != col_dict[tree[delete][3]]:
output += """<b><span class="info">Removed the %s collection '%s' and its subcollections in subdirectory '%s'.</span></b><br><br>
""" % ((tree[delete][4]=="r" and 'regular' or 'virtual'), col_dict[tree[delete][0]], col_dict[tree[delete][3]])
else:
output += """<b><span class="info">Removed the subcollections of the %s collection '%s'.</span></b><br><br>
""" % ((rtype=="r" and 'regular' or 'virtual'), col_dict[tree[delete][3]])
else:
output += """<b><span class="info">Could not remove the collection from the tree.</span></b><br><br>
"""
delete = ''
elif move_from and not move_to:
move_from_rtype = move_from[0]
move_from_id = int(move_from[1:len(move_from)])
text = """<b>Select collection to place the %s collection '%s' under.</b><br><br>
""" % ((move_from_rtype=="r" and 'regular' or 'virtual'), col_dict[tree[move_from_id][0]])
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/index?mtype=perform_modifycollectiontree#tree" % weburl,
text=text,
button="Cancel",
colID=colID,
ln=ln)
elif move_from and move_to:
move_from_rtype = move_from[0]
move_from_id = int(move_from[1:len(move_from)])
move_to_rtype = move_to[0]
move_to_id = int(move_to[1:len(move_to)])
tree_from = get_col_tree(colID, move_from_rtype)
tree_to = get_col_tree(colID, move_to_rtype)
if confirm in [0, '0']:
if move_from_id == move_to_id and move_from_rtype==move_to_rtype:
output += """<b><span class="info">Cannot move to itself.</span></b><br><br>
"""
elif tree_from[move_from_id][3] == tree_to[move_to_id][0] and move_from_rtype==move_to_rtype:
output += """<b><span class="info">The collection is already there.</span></b><br><br>
"""
elif check_col(tree_to[move_to_id][0], tree_from[move_from_id][0]) or (tree_to[move_to_id][0] == 1 and tree_from[move_from_id][3] == tree_to[move_to_id][0] and move_from_rtype != move_to_rtype):
text = """<b>Move %s collection '%s' to the %s collection '%s'.</b>
""" % ((tree_from[move_from_id][4]=="r" and 'regular' or 'virtual'), col_dict[tree_from[move_from_id][0]], (tree_to[move_to_id][4]=="r" and 'regular' or 'virtual'), col_dict[tree_to[move_to_id][0]])
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/modifycollectiontree#tree" % weburl,
text=text,
button="Confirm",
colID=colID,
move_from=move_from,
move_to=move_to,
ln=ln,
rtype=rtype,
confirm=1)
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/index?mtype=perform_modifycollectiontree#tree" % weburl,
text="""<b>To cancel</b>""",
button="Cancel",
colID=colID,
ln=ln)
else:
output += """<b><span class="info">Cannot move the collection '%s' and set it as a subcollection of '%s' since it will create a loop.</span></b><br><br>
""" % (col_dict[tree_from[move_from_id][0]], col_dict[tree_to[move_to_id][0]])
else:
if (move_to_id != 0 and move_col_tree(tree_from[move_from_id], tree_to[move_to_id])) or (move_to_id == 0 and move_col_tree(tree_from[move_from_id], tree_to[move_to_id], move_to_rtype)):
output += """<b><span class="info">Moved %s collection '%s' to the %s collection '%s'.</span></b><br><br>
""" % ((move_from_rtype=="r" and 'regular' or 'virtual'), col_dict[tree_from[move_from_id][0]], (move_to_rtype=="r" and 'regular' or 'virtual'), col_dict[tree_to[move_to_id][0]])
else:
output += """<b><span class="info">Could not move %s collection '%s' to the %s collection '%s'.</span></b><br><br>
""" % ((move_from_rtype=="r" and 'regular' or 'virtual'), col_dict[tree_from[move_from_id][0]], (move_to_rtype=="r" and 'regular' or 'virtual'), col_dict[tree_to[move_to_id][0]])
move_from = ''
move_to = ''
else:
output += """
"""
except StandardError, e:
return """<b><span class="info">An error occured.</span></b>
"""
output += """<table border ="0" width="100%">
<tr><td width="50%">
<b>Narrow by collection:</b>
</td><td width="50%">
<b>Focus on...:</b>
</td></tr><tr><td valign="top">
"""
tree = get_col_tree(colID, 'r')
output += create_colltree(tree, col_dict, colID, ln, move_from, move_to, 'r', "yes")
output += """</td><td valign="top">
"""
tree = get_col_tree(colID, 'v')
output += create_colltree(tree, col_dict, colID, ln, move_from, move_to, 'v', "yes")
output += """</td>
</tr>
</table>
"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(colID, ln, mtype="perform_modifycollectiontree", content=addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_showtree(colID, ln):
"""create collection tree/hiarchy"""
col_dict = dict(get_def_name('', "collection"))
subtitle = "Collection tree: %s" % col_dict[int(colID)]
output = """<table border ="0" width="100%">
<tr><td width="50%">
<b>Narrow by collection:</b>
</td><td width="50%">
<b>Focus on...:</b>
</td></tr><tr><td valign="top">
"""
tree = get_col_tree(colID, 'r')
output += create_colltree(tree, col_dict, colID, ln, '', '', 'r', '')
output += """</td><td valign="top">
"""
tree = get_col_tree(colID, 'v')
output += create_colltree(tree, col_dict, colID, ln, '', '', 'v', '')
output += """</td>
</tr>
</table>
"""
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle, body)
def perform_addportalbox(colID, ln, title='', body='', callback='yes', confirm=-1):
"""form to add a new portalbox
title - the title of the portalbox
body - the body of the portalbox"""
col_dict = dict(get_def_name('', "collection"))
colID = int(colID)
subtitle = """<a name="5.1"></a>Create new portalbox"""
text = """
<span class="adminlabel">Title</span>
<textarea cols="50" rows="1" class="admin_wvar" type="text" name="title">%s</textarea><br>
<span class="adminlabel">Body</span>
<textarea cols="50" rows="10" class="admin_wvar" type="text" name="body">%s</textarea><br>
""" % (cgi.escape(title), cgi.escape(body))
output = createhiddenform(action="addportalbox#5.1",
text=text,
button="Add",
colID=colID,
ln=ln,
confirm=1)
if body and confirm in [1, "1"]:
title = cgi.escape(title)
body = cgi.escape(body)
res = add_pbx(title, body)
output += write_outcome(res)
if res[1] == 1:
output += """<b><span class="info"><a href="addexistingportalbox?colID=%s&amp;ln=%s&amp;pbxID=%s#5">Add portalbox to collection</a></span></b>""" % (colID, ln, res[1])
elif confirm not in [-1, "-1"]:
output += """<b><span class="info">Body field must be filled.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
return perform_showportalboxes(colID, ln, content=addadminbox(subtitle, body))
def perform_addexistingportalbox(colID, ln, pbxID=-1, score=0, position='', sel_ln='', callback='yes', confirm=-1):
"""form to add an existing portalbox to a collection.
colID - the collection to add the portalbox to
pbxID - the portalbox to add
score - the importance of the portalbox.
position - the position of the portalbox on the page
sel_ln - the language of the portalbox"""
subtitle = """<a name="5.2"></a>Add existing portalbox to collection"""
output = ""
colID = int(colID)
res = get_pbx()
pos = get_pbx_pos()
lang = dict(get_languages())
col_dict = dict(get_def_name('', "collection"))
pbx_dict = dict(map(lambda x: (x[0], x[1]), res))
col_pbx = get_col_pbx(colID)
col_pbx = dict(map(lambda x: (x[0], x[5]), col_pbx))
if len(res) > 0:
text = """
<span class="adminlabel">Portalbox</span>
<select name="pbxID" class="admin_w200">
<option value="-1">- Select portalbox -</option>
"""
for (id, t_title, t_body) in res:
if not col_pbx.has_key(id):
text += """<option value="%s" %s>%s - %s...</option>
""" % (id, id == int(pbxID) and 'selected="selected"' or '', t_title, cgi.escape(t_body[0:25 - len(t_title)]))
text += """</select><br>
<span class="adminlabel">Language</span>
<select name="sel_ln" class="admin_w200">
<option value="">- Select language -</option>
"""
listlang = lang.items()
listlang.sort()
for (key, name) in listlang:
text += """<option value="%s" %s>%s</option>
""" % (key, key == sel_ln and 'selected="selected"' or '', name)
text += """</select><br>
<span class="adminlabel">Position</span>
<select name="position" class="admin_w200">
<option value="">- Select position -</option>
"""
listpos = pos.items()
listpos.sort()
for (key, name) in listpos:
text += """<option value="%s" %s>%s</option>""" % (key, key==position and 'selected="selected"' or '', name)
text += "</select>"
output += createhiddenform(action="addexistingportalbox#5.2",
text=text,
button="Add",
colID=colID,
ln=ln,
confirm=1)
else:
output = """No existing portalboxes to add, please create a new one.
"""
if pbxID > -1 and position and sel_ln and confirm in [1, "1"]:
pbxID = int(pbxID)
res = add_col_pbx(colID, pbxID, sel_ln, position, '')
output += write_outcome(res)
elif pbxID > -1 and confirm not in [-1, "-1"]:
output += """<b><span class="info">All fields must be filled.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showportalboxes(colID, ln, content=output)
def perform_deleteportalbox(colID, ln, pbxID=-1, callback='yes', confirm=-1):
"""form to delete a portalbox which is not in use.
colID - the current collection.
pbxID - the id of the portalbox"""
subtitle = """<a name="5.3"></a>Delete an unused portalbox"""
output = ""
colID = int(colID)
if pbxID not in [-1," -1"] and confirm in [1, "1"]:
ares = get_pbx()
pbx_dict = dict(map(lambda x: (x[0], x[1]), ares))
if pbx_dict.has_key(int(pbxID)):
pname = pbx_dict[int(pbxID)]
ares = delete_pbx(int(pbxID))
else:
return """<b><span class="info">This portalbox does not exist</span></b>"""
res = get_pbx()
col_dict = dict(get_def_name('', "collection"))
pbx_dict = dict(map(lambda x: (x[0], x[1]), res))
col_pbx = get_col_pbx()
col_pbx = dict(map(lambda x: (x[0], x[5]), col_pbx))
if len(res) > 0:
text = """
<span class="adminlabel">Portalbox</span>
<select name="pbxID" class="admin_w200">
"""
text += """<option value="-1">- Select portalbox -"""
for (id, t_title, t_body) in res:
if not col_pbx.has_key(id):
text += """<option value="%s" %s>%s - %s...""" % (id, id == int(pbxID) and 'selected="selected"' or '', t_title, cgi.escape(t_body[0:10]))
text += "</option>"
text += """</select><br>"""
output += createhiddenform(action="deleteportalbox#5.3",
text=text,
button="Delete",
colID=colID,
ln=ln,
confirm=1)
if pbxID not in [-1,"-1"]:
pbxID = int(pbxID)
if confirm in [1, "1"]:
output += write_outcome(ares)
elif confirm not in [-1, "-1"]:
output += """<b><span class="info">Choose a portalbox to delete.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showportalboxes(colID, ln, content=output)
def perform_modifyportalbox(colID, ln, pbxID=-1, score='', position='', sel_ln='', title='', body='', callback='yes', confirm=-1):
"""form to modify a portalbox in a collection, or change the portalbox itself.
colID - the id of the collection.
pbxID - the portalbox to change
score - the score of the portalbox connected to colID which should be changed.
position - the position of the portalbox in collection colID to change."""
subtitle = ""
output = ""
colID = int(colID)
res = get_pbx()
pos = get_pbx_pos()
lang = dict(get_languages())
col_dict = dict(get_def_name('', "collection"))
pbx_dict = dict(map(lambda x: (x[0], x[1]), res))
col_pbx = get_col_pbx(colID)
col_pbx = dict(map(lambda x: (x[0], x[5]), col_pbx))
if pbxID not in [-1, "-1"]:
pbxID = int(pbxID)
subtitle = """<a name="5.4"></a>Modify portalbox '%s' for this collection""" % pbx_dict[pbxID]
col_pbx = get_col_pbx(colID)
if not (score and position) and not (body and title):
for (id_pbx, id_collection, tln, score, position, title, body) in col_pbx:
if id_pbx == pbxID:
break
output += """Collection (presentation) specific values (Changes implies only to this collection.)<br>"""
text = """
<span class="adminlabel">Position</span>
<select name="position" class="admin_w200">
"""
listpos = pos.items()
listpos.sort()
for (key, name) in listpos:
text += """<option value="%s" %s>%s""" % (key, key==position and 'selected="selected"' or '', name)
text += "</option>"
text += """</select><br>"""
output += createhiddenform(action="modifyportalbox#5.4",
text=text,
button="Modify",
colID=colID,
pbxID=pbxID,
score=score,
title=title,
body=cgi.escape(body, 1),
sel_ln=sel_ln,
ln=ln,
confirm=3)
if pbxID > -1 and score and position and confirm in [3, "3"]:
pbxID = int(pbxID)
res = modify_pbx(colID, pbxID, sel_ln, score, position, '', '')
res2 = get_pbx()
pbx_dict = dict(map(lambda x: (x[0], x[1]), res2))
output += write_outcome(res)
output += """<br>Portalbox (content) specific values (any changes appears everywhere the portalbox is used.)"""
text = """
<span class="adminlabel">Title</span>
<textarea cols="50" rows="1" class="admin_wvar" type="text" name="title">%s</textarea><br>
""" % cgi.escape(title)
text += """
<span class="adminlabel">Body</span>
<textarea cols="50" rows="10" class="admin_wvar" type="text" name="body">%s</textarea><br>
""" % cgi.escape(body)
output += createhiddenform(action="modifyportalbox#5.4",
text=text,
button="Modify",
colID=colID,
pbxID=pbxID,
sel_ln=sel_ln,
score=score,
position=position,
ln=ln,
confirm=4)
if pbxID > -1 and confirm in [4, "4"]:
pbxID = int(pbxID)
res = modify_pbx(colID, pbxID, sel_ln, '', '', title, body)
output += write_outcome(res)
else:
output = """No portalbox to modify."""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showportalboxes(colID, ln, content=output)
def perform_switchpbxscore(colID, id_1, id_2, sel_ln, ln):
"""Switch the score of id_1 and id_2 in collection_portalbox.
colID - the current collection
id_1/id_2 - the id's to change the score for.
sel_ln - the language of the portalbox"""
res = get_pbx()
pbx_dict = dict(map(lambda x: (x[0], x[1]), res))
res = switch_pbx_score(colID, id_1, id_2, sel_ln)
output += write_outcome(res)
return perform_showportalboxes(colID, ln, content=output)
def perform_showportalboxes(colID, ln, callback='yes', content='', confirm=-1):
"""show the portalboxes of this collection.
colID - the portalboxes to show the collection for."""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
subtitle = """<a name="5">5. Modify portalboxes for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.5">?</a>]</small>""" % (col_dict[colID], weburl)
output = ""
pos = get_pbx_pos()
output = """<dl>
<dt>Portalbox actions (not related to this collection)
<dd><a href="addportalbox?colID=%s&amp;ln=%s#5.1">Create new portalbox</a></dd>
<dd><a href="deleteportalbox?colID=%s&amp;ln=%s#5.3">Delete an unused portalbox</a></dd>
<dt>Collection specific actions
<dd><a href="addexistingportalbox?colID=%s&amp;ln=%s#5.2">Add existing portalbox to collection</a></dd>
</dl>
""" % (colID, ln, colID, ln, colID, ln)
header = ['Position', 'Language', '', 'Title', 'Actions']
actions = []
cdslang = get_languages()
lang = dict(cdslang)
pos_list = pos.items()
pos_list.sort()
if len(get_col_pbx(colID)) > 0:
for (key, value) in cdslang:
for (pos_key, pos_value) in pos_list:
res = get_col_pbx(colID, key, pos_key)
i = 0
for (pbxID, colID_pbx, tln, score, position, title, body) in res:
move = """<table cellspacing="1" cellpadding="0" border="0"><tr><td>"""
if i != 0:
move += """<a href="%s/admin/websearch/websearchadmin.py/switchpbxscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;sel_ln=%s&amp;rand=%s#5"><img border="0" src="%s/img/smallup.gif" title="Move portalbox up"></a>""" % (weburl, colID, ln, pbxID, res[i - 1][0], tln, random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;"
move += "</td><td>"
i += 1
if i != len(res):
move += """<a href="%s/admin/websearch/websearchadmin.py/switchpbxscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;sel_ln=%s&amp;rand=%s#5"><img border="0" src="%s/img/smalldown.gif" title="Move portalbox down"></a>""" % (weburl, colID, ln, pbxID, res[i][0], tln, random.randint(0, 1000), weburl)
move += """</td></tr></table>"""
actions.append(["%s" % (i==1 and pos[position] or ''), "%s" % (i==1 and lang[tln] or ''), move, "%s" % title])
for col in [(('Modify', 'modifyportalbox'), ('Remove', 'removeportalbox'),)]:
actions[-1].append('<a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;pbxID=%s&amp;sel_ln=%s#5.4">%s</a>' % (weburl, col[0][1], colID, ln, pbxID, tln, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;pbxID=%s&amp;sel_ln=%s#5.5">%s</a>' % (weburl, function, colID, ln, pbxID, tln, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No portalboxes exists for this collection"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_showportalboxes", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_removeportalbox(colID, ln, pbxID='', sel_ln='', callback='yes', confirm=0):
"""form to remove a portalbox from a collection.
colID - the current collection, remove the portalbox from this collection.
sel_ln - remove the portalbox with this language
pbxID - remove the portalbox with this id"""
subtitle = """<a name="5.5"></a>Remove portalbox"""
output = ""
col_dict = dict(get_def_name('', "collection"))
res = get_pbx()
pbx_dict = dict(map(lambda x: (x[0], x[1]), res))
if colID and pbxID and sel_ln:
colID = int(colID)
pbxID = int(pbxID)
if confirm in ["0", 0]:
text = """Do you want to remove the portalbox '%s' from the collection '%s'.""" % (pbx_dict[pbxID], col_dict[colID])
output += createhiddenform(action="removeportalbox#5.5",
text=text,
button="Confirm",
colID=colID,
pbxID=pbxID,
sel_ln=sel_ln,
confirm=1)
elif confirm in ["1", 1]:
res = remove_pbx(colID, pbxID, sel_ln)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showportalboxes(colID, ln, content=output)
def perform_switchfmtscore(colID, type, id_1, id_2, ln):
"""Switch the score of id_1 and id_2 in the table type.
colID - the current collection
id_1/id_2 - the id's to change the score for.
type - like "format" """
fmt_dict = dict(get_def_name('', "format"))
res = switch_score(colID, id_1, id_2, type)
output = write_outcome(res)
return perform_showoutputformats(colID, ln, content=output)
def perform_switchfldscore(colID, id_1, id_2, fmeth, ln):
"""Switch the score of id_1 and id_2 in collection_field_fieldvalue.
colID - the current collection
id_1/id_2 - the id's to change the score for."""
fld_dict = dict(get_def_name('', "field"))
res = switch_fld_score(colID, id_1, id_2)
output = write_outcome(res)
if fmeth == "soo":
return perform_showsortoptions(colID, ln, content=output)
elif fmeth == "sew":
return perform_showsearchfields(colID, ln, content=output)
elif fmeth == "seo":
return perform_showsearchoptions(colID, ln, content=output)
def perform_switchfldvaluescore(colID, id_1, id_fldvalue_1, id_fldvalue_2, ln):
"""Switch the score of id_1 and id_2 in collection_field_fieldvalue.
colID - the current collection
id_1/id_2 - the id's to change the score for."""
name_1 = run_sql("SELECT name from fieldvalue where id=%s" % id_fldvalue_1)[0][0]
name_2 = run_sql("SELECT name from fieldvalue where id=%s" % id_fldvalue_2)[0][0]
res = switch_fld_value_score(colID, id_1, id_fldvalue_1, id_fldvalue_2)
output = write_outcome(res)
return perform_modifyfield(colID, fldID=id_1, ln=ln, content=output)
def perform_addnewfieldvalue(colID, fldID, ln, name='', value='', callback="yes", confirm=-1):
"""form to add a new fieldvalue.
name - the name of the new fieldvalue
value - the value of the new fieldvalue
"""
output = ""
subtitle = """<a name="7.4"></a>Add new value"""
text = """
<span class="adminlabel">Display name</span>
<input class="admin_w200" type="text" name="name" value="%s" /><br>
<span class="adminlabel">Search value</span>
<input class="admin_w200" type="text" name="value" value="%s" /><br>
""" % (name, value)
output = createhiddenform(action="%s/admin/websearch/websearchadmin.py/addnewfieldvalue" % weburl,
text=text,
colID=colID,
fldID=fldID,
ln=ln,
button="Add",
confirm=1)
if name and value and confirm in ["1", 1]:
res = add_fldv(name, value)
output += write_outcome(res)
if res[0] == 1:
res = add_col_fld(colID, fldID, 'seo', res[1])
if res[0] == 0:
output += "<br>" + write_outcome(res)
elif confirm not in ["-1", -1]:
output += """<b><span class="info">Please fill in name and value.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_modifyfield(colID, fldID=fldID, ln=ln, content=output)
def perform_modifyfieldvalue(colID, fldID, fldvID, ln, name='', value='', callback="yes", confirm=-1):
"""form to modify a fieldvalue.
name - the name of the fieldvalue
value - the value of the fieldvalue
"""
if confirm in [-1, "-1"]:
res = get_fld_value(fldvID)
(id, name, value) = res[0]
output = ""
subtitle = """<a name="7.4"></a>Modify existing value"""
output = """<dl>
<dt><b><span class="info">Warning: Modifications done below will also inflict on all places the modified data is used.</span></b></dt>
</dl>"""
text = """
<span class="adminlabel">Display name</span>
<input class="admin_w200" type="text" name="name" value="%s" /><br>
<span class="adminlabel">Search value</span>
<input class="admin_w200" type="text" name="value" value="%s" /><br>
""" % (name, value)
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/modifyfieldvalue" % weburl,
text=text,
colID=colID,
fldID=fldID,
fldvID=fldvID,
ln=ln,
button="Update",
confirm=1)
output += createhiddenform(action="%s/admin/websearch/websearchadmin.py/modifyfieldvalue" % weburl,
text="Delete value and all associations",
colID=colID,
fldID=fldID,
fldvID=fldvID,
ln=ln,
button="Delete",
confirm=2)
if name and value and confirm in ["1", 1]:
res = update_fldv(fldvID, name, value)
output += write_outcome(res)
#if res:
# output += """<b><span class="info">Operation successfully completed.</span></b>"""
#else:
# output += """<b><span class="info">Operation failed.</span></b>"""
elif confirm in ["2", 2]:
res = delete_fldv(fldvID)
output += write_outcome(res)
elif confirm not in ["-1", -1]:
output += """<b><span class="info">Please fill in name and value.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_modifyfield(colID, fldID=fldID, ln=ln, content=output)
def perform_removefield(colID, ln, fldID='', fldvID='', fmeth='', callback='yes', confirm=0):
"""form to remove a field from a collection.
colID - the current collection, remove the field from this collection.
sel_ln - remove the field with this language
fldID - remove the field with this id"""
if fmeth == "soo":
field = "sort option"
elif fmeth == "sew":
field = "search field"
elif fmeth == "seo":
field = "search option"
else:
field = "field"
subtitle = """<a name="6.4"><a name="7.4"><a name="8.4"></a>Remove %s""" % field
output = ""
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
res = get_fld_value()
fldv_dict = dict(map(lambda x: (x[0], x[1]), res))
if colID and fldID:
colID = int(colID)
fldID = int(fldID)
if fldvID and fldvID != "None":
fldvID = int(fldvID)
if confirm in ["0", 0]:
text = """Do you want to remove the %s '%s' %s from the collection '%s'.""" % (field, fld_dict[fldID], (fldvID not in["", "None"] and "with value '%s'" % fldv_dict[fldvID] or ''), col_dict[colID])
output += createhiddenform(action="removefield#6.5",
text=text,
button="Confirm",
colID=colID,
fldID=fldID,
fldvID=fldvID,
fmeth=fmeth,
confirm=1)
elif confirm in ["1", 1]:
res = remove_fld(colID, fldID, fldvID)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
if fmeth == "soo":
return perform_showsortoptions(colID, ln, content=output)
elif fmeth == "sew":
return perform_showsearchfields(colID, ln, content=output)
elif fmeth == "seo":
return perform_showsearchoptions(colID, ln, content=output)
def perform_removefieldvalue(colID, ln, fldID='', fldvID='', fmeth='', callback='yes', confirm=0):
"""form to remove a field from a collection.
colID - the current collection, remove the field from this collection.
sel_ln - remove the field with this language
fldID - remove the field with this id"""
subtitle = """<a name="7.4"></a>Remove value"""
output = ""
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
res = get_fld_value()
fldv_dict = dict(map(lambda x: (x[0], x[1]), res))
if colID and fldID:
colID = int(colID)
fldID = int(fldID)
if fldvID and fldvID != "None":
fldvID = int(fldvID)
if confirm in ["0", 0]:
text = """Do you want to remove the value '%s' from the search option '%s'.""" % (fldv_dict[fldvID], fld_dict[fldID])
output += createhiddenform(action="removefieldvalue#7.4",
text=text,
button="Confirm",
colID=colID,
fldID=fldID,
fldvID=fldvID,
fmeth=fmeth,
confirm=1)
elif confirm in ["1", 1]:
res = remove_fld(colID, fldID, fldvID)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_modifyfield(colID, fldID=fldID, ln=ln, content=output)
def perform_rearrangefieldvalue(colID, fldID, ln, callback='yes', confirm=-1):
"""rearrang the fieldvalues alphabetically
colID - the collection
fldID - the field to rearrange the fieldvalue for
"""
subtitle = "Order values alphabetically"
output = ""
col_fldv = get_col_fld(colID, 'seo', fldID)
col_fldv = dict(map(lambda x: (x[1], x[0]), col_fldv))
fldv_names = get_fld_value()
fldv_names = map(lambda x: (x[0], x[1]), fldv_names)
if not col_fldv.has_key(None):
vscore = len(col_fldv)
for (fldvID, name) in fldv_names:
if col_fldv.has_key(fldvID):
run_sql("UPDATE collection_field_fieldvalue SET score_fieldvalue=%s WHERE id_collection=%s and id_field=%s and id_fieldvalue=%s" % (vscore, colID, fldID, fldvID))
vscore -= 1
output += write_outcome((1, ""))
else:
output += write_outcome((0, (0, "No values to order")))
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_modifyfield(colID, fldID, ln, content=output)
def perform_rearrangefield(colID, ln, fmeth, callback='yes', confirm=-1):
"""rearrang the fields alphabetically
colID - the collection
"""
subtitle = "Order fields alphabetically"
output = ""
col_fld = dict(map(lambda x: (x[0], x[1]), get_col_fld(colID, fmeth)))
fld_names = get_def_name('', "field")
if len(col_fld) > 0:
score = len(col_fld)
for (fldID, name) in fld_names:
if col_fld.has_key(fldID):
run_sql("UPDATE collection_field_fieldvalue SET score=%s WHERE id_collection=%s and id_field=%s" % (score, colID, fldID))
score -= 1
output += write_outcome((1, ""))
else:
output += write_outcome((0, (0, "No fields to order")))
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
if fmeth == "soo":
return perform_showsortoptions(colID, ln, content=output)
elif fmeth == "sew":
return perform_showsearchfields(colID, ln, content=output)
elif fmeth == "seo":
return perform_showsearchoptions(colID, ln, content=output)
def perform_addexistingfieldvalue(colID, fldID, fldvID=-1, ln=cdslang, callback='yes', confirm=-1):
"""form to add an existing fieldvalue to a field.
colID - the collection
fldID - the field to add the fieldvalue to
fldvID - the fieldvalue to add"""
subtitle = """</a><a name="7.4"></a>Add existing value to search option"""
output = ""
if fldvID not in [-1, "-1"] and confirm in [1, "1"]:
fldvID = int(fldvID)
ares = add_col_fld(colID, fldID, 'seo', fldvID)
colID = int(colID)
fldID = int(fldID)
lang = dict(get_languages())
res = get_def_name('', "field")
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(res)
col_fld = dict(map(lambda x: (x[0], x[1]), get_col_fld(colID, 'seo')))
fld_value = get_fld_value()
fldv_dict = dict(map(lambda x: (x[0], x[1]), fld_value))
text = """
<span class="adminlabel">Value</span>
<select name="fldvID" class="admin_w200">
<option value="-1">- Select value -</option>
"""
res = run_sql("SELECT id,name,value FROM fieldvalue ORDER BY name")
for (id, name, value) in res:
text += """<option value="%s" %s>%s - %s</option>
""" % (id, id == int(fldvID) and 'selected="selected"' or '', name, value)
text += """</select><br>"""
output += createhiddenform(action="addexistingfieldvalue#7.4",
text=text,
button="Add",
colID=colID,
fldID=fldID,
ln=ln,
confirm=1)
if fldvID not in [-1, "-1"] and confirm in [1, "1"]:
output += write_outcome(ares)
elif confirm in [1, "1"]:
output += """<b><span class="info">Select a value to add and try again.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_modifyfield(colID, fldID, ln, content=output)
def perform_addexistingfield(colID, ln, fldID=-1, fldvID=-1, fmeth='', callback='yes', confirm=-1):
"""form to add an existing field to a collection.
colID - the collection to add the field to
fldID - the field to add
sel_ln - the language of the field"""
subtitle = """<a name="6.2"></a><a name="7.2"></a><a name="8.2"></a>Add existing field to collection"""
output = ""
if fldID not in [-1, "-1"] and confirm in [1, "1"]:
fldID = int(fldID)
ares = add_col_fld(colID, fldID, fmeth, fldvID)
colID = int(colID)
lang = dict(get_languages())
res = get_def_name('', "field")
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(res)
col_fld = dict(map(lambda x: (x[0], x[1]), get_col_fld(colID, fmeth)))
fld_value = get_fld_value()
fldv_dict = dict(map(lambda x: (x[0], x[1]), fld_value))
if fldvID:
fldvID = int(fldvID)
text = """
<span class="adminlabel">Field</span>
<select name="fldID" class="admin_w200">
<option value="-1">- Select field -</option>
"""
for (id, var) in res:
if fmeth == 'seo' or (fmeth != 'seo' and not col_fld.has_key(id)):
text += """<option value="%s" %s>%s</option>
""" % (id, '', fld_dict[id])
text += """</select><br>"""
output += createhiddenform(action="addexistingfield#6.2",
text=text,
button="Add",
colID=colID,
fmeth=fmeth,
ln=ln,
confirm=1)
if fldID not in [-1, "-1"] and confirm in [1, "1"]:
output += write_outcome(ares)
elif fldID in [-1, "-1"] and confirm not in [-1, "-1"]:
output += """<b><span class="info">Select a field.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
if fmeth == "soo":
return perform_showsortoptions(colID, ln, content=output)
elif fmeth == "sew":
return perform_showsearchfields(colID, ln, content=output)
elif fmeth == "seo":
return perform_showsearchoptions(colID, ln, content=output)
def perform_showsortoptions(colID, ln, callback='yes', content='', confirm=-1):
"""show the sort fields of this collection.."""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
fld_type = get_sort_nametypes()
subtitle = """<a name="8">8. Modify sort options for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.8">?</a>]</small>""" % (col_dict[colID], weburl)
output = """<dl>
<dt>Field actions (not related to this collection)</dt>
<dd>Go to the BibIndex interface to modify the available sort options</dd>
<dt>Collection specific actions
<dd><a href="addexistingfield?colID=%s&amp;ln=%s&amp;fmeth=soo#8.2">Add sort option to collection</a></dd>
<dd><a href="rearrangefield?colID=%s&amp;ln=%s&amp;fmeth=soo#8.2">Order sort options alphabetically</a></dd>
</dl>
""" % (colID, ln, colID, ln)
header = ['', 'Sort option', 'Actions']
actions = []
cdslang = get_languages()
lang = dict(cdslang)
fld_type_list = fld_type.items()
if len(get_col_fld(colID, 'soo')) > 0:
res = get_col_fld(colID, 'soo')
i = 0
for (fldID, fldvID, stype, score, score_fieldvalue) in res:
move = """<table cellspacing="1" cellpadding="0" border="0"><tr><td>"""
if i != 0:
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfldscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;fmeth=soo&amp;rand=%s#8"><img border="0" src="%s/img/smallup.gif" title="Move up"></a>""" % (weburl, colID, ln, fldID, res[i - 1][0], random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;&nbsp;"
move += "</td><td>"
i += 1
if i != len(res):
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfldscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;fmeth=soo&amp;rand=%s#8"><img border="0" src="%s/img/smalldown.gif" title="Move down"></a>""" % (weburl, colID, ln, fldID, res[i][0], random.randint(0, 1000), weburl)
move += """</td></tr></table>"""
actions.append([move, fld_dict[int(fldID)]])
for col in [(('Remove sort option', 'removefield'),)]:
actions[-1].append('<a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s&amp;fmeth=soo#8.4">%s</a>' % (weburl, col[0][1], colID, ln, fldID, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s&amp;fmeth=soo#8.5">%s</a>' % (weburl, function, colID, ln, fldID, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No sort options exists for this collection"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_showsortoptions", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_showsearchfields(colID, ln, callback='yes', content='', confirm=-1):
"""show the search fields of this collection.."""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
fld_type = get_sort_nametypes()
subtitle = """<a name="6">6. Modify search fields for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.6">?</a>]</small>""" % (col_dict[colID], weburl)
output = """<dl>
<dt>Field actions (not related to this collection)</dt>
<dd>Go to the BibIndex interface to modify the available search fields</dd>
<dt>Collection specific actions
<dd><a href="addexistingfield?colID=%s&amp;ln=%s&amp;fmeth=sew#6.2">Add search field to collection</a></dd>
<dd><a href="rearrangefield?colID=%s&amp;ln=%s&amp;fmeth=sew#6.2">Order search fields alphabetically</a></dd>
</dl>
""" % (colID, ln, colID, ln)
header = ['', 'Search field', 'Actions']
actions = []
cdslang = get_languages()
lang = dict(cdslang)
fld_type_list = fld_type.items()
if len(get_col_fld(colID, 'sew')) > 0:
res = get_col_fld(colID, 'sew')
i = 0
for (fldID, fldvID, stype, score, score_fieldvalue) in res:
move = """<table cellspacing="1" cellpadding="0" border="0"><tr><td>"""
if i != 0:
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfldscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;fmeth=sew&amp;rand=%s#6"><img border="0" src="%s/img/smallup.gif" title="Move up"></a>""" % (weburl, colID, ln, fldID, res[i - 1][0], random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;"
move += "</td><td>"
i += 1
if i != len(res):
move += '<a href="%s/admin/websearch/websearchadmin.py/switchfldscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;fmeth=sew&amp;rand=%s#6"><img border="0" src="%s/img/smalldown.gif" title="Move down"></a>' % (weburl, colID, ln, fldID, res[i][0], random.randint(0, 1000), weburl)
move += """</td></tr></table>"""
actions.append([move, fld_dict[int(fldID)]])
for col in [(('Remove search field', 'removefield'),)]:
actions[-1].append('<a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s&amp;fmeth=sew#6.4">%s</a>' % (weburl, col[0][1], colID, ln, fldID, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s#6.5">%s</a>' % (weburl, function, colID, ln, fldID, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No search fields exists for this collection"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_showsearchfields", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_showsearchoptions(colID, ln, callback='yes', content='', confirm=-1):
"""show the sort and search options of this collection.."""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
fld_type = get_sort_nametypes()
subtitle = """<a name="7">7. Modify search options for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.7">?</a>]</small>""" % (col_dict[colID], weburl)
output = """<dl>
<dt>Field actions (not related to this collection)</dt>
<dd>Go to the BibIndex interface to modify the available search options</dd>
<dt>Collection specific actions
<dd><a href="addexistingfield?colID=%s&amp;ln=%s&amp;fmeth=seo#7.2">Add search option to collection</a></dd>
<dd><a href="rearrangefield?colID=%s&amp;ln=%s&amp;fmeth=seo#7.2">Order search options alphabetically</a></dd>
</dl>
""" % (colID, ln, colID, ln)
header = ['', 'Search option', 'Actions']
actions = []
cdslang = get_languages()
lang = dict(cdslang)
fld_type_list = fld_type.items()
fld_distinct = run_sql("SELECT distinct(id_field) FROM collection_field_fieldvalue WHERE type='seo' AND id_collection=%s ORDER by score desc" % colID)
if len(fld_distinct) > 0:
i = 0
for (id) in fld_distinct:
fldID = id[0]
col_fld = get_col_fld(colID, 'seo', fldID)
move = ""
if i != 0:
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfldscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;fmeth=seo&amp;rand=%s#7"><img border="0" src="%s/img/smallup.gif" title="Move up"></a>""" % (weburl, colID, ln, fldID, fld_distinct[i - 1][0], random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;"
i += 1
if i != len(fld_distinct):
move += '<a href="%s/admin/websearch/websearchadmin.py/switchfldscore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_2=%s&amp;fmeth=seo&amp;rand=%s#7"><img border="0" src="%s/img/smalldown.gif" title="Move down"></a>' % (weburl, colID, ln, fldID, fld_distinct[i][0], random.randint(0, 1000), weburl)
actions.append([move, "%s" % fld_dict[fldID]])
for col in [(('Modify values', 'modifyfield'), ('Remove search option', 'removefield'),)]:
actions[-1].append('<a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s#7.3">%s</a>' % (weburl, col[0][1], colID, ln, fldID, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s&amp;fmeth=seo#7.3">%s</a>' % (weburl, function, colID, ln, fldID, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No search options exists for this collection"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_showsearchoptions", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_modifyfield(colID, fldID, fldvID='', ln=cdslang, content='',callback='yes', confirm=0):
"""Modify the fieldvalues for a field"""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
fld_dict = dict(get_def_name('', "field"))
fld_type = get_sort_nametypes()
fldID = int(fldID)
subtitle = """<a name="7.3">Modify values for field '%s'</a>""" % (fld_dict[fldID])
output = """<dl>
<dt>Value specific actions
<dd><a href="addexistingfieldvalue?colID=%s&amp;ln=%s&amp;fldID=%s#7.4">Add existing value to search option</a></dd>
<dd><a href="addnewfieldvalue?colID=%s&amp;ln=%s&amp;fldID=%s#7.4">Add new value to search option</a></dd>
<dd><a href="rearrangefieldvalue?colID=%s&amp;ln=%s&amp;fldID=%s#7.4">Order values alphabetically</a></dd>
</dl>
""" % (colID, ln, fldID, colID, ln, fldID, colID, ln, fldID)
header = ['', 'Value name', 'Actions']
actions = []
cdslang = get_languages()
lang = dict(cdslang)
fld_type_list = fld_type.items()
col_fld = list(get_col_fld(colID, 'seo', fldID))
if len(col_fld) == 1 and col_fld[0][1] == None:
output += """<b><span class="info">No values added for this search option yet</span></b>"""
else:
j = 0
for (fldID, fldvID, stype, score, score_fieldvalue) in col_fld:
fieldvalue = get_fld_value(fldvID)
move = ""
if j != 0:
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfldvaluescore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_fldvalue_1=%s&amp;id_fldvalue_2=%s&amp;rand=%s#7.3"><img border="0" src="%s/img/smallup.gif" title="Move up"></a>""" % (weburl, colID, ln, fldID, fldvID, col_fld[j - 1][1], random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;"
j += 1
if j != len(col_fld):
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfldvaluescore?colID=%s&amp;ln=%s&amp;id_1=%s&amp;id_fldvalue_1=%s&amp;id_fldvalue_2=%s&amp;rand=%s#7.3"><img border="0" src="%s/img/smalldown.gif" title="Move down"></a>""" % (weburl, colID, ln, fldID, fldvID, col_fld[j][1], random.randint(0, 1000), weburl)
if fieldvalue[0][1] != fieldvalue[0][2] and fldvID != None:
actions.append([move, "%s - %s" % (fieldvalue[0][1],fieldvalue[0][2])])
elif fldvID != None:
actions.append([move, "%s" % fieldvalue[0][1]])
move = ''
for col in [(('Modify value', 'modifyfieldvalue'), ('Remove value', 'removefieldvalue'),)]:
actions[-1].append('<a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s&amp;fldvID=%s&amp;fmeth=seo#7.4">%s</a>' % (weburl, col[0][1], colID, ln, fldID, fldvID, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fldID=%s&amp;fldvID=%s#7.4">%s</a>' % (weburl, function, colID, ln, fldID, fldvID, str)
output += tupletotable(header=header, tuple=actions)
output += content
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
if len(col_fld) == 0:
output = content
return perform_showsearchoptions(colID, ln, content=output)
def perform_showoutputformats(colID, ln, callback='yes', content='', confirm=-1):
"""shows the outputformats of the current collection
colID - the collection id."""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
subtitle = """<a name="10">10. Modify output formats for collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.10">?</a>]</small>""" % (col_dict[colID], weburl)
output = """
<dl>
<dt>Output format actions (not specific to the chosen collection)
<dd>Go to the BibFormat interface to modify</dd>
<dt>Collection specific actions
<dd><a href="addexistingoutputformat?colID=%s&amp;ln=%s#10.2">Add existing output format to collection</a></dd>
</dl>
""" % (colID, ln)
header = ['', 'Code', 'Output format', 'Actions']
actions = []
col_fmt = get_col_fmt(colID)
fmt_dict = dict(get_def_name('', "format"))
i = 0
if len(col_fmt) > 0:
for (id_format, colID_fld, code, score) in col_fmt:
move = """<table cellspacing="1" cellpadding="0" border="0"><tr><td>"""
if i != 0:
move += """<a href="%s/admin/websearch/websearchadmin.py/switchfmtscore?colID=%s&amp;ln=%s&amp;type=format&amp;id_1=%s&amp;id_2=%s&amp;rand=%s#10"><img border="0" src="%s/img/smallup.gif" title="Move format up"></a>""" % (weburl, colID, ln, id_format, col_fmt[i - 1][0], random.randint(0, 1000), weburl)
else:
move += "&nbsp;&nbsp;&nbsp;"
move += "</td><td>"
i += 1
if i != len(col_fmt):
move += '<a href="%s/admin/websearch/websearchadmin.py/switchfmtscore?colID=%s&amp;ln=%s&amp;type=format&amp;id_1=%s&amp;id_2=%s&amp;rand=%s#10"><img border="0" src="%s/img/smalldown.gif" title="Move format down"></a>' % (weburl, colID, ln, id_format, col_fmt[i][0], random.randint(0, 1000), weburl)
move += """</td></tr></table>"""
actions.append([move, code, fmt_dict[int(id_format)]])
for col in [(('Remove', 'removeoutputformat'),)]:
actions[-1].append('<a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fmtID=%s#10">%s</a>' % (weburl, col[0][1], colID, ln, id_format, col[0][0]))
for (str, function) in col[1:]:
actions[-1][-1] += ' / <a href="%s/admin/websearch/websearchadmin.py/%s?colID=%s&amp;ln=%s&amp;fmtID=%s#10">%s</a>' % (weburl, function, colID, ln, id_format, str)
output += tupletotable(header=header, tuple=actions)
else:
output += """No output formats exists for this collection"""
output += content
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_showoutputformats", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_addexistingoutputformat(colID, ln, fmtID=-1, callback='yes', confirm=-1):
"""form to add an existing output format to a collection.
colID - the collection the format should be added to
fmtID - the format to add."""
subtitle = """<a name="10.2"></a>Add existing output format to collection"""
output = ""
if fmtID not in [-1, "-1"] and confirm in [1, "1"]:
ares = add_col_fmt(colID, fmtID)
colID = int(colID)
res = get_def_name('', "format")
fmt_dict = dict(res)
col_dict = dict(get_def_name('', "collection"))
col_fmt = get_col_fmt(colID)
col_fmt = dict(map(lambda x: (x[0], x[2]), col_fmt))
if len(res) > 0:
text = """
<span class="adminlabel">Output format</span>
<select name="fmtID" class="admin_w200">
<option value="-1">- Select output format -</option>
"""
for (id, name) in res:
if not col_fmt.has_key(id):
text += """<option value="%s" %s>%s</option>
""" % (id, id == int(fmtID) and 'selected="selected"' or '', name)
text += """</select><br>
"""
output += createhiddenform(action="addexistingoutputformat#10.2",
text=text,
button="Add",
colID=colID,
ln=ln,
confirm=1)
else:
output = """No existing output formats to add, please create a new one."""
if fmtID not in [-1, "-1"] and confirm in [1, "1"]:
output += write_outcome(ares)
elif fmtID in [-1, "-1"] and confirm not in [-1, "-1"]:
output += """<b><span class="info">Please select output format.</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showoutputformats(colID, ln, content=output)
def perform_deleteoutputformat(colID, ln, fmtID=-1, callback='yes', confirm=-1):
"""form to delete an output format not in use.
colID - the collection id of the current collection.
fmtID - the format id to delete."""
subtitle = """<a name="10.3"></a>Delete an unused output format"""
output = """
<dl>
<dd>Deleting an output format will also delete the translations associated.</dd>
</dl>
"""
colID = int(colID)
if fmtID not in [-1," -1"] and confirm in [1, "1"]:
fmt_dict = dict(get_def_name('', "format"))
old_colNAME = fmt_dict[int(fmtID)]
ares = delete_fmt(int(fmtID))
res = get_def_name('', "format")
fmt_dict = dict(res)
col_dict = dict(get_def_name('', "collection"))
col_fmt = get_col_fmt()
col_fmt = dict(map(lambda x: (x[0], x[2]), col_fmt))
if len(res) > 0:
text = """
<span class="adminlabel">Output format</span>
<select name="fmtID" class="admin_w200">
"""
text += """<option value="-1">- Select output format -"""
for (id, name) in res:
if not col_fmt.has_key(id):
text += """<option value="%s" %s>%s""" % (id, id == int(fmtID) and 'selected="selected"' or '', name)
text += "</option>"
text += """</select><br>"""
output += createhiddenform(action="deleteoutputformat#10.3",
text=text,
button="Delete",
colID=colID,
ln=ln,
confirm=0)
if fmtID not in [-1,"-1"]:
fmtID = int(fmtID)
if confirm in [0, "0"]:
text = """<b>Do you want to delete the output format '%s'.</b>
""" % fmt_dict[fmtID]
output += createhiddenform(action="deleteoutputformat#10.3",
text=text,
button="Confirm",
colID=colID,
fmtID=fmtID,
ln=ln,
confirm=1)
elif confirm in [1, "1"]:
output += write_outcome(ares)
elif confirm not in [-1, "-1"]:
output += """<b><span class="info">Choose a output format to delete.</span></b>
"""
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showoutputformats(colID, ln, content=output)
def perform_removeoutputformat(colID, ln, fmtID='', callback='yes', confirm=0):
"""form to remove an output format from a collection.
colID - the collection id of the current collection.
fmtID - the format id.
"""
subtitle = """<a name="10.5"></a>Remove output format"""
output = ""
col_dict = dict(get_def_name('', "collection"))
fmt_dict = dict(get_def_name('', "format"))
if colID and fmtID:
colID = int(colID)
fmtID = int(fmtID)
if confirm in ["0", 0]:
text = """Do you want to remove the output format '%s' from the collection '%s'.""" % (fmt_dict[fmtID], col_dict[colID])
output += createhiddenform(action="removeoutputformat#10.5",
text=text,
button="Confirm",
colID=colID,
fmtID=fmtID,
confirm=1)
elif confirm in ["1", 1]:
res = remove_fmt(colID, fmtID)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showoutputformats(colID, ln, content=output)
def perform_index(colID=1, ln=cdslang, mtype='', content='', confirm=0):
"""The index method, calling methods to show the collection tree, create new collections and add collections to tree.
"""
subtitle = "Overview"
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
output = ""
fin_output = ""
if not col_dict.has_key(1):
res = add_col(cdsname, '', '')
if res:
fin_output += """<b><span class="info">Created root collection.</span></b><br>"""
else:
return "Cannot create root collection, please check database."
if cdsname != run_sql("SELECT name from collection WHERE id=1")[0][0]:
res = run_sql("update collection set name='%s' where id=1" % cdsname)
if res:
fin_output += """<b><span class="info">The name of the root collection has been modified to be the same as the cdsware installation name given prior to installing cdsware.</span><b><br>"""
else:
return "Error renaming root collection."
fin_output += """
<table>
<tr>
<td>0.&nbsp;<small><a href="%s/admin/websearch/websearchadmin.py?colID=%s&amp;ln=%s&amp;mtype=perform_showall">Show all</a></small></td>
<td>1.&nbsp;<small><a href="%s/admin/websearch/websearchadmin.py?colID=%s&amp;ln=%s&amp;mtype=perform_addcollection">Create new collection</a></small></td>
<td>2.&nbsp;<small><a href="%s/admin/websearch/websearchadmin.py?colID=%s&amp;ln=%s&amp;mtype=perform_addcollectiontotree">Attach collection to tree</a></small></td>
<td>3.&nbsp;<small><a href="%s/admin/websearch/websearchadmin.py?colID=%s&amp;ln=%s&amp;mtype=perform_modifycollectiontree">Modify collection tree</a></small></td>
<td>4.&nbsp;<small><a href="%s/admin/websearch/websearchadmin.py?colID=%s&amp;ln=%s&amp;mtype=perform_checkwebcollstatus">Webcoll Status</a></small></td>
</tr><tr>
<td>5.&nbsp;<small><a href="%s/admin/websearch/websearchadmin.py?colID=%s&amp;ln=%s&amp;mtype=perform_checkcollectionstatus">Collections Status</a></small></td>
</tr>
</table>
""" % (weburl, colID, ln, weburl, colID, ln, weburl, colID, ln, weburl, colID, ln, weburl, colID, ln, weburl, colID, ln)
if mtype == "":
fin_output += """<br><br><b><span class="info">For managing the collections, select an item from the menu.</span><b><br>"""
if mtype == "perform_addcollection" and content:
fin_output += content
elif mtype == "perform_addcollection" or mtype == "perform_showall":
fin_output += perform_addcollection(colID=colID, ln=ln, callback='')
fin_output += "<br>"
if mtype == "perform_addcollectiontotree" and content:
fin_output += content
elif mtype == "perform_addcollectiontotree" or mtype == "perform_showall":
fin_output += perform_addcollectiontotree(colID=colID, ln=ln, callback='')
fin_output += "<br>"
if mtype == "perform_modifycollectiontree" and content:
fin_output += content
elif mtype == "perform_modifycollectiontree" or mtype == "perform_showall":
fin_output += perform_modifycollectiontree(colID=colID, ln=ln, callback='')
fin_output += "<br>"
if mtype == "perform_checkwebcollstatus" and content:
fin_output += content
elif mtype == "perform_checkwebcollstatus" or mtype == "perform_showall":
fin_output += perform_checkwebcollstatus(colID, ln, callback='')
if mtype == "perform_checkcollectionstatus" and content:
fin_output += content
elif mtype == "perform_checkcollectionstatus" or mtype == "perform_showall":
fin_output += perform_checkcollectionstatus(colID, ln, callback='')
try:
body = [fin_output, extra]
except NameError:
body = [fin_output]
return addadminbox('<b>Menu</b>', body)
def show_coll_not_in_tree(colID, ln, col_dict):
"""Returns collections not in tree"""
tree = get_col_tree(colID)
in_tree = {}
output = "These collections are not in the tree, and should be added:<br>"
for (id, up, down, dad, reltype) in tree:
in_tree[id] = 1
in_tree[dad] = 1
res = run_sql("SELECT id from collection")
if len(res) != len(in_tree):
for id in res:
if not in_tree.has_key(id[0]):
output += """<a href="%s/admin/websearch/websearchadmin.py/editcollection?colID=%s&amp;ln=%s" title="Edit collection">%s</a> ,
""" % (weburl, id[0], ln, col_dict[id[0]])
output += "<br><br>"
else:
output = ""
return output
def create_colltree(tree, col_dict, colID, ln, move_from='', move_to='', rtype='', edit=''):
"""Creates the presentation of the collection tree, with the buttons for modifying it.
tree - the tree to present, from get_tree()
col_dict - the name of the collections in a dictionary
colID - the collection id to start with
move_from - if a collection to be moved has been chosen
move_to - the collection which should be set as father of move_from
rtype - the type of the tree, regular or virtual
edit - if the method should output the edit buttons."""
if move_from:
move_from_rtype = move_from[0]
move_from_id = int(move_from[1:len(move_from)])
tree_from = get_col_tree(colID, move_from_rtype)
tree_to = get_col_tree(colID, rtype)
tables = 0
tstack = []
i = 0
text = """
<table border ="0" cellspacing="0" cellpadding="0">"""
for i in range(0, len(tree)):
id_son = tree[i][0]
up = tree[i][1]
down = tree[i][2]
dad = tree[i][3]
reltype = tree[i][4]
tmove_from = ""
j = i
while j > 0:
j = j - 1
try:
if tstack[j][1] == dad:
table = tstack[j][2]
for k in range(0, tables - table):
tables = tables - 1
text += """</table></td></tr>
"""
break
except StandardError, e:
pass
text += """<tr><td>
"""
if i > 0 and tree[i][1] == 0:
tables = tables + 1
text += """</td><td></td><td></td><td></td><td><table border="0" cellspacing="0" cellpadding="0"><tr><td>
"""
if i == 0:
tstack.append((id_son, dad, 1))
else:
tstack.append((id_son, dad, tables))
if up == 1 and edit:
text += """<a href="%s/admin/websearch/websearchadmin.py/modifycollectiontree?colID=%s&amp;ln=%s&amp;move_up=%s&amp;rtype=%s#%s"><img border="0" src="%s/img/smallup.gif" title="Move collection up"></a>""" % (weburl, colID, ln, i, rtype, tree[i][0], weburl)
else:
text += """&nbsp;"""
text += "</td><td>"
if down == 1 and edit:
text += """<a href="%s/admin/websearch/websearchadmin.py/modifycollectiontree?colID=%s&amp;ln=%s&amp;move_down=%s&amp;rtype=%s#%s"><img border="0" src="%s/img/smalldown.gif" title="Move collection down"></a>""" % (weburl, colID, ln, i, rtype, tree[i][0], weburl)
else:
text += """&nbsp;"""
text += "</td><td>"
if edit:
if move_from and move_to:
tmove_from = move_from
move_from = ''
if not (move_from == "" and i == 0) and not (move_from != "" and int(move_from[1:len(move_from)]) == i and rtype == move_from[0]):
check = "true"
if move_from:
#if tree_from[move_from_id][0] == tree_to[i][0] or not check_col(tree_to[i][0], tree_from[move_from_id][0]):
# check = ''
#elif not check_col(tree_to[i][0], tree_from[move_from_id][0]):
# check = ''
#if not check and (tree_to[i][0] == 1 and tree_from[move_from_id][3] == tree_to[i][0] and move_from_rtype != rtype):
# check = "true"
if check:
text += """<a href="%s/admin/websearch/websearchadmin.py/modifycollectiontree?colID=%s&amp;ln=%s&amp;move_from=%s&amp;move_to=%s%s&amp;rtype=%s#tree"><img border="0" src="%s/img/move_to.gif" title="Move '%s' to '%s'"></a>
""" % (weburl, colID, ln, move_from, rtype, i, rtype, weburl, col_dict[tree_from[int(move_from[1:len(move_from)])][0]], col_dict[tree_to[i][0]])
else:
try:
text += """<a href="%s/admin/websearch/websearchadmin.py/modifycollectiontree?colID=%s&amp;ln=%s&amp;move_from=%s%s&amp;rtype=%s#%s"><img border="0" src="%s/img/move_from.gif" title="Move '%s' from this location."></a>""" % (weburl, colID, ln, rtype, i, rtype, tree[i][0], weburl, col_dict[tree[i][0]])
except KeyError:
pass
else:
text += """<img border="0" src="%s/img/white_field.gif">
""" % weburl
else:
text += """<img border="0" src="%s/img/white_field.gif">
""" % weburl
text += """
</td>
<td>"""
if edit:
try:
text += """<a href="%s/admin/websearch/websearchadmin.py/modifycollectiontree?colID=%s&amp;ln=%s&amp;delete=%s&amp;rtype=%s#%s"><img border="0" src="%s/img/iconcross.gif" title="Remove colletion from tree"></a>""" % (weburl, colID, ln, i, rtype, tree[i][0], weburl)
except KeyError:
pass
elif i != 0:
text += """<img border="0" src="%s/img/white_field.gif">
""" % weburl
text += """</td><td>
"""
if tmove_from:
move_from = tmove_from
try:
text += """<a name="%s"></a>%s<a href="%s/admin/websearch/websearchadmin.py/editcollection?colID=%s&amp;ln=%s" title="Edit collection">%s</a>%s%s%s""" % (tree[i][0], (reltype=="v" and '<i>' or ''), weburl, tree[i][0], ln, col_dict[id_son], (move_to=="%s%s" %(rtype,i) and '&nbsp;<img border="0" src="%s/img/move_to.gif">' % weburl or ''), (move_from=="%s%s" % (rtype,i) and '&nbsp;<img border="0" src="%s/img/move_from.gif">' % weburl or ''), (reltype=="v" and '</i>' or ''))
except KeyError:
pass
text += """</td></tr>
"""
while tables > 0:
text += """</table></td></tr>
"""
tables = tables - 1
text += """</table>
"""
return text
def perform_deletecollection(colID, ln, confirm=-1, callback='yes'):
"""form to delete a collection
colID - id of collection
"""
subtitle =''
output = """
<span class="warning">
<strong>
<dl>
<dt>WARNING:</dt>
<dd>When deleting a collection, you also deletes all data related to the collection like translations, relations to other collections and information about which rank methods to use.
<br>For more information, please go to the <a title="See guide" href="%s/admin/websearch/guide.html">WebSearch guide</a> and read the section regarding deleting a collection.</dd>
</dl>
</strong>
</span>
""" % weburl
col_dict = dict(get_def_name('', "collection"))
if colID !=1 and colID and col_dict.has_key(int(colID)):
colID = int(colID)
subtitle = """<a name="4">4. Delete collection '%s'</a>&nbsp;&nbsp&nbsp;<small>[<a title="See guide" href="%s/admin/websearch/guide.html#3.4">?</a>]</small>""" % (col_dict[colID], weburl)
res = run_sql("SELECT * from collection_collection WHERE id_dad=%s" % colID)
res2 = run_sql("SELECT * from collection_collection WHERE id_son=%s" % colID)
if not res and not res2:
if confirm in ["-1", -1]:
text = """Do you want to delete this collection."""
output += createhiddenform(action="deletecollection#4",
text=text,
colID=colID,
button="Delete",
confirm=0)
elif confirm in ["0", 0]:
text = """Are you sure you want to delete this collection."""
output += createhiddenform(action="deletecollection#4",
text=text,
colID=colID,
button="Confirm",
confirm=1)
elif confirm in ["1", 1]:
result = delete_col(colID)
if not result:
raise StandardException
else:
output = """<b><span class="info">Can not delete a collection that is a part of the collection tree, remove collection from the tree and try again.</span></b>"""
else:
subtitle = """4. Delete collection"""
output = """<b><span class="info">Not possible to delete the root collection</span></b>"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_editcollection(colID, ln, "perform_deletecollection", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_editcollection(colID=1, ln=cdslang, mtype='', content=''):
"""interface to modify a collection. this method is calling other methods which again is calling this and sending back the output of the method.
if callback, the method will call perform_editcollection, if not, it will just return its output.
colID - id of the collection
mtype - the method that called this method.
content - the output from that method."""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
if not col_dict.has_key(colID):
return """<b><span class="info">Collection deleted.</span></b>
"""
fin_output = """
<table>
<tr>
<td><b>Menu</b></td>
</tr>
<tr>
<td>0.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s">Show all</a></small></td>
<td>1.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_modifydbquery">Modify collection query</a></small></td>
<td>2.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_modifyrestricted">Modify access restrictions</a></small></td>
<td>3.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_modifytranslations">Modify translations</a></small></td>
<td>4.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_deletecollection">Delete collection</a></small></td>
</tr><tr>
<td>5.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_showportalboxes">Modify portalboxes</a></small></td>
<td>6.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_showsearchfields#6">Modify search fields</a></small></td>
<td>7.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_showsearchoptions#7">Modify search options</a></small></td>
<td>8.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_showsortoptions#8">Modify sort options</a></small></td>
<td>9.&nbsp;<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_modifyrankmethods#9">Modify rank options</a></small></td>
</tr><tr>
<td>10.<small><a href="editcollection?colID=%s&amp;ln=%s&amp;mtype=perform_showoutputformats#10">Modify output formats</a></small></td>
</tr>
</table>
""" % (colID, ln, colID, ln, colID, ln, colID, ln, colID, ln, colID, ln, colID, ln, colID, ln, colID, ln, colID, ln, colID, ln)
if mtype == "perform_modifydbquery" and content:
fin_output += content
elif mtype == "perform_modifydbquery" or not mtype:
fin_output += perform_modifydbquery(colID, ln, callback='')
if mtype == "perform_modifyrestricted" and content:
fin_output += content
elif mtype == "perform_modifyrestricted" or not mtype:
fin_output += perform_modifyrestricted(colID, ln, callback='')
if mtype == "perform_modifytranslations" and content:
fin_output += content
elif mtype == "perform_modifytranslations" or not mtype:
fin_output += perform_modifytranslations(colID, ln, callback='')
if mtype == "perform_deletecollection" and content:
fin_output += content
elif mtype == "perform_deletecollection" or not mtype:
fin_output += perform_deletecollection(colID, ln, callback='')
if mtype == "perform_showportalboxes" and content:
fin_output += content
elif mtype == "perform_showportalboxes" or not mtype:
fin_output += perform_showportalboxes(colID, ln, callback='')
if mtype == "perform_showsearchfields" and content:
fin_output += content
elif mtype == "perform_showsearchfields" or not mtype:
fin_output += perform_showsearchfields(colID, ln, callback='')
if mtype == "perform_showsearchoptions" and content:
fin_output += content
elif mtype == "perform_showsearchoptions" or not mtype:
fin_output += perform_showsearchoptions(colID, ln, callback='')
if mtype == "perform_showsortoptions" and content:
fin_output += content
elif mtype == "perform_showsortoptions" or not mtype:
fin_output += perform_showsortoptions(colID, ln, callback='')
if mtype == "perform_modifyrankmethods" and content:
fin_output += content
elif mtype == "perform_modifyrankmethods" or not mtype:
fin_output += perform_modifyrankmethods(colID, ln, callback='')
if mtype == "perform_showoutputformats" and content:
fin_output += content
elif mtype == "perform_showoutputformats" or not mtype:
fin_output += perform_showoutputformats(colID, ln, callback='')
return addadminbox("Overview of edit options for collection '%s'" % col_dict[colID], [fin_output])
def perform_checkwebcollstatus(colID, ln, confirm=0, callback='yes'):
"""Check status of the collection tables with respect to the webcoll cache."""
subtitle = """<a name="11"></a>Webcoll Status&nbsp;&nbsp&nbsp;[<a href="%s/admin/websearch/guide.html#4">?</a>]""" % weburl
output = ""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
output += """<br><b>Last updates:</b><br>"""
collection_table_update_time = ""
collection_web_update_time = ""
res = run_sql("SHOW TABLE STATUS LIKE 'collection'")
if res:
collection_table_update_time = re.sub(r'\.00$', '', str(res[0][11]))
output += "Collection table last updated: %s<br>" % collection_table_update_time
try:
file = open("%s/collections/1/last-updated-ln=en.html" % cachedir)
collection_web_update_time = string.strip(file.readline())
collection_web_update_time = re.sub(r'[A-Z ]+$', '', collection_web_update_time)
output += "Collection webpage last updated: %s<br>" % collection_web_update_time
file.close()
except StandardError, e:
pass
# reformat collection_web_update_time to the format suitable for comparisons
try:
collection_web_update_time = time.strftime("%Y-%m-%d %H:%M:%S",
time.strptime(collection_web_update_time, "%d %b %Y %H:%M:%S"))
except ValueError, e:
pass
if collection_table_update_time > collection_web_update_time:
output += """<br><b><span class="info">Warning: The collections has been modified since last time Webcoll was executed, to process the changes, Webcoll must be executed.</span></b><br>"""
header = ['ID', 'Name', 'Time', 'Status', 'Progress']
actions = []
output += """<br><b>Last BibSched tasks:</b><br>"""
res = run_sql("select id, proc, host, user, runtime, sleeptime, arguments, status, progress from schTASK where proc='webcoll' and runtime< now() ORDER by runtime")
if len(res) > 0:
(id, proc, host, user, runtime, sleeptime, arguments, status, progress) = res[len(res) - 1]
webcoll__update_time = runtime
actions.append([id, proc, runtime, (status !="" and status or ''), (progress !="" and progress or '')])
else:
actions.append(['', 'webcoll', '', '', 'Not executed yet'])
res = run_sql("select id, proc, host, user, runtime, sleeptime, arguments, status, progress from schTASK where proc='bibindex' and runtime< now() ORDER by runtime")
if len(res) > 0:
(id, proc, host, user, runtime, sleeptime, arguments, status, progress) = res[len(res) - 1]
actions.append([id, proc, runtime, (status !="" and status or ''), (progress !="" and progress or '')])
else:
actions.append(['', 'bibindex', '', '', 'Not executed yet'])
output += tupletotable(header=header, tuple=actions)
output += """<br><b>Next scheduled BibSched run:</b><br>"""
actions = []
res = run_sql("select id, proc, host, user, runtime, sleeptime, arguments, status, progress from schTASK where proc='webcoll' and runtime > now() ORDER by runtime")
webcoll_future = ""
if len(res) > 0:
(id, proc, host, user, runtime, sleeptime, arguments, status, progress) = res[0]
webcoll__update_time = runtime
actions.append([id, proc, runtime, (status !="" and status or ''), (progress !="" and progress or '')])
webcoll_future = "yes"
else:
actions.append(['', 'webcoll', '', '', 'Not scheduled'])
res = run_sql("select id, proc, host, user, runtime, sleeptime, arguments, status, progress from schTASK where proc='bibindex' and runtime > now() ORDER by runtime")
bibindex_future = ""
if len(res) > 0:
(id, proc, host, user, runtime, sleeptime, arguments, status, progress) = res[0]
actions.append([id, proc, runtime, (status !="" and status or ''), (progress !="" and progress or '')])
bibindex_future = "yes"
else:
actions.append(['', 'bibindex', '', '', 'Not scheduled'])
output += tupletotable(header=header, tuple=actions)
if webcoll_future == "":
output += """<br><b><span class="info">Warning: Webcoll is not scheduled for a future run by bibsched, any updates to the collection will not be processed.</span></b><br>"""
if bibindex_future == "":
output += """<br><b><span class="info">Warning: Bibindex is not scheduled for a future run by bibsched, any updates to the records will not be processed.</span></b><br>"""
try:
body = [output, extra]
except NameError:
body = [output]
if callback:
return perform_index(colID, ln, "perform_checkwebcollstatus", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_checkcollectionstatus(colID, ln, confirm=0, callback='yes'):
"""Check the configuration of the collections."""
subtitle = """<a name="11"></a>Collections Status&nbsp;&nbsp&nbsp;[<a href="%s/admin/websearch/guide.html#5">?</a>]""" % weburl
output = ""
colID = int(colID)
col_dict = dict(get_def_name('', "collection"))
collections = run_sql("SELECT id, name, dbquery, restricted FROM collection ORDER BY id")
header = ['ID', 'Name', 'Query', 'Subcollections', 'Restricted', 'I18N','Status']
rnk_list = get_def_name('', "rnkMETHOD")
actions = []
for (id, name, dbquery, restricted) in collections:
reg_sons = len(get_col_tree(id, 'r'))
vir_sons = len(get_col_tree(id, 'v'))
status = ""
langs = run_sql("SELECT ln from collectionname where id_collection=%s" % id)
i8n = ""
if len(langs) > 0:
for lang in langs:
i8n += "%s, " % lang
else:
i8n = """<b><span class="info">None</span></b>"""
if (reg_sons > 1 and dbquery) or dbquery=="":
status = """<b><span class="warning">1:Query</span></b>"""
elif dbquery is None and reg_sons == 1:
status = """<b><span class="warning">2:Query</span></b>"""
elif dbquery == "" and reg_sons == 1:
status = """<b><span class="warning">3:Query</span></b>"""
if (reg_sons > 1 or vir_sons > 1):
subs = """<b><span class="info">Yes</span></b>"""
else:
subs = """<b><span class="info">No</span></b>"""
if dbquery is None:
dbquery = """<b><span class="info">No</span></b>"""
if restricted == "":
restricted = ""
if status:
status += """<b><span class="warning">,4:Restricted</span></b>"""
else:
status += """<b><span class="warning">4:Restricted</span></b>"""
elif restricted is None:
restricted = """<b><span class="info">No</span></b>"""
if status == "":
status = """<b><span class="info">OK</span></b>"""
actions.append([id, """<a href="%s/admin/websearch/websearchadmin.py/editcollection?colID=%s&amp;ln=%s">%s</a>""" % (weburl, id, ln, name), dbquery, subs, restricted, i8n, status])
output += tupletotable(header=header, tuple=actions)
try:
body = [output, extra]
except NameError:
body = [output]
return addadminbox(subtitle, body)
if callback:
return perform_index(colID, ln, "perform_checkcollectionstatus", addadminbox(subtitle, body))
else:
return addadminbox(subtitle, body)
def perform_removeoutputformat(colID, ln, fmtID='', callback='yes', confirm=0):
"""form to remove an output format from a collection.
colID - the collection id of the current collection.
fmtID - the format id.
"""
subtitle = """<a name="10.5"></a>Remove output format"""
output = ""
col_dict = dict(get_def_name('', "collection"))
fmt_dict = dict(get_def_name('', "format"))
if colID and fmtID:
colID = int(colID)
fmtID = int(fmtID)
if confirm in ["0", 0]:
text = """Do you want to remove the output format '%s' from the collection '%s'.""" % (fmt_dict[fmtID], col_dict[colID])
output += createhiddenform(action="removeoutputformat#10.5",
text=text,
button="Confirm",
colID=colID,
fmtID=fmtID,
confirm=1)
elif confirm in ["1", 1]:
res = remove_fmt(colID, fmtID)
output += write_outcome(res)
try:
body = [output, extra]
except NameError:
body = [output]
output = "<br>" + addadminbox(subtitle, body)
return perform_showoutputformats(colID, ln, content=output)
def get_col_tree(colID, rtype=''):
"""Returns a presentation of the tree as a list. TODO: Add loop detection
colID - startpoint for the tree
rtype - get regular or virtual part of the tree"""
try:
colID = int(colID)
stack = [colID]
ssize = 0
tree = [(colID, 0, 0, colID, 'r')]
while len(stack) > 0:
ccolID = stack.pop()
if ccolID == colID and rtype:
res = run_sql("SELECT id_son, score, type FROM collection_collection WHERE id_dad=%s AND type='%s' ORDER BY score ASC,id_son" % (ccolID,rtype))
else:
res = run_sql("SELECT id_son, score, type FROM collection_collection WHERE id_dad=%s ORDER BY score ASC,id_son" % ccolID)
ssize += 1
ntree = []
for i in range(0,len(res)):
id_son = res[i][0]
score = res[i][1]
rtype = res[i][2]
stack.append(id_son)
if i == (len(res) - 1):
up = 0
else:
up = 1
if i == 0:
down = 0
else:
down = 1
ntree.insert(0, (id_son, up, down, ccolID, rtype))
tree = tree[0:ssize] + ntree + tree[ssize:len(tree)]
return tree
except StandardError, e:
return ()
def add_col_dad_son(add_dad, add_son, rtype):
"""Add a son to a collection (dad)
add_dad - add to this collection id
add_son - add this collection id
rtype - either regular or virtual"""
try:
res = run_sql("SELECT score FROM collection_collection WHERE id_dad=%s ORDER BY score ASC" % add_dad)
highscore = 0
for score in res:
if int(score[0]) > highscore:
highscore = int(score[0])
highscore += 1
res = run_sql("INSERT INTO collection_collection(id_dad,id_son,score,type) values(%s,%s,%s,'%s')" % (add_dad, add_son, highscore, rtype))
return (1, highscore)
except StandardError, e:
return (0, e)
def compare_on_val(first, second):
"""Compare the two values"""
return cmp(first[1], second[1])
def get_col_fld(colID=-1, type = '', id_field=''):
"""Returns either all portalboxes associated with a collection, or based on either colID or language or both.
colID - collection id
ln - language id"""
sql = "SELECT id_field,id_fieldvalue,type,score,score_fieldvalue FROM collection_field_fieldvalue, field WHERE id_field=field.id"
try:
if colID > -1:
sql += " AND id_collection=%s" % colID
if id_field:
sql += " AND id_field=%s" % id_field
if type:
sql += " AND type='%s'" % type
sql += " ORDER BY type, score desc, score_fieldvalue desc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_col_pbx(colID=-1, ln='', position = ''):
"""Returns either all portalboxes associated with a collection, or based on either colID or language or both.
colID - collection id
ln - language id"""
sql = "SELECT id_portalbox, id_collection, ln, score, position, title, body FROM collection_portalbox, portalbox WHERE id_portalbox = portalbox.id"
try:
if colID > -1:
sql += " AND id_collection=%s" % colID
if ln:
sql += " AND ln='%s'" % ln
if position:
sql += " AND position='%s'" % position
sql += " ORDER BY position, ln, score desc"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_col_fmt(colID=-1):
"""Returns all formats currently associated with a collection, or for one specific collection
colID - the id of the collection"""
try:
if colID not in [-1, "-1"]:
res = run_sql("SELECT id_format, id_collection, code, score FROM collection_format, format WHERE id_format = format.id AND id_collection=%s ORDER BY score desc" % colID)
else:
res = run_sql("SELECT id_format, id_collection, code, score FROM collection_format, format WHERE id_format = format.id ORDER BY score desc")
return res
except StandardError, e:
return ""
def get_col_rnk(colID, ln):
""" Returns a list of the rank methods the given collection is attached to
colID - id from collection"""
try:
res1 = dict(run_sql("SELECT id_rnkMETHOD, '' FROM collection_rnkMETHOD WHERE id_collection=%s" % colID))
res2 = get_def_name('', "rnkMETHOD")
result = filter(lambda x: res1.has_key(x[0]), res2)
return result
except StandardError, e:
return ()
def get_pbx():
"""Returns all portalboxes"""
try:
res = run_sql("SELECT id, title, body FROM portalbox ORDER by title,body")
return res
except StandardError, e:
return ""
def get_fld_value(fldvID = ''):
"""Returns fieldvalue"""
try:
sql = "SELECT id, name, value FROM fieldvalue"
if fldvID:
sql += " WHERE id=%s" % fldvID
sql += " ORDER BY name"
res = run_sql(sql)
return res
except StandardError, e:
return ""
def get_pbx_pos():
"""Returns a list of all the positions for a portalbox"""
position = {}
position["rt"] = "Right Top"
position["lt"] = "Left Top"
position["te"] = "Title Epilog"
position["tp"] = "Title Prolog"
position["ne"] = "Narrow by coll epilog"
position["np"] = "Narrow by coll prolog"
return position
def get_sort_nametypes():
"""Return a list of the various translationnames for the fields"""
type = {}
type['soo'] = 'Sort options'
type['seo'] = 'Search options'
type['sew'] = 'Search within'
return type
def get_fmt_nametypes():
"""Return a list of the various translationnames for the output formats"""
type = []
type.append(('ln', 'Long name'))
return type
def get_fld_nametypes():
"""Return a list of the various translationnames for the fields"""
type = []
type.append(('ln', 'Long name'))
return type
def get_col_nametypes():
"""Return a list of the various translationnames for the collections"""
type = []
type.append(('ln', 'Long name'))
return type
def find_last(tree, start_son):
"""Find the previous collection in the tree with the same father as start_son"""
id_dad = tree[start_son][3]
while start_son > 0:
start_son -= 1
if tree[start_son][3] == id_dad:
return start_son
def find_next(tree, start_son):
"""Find the next collection in the tree with the same father as start_son"""
id_dad = tree[start_son][3]
while start_son < len(tree):
start_son += 1
if tree[start_son][3] == id_dad:
return start_son
def remove_col_subcol(id_son, id_dad, type):
"""Remove a collection as a son of another collection in the tree, if collection isn't used elsewhere in the tree, remove all registered sons of the id_son.
id_son - collection id of son to remove
id_dad - the id of the dad"""
try:
if id_son != id_dad:
tree = get_col_tree(id_son)
res = run_sql("DELETE FROM collection_collection WHERE id_son=%s and id_dad=%s" % (id_son, id_dad))
else:
tree = get_col_tree(id_son, type)
res = run_sql("DELETE FROM collection_collection WHERE id_son=%s and id_dad=%s and type='%s'" % (id_son, id_dad, type))
if not run_sql("SELECT * from collection_collection WHERE id_son=%s and type='%s'" % (id_son, type)):
for (id, up, down, dad, rtype) in tree:
res = run_sql("DELETE FROM collection_collection WHERE id_son=%s and id_dad=%s" % (id, dad))
return (1, "")
except StandardError, e:
return (0, e)
def check_col(add_dad, add_son):
"""Check if the collection can be placed as a son of the dad without causing loops.
add_dad - collection id
add_son - collection id"""
try:
stack = [add_dad]
res = run_sql("SELECT id_dad FROM collection_collection WHERE id_dad=%s AND id_son=%s" % (add_dad,add_son))
if res:
raise StandardError
while len(stack) > 0:
colID = stack.pop()
res = run_sql("SELECT id_dad FROM collection_collection WHERE id_son=%s" % colID)
for id in res:
if int(id[0]) == int(add_son):
raise StandardError
else:
stack.append(id[0])
return (1, "")
except StandardError, e:
return (0, e)
def attach_rnk_col(colID, rnkID):
"""attach rank method to collection
rnkID - id from rnkMETHOD table
colID - id of collection, as in collection table """
try:
res = run_sql("INSERT INTO collection_rnkMETHOD(id_collection, id_rnkMETHOD) values (%s,%s)" % (colID, rnkID))
return (1, "")
except StandardError, e:
return (0, e)
def detach_rnk_col(colID, rnkID):
"""detach rank method from collection
rnkID - id from rnkMETHOD table
colID - id of collection, as in collection table """
try:
res = run_sql("DELETE FROM collection_rnkMETHOD WHERE id_collection=%s AND id_rnkMETHOD=%s" % (colID, rnkID))
return (1, "")
except StandardError, e:
return (0, e)
def switch_col_treescore(col_1, col_2):
try:
res1 = run_sql("SELECT score FROM collection_collection WHERE id_dad=%s and id_son=%s" % (col_1[3], col_1[0]))
res2 = run_sql("SELECT score FROM collection_collection WHERE id_dad=%s and id_son=%s" % (col_2[3], col_2[0]))
res = run_sql("UPDATE collection_collection SET score=%s WHERE id_dad=%s and id_son=%s" % (res2[0][0], col_1[3], col_1[0]))
res = run_sql("UPDATE collection_collection SET score=%s WHERE id_dad=%s and id_son=%s" % (res1[0][0], col_2[3], col_2[0]))
return (1, "")
except StandardError, e:
return (0, e)
def move_col_tree(col_from, col_to, move_to_rtype=''):
"""Move a collection from one point in the tree to another. becomes a son of the endpoint.
col_from - move this collection from current point
col_to - and set it as a son of this collection.
move_to_rtype - either virtual or regular collection"""
try:
res = run_sql("SELECT score FROM collection_collection WHERE id_dad=%s ORDER BY score asc" % col_to[0])
highscore = 0
for score in res:
if int(score[0]) > highscore:
highscore = int(score[0])
highscore += 1
if not move_to_rtype:
move_to_rtype = col_from[4]
res = run_sql("DELETE FROM collection_collection WHERE id_son=%s and id_dad=%s" % (col_from[0], col_from[3]))
res = run_sql("INSERT INTO collection_collection(id_dad,id_son,score,type) values(%s,%s,%s,'%s')" % (col_to[0], col_from[0], highscore, move_to_rtype))
return (1, "")
except StandardError, e:
return (0, e)
def remove_pbx(colID, pbxID, ln):
"""Removes a portalbox from the collection given.
colID - the collection the format is connected to
pbxID - the portalbox which should be removed from the collection.
ln - the language of the portalbox to be removed"""
try:
res = run_sql("DELETE FROM collection_portalbox WHERE id_collection=%s AND id_portalbox=%s AND ln='%s'" % (colID, pbxID, ln))
return (1, "")
except StandardError, e:
return (0, e)
def remove_fmt(colID,fmtID):
"""Removes a format from the collection given.
colID - the collection the format is connected to
fmtID - the format which should be removed from the collection."""
try:
res = run_sql("DELETE FROM collection_format WHERE id_collection=%s AND id_format=%s" % (colID, fmtID))
return (1, "")
except StandardError, e:
return (0, e)
def remove_fld(colID,fldID, fldvID=''):
"""Removes a field from the collection given.
colID - the collection the format is connected to
fldID - the field which should be removed from the collection."""
try:
sql = "DELETE FROM collection_field_fieldvalue WHERE id_collection=%s AND id_field=%s" % (colID, fldID)
if fldvID:
if fldvID != "None":
sql += " AND id_fieldvalue=%s" % fldvID
else:
sql += " AND id_fieldvalue is NULL"
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def delete_fldv(fldvID):
"""Deletes all data for the given fieldvalue
fldvID - delete all data in the tables associated with fieldvalue and this id"""
try:
res = run_sql("DELETE FROM collection_field_fieldvalue WHERE id_fieldvalue=%s" % fldvID)
res = run_sql("DELETE FROM fieldvalue WHERE id=%s" % fldvID)
return (1, "")
except StandardError, e:
return (0, e)
def delete_pbx(pbxID):
"""Deletes all data for the given portalbox
pbxID - delete all data in the tables associated with portalbox and this id """
try:
res = run_sql("DELETE FROM collection_portalbox WHERE id_portalbox=%s" % pbxID)
res = run_sql("DELETE FROM portalbox WHERE id=%s" % pbxID)
return (1, "")
except StandardError, e:
return (0, e)
def delete_fmt(fmtID):
"""Deletes all data for the given format
fmtID - delete all data in the tables associated with format and this id """
try:
res = run_sql("DELETE FROM format WHERE id=%s" % fmtID)
res = run_sql("DELETE FROM collection_format WHERE id_format=%s" % fmtID)
res = run_sql("DELETE FROM formatname WHERE id_format=%s" % fmtID)
return (1, "")
except StandardError, e:
return (0, e)
def delete_col(colID):
"""Deletes all data for the given collection
colID - delete all data in the tables associated with collection and this id """
try:
res = run_sql("DELETE FROM collection WHERE id=%s" % colID)
res = run_sql("DELETE FROM collectionname WHERE id_collection=%s" % colID)
res = run_sql("DELETE FROM collection_rnkMETHOD WHERE id_collection=%s" % colID)
res = run_sql("DELETE FROM collection_collection WHERE id_dad=%s" % colID)
res = run_sql("DELETE FROM collection_collection WHERE id_son=%s" % colID)
res = run_sql("DELETE FROM collection_portalbox WHERE id_collection=%s" % colID)
res = run_sql("DELETE FROM collection_format WHERE id_collection=%s" % colID)
res = run_sql("DELETE FROM collection_field_fieldvalue WHERE id_collection=%s" % colID)
return (1, "")
except StandardError, e:
return (0, e)
def add_fmt(code, name, rtype):
"""Add a new output format. Returns the id of the format.
code - the code for the format, max 6 chars.
name - the default name for the default language of the format.
rtype - the default nametype"""
try:
res = run_sql("INSERT INTO format (code, name) values ('%s','%s')" % (MySQLdb.escape_string(code), MySQLdb.escape_string(name)))
fmtID = run_sql("SELECT id FROM format WHERE code='%s'" % MySQLdb.escape_string(code))
res = run_sql("INSERT INTO formatname(id_format, type, ln, value) VALUES (%s,'%s','%s','%s')" % (fmtID[0][0], rtype, cdslang, MySQLdb.escape_string(name)))
return (1, fmtID)
except StandardError, e:
return (0, e)
def update_fldv(fldvID, name, value):
"""Modify existing fieldvalue
fldvID - id of fieldvalue to modify
value - the value of the fieldvalue
name - the name of the fieldvalue."""
try:
res = run_sql("UPDATE fieldvalue set name='%s' where id=%s" % (MySQLdb.escape_string(name), fldvID))
res = run_sql("UPDATE fieldvalue set value='%s' where id=%s" % (MySQLdb.escape_string(value), fldvID))
return (1, "")
except StandardError, e:
return (0, e)
def add_fldv(name, value):
"""Add a new fieldvalue, returns id of fieldvalue
value - the value of the fieldvalue
name - the name of the fieldvalue."""
try:
res = run_sql("SELECT id FROM fieldvalue WHERE name='%s' and value='%s'" % (MySQLdb.escape_string(name), MySQLdb.escape_string(value)))
if not res:
res = run_sql("INSERT INTO fieldvalue (name, value) values ('%s','%s')" % (MySQLdb.escape_string(name), MySQLdb.escape_string(value)))
res = run_sql("SELECT id FROM fieldvalue WHERE name='%s' and value='%s'" % (MySQLdb.escape_string(name), MySQLdb.escape_string(value)))
if res:
return (1, res[0][0])
else:
raise StandardError
except StandardError, e:
return (0, e)
def add_pbx(title, body):
try:
res = run_sql("INSERT INTO portalbox (title, body) values ('%s','%s')" % (MySQLdb.escape_string(title), MySQLdb.escape_string(body)))
res = run_sql("SELECT id FROM portalbox WHERE title='%s' AND body='%s'" % (MySQLdb.escape_string(title), MySQLdb.escape_string(body)))
if res:
return (1, res[0][0])
else:
raise StandardError
except StandardError, e:
return (0, e)
def add_col(colNAME, dbquery, rest):
"""Adds a new collection to collection table
colNAME - the default name for the collection, saved to collection and collectionname
dbquery - query related to the collection
rest - name of apache group allowed to access collection"""
try:
rtype = get_col_nametypes()[0][0]
colID = run_sql("SELECT id FROM collection WHERE id=1")
if colID:
sql = "INSERT INTO collection(name,dbquery,restricted) VALUES('%s'" % MySQLdb.escape_string(colNAME)
else:
sql = "INSERT INTO collection(id,name,dbquery,restricted) VALUES(1,'%s'" % MySQLdb.escape_string(colNAME)
if dbquery:
sql += ",'%s'" % MySQLdb.escape_string(dbquery)
else:
sql += ",null"
if rest:
sql += ",'%s'" % MySQLdb.escape_string(rest)
else:
sql += ",null"
sql += ")"
res = run_sql(sql)
colID = run_sql("SELECT id FROM collection WHERE name='%s'" % MySQLdb.escape_string(colNAME))
res = run_sql("INSERT INTO collectionname(id_collection, type, ln, value) VALUES (%s,'%s','%s','%s')" % (colID[0][0], rtype, cdslang, MySQLdb.escape_string(colNAME)))
if colID:
return (1, colID[0][0])
else:
raise StandardError
except StandardError, e:
return (0, e)
def add_col_pbx(colID, pbxID, ln, position, score=''):
"""add a portalbox to the collection.
colID - the id of the collection involved
pbxID - the portalbox to add
ln - which language the portalbox is for
score - decides which portalbox is the most important
position - position on page the portalbox should appear."""
try:
if score:
res = run_sql("INSERT INTO collection_portalbox(id_portalbox, id_collection, ln, score, position) values (%s,%s,'%s',%s,'%s')" % (pbxID, colID, ln, score, position))
else:
res = run_sql("SELECT score FROM collection_portalbox WHERE id_collection=%s and ln='%s' and position='%s' ORDER BY score desc, ln, position" % (colID, ln, position))
if res:
score = int(res[0][0])
else:
score = 0
res = run_sql("INSERT INTO collection_portalbox(id_portalbox, id_collection, ln, score, position) values (%s,%s,'%s',%s,'%s')" % (pbxID, colID, ln, (score + 1), position))
return (1, "")
except StandardError, e:
return (0, e)
def add_col_fmt(colID, fmtID, score=''):
"""Add a output format to the collection.
colID - the id of the collection involved
fmtID - the id of the format.
score - the score of the format, decides sorting, if not given, place the format on top"""
try:
if score:
res = run_sql("INSERT INTO collection_format(id_format, id_collection, score) values (%s,%s,%s)" % (fmtID, colID, score))
else:
res = run_sql("SELECT score FROM collection_format WHERE id_collection=%s ORDER BY score desc" % colID)
if res:
score = int(res[0][0])
else:
score = 0
res = run_sql("INSERT INTO collection_format(id_format, id_collection, score) values (%s,%s,%s)" % (fmtID, colID, (score + 1)))
return (1, "")
except StandardError, e:
return (0, e)
def add_col_fld(colID, fldID, type, fldvID=''):
"""Add a sort/search/field to the collection.
colID - the id of the collection involved
fldID - the id of the field.
fldvID - the id of the fieldvalue.
type - which type, seo, sew...
score - the score of the format, decides sorting, if not given, place the format on top"""
try:
if fldvID and fldvID not in [-1, "-1"]:
run_sql("DELETE FROM collection_field_fieldvalue WHERE id_collection=%s AND id_field=%s and type='%s' and id_fieldvalue is NULL" % (colID, fldID, type))
res = run_sql("SELECT score FROM collection_field_fieldvalue WHERE id_collection=%s AND id_field=%s and type='%s' ORDER BY score desc" % (colID, fldID, type))
if res:
score = int(res[0][0])
res = run_sql("SELECT score_fieldvalue FROM collection_field_fieldvalue WHERE id_collection=%s AND id_field=%s and type='%s' ORDER BY score_fieldvalue desc" % (colID, fldID, type))
else:
res = run_sql("SELECT score FROM collection_field_fieldvalue WHERE id_collection=%s and type='%s' ORDER BY score desc" % (colID, type))
if res:
score = int(res[0][0]) + 1
else:
score = 1
res = run_sql("SELECT * FROM collection_field_fieldvalue where id_field=%s and id_collection=%s and type='%s' and id_fieldvalue=%s" % (fldID, colID, type, fldvID))
if not res:
run_sql("UPDATE collection_field_fieldvalue SET score_fieldvalue=score_fieldvalue+1 WHERE id_field=%s AND id_collection=%s and type='%s'" % (fldID, colID, type))
res = run_sql("INSERT INTO collection_field_fieldvalue(id_field, id_fieldvalue, id_collection, type, score, score_fieldvalue) values (%s,%s,%s,'%s',%s,%s)" % (fldID, fldvID, colID, type, score, 1))
else:
return (0, (1, "Already exists"))
else:
res = run_sql("SELECT * FROM collection_field_fieldvalue WHERE id_collection=%s AND type='%s' and id_field=%s and id_fieldvalue is NULL" % (colID, type, fldID))
if res:
return (0, (1, "Already exists"))
else:
run_sql("UPDATE collection_field_fieldvalue SET score=score+1")
res = run_sql("INSERT INTO collection_field_fieldvalue(id_field, id_collection, type, score,score_fieldvalue) values (%s,%s,'%s',%s, 0)" % (fldID, colID, type, 1))
return (1, "")
except StandardError, e:
return (0, e)
def modify_restricted(colID, rest):
"""Modify which apache group is allowed to use the collection.
colID - the id of the collection involved
restricted - the new group"""
try:
sql = "UPDATE collection SET restricted="
if rest:
sql += "'%s'" % MySQLdb.escape_string(rest)
else:
sql += "null"
sql += " WHERE id=%s" % colID
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def modify_dbquery(colID, dbquery):
"""Modify the dbquery of an collection.
colID - the id of the collection involved
dbquery - the new dbquery"""
try:
sql = "UPDATE collection SET dbquery="
if dbquery:
sql += "'%s'" % MySQLdb.escape_string(dbquery)
else:
sql += "null"
sql += " WHERE id=%s" % colID
res = run_sql(sql)
return (1, "")
except StandardError, e:
return (0, e)
def modify_pbx(colID, pbxID, sel_ln, score='', position='', title='', body=''):
"""Modify a portalbox
colID - the id of the collection involved
pbxID - the id of the portalbox that should be modified
sel_ln - the language of the portalbox that should be modified
title - the title
body - the content
score - if several portalboxes in one position, who should appear on top.
position - position on page"""
try:
if title:
res = run_sql("UPDATE portalbox SET title='%s' WHERE id=%s" % (MySQLdb.escape_string(title), pbxID))
if body:
res = run_sql("UPDATE portalbox SET body='%s' WHERE id=%s" % (MySQLdb.escape_string(body), pbxID))
if score:
res = run_sql("UPDATE collection_portalbox SET score='%s' WHERE id_collection=%s and id_portalbox=%s and ln='%s'" % (score, colID, pbxID, sel_ln))
if position:
res = run_sql("UPDATE collection_portalbox SET position='%s' WHERE id_collection=%s and id_portalbox=%s and ln='%s'" % (position, colID, pbxID, sel_ln))
return (1, "")
except Exception, e:
return (0, e)
def switch_fld_score(colID, id_1, id_2):
"""Switch the scores of id_1 and id_2 in collection_field_fieldvalue
colID - collection the id_1 or id_2 is connected to
id_1/id_2 - id field from tables like format..portalbox...
table - name of the table"""
try:
res1 = run_sql("SELECT score FROM collection_field_fieldvalue WHERE id_collection=%s and id_field=%s" % (colID, id_1))
res2 = run_sql("SELECT score FROM collection_field_fieldvalue WHERE id_collection=%s and id_field=%s" % (colID, id_2))
if res1[0][0] == res2[0][0]:
return (0, (1, "Cannot rearrange the selected fields, either rearrange by name or use the mySQL client to fix the problem."))
else:
res = run_sql("UPDATE collection_field_fieldvalue SET score=%s WHERE id_collection=%s and id_field=%s" % (res2[0][0], colID, id_1))
res = run_sql("UPDATE collection_field_fieldvalue SET score=%s WHERE id_collection=%s and id_field=%s" % (res1[0][0], colID, id_2))
return (1, "")
except StandardError, e:
return (0, e)
def switch_fld_value_score(colID, id_1, fldvID_1, fldvID_2):
"""Switch the scores of two field_value
colID - collection the id_1 or id_2 is connected to
id_1/id_2 - id field from tables like format..portalbox...
table - name of the table"""
try:
res1 = run_sql("SELECT score_fieldvalue FROM collection_field_fieldvalue WHERE id_collection=%s and id_field=%s and id_fieldvalue=%s" % (colID, id_1, fldvID_1))
res2 = run_sql("SELECT score_fieldvalue FROM collection_field_fieldvalue WHERE id_collection=%s and id_field=%s and id_fieldvalue=%s" % (colID, id_1, fldvID_2))
if res1[0][0] == res2[0][0]:
return (0, (1, "Cannot rearrange the selected fields, either rearrange by name or use the mySQL client to fix the problem."))
else:
res = run_sql("UPDATE collection_field_fieldvalue SET score_fieldvalue=%s WHERE id_collection=%s and id_field=%s and id_fieldvalue=%s" % (res2[0][0], colID, id_1, fldvID_1))
res = run_sql("UPDATE collection_field_fieldvalue SET score_fieldvalue=%s WHERE id_collection=%s and id_field=%s and id_fieldvalue=%s" % (res1[0][0], colID, id_1, fldvID_2))
return (1, "")
except Exception, e:
return (0, e)
def switch_pbx_score(colID, id_1, id_2, sel_ln):
"""Switch the scores of id_1 and id_2 in the table given by the argument.
colID - collection the id_1 or id_2 is connected to
id_1/id_2 - id field from tables like format..portalbox...
table - name of the table"""
try:
res1 = run_sql("SELECT score FROM collection_portalbox WHERE id_collection=%s and id_portalbox=%s and ln='%s'" % (colID, id_1, sel_ln))
res2 = run_sql("SELECT score FROM collection_portalbox WHERE id_collection=%s and id_portalbox=%s and ln='%s'" % (colID, id_2, sel_ln))
if res1[0][0] == res2[0][0]:
return (0, (1, "Cannot rearrange the selected fields, either rearrange by name or use the mySQL client to fix the problem."))
res = run_sql("UPDATE collection_portalbox SET score=%s WHERE id_collection=%s and id_portalbox=%s and ln='%s'" % (res2[0][0], colID, id_1, sel_ln))
res = run_sql("UPDATE collection_portalbox SET score=%s WHERE id_collection=%s and id_portalbox=%s and ln='%s'" % (res1[0][0], colID, id_2, sel_ln))
return (1, "")
except Exception, e:
return (0, e)
def switch_score(colID, id_1, id_2, table):
"""Switch the scores of id_1 and id_2 in the table given by the argument.
colID - collection the id_1 or id_2 is connected to
id_1/id_2 - id field from tables like format..portalbox...
table - name of the table"""
try:
res1 = run_sql("SELECT score FROM collection_%s WHERE id_collection=%s and id_%s=%s" % (table, colID, table, id_1))
res2 = run_sql("SELECT score FROM collection_%s WHERE id_collection=%s and id_%s=%s" % (table, colID, table, id_2))
if res1[0][0] == res2[0][0]:
return (0, (1, "Cannot rearrange the selected fields, either rearrange by name or use the mySQL client to fix the problem."))
res = run_sql("UPDATE collection_%s SET score=%s WHERE id_collection=%s and id_%s=%s" % (table, res2[0][0], colID, table, id_1))
res = run_sql("UPDATE collection_%s SET score=%s WHERE id_collection=%s and id_%s=%s" % (table, res1[0][0], colID, table, id_2))
return (1, "")
except Exception, e:
return (0, e)
diff --git a/modules/websearch/web/Makefile.am b/modules/websearch/web/Makefile.am
index f54b2cf0c..695b3db77 100644
--- a/modules/websearch/web/Makefile.am
+++ b/modules/websearch/web/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
webappdir = $(WEBDIR)
webapp_DATA = search.py index.py
EXTRA_DIST = $(webapp_DATA)
CLEANFILES = *~ *.tmp search.pyc
diff --git a/modules/websearch/web/admin/Makefile.am b/modules/websearch/web/admin/Makefile.am
index 8e2982278..302b0e5ab 100644
--- a/modules/websearch/web/admin/Makefile.am
+++ b/modules/websearch/web/admin/Makefile.am
@@ -1,26 +1,26 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/websearch
webapp_DATA = websearchadmin.py
EXTRA_DIST = websearchadmin.py
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/websearch/web/admin/websearchadmin.py b/modules/websearch/web/admin/websearchadmin.py
index 75ff684e5..af9b15c27 100644
--- a/modules/websearch/web/admin/websearchadmin.py
+++ b/modules/websearch/web/admin/websearchadmin.py
@@ -1,1054 +1,1054 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware WebSearch Administrator Interface."""
__lastupdated__ = """$Date$"""
import sys
import cdsware.websearchadminlib as wsc
#reload(wsc)
from cdsware.webpage import page, create_error_box
from cdsware.config import weburl,cdslang
from cdsware.webuser import getUid, page_not_authorized
from cdsware.messages import gettext_set_language
__version__ = "$Id$"
def switchfmtscore(req, colID, type, id_1, id_2, ln=cdslang):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_switchfmtscore(colID=colID,
ln=ln,
type=type,
id_1=id_1,
id_2=id_2),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def switchfldscore(req, colID, id_1, id_2, fmeth, ln=cdslang):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_switchfldscore(colID=colID,
ln=ln,
id_1=id_1,
id_2=id_2,
fmeth=fmeth),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def switchfldvaluescore(req, colID, id_1, id_fldvalue_1, id_fldvalue_2, ln=cdslang):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_switchfldvaluescore(colID=colID,
ln=ln,
id_1=id_1,
id_fldvalue_1=id_fldvalue_1,
id_fldvalue_2=id_fldvalue_2),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def runwebcoll(req, colID, ln=cdslang, confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Collection Management",
body=wsc.perform_checkwebcollstatus(colID=colID,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def switchpbxscore(req, colID, id_1, id_2, sel_ln,ln=cdslang):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_switchpbxscore(colID=colID,
ln=ln,
id_1=id_1,
id_2=id_2,
sel_ln=sel_ln),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifydbquery(req, colID, ln=cdslang, dbquery='', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifydbquery(colID=colID,
ln=ln,
dbquery=dbquery,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showtree(req, colID, ln=cdslang):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Collection tree",
body=wsc.perform_showtree(colID=colID,
ln=ln),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyrestricted(req, colID, ln=cdslang, rest='', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifyrestricted(colID=colID,
ln=ln,
rest=rest,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifytranslations(req, colID, ln=cdslang, sel_type='', trans = [], confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifytranslations(colID=colID,
ln=ln,
sel_type=sel_type,
trans=trans,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addcollectiontotree(req, colID, ln=cdslang, add_dad='', add_son='', rtype='', mtype='', callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Collection Management",
body=wsc.perform_addcollectiontotree(colID=colID,
ln=cdslang,
add_dad=add_dad,
add_son=add_son,
rtype=rtype,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addcollection(req, colID, ln=cdslang, colNAME='', dbquery='', rest='', callback="yes", confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Collection Management",
body=wsc.perform_addcollection(colID=colID,
ln=cdslang,
colNAME=colNAME,
dbquery=dbquery,
rest=rest,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyrankmethods(req, colID, ln=cdslang, func='', rnkID='', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifyrankmethods(colID=colID,
ln=ln,
func=func,
rnkID=rnkID,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def deletecollection(req, colID, ln=cdslang, confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_deletecollection(colID=colID,
ln=ln,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def editcollection(req, colID=1, ln=cdslang, mtype=''):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_editcollection(colID=colID,
ln=ln,
mtype=mtype),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addoutputformat(req, colID, ln=cdslang, code='', name='', callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addoutputformat(colID=colID,
ln=ln,
code=code,
name=name,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showoutputformats(req, colID, ln=cdslang, callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_showoutputformats(colID=colID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addexistingoutputformat(req, colID, ln=cdslang, fmtID=-1, callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addexistingoutputformat(colID=colID,
ln=ln,
fmtID=fmtID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def deleteoutputformat(req, colID, ln=cdslang, fmtID=-1, callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_deleteoutputformat(colID=colID,
ln=ln,
fmtID=fmtID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def removeoutputformat(req, colID, ln=cdslang, fmtID='', callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_removeoutputformat(colID=colID,
ln=ln,
fmtID=fmtID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def removefieldvalue(req, colID, ln=cdslang, fldID='', fldvID='', fmeth='', callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_removefieldvalue(colID=colID,
ln=ln,
fldID=fldID,
fldvID=fldvID,
fmeth=fmeth,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def removefield(req, colID, ln=cdslang, fldID='', fldvID='', fmeth='', callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_removefield(colID=colID,
ln=ln,
fldID=fldID,
fldvID=fldvID,
fmeth=fmeth,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyfield(req, colID, fldID, fldvID='', ln=cdslang, callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifyfield(colID=colID,
fldID=fldID,
fldvID=fldvID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyoutputformat(req, colID, ln=cdslang, fmtID=-1, sel_type='', trans=[], confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifyoutputformat(colID=colID,
ln=ln,
fmtID=fmtID,
sel_type=sel_type,
trans=trans,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showsearchoptions(req, colID, ln=cdslang, callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_showsearchoptions(colID=colID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addexistingfield(req, colID, ln=cdslang, fldID=-1, fldvID=-1, fmeth='', callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addexistingfield(colID=colID,
ln=ln,
fldID=fldID,
fldvID=fldvID,
fmeth=fmeth,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page(title='Authorization failure',
uid=uid,
body=wsc.adderrorbox('try to login first',
datalist=["""You are not a user authorized to perform admin tasks, try to
<a href="%s/youraccount.py/login?referer=%s/admin/websearch/">login</a> with another account.""" % (weburl, weburl)]),
navtrail= navtrail_previous_links,
lastupdated=__lastupdated__)
def rearrangefield(req, colID, ln=cdslang, fmeth='', callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_rearrangefield(colID=colID,
ln=ln,
fmeth=fmeth,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page(title='Authorization failure',
uid=uid,
body=wsc.adderrorbox('try to login first',
datalist=["""You are not a user authorized to perform admin tasks, try to
<a href="%s/youraccount.py/login?referer=%s/admin/websearch/">login</a> with another account.""" % (weburl, weburl)]),
navtrail= navtrail_previous_links,
lastupdated=__lastupdated__)
def addexistingfieldvalue(req, colID, fldID, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addexistingfieldvalue(colID=colID,
ln=ln,
fldID=fldID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page(title='Authorization failure',
uid=uid,
body=wsc.adderrorbox('try to login first',
datalist=["""You are not a user authorized to perform admin tasks, try to
<a href="%s/youraccount.py/login?referer=%s/admin/websearch/">login</a> with another account.""" % (weburl, weburl)]),
navtrail= navtrail_previous_links,
lastupdated=__lastupdated__)
def rearrangefieldvalue(req, colID, fldID, ln=cdslang, callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_rearrangefieldvalue(colID=colID,
ln=ln,
fldID=fldID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page(title='Authorization failure',
uid=uid,
body=wsc.adderrorbox('try to login first',
datalist=["""You are not a user authorized to perform admin tasks, try to
<a href="%s/youraccount.py/login?referer=%s/admin/websearch/">login</a> with another account.""" % (weburl, weburl)]),
navtrail= navtrail_previous_links,
lastupdated=__lastupdated__)
def addnewfieldvalue(req, colID, fldID, ln=cdslang, name='', value='', callback="yes", confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addnewfieldvalue(colID=colID,
fldID=fldID,
ln=cdslang,
name=name,
value=value,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyfieldvalue(req, colID, fldID, fldvID, ln=cdslang, name='', value='', callback="yes", confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifyfieldvalue(colID=colID,
fldID=fldID,
fldvID=fldvID,
ln=cdslang,
name=name,
value=value,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
navtrail = navtrail_previous_links,
urlargs=req.args,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showsearchfields(req, colID, ln=cdslang, callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_showsearchfields(colID=colID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showsortoptions(req, colID, ln=cdslang, callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_showsortoptions(colID=colID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifyportalbox(req, colID, ln=cdslang, pbxID=-1, score='', position='', sel_ln='', title='', body='', callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_modifyportalbox(colID=colID,
ln=ln,
pbxID=pbxID,
score=score,
position=position,
sel_ln=sel_ln,
title=title,
body=body,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def removeportalbox(req, colID, ln=cdslang, pbxID='', sel_ln='', callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_removeportalbox(colID=colID,
ln=ln,
pbxID=pbxID,
sel_ln=sel_ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addexistingportalbox(req, colID, ln=cdslang, pbxID=-1, score=0, position='', sel_ln='', callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addexistingportalbox(colID=colID,
ln=ln,
pbxID=pbxID,
score=score,
position=position,
sel_ln=sel_ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page(title='Authorization failure',
uid=uid,
body=wsc.adderrorbox('try to login first',
datalist=["""You are not a user authorized to perform admin tasks, try to
<a href="%s/youraccount.py/login?referer=%s/admin/websearch/">login</a> with another account.""" % (weburl, weburl)]),
navtrail= navtrail_previous_links,
lastupdated=__lastupdated__)
def deleteportalbox(req, colID, ln=cdslang, pbxID=-1, callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_deleteportalbox(colID=colID,
ln=ln,
pbxID=pbxID,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def showportalboxes(req, colID, ln=cdslang, callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_showportalboxes(colID=colID,
ln=ln,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def addportalbox(req, colID, ln=cdslang, title='', body='', callback='yes', confirm=-1):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Edit Collection",
body=wsc.perform_addportalbox(colID=colID,
ln=ln,
title=title,
body=body,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def modifycollectiontree(req, colID, ln=cdslang, move_up='', move_down='', move_from='', move_to='', delete='', rtype='', callback='yes', confirm=0):
navtrail_previous_links = wsc.getnavtrail() + """&gt; <a class=navtrail href="%s/admin/websearch/websearchadmin.py/">Collection Management</a> """ % (weburl)
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Collection Management",
body=wsc.perform_modifycollectiontree(colID=colID,
ln=ln,
move_up=move_up,
move_down=move_down,
move_from=move_from,
move_to=move_to,
delete=delete,
rtype=rtype,
callback=callback,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def index(req, colID=1, ln=cdslang, mtype='', content='', confirm=0):
navtrail_previous_links = wsc.getnavtrail()
try:
uid = getUid(req)
except MySQLdb.Error, e:
return error_page(req)
auth = wsc.check_user(uid,'cfgwebsearch')
if not auth[0]:
return page(title="Collection Management",
body=wsc.perform_index(colID=colID,
ln=ln,
mtype=mtype,
content=content,
confirm=confirm),
uid=uid,
language=ln,
urlargs=req.args,
navtrail = navtrail_previous_links,
lastupdated=__lastupdated__)
else:
return page_not_authorized(req=req, text=auth[1], navtrail=navtrail_previous_links)
def error_page(req, ln = cdslang):
_ = gettext_set_language(ln)
return page(title=_("Internal Error"),
body = create_error_box(req, verbose=verbose, ln=ln),
description="%s - Internal Error" % cdsname,
keywords="%s, CDSware, Internal Error" % cdsname,
language=ln,
urlargs=req.args)
diff --git a/modules/websearch/web/index.py b/modules/websearch/web/index.py
index fd2b8ec5e..8b189fb28 100644
--- a/modules/websearch/web/index.py
+++ b/modules/websearch/web/index.py
@@ -1,129 +1,129 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import sys
import sre
import MySQLdb
from cdsware.config import weburl,cdsname,cdslang,cachedir,cdsnameintl
def index(req, c=cdsname, as="0", verbose="1", ln=cdslang):
"Display search interface page for collection c by looking in the collection cache."
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, page_not_authorized
from cdsware.messages import wash_language, gettext_set_language
from cdsware.search_engine import get_colID, get_coll_i18nname
# wash params:
try:
as = int(as)
except:
as = 0
try:
verbose = int(verbose)
except:
verbose = 1
if type(c) is list:
c = c[0]
ln = wash_language(ln)
_ = gettext_set_language(ln)
# get user ID:
try:
uid = getUid(req)
if uid == -1:
return page_not_authorized(req, "../")
except MySQLdb.Error, e:
return page(title=_("Internal Error"),
body = create_error_box(req, verbose=verbose, ln=ln),
description="%s - Internal Error" % cdsname,
keywords="%s, CDSware, Internal Error" % cdsname,
language=ln,
urlargs=req.args)
# start display:
req.content_type = "text/html"
req.send_http_header()
# deduce collection id:
colID = get_colID(c)
if type(colID) is not int:
return page(title=_("Collection %s Not Found") % c,
body=_("<p>Sorry, collection <strong>%s</strong> does not seem to exist. "
"<p>You may want to start browsing from <a href=\"%s\">%s</a>.") % (c, "%s?ln=%s" % (weburl, ln), cdsnameintl[ln]),
description="%s - Not found: %s " % (cdsname, c),
keywords="%s, CDSware" % cdsname,
uid=uid,
language=ln,
urlargs=req.args)
# display collection interface page:
try:
fp = open("%s/collections/%d/navtrail-as=%d-ln=%s.html" % (cachedir, colID, as, ln), "r")
c_navtrail = fp.read()
fp.close()
fp = open("%s/collections/%d/body-as=%d-ln=%s.html" % (cachedir, colID, as, ln), "r")
c_body = fp.read()
fp.close()
fp = open("%s/collections/%d/portalbox-tp-ln=%s.html" % (cachedir, colID, ln), "r")
c_portalbox_tp = fp.read()
fp.close()
fp = open("%s/collections/%d/portalbox-te-ln=%s.html" % (cachedir, colID, ln), "r")
c_portalbox_te = fp.read()
fp.close()
fp = open("%s/collections/%d/portalbox-lt-ln=%s.html" % (cachedir, colID, ln), "r")
c_portalbox_lt = fp.read()
fp.close()
fp = open("%s/collections/%d/portalbox-rt-ln=%s.html" % (cachedir, colID, ln), "r")
c_portalbox_rt = fp.read()
fp.close()
fp = open("%s/collections/%d/last-updated-ln=%s.html" % (cachedir, colID, ln), "r")
c_last_updated = fp.read()
fp.close()
if c == cdsname:
title = cdsnameintl[ln]
else:
title = get_coll_i18nname(c, ln)
return page(title=title,
body=c_body,
navtrail=c_navtrail,
description="%s - %s" % (cdsname, c),
keywords="%s, CDSware, %s" % (cdsname, c),
uid=uid,
language=ln,
urlargs=req.args,
cdspageboxlefttopadd=c_portalbox_lt,
cdspageboxrighttopadd=c_portalbox_rt,
titleprologue=c_portalbox_tp,
titleepilogue=c_portalbox_te,
lastupdated=c_last_updated)
except:
if verbose >= 9:
req.write("<br>c=%s" % c)
req.write("<br>as=%s" % as)
req.write("<br>ln=%s" % ln)
req.write("<br>colID=%s" % colID)
req.write("<br>uid=%s" % uid)
return page(title=_("Internal Error"),
body = create_error_box(req, ln=ln),
description="%s - Internal Error" % cdsname,
keywords="%s, CDSware, Internal Error" % cdsname,
uid=uid,
language=ln,
urlargs=req.args)
return "\n"
diff --git a/modules/websearch/web/search.py b/modules/websearch/web/search.py
index cfac24180..7c538ea89 100644
--- a/modules/websearch/web/search.py
+++ b/modules/websearch/web/search.py
@@ -1,120 +1,120 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Search Engine Web Interface."""
import sys
from mod_python import apache
from cdsware.config import weburl,cdsname,cdslang
from cdsware import search_engine
from cdsware.webuser import getUid, page_not_authorized
__version__ = "$Id$"
def index(req, cc=cdsname, c=None, p="", f="", rg="10", sf="", so="d", sp="", rm="", of="hb", ot="", as="0",
p1="", f1="", m1="", op1="", p2="", f2="", m2="", op2="", p3="", f3="", m3="", sc="0", jrec="0",
recid="-1", recidb="-1", sysno="", id="-1", idb="-1", sysnb="", action="",
d1y="0", d1m="0", d1d="0", d2y="0", d2m="0", d2d="0", verbose="0", ap="1", ln=cdslang):
"""Main entry point to WebSearch search engine. See the docstring
of search_engine.perform_request_search for the detailed
explanation of arguments.
"""
uid = getUid(req)
if uid == -1:
return page_not_authorized(req, "../search.py")
need_authentication = 0
# check c
if type(c) is list:
for coll in c:
if search_engine.coll_restricted_p(coll):
need_authentication = 1
else:
pass
elif search_engine.coll_restricted_p(c):
need_authentication = 1
# check cc
if type(cc) is list:
for coll in cc:
if search_engine.coll_restricted_p(coll):
need_authentication = 1
else:
pass
elif search_engine.coll_restricted_p(cc):
need_authentication = 1
# is authentication needed?
if need_authentication:
req.err_headers_out.add("Location", "%s/search.py/authenticate?%s" % (weburl, req.args))
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
else:
return search_engine.perform_request_search(req, cc, c, p, f, rg, sf, so, sp, rm, of, ot, as,
p1, f1, m1, op1, p2, f2, m2, op2, p3, f3, m3, sc, jrec,
recid, recidb, sysno, id, idb, sysnb, action,
d1y, d1m, d1d, d2y, d2m, d2d, verbose, ap, ln)
def authenticate(req, cc=cdsname, c=None, p="", f="", rg="10", sf="", so="d", sp="", rm="", of="hb", ot="", as="0",
p1="", f1="", m1="", op1="", p2="", f2="", m2="", op2="", p3="", f3="", m3="", sc="0", jrec="0",
recid="-1", recidb="-1", sysno="", id="-1", idb="-1", sysnb="", action="",
d1y="0", d1m="0", d1d="0", d2y="0", d2m="0", d2d="0", verbose="0", ap="1", ln=cdslang):
"""Authenticate the user before launching the search. See the
docstring of search_engine.perform_request_search for the
detailed explanation of arguments.
"""
__auth_realm__ = "restricted collection"
def __auth__(req, user, password):
"""Is user authorized to proceed with the request?"""
import sys
from cdsware.config import cdsname
from cdsware.webuser import auth_apache_user_collection_p
from cgi import parse_qs
# let's parse collection list from given URL request:
parsed_args = parse_qs(req.args)
l_cc = parsed_args.get('cc', [cdsname])
l_c = parsed_args.get('c', [])
# let's check user authentication for each collection:
for coll in l_c + l_cc:
if not auth_apache_user_collection_p(user, password, coll):
return 0
return 1
return search_engine.perform_request_search(req, cc, c, p, f, rg, sf, so, sp, rm, of, ot, as,
p1, f1, m1, op1, p2, f2, m2, op2, p3, f3, m3, sc, jrec,
recid, recidb, sysno, id, idb, sysnb, action,
d1y, d1m, d1d, d2y, d2m, d2d, verbose, ap, ln)
def cache(req, action="show"):
"""Manipulates the search engine cache."""
return search_engine.perform_request_cache(req, action)
def log(req, date=""):
"""Display search log information for given date."""
return search_engine.perform_request_log(req, date)
def test(req):
import cgi
req.content_type = "text/plain"
req.send_http_header()
args = cgi.parse_qs(req.args)
req.write("BEG\n")
req.write("%s\n" % args.get('c'))
req.write("END\n")
return "\n"
diff --git a/modules/websession/Makefile.am b/modules/websession/Makefile.am
index f182b89da..dd77afe9d 100644
--- a/modules/websession/Makefile.am
+++ b/modules/websession/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc lib web
CLEANFILES = *~
diff --git a/modules/websession/bin/Makefile.am b/modules/websession/bin/Makefile.am
index c7c8e7498..ed978d539 100644
--- a/modules/websession/bin/Makefile.am
+++ b/modules/websession/bin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS=sessiongc
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(bin_SCRIPTS) *~ *.tmp sessiongcc
%: %.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdswmllib.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
chmod u+x $@
\ No newline at end of file
diff --git a/modules/websession/bin/sessiongc.wml b/modules/websession/bin/sessiongc.wml
index 893636136..a2067e954 100644
--- a/modules/websession/bin/sessiongc.wml
+++ b/modules/websession/bin/sessiongc.wml
@@ -1,388 +1,388 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
#include "cdswmllib.wml"
## start Python:
<protect>#!</protect><PYTHON>
<protect># -*- coding: utf-8 -*-</protect>
<protect>## $Id$</protect>
<protect>## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.</protect>
"""
Guest user sessions garbage collector. To be run via cron once per day. (say)
"""
__version__ = "<: print generate_pretty_version_string('$Id$'); :>"
## okay, rest of the Python code goes below
#######
import sys
try:
import getopt
import time
except ImportError, e:
print "Error: %s" % (e, )
sys.exit(1)
# configure variables
cfg_mysql_argumentlist_size = 100
def guest_user_garbage_collector(verbose=1):
"""Session Garbage Collector
program flow/tasks:
1: delete expired sessions
1b:delete guest users without session
2: delete queries not attached to any user
3: delete baskets not attached to any user
4: delete alerts not attached to any user
verbose - level of program output.
0 - nothing
1 - default
9 - max, debug"""
# dictionary used to keep track of number of deleted entries
delcount = {'session': 0,
'user': 0,
'user_query': 0,
'query': 0,
'basket': 0,
'user_basket': 0,
'user_query_basket': 0}
if verbose: print """\nGUEST USER SESSIONS GARBAGE COLLECTOR STARTED: %s.\n""" % (time.ctime(), )
# 1 - DELETE EXPIRED SESSIONS
if verbose: print "- deleting expired sessions"
timelimit = time.time()
if verbose >= 9: print """ DELETE FROM session WHERE session_expiry < %d \n""" % (timelimit, )
delcount['session'] += run_sql("""DELETE FROM session WHERE session_expiry < %s """ % (timelimit, ))
# 1b - DELETE GUEST USERS WITHOUT SESSION
if verbose: print "- deleting guest users without session"
# get uids
if verbose >= 9: print """ SELECT u.id\n FROM user AS u LEFT JOIN session AS s\n ON u.id = s.uid\n WHERE s.uid IS NULL AND u.email = ''"""
result = run_sql("""SELECT u.id
FROM user AS u LEFT JOIN session AS s
ON u.id = s.uid
WHERE s.uid IS NULL AND u.email = ''""")
if verbose >= 9: print result
if result:
# work on slices of result list in case of big result
for i in range(0, len(result), cfg_mysql_argumentlist_size):
# create string of uids
uidstr = ''
for (id_user, ) in result[i:i+cfg_mysql_argumentlist_size]:
if uidstr: uidstr += ','
uidstr += "%s" % (id_user, )
# delete users
if verbose >= 9: print """ DELETE FROM user WHERE id IN (TRAVERSE LAST RESULT) AND email = '' \n"""
delcount['user'] += run_sql("""DELETE FROM user WHERE id IN (%s) AND email = ''""" % (uidstr, ))
# 2 - DELETE QUERIES NOT ATTACHED TO ANY USER
# first step, delete from user_query
if verbose: print "- deleting user_queries referencing non-existent users"
# find user_queries referencing non-existent users
if verbose >= 9: print """ SELECT DISTINCT uq.id_user\n FROM user_query AS uq LEFT JOIN user AS u\n ON uq.id_user = u.id\n WHERE u.id IS NULL"""
result = run_sql("""SELECT DISTINCT uq.id_user
FROM user_query AS uq LEFT JOIN user AS u
ON uq.id_user = u.id
WHERE u.id IS NULL""")
if verbose >= 9: print result
# delete in user_query one by one
if verbose >= 9: print """ DELETE FROM user_query WHERE id_user = 'TRAVERSE LAST RESULT' \n"""
for (id_user, ) in result:
delcount['user_query'] += run_sql("""DELETE FROM user_query WHERE id_user = %s""" % (id_user, ))
# delete the actual queries
if verbose: print "- deleting queries not attached to any user"
# select queries that must be deleted
if verbose >= 9: print """ SELECT DISTINCT q.id\n FROM query AS q LEFT JOIN user_query AS uq\n ON uq.id_query = q.id\n WHERE uq.id_query IS NULL AND\n q.type <> 'p' """
result = run_sql("""SELECT DISTINCT q.id
FROM query AS q LEFT JOIN user_query AS uq
ON uq.id_query = q.id
WHERE uq.id_query IS NULL AND
q.type <> 'p'""")
if verbose >= 9: print result
# delete queries one by one
if verbose >= 9: print """ DELETE FROM query WHERE id = 'TRAVERSE LAST RESULT \n"""
for (id_user, ) in result:
delcount['query'] += run_sql("""DELETE FROM query WHERE id = %s""" % (id_user, ))
# 3 - DELETE BASKETS NOT OWNED BY ANY USER
if verbose: print "- deleting baskets not owned by any user"
# select basket ids
if verbose >= 9: print """ SELECT ub.id_basket\n FROM user_basket AS ub LEFT JOIN user AS u\n ON u.id = ub.id_user\n WHERE u.id IS NULL"""
result = run_sql("""SELECT ub.id_basket
FROM user_basket AS ub LEFT JOIN user AS u
ON u.id = ub.id_user
WHERE u.id IS NULL""")
if verbose >= 9: print result
# delete from user_basket and basket one by one
if verbose >= 9:
print """ DELETE FROM user_basket WHERE id_basket = 'TRAVERSE LAST RESULT' """
print """ DELETE FROM basket WHERE id = 'TRAVERSE LAST RESULT' \n"""
for (id_basket, ) in result:
delcount['user_basket'] += run_sql("""DELETE FROM user_basket WHERE id_basket = %s""" % (id_basket, ))
delcount['basket'] += run_sql("""DELETE FROM basket WHERE id = %s""" % (id_basket, ))
# 4 - DELETE ALERTS NOT OWNED BY ANY USER
if verbose: print '- deleting alerts not owned by any user'
# select user ids in uqb that reference non-existent users
if verbose >= 9: print """SELECT DISTINCT uqb.id_user FROM user_query_basket AS uqb LEFT JOIN user AS u ON uqb.id_user = u.id WHERE u.id IS NULL"""
result = run_sql("""SELECT DISTINCT uqb.id_user FROM user_query_basket AS uqb LEFT JOIN user AS u ON uqb.id_user = u.id WHERE u.id IS NULL""")
if verbose >= 9: print result
# delete all these entries
for (id_user, ) in result:
if verbose >= 9: print """DELETE FROM user_query_basket WHERE id_user = 'TRAVERSE LAST RESULT """
delcount['user_query_basket'] += run_sql("""DELETE FROM user_query_basket WHERE id_user = %s """ % (id_user, ))
# PRINT STATISTICS
if verbose:
print """\nSTATISTICS - DELETED DATA: """
print """- %7s sessions.""" % (delcount['session'], )
print """- %7s users.""" % (delcount['user'], )
print """- %7s user_queries.""" % (delcount['user_query'], )
print """- %7s queries.""" % (delcount['query'], )
print """- %7s baskets.""" % (delcount['basket'], )
print """- %7s user_baskets.""" % (delcount['user_basket'], )
print """- %7s user_query_baskets.""" % (delcount['user_query_basket'], )
print """\nGUEST USER SESSIONS GARBAGE COLLECTOR FINISHED: %s. """ % (time.ctime(), )
print """\nEXECUTION LASTED %.2f SECONDS.\n""" % (time.time() - timelimit, )
return
def usage(exitcode=1, msg=""):
"""Prints usage info."""
if msg:
sys.stderr.write("Error: %s.\n" % msg)
sys.stderr.write("Usage: %s [options]\n" % sys.argv[0])
sys.stderr.write("General options:\n")
sys.stderr.write(" -h, --help \t\t Print this help.\n")
sys.stderr.write(" -V, --version \t\t Print version information.\n")
sys.stderr.write(" -v, --verbose=LEVEL \t Verbose level (0=min, 1=default, 9=max).\n")
sys.exit(exitcode)
def test_insertdata():
"""insert testdata for the garbage collector.
something will be deleted, other data kept.
test_checkdata() checks if the remains are correct."""
test_deletedata_nooutput()
print 'insert into session 6'
for (key, uid) in [('23A', 2000), ('24B', 2100), ('25C', 2200), ('26D', 2300)]:
run_sql("""INSERT INTO session (session_key, session_expiry, uid) values ('%s', %d, %s) """ % (key, time.time(), uid))
for (key, uid) in [('27E', 2400), ('28F', 2500)]:
run_sql("""INSERT INTO session (session_key, session_expiry, uid) values ('%s', %d, %s) """ % (key, time.time()+20000, uid))
print 'insert into user 6'
for id in range(2000, 2600, 100):
run_sql("""INSERT INTO user (id, email) values (%s, '') """ % (id, ))
print 'insert into user_query 6'
for (id_user, id_query) in [(2000, 155), (2100, 231), (2200, 155), (2300, 574), (2400, 155), (2500, 988)]:
run_sql("""INSERT INTO user_query (id_user, id_query) values (%s, %s) """ % (id_user, id_query))
print 'insert into query 4'
for (id, urlargs) in [(155, 'p=cern'), (231, 'p=muon'), (574, 'p=physics'), (988, 'cc=Atlantis+Institute+of+Science&as=0&p=')]:
run_sql("""INSERT INTO query (id, type, urlargs) values (%s, 'r', '%s') """ % (id, urlargs))
print 'insert into basket 4'
for (id, name) in [(6, 'general'), (7, 'physics'), (8, 'cern'), (9, 'diverse')]:
run_sql("""INSERT INTO basket (id, name, public) values (%s, '%s', 'n')""" % (id, name))
print 'insert into user_basket 4'
for (id_user, id_basket) in [(2000, 6), (2200, 7), (2200, 8), (2500, 9)]:
run_sql("""INSERT INTO user_basket (id_user, id_basket) values (%s, %s) """ % (id_user, id_basket))
print 'insert into user_query_basket 2'
for (id_user, id_query, id_basket) in [(2200, 155, 6), (2500, 988, 9)]:
run_sql("""INSERT INTO user_query_basket (id_user, id_query, id_basket) values (%s, %s, %s) """ % (id_user, id_query, id_basket))
def test_deletedata():
"""deletes all the testdata inserted in the insert function.
outputs how many entries are deleted"""
print 'delete from session',
print run_sql("DELETE FROM session WHERE uid IN (2000,2100,2200,2300,2400,2500) ")
print 'delete from user',
print run_sql("DELETE FROM user WHERE id IN (2000,2100,2200,2300,2400,2500) ")
print 'delete from user_query',
print run_sql("DELETE FROM user_query WHERE id_user IN (2000,2100,2200,2300,2400,2500) OR id_query IN (155,231,574,988) ")
print 'delete from query',
print run_sql("DELETE FROM query WHERE id IN (155,231,574,988) ")
print 'delete from basket',
print run_sql("DELETE FROM basket WHERE id IN (6,7,8,9) ")
print 'delete from user_basket',
print run_sql("DELETE FROM user_basket WHERE id_basket IN (6,7,8,9) OR id_user IN (2000, 2200, 2500) ")
print 'delete from user_query_basket',
print run_sql("DELETE FROM user_query_basket WHERE id_user IN (2200, 2500) ")
def test_deletedata_nooutput():
"""same as test_deletedata without output."""
run_sql("DELETE FROM session WHERE uid IN (2000,2100,2200,2300,2400,2500) ")
run_sql("DELETE FROM user WHERE id IN (2000,2100,2200,2300,2400,2500) ")
run_sql("DELETE FROM user_query WHERE id_user IN (2000,2100,2200,2300,2400,2500) OR id_query IN (155,231,574,988) ")
run_sql("DELETE FROM query WHERE id IN (155,231,574,988) ")
run_sql("DELETE FROM basket WHERE id IN (6,7,8,9) ")
run_sql("DELETE FROM user_basket WHERE id_basket IN (6,7,8,9) OR id_user IN (2000, 2200, 2500) ")
run_sql("DELETE FROM user_query_basket WHERE id_user IN (2200, 2500) ")
def test_showdata():
print '\nshow test data:'
print '\n- select * from session:'
for r in run_sql("SELECT * FROM session WHERE session_key IN ('23A','24B','25C','26D','27E','28F') "): print r
print '\n- select * from user:'
for r in run_sql("SELECT * FROM user WHERE email = '' AND id IN (2000,2100,2200,2300,2400,2500) "): print r
print '\n- select * from user_query:'
for r in run_sql("SELECT * FROM user_query WHERE id_user IN (2000,2100,2200,2300,2400,2500) "): print r
print '\n- select * from query:'
for r in run_sql("SELECT * FROM query WHERE id IN (155,231,574,988) "): print r
print '\n- select * from basket:'
for r in run_sql("SELECT * FROM basket WHERE id IN (6,7,8,9) "): print r
print '\n- select * from user_basket:'
for r in run_sql("SELECT * FROM user_basket WHERE id_basket IN (6,7,8,9)"): print r
print '\n- select * from user_query_basket:'
for r in run_sql("SELECT * FROM user_query_basket WHERE id_basket IN (6,7,8,9) "): print r
def test_checkdata():
"""checks wether the data in the database is correct after
the garbage collector has run.
test_insertdata must have been run followed by the gc for this to be true."""
result = run_sql("SELECT DISTINCT session_key FROM session WHERE session_key IN ('23A','24B','25C','26D','27E','28F') ")
if len(result) != 2: return 0
for r in [('27E', ), ('28F', )]:
if r not in result: return 0
result = run_sql("SELECT id FROM user WHERE email = '' AND id IN (2000,2100,2200,2300,2400,2500) ")
if len(result) != 2: return 0
for r in [(2400, ), (2500, )]:
if r not in result: return 0
result = run_sql("SELECT DISTINCT id_user FROM user_query WHERE id_user IN (2000,2100,2200,2300,2400,2500) ")
if len(result) != 2: return 0
for r in [(2400, ), (2500, )]:
if r not in result: return 0
result = run_sql("SELECT id FROM query WHERE id IN (155,231,574,988) ")
if len(result) != 2: return 0
for r in [(155, ), (988, )]:
if r not in result: return 0
result = run_sql("SELECT id FROM basket WHERE id IN (6,7,8,9) ")
if len(result) != 1: return 0
for r in [(9, )]:
if r not in result: return 0
result = run_sql("SELECT id_user, id_basket FROM user_basket WHERE id_basket IN (6,7,8,9)")
if len(result) != 1: return 0
for r in [(2500, 9)]:
if r not in result: return 0
result = run_sql("SELECT id_user, id_query, id_basket FROM user_query_basket WHERE id_basket IN (6,7,8,9) ")
if len(result) != 1: return 0
for r in [(2500, 988, 9)]:
if r not in result: return 0
return 1
def test_runtest_guest_user_garbage_collector():
"""a test to see if the garbage collector works correctly."""
test_insertdata()
test_showdata()
guest_user_garbage_collector(verbose=9)
test_showdata()
if test_checkdata():
print '\n\nGARBAGE COLLECTOR CLEANED UP THE CORRECT DATA \n\n'
else:
print '\n\nERROR ERROR ERROR - WRONG DATA CLEANED - ERROR ERROR ERROR \n\n'
test_deletedata_nooutput()
return
def main():
"""CLI to the session garbage collector.
Gets arguments from sys.argv and dispatch to guest_user_garbage_collector"""
options = {}
options['verbose'] = 1
try:
opts, args = getopt.getopt(sys.argv[1:], "hVv:", ["help", "version", "verbose="])
except getopt.GetoptError, e:
usage(e)
try:
for opt in opts:
if opt[0] in ['-h', '--help']:
usage(0)
elif opt[0] in ['-V', '--version']:
print __version__
sys.exit(0)
elif opt[0] in ['-v', '--verbose']:
options['verbose'] = int(opt[1])
except StandardError, e:
usage(e)
guest_user_garbage_collector(**options)
return
if __name__ == '__main__':
main()
diff --git a/modules/websession/doc/Makefile.am b/modules/websession/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/websession/doc/Makefile.am
+++ b/modules/websession/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/websession/doc/admin/Makefile.am b/modules/websession/doc/admin/Makefile.am
index 0cfcd0f8a..881f35603 100644
--- a/modules/websession/doc/admin/Makefile.am
+++ b/modules/websession/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/websession
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/websession/doc/admin/guide.html.wml b/modules/websession/doc/admin/guide.html.wml
index c5d1240ea..f55714457 100644
--- a/modules/websession/doc/admin/guide.html.wml
+++ b/modules/websession/doc/admin/guide.html.wml
@@ -1,65 +1,65 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebSession Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websession/>WebSession Admin</a>" \
navbar_name="admin" \
navbar_select="websession-admin-guide"
<p><table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
WARNING: THIS ADMIN GUIDE IS NOT FULLY COMPLETED
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
This Admin Guide is not yet completed. Moreover, some
admin-level functionality for this module exists only in the form of
manual recipes. We are in the process of developing both the
guide as well as the web admin interface. If you are interested
in seeing some specific things implemented with high priority,
please contact us at <SUPPORTEMAIL>. Thanks for your interest!
</td>
</tr>
</tbody>
</table>
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Guest User Sessions</h2>
<p>Guest users create a lot of entries in <CDSNAME> tables that are
related to their web sessions, their search history, personal baskets,
etc. This data has to be garbage-collected periodically. At the
moment this is done via a command line program:
<blockquote>
<pre>
$ sessiongc
</pre>
</blockquote>
<strong>HINT:</strong> You may want to launch this command every day.
In the future the garbage collection task may be done via BibSched task
queue.
diff --git a/modules/websession/doc/admin/index.html.wml b/modules/websession/doc/admin/index.html.wml
index 429a7fe02..0e571029c 100644
--- a/modules/websession/doc/admin/index.html.wml
+++ b/modules/websession/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebSession Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="websession"
<dl>
<dt><a href="guide.html">WebSession Admin Guide</a></dt>
<dd>Everything you want to know about WebSession administration</dd>
</dl>
diff --git a/modules/websession/lib/Makefile.am b/modules/websession/lib/Makefile.am
index f279f3f0d..c3738ed58 100644
--- a/modules/websession/lib/Makefile.am
+++ b/modules/websession/lib/Makefile.am
@@ -1,27 +1,27 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir = $(libdir)/python/cdsware
pylib_DATA = websession.py session.py webuser.py webaccount.py \
websession_templates.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/websession/lib/session.py b/modules/websession/lib/session.py
index af327bfbc..7a1a341b9 100644
--- a/modules/websession/lib/session.py
+++ b/modules/websession/lib/session.py
@@ -1,748 +1,748 @@
## $Id$
## CDSware Session utilities, without persistence. See websession.py
## for persistence.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
CDS session management, without persistence (code adpated from Quixote).
See websession.py for persistence.
There are two levels to CDS session management system:
- SessionManager
- Session
A SessionManager is responsible for creating sessions, setting and reading
session cookies, maintaining the collection of all sessions, and so forth.
There should be one SessionManager instance per process.
SessionManager is a generic class borrowed from Quixote, the class
MPSessionManager provides the session management on top of mod_python requests.
A Session is the umbrella object for a single session (notionally, a (user,
host, browser_process) triple). Simple applications can probably get away
with putting all session data into a Session object (or, better, into an
application-specific subclass of Session).
The default implementation provided here is not persistent: when the
process shuts down, all session data is lost. You will need to
subclass SessionManager if you want to implement persistent sessions.
"""
#default configuration values
DEFAULT_SESSION_COOKIE_NAME = "CDSSESSION"
DEFAULT_SESSION_COOKIE_DOMAIN = None
DEFAULT_SESSION_COOKIE_PATH = "/"
DEFAULT_CHECK_SESSION_ADDR = 1
import sys, string, re
from time import time, localtime, strftime, clock
try:
from mod_python import apache
except ImportError:
pass
_qparm_re = re.compile(r'([\0- ]*'
r'([^\0- ;,=\"]+)="([^"]*)"'
r'([\0- ]*[;,])?[\0- ]*)')
_parm_re = re.compile(r'([\0- ]*'
r'([^\0- ;,="]+)=([^\0- ;,"]*)'
r'([\0- ]*[;,])?[\0- ]*)')
def parse_cookie (text):
result = {}
pos = 0
while 1:
mq = _qparm_re.match(text, pos)
m = _parm_re.match(text, pos)
if mq is not None:
# Match quoted correct cookies
name = mq.group(2)
value = mq.group(3)
pos = mq.end()
elif m is not None:
# Match evil MSIE cookies ;)
name = m.group(2)
value = m.group(3)
pos = m.end()
else:
# this may be an invalid cookie.
# We'll simply bail without raising an error
# if the cookie is invalid.
return result
if not result.has_key(name):
result[name] = value
return result
def packbytes(s):
"convert a string of bytes into a long integer"
n = 0L
for b in s:
n <<= 8
n |= ord(b)
return n
try:
# /dev/urandom is just as good as /dev/random for cookies (assuming
# SHA-1 is secure) and it never blocks.
open("/dev/urandom")
def randlong(bytes):
"""Return bits of random data as a long integer."""
return packbytes(open("/dev/urandom").read(bytes))
except IOError:
# this is much less secure than the above function
import sha
_randstate = sha.new(str(time() + clock()))
def randlong(bytes):
"""Return bits of random data as a long integer."""
global _randstate
s = ""
while len(s) < bytes:
_randstate.update(str(time() + clock()))
s += _randstate.digest()
return packbytes(s[:bytes])
#-----------------------------------------------------------------------
class SessionManager:
"""
SessionManager acts as a dictionary of all sessions, mapping session
ID strings to individual session objects. Session objects are
instances of Session (or a custom subclass for your application).
SessionManager is also responsible for creating and destroying
sessions, for generating and interpreting session cookies, and for
session persistence (if any -- this implementation is not
persistent).
Most applications can just use this class directly; sessions will
be kept in memory-based dictionaries, and will be lost when the
handling process dies. Alternatively an application can subclass
SessionManager to implement specific behaviour, such as persistence.
For working on top of mod_python, the base class must be MPSessionManager.
Instance attributes:
session_class : class
the class that is instantiated to create new session objects
(in new_session())
sessions : mapping { session_id:string : Session }
the collection of sessions managed by this SessionManager
"""
ACCESS_TIME_RESOLUTION = 1 # in seconds
def __init__ (self, session_class=None, session_mapping=None):
"""SessionManager(session_class : class = Session,
session_mapping : mapping = {})
Create a new session manager. There should be one session
manager per handling process (or even better per application).
session_class is used by the new_session() method -- it returns
an instance of session_class.
"""
self.sessions = {}
if session_class is None:
self.session_class = Session
else:
self.session_class = session_class
if session_mapping is None:
self.sessions = {}
else:
self.sessions = session_mapping
def __repr__ (self):
return "<%s at %x>" % (self.__class__.__name__, id(self))
# -- Mapping interface ---------------------------------------------
# (subclasses shouldn't need to override any of this, unless
# your application passes in a session_mapping object that
# doesn't provide all of the mapping methods needed here)
def keys (self):
"""keys() -> [string]
Return the list of session IDs of sessions in this session manager.
"""
return self.sessions.keys()
def sorted_keys (self):
"""sorted_keys() -> [string]
Return the same list as keys(), but sorted.
"""
keys = self.keys()
keys.sort()
return keys
def values (self):
"""values() -> [Session]
Return the list of sessions in this session manager.
"""
return self.sessions.values()
def items (self):
"""items() -> [(string, Session)]
Return the list of (session_id, session) pairs in this session
manager.
"""
return self.sessions.items()
def get (self, session_id, default=None):
"""get(session_id : string, default : any = None) -> Session
Return the session object identified by 'session_id', or None if
no such session.
"""
return self.sessions.get(session_id, default)
def __getitem__ (self, session_id):
"""__getitem__(session_id : string) -> Session
Return the session object identified by 'session_id'. Raise KeyError
if no such session.
"""
return self.sessions[session_id]
def has_key (self, session_id):
"""has_key(session_id : string) -> boolean
Return true if a session identified by 'session_id' exists in
the session manager.
"""
return self.sessions.has_key(session_id)
# has_session() is a synonym for has_key() -- if you override
# has_key(), be sure to repeat this alias!
has_session = has_key
def __setitem__ (self, session_id, session):
"""__setitem__(session_id : string, session : Session)
Store 'session' in the session manager under 'session_id'.
"""
if not isinstance(session, self.session_class):
raise TypeError("session not an instance of %r: %r"
% (self.session_class, session))
assert session_id == session.id, "session ID mismatch"
self.sessions[session_id] = session
def __delitem__ (self, session_id):
"""__getitem__(session_id : string) -> Session
Remove the session object identified by 'session_id' from the session
manager. Raise KeyError if no such session.
"""
del self.sessions[session_id]
# -- Configuration params--------------------------------------------
# Some configurable aspects. It returns the default values provided
# by the module constants. Subclasses can override these methods
# and set up the values at their convenience (example: from a
# configuration object)
def _getSessionCookieName(self):
"""Returns the preferred cookie name for the sessions
"""
return DEFAULT_SESSION_COOKIE_NAME
def _getSessionCheckAddress(self):
"""Indicates whether the IP address of the session must be checked
to ensure a session is only allowed in the scope of a single IP
"""
return DEFAULT_CHECK_SESSION_ADDR
def _getSessionCookieDomain(self):
"""Returns the preferred cookie domain for the sessions
"""
return DEFAULT_SESSION_COOKIE_DOMAIN
def _getSessionCookiePath(self):
"""Returns the preferred cookie path for the sessions
"""
return DEFAULT_SESSION_COOKIE_PATH
# -- Session management --------------------------------------------
# these build on the storage mechanism implemented by the
# above mapping methods, and are concerned with all the high-
# level details of managing web sessions
def new_session(self, request, id):
"""new_session(request : HTTPRequest, id : string)
-> Session
Return a new session object, ie. an instance of the session_class
class passed to the constructor (defaults to Session).
"""
return self.session_class(request, id)
def _get_session_id (self, request):
"""_get_session_id(request : HTTPRequest) -> string
Find the ID of the current session by looking for the session
cookie in 'request'. Return None if no such cookie or the
cookie has been expired, otherwise return the cookie's value.
"""
id = request.cookies.get(self._getSessionCookieName())
if id == "" or id == "*del*":
return None
else:
return id
def _create_session (self, request):
# Generate a session ID, which is just the value of the session
# cookie we are about to drop on the user. (It's also the key
# used with the session manager mapping interface.)
id = None
while id is None or self.has_session(id):
id = "%016X" % randlong(8) # 64-bit random number
# Create a session object which will be looked up the next
# time this user comes back carrying the session cookie
# with the session ID just generated.
return self.new_session(request, id)
def get_session (self, request):
"""get_session(request : HTTPRequest) -> Session
Fetch or create a session object for the current session, and
return it. If a session cookie is found in the HTTP request
object 'request', use it to look up and return an existing
session object. If no session cookie is found, create a new
session. If the session cookie refers to a non-existent
session, raise SessionError. If the check_session_addr flag
is true, then a mismatch between the IP address stored
in an existing session the IP address of the current request
also causes SessionError.
Note that this method does *not* cause the new session to be
stored in the session manager, nor does it drop a session cookie
on the user. Those are both the responsibility of
maintain_session(), called at the end of a request.
"""
id = self._get_session_id(request)
session = None
if id is not None:
session = self.get(id)
if session is None:
# Note that it's important to revoke the session cookie
# so the user doesn't keep getting "Expired session ID"
# error pages. However, it has to be done in the
# response object for the error document, which doesn't
# exist yet. Thus, the code that formats SessionError
# exceptions -- SessionError.format() by default -- is
# responsible for revoking the session cookie. Yuck.
raise SessionError(session_id=id)
if (self._getSessionCheckAddress() and
session.get_remote_address() != request.get_environ("REMOTE_ADDR")):
raise SessionError("Remote IP address does not match the "
"IP address that created the session",
session_id=id)
if id is None or session is None:
# Generate a session ID and create the session.
session = self._create_session(request)
session._set_access_time(self.ACCESS_TIME_RESOLUTION)
return session
# get_session ()
def maintain_session (self, request, session):
"""maintain_session(request : HTTPRequest, session : Session)
Maintain session information. This method is called by
SessionPublisher after servicing an HTTP request, just before
the response is returned. If a session contains information it
is saved and a cookie dropped on the client. If not, the
session is discarded and the client will be instructed to delete
the session cookie (if any).
"""
if not session.has_info():
# Session has no useful info -- forget it. If it previously
# had useful information and no longer does, we have to
# explicitly forget it.
if self.has_session(session.id):
del self[session.id]
self.revoke_session_cookie(request)
return
if not self.has_session(session.id):
# This is the first time this session has had useful
# info -- store it and set the session cookie.
self[session.id] = session
self.set_session_cookie(request, session.id)
elif session.is_dirty():
# We have already stored this session, but it's dirty
# and needs to be stored again. This will never happen
# with the default Session class, but it's there for
# applications using a persistence mechanism that requires
# repeatedly storing the same object in the same mapping.
self[session.id] = session
def set_session_cookie (self, request, session_id):
"""set_session_cookie(request : HTTPRequest, session_id : string)
Ensure that a session cookie with value 'session_id' will be
returned to the client via 'request.response'.
"""
request.response.set_cookie(self._getSessionCookieName(), session_id,
domain = self._getSessionCookieDomain(),
path = self._getSessionCookiePath())
def revoke_session_cookie (self, request):
"""revoke_session_cookie(request : HTTPRequest)
Remove the session cookie from the remote user's session by
resetting the value and maximum age in 'request.response'. Also
remove the cookie from 'request' so that further processing of
this request does not see the cookie's revoked value.
"""
response = request.response
response.set_cookie(self._getSessionCookieName(), "",
domain = self._getSessionCookieDomain(),
path = self._getSessionCookiePath(),
max_age = 0)
if request.cookies.has_key(self._getSessionCookieName()):
del request.cookies[self._getSessionCookieName()]
def expire_session (self, request):
"""expire_session(request : HTTPRequest)
Expire the current session, ie. revoke the session cookie from
the client and remove the session object from the session
manager and from 'request'.
"""
self.revoke_session_cookie(request)
try:
del self[request.session.id]
except KeyError:
# This can happen if the current session hasn't been saved
# yet, eg. if someone tries to leave a session with no
# interesting data. That's not a big deal, so ignore it.
pass
request.session = None
def has_session_cookie (self, request, must_exist=0):
"""has_session_cookie(request : HTTPRequest,
must_exist : boolean = false)
-> boolean
Return true if 'request' already has a cookie identifying a
session object. If 'must_exist' is true, the cookie must
correspond to a currently existing session; otherwise (the
default), we just check for the existence of the session cookie
and don't inspect its content at all.
"""
id = request.cookies.get(self._getSessionCookieName())
if id is None:
return 0
if must_exist:
return self.has_session(id)
else:
return 1
# SessionManager
class Session:
"""
Holds information about the current session. The only information
that is likely to be useful to applications is the 'user' attribute,
which applications can use as they please.
Instance attributes:
id : string
the session ID (generated by SessionManager and used as the
value of the session cookie)
__remote_address : string
IP address of user owning this session (only set when the
session is created -- requests for this session from a different
IP address will either raise SessionError or be treated
normally, depending on the CHECK_SESSION_ADDR flag)
__creation_time : float
__access_time : float
two ways of keeping track of the "age" of the session.
Note that '__access_time' is maintained by the SessionManager that
owns this session, using _set_access_time().
Feel free to access 'id' directly, but do not modify it. The other
attributes are private -- keep your grubby hands off of them and use
the appropriate accessor methods.
"""
MAX_FORM_TOKENS = 16 # maximum number of outstanding form tokens
def __init__ (self, request, id):
self.id = id
self.__remote_address = request.get_environ("REMOTE_ADDR")
self.__creation_time = self.__access_time = time()
def __repr__ (self):
return "<%s at %x: %s>" % (self.__class__.__name__, id(self), self.id)
def __str__ (self):
return "session %s" % self.id
def has_info (self):
"""has_info() -> boolean
Return true if this session contains any information that must
be saved.
"""
return 1
def is_dirty (self):
"""is_dirty() -> boolean
Return true if this session has changed since it was last saved
such that it needs to be saved again.
Default implementation always returns false since the default
storage mechanism is an in-memory dictionary, and you don't have
to put the same object into the same slot of a dictionary twice.
If sessions are stored to, eg., files in a directory or slots in
a hash file, is_dirty() should probably be an alias or wrapper
for has_info(). See doc/session-mgmt.txt.
"""
return 0
def dump (self, file=None, header=1, deep=1):
time_fmt = "%Y-%m-%d %H:%M:%S"
ctime = strftime(time_fmt, localtime(self.__creation_time))
atime = strftime(time_fmt, localtime(self.__access_time))
if header:
file.write('session %s:' % self.id)
file.write(' user %s' % self.user)
file.write(' __remote_address: %s' % self.__remote_address)
file.write(' created %s, last accessed %s' % (ctime, atime))
file.write(' _form_tokens: %s\n' % self._form_tokens)
# dump()
# -- Simple accessors and modifiers --------------------------------
def get_remote_address (self):
"""Return the IP address (dotted-quad string) that made the
initial request in this session.
"""
return self.__remote_address
def get_creation_time (self):
"""Return the time that this session was created (seconds
since epoch).
"""
return self.__creation_time
def get_access_time (self):
"""Return the time that this session was last accessed (seconds
since epoch).
"""
return self.__access_time
def get_creation_age (self, _now=None):
"""Return the number of seconds since session was created."""
# _now arg is not strictly necessary, but there for consistency
# with get_access_age()
return (_now or time()) - self.__creation_time
def get_access_age (self, _now=None):
"""Return the number of seconds since session was last accessed."""
# _now arg is for SessionManager's use
return (_now or time()) - self.__access_time
# -- Methods for SessionManager only -------------------------------
def _set_access_time (self, resolution):
now = time()
if now - self.__access_time > resolution:
self.__access_time = now
class MPSessionManager(SessionManager):
"""Specialised SessionManager which allows to use Quixote's session
management system with mod_python request objects. The role of this
class is basically convert mod_python request objects in other type
of objects (RequestWrapper) which can be handled by the SessionManager
class.
With this we are able to re-use the Quixote's code (very few
modifications have been done) in a very transparent way.
"""
def get_session (self, request):
"""Proxy method to SessionManager get_session. It converts the
mod_python request objects in a SessionManager compatible one
and executes the parent implementation passing the compatible object
"""
rw = RequestWrapper.getWrapper( request )
s = SessionManager.get_session( self, rw )
rw.setSession( s )
return s
def maintain_session (self, request, session):
"""Proxy method to SessionManager maintain_session. It converts the
mod_python request objects in a SessionManager compatible one
and executes the parent implementation passing the compatible object
"""
rw = RequestWrapper.getWrapper( request )
SessionManager.maintain_session( self, rw, session )
def has_session_cookie (self, request, must_exist=0):
"""Proxy method to SessionManager has_session_cookie. It converts the
mod_python request objects in a SessionManager compatible one
and executes the parent implementation passing the compatible object
"""
rw = RequestWrapper.getWrapper( request )
return SessionManager.has_session_cookie( self, rw, must_exist )
def expire_session (self, request):
"""Proxy method to SessionManager expire_session. It converts the
mod_python request objects in a SessionManager compatible one
and executes the parent implementation passing the compatible object
"""
rw = RequestWrapper.getWrapper( request )
SessionManager.expire_session(self, rw )
def revoke_session_cookie (self, request):
"""Proxy method to SessionManager revoke_session_cookie. It converts the
mod_python request objects in a SessionManager compatible one
and executes the parent implementation passing the compatible object
"""
rw = RequestWrapper.getWrapper( request)
SessionManager.revoke_session_cookie(self,rw)
class RequestWrapper:
"""This class implements a HTTP request which is compatible with Quixote's
session management system. It builds a wrapper arround mod_python request
objects to adapt it to Quixote's classes.
Intance attributes:
__request: MPRequest
Reference to the wrapped mod_python request object
cookies: Dictionary
Conatins the received cookies (these found in headers_in)
indexed by the cookie name
environ: Dictionary
Contains a list of different variables or parameters of the
HTTP request
response: ResponseWrapper
Reference to the HTTP response wrapping object
session: Session
Refence to the current session associated with the request,
if any
"""
def __init__(self, request):
"""Constructor of the class. Initialises the necessesary values. It
should never be used, use getWrapper method instead.
"""
self.__request = request
try:
self.cookies = parse_cookie(self.__request.headers_in[ "Cookie" ])
except KeyError, e:
self.cookies = {}
self.environ = {}
self.environ["REMOTE_ADDR"] = self.__request.get_remote_host(apache.REMOTE_NOLOOKUP)
self.response = ResponseWrapper( request )
try:
self.session = request.session
except AttributeError, e:
self.session = None
request.cds_wrapper = self #sticks the current wrapper to the mp request
# so in succesive request it can be recovered
def getWrapper( req ):
"""Returns a RequestWrapper for a given request.
The session manager modifies the contents of the wrapper and
therefore its state must be kept. This method returns the request
sticked wrapper (carrying the current status) and if it doesn't
have any it creates a new one. The RequestWrapper initialisation
method will take care of sticking any new wrapper to the request.
"""
try:
w = req.cds_wrapper
except AttributeError:
w = RequestWrapper( req )
return w
getWrapper = staticmethod( getWrapper )
def get_environ(self, name):
"""Returns a "environ" variable value
"""
return self.environ[name]
def setSession(self, session):
"""Sets the reference to a sessioni. It also sets this reference in the
mod_python request object so it can be kept for future requests.
"""
self.session = session
self.__request.session = session
class ResponseWrapper:
"""This class implements a HTTP response which is compatible with Quixote's
session management system. It builds a wrapper arround mod_python request
objects to adapt it to Quixote's classes.
Instance attributes:
request: RequestWrapper
Reference to the request object to which this will represent
the reply
"""
def __init__(self, request):
"""Constructor of the class.
"""
self.request = request
def set_cookie(self, cookie_name, cookie_value, **attrs):
"""
"""
options = ""
for (name, value) in attrs.items():
if value is None:
continue
if name in ("max_age", "path"):
name = name.replace("_", "-")
options += "; %s=%s"%(name, value)
elif name =="secure" and value:
options += "; secure"
self.request.headers_out["Set-Cookie"] = "%s=%s%s"%(cookie_name, cookie_value, options)
class SessionError(Exception):
"""
"""
def __init__(self, msg="", **args):
pass
diff --git a/modules/websession/lib/webaccount.py b/modules/websession/lib/webaccount.py
index d2a24757b..d1f58fb8f 100644
--- a/modules/websession/lib/webaccount.py
+++ b/modules/websession/lib/webaccount.py
@@ -1,245 +1,245 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import sys
import string
import cgi
from cdsware.config import *
from cdsware.webpage import page
from cdsware.dbquery import run_sql
from cdsware.webuser import getUid,isGuestUser, get_user_preferences, set_user_preferences
from cdsware.access_control_admin import acc_findUserRoleActions
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS, CFG_EXTERNAL_AUTHENTICATION
from cdsware.messages import gettext_set_language
import cdsware.template
websession_templates = cdsware.template.load('websession')
imagesurl = "%s/img" % weburl
# perform_info(): display the main features of CDS personalize
def perform_info(req, ln):
out = ""
uid = getUid(req)
return websession_templates.tmpl_account_info(
ln = ln,
uid = uid,
guest = isGuestUser(uid),
cfg_cern_site = cfg_cern_site,
);
def perform_youradminactivities(uid, ln):
"""Return text for the `Your Admin Activities' box. Analyze
whether user UID has some admin roles, and if yes, then print
suitable links for the actions he can do. If he's not admin,
print a simple non-authorized message."""
your_role_actions = acc_findUserRoleActions(uid)
your_roles = []
your_admin_activities = []
guest = isGuestUser(uid)
for (role, action) in your_role_actions:
if role not in your_roles:
your_roles.append(role)
if action not in your_admin_activities:
your_admin_activities.append(action)
if "superadmin" in your_roles:
for action in ["cfgbibformat", "cfgbibharvest", "cfgbibrank", "cfgbibindex", "cfgwebaccess", "cfgwebcomment", "cfgwebsearch", "cfgwebsubmit"]:
if action not in your_admin_activities:
your_admin_activities.append(action)
return websession_templates.tmpl_account_adminactivities(
ln = ln,
uid = uid,
guest = guest,
roles = your_roles,
activities = your_admin_activities,
weburl = weburl,
)
# perform_display_account(): display a dynamic page that shows the user's account
def perform_display_account(req,data,bask,aler,sear,msgs,ln):
# load the right message language
_ = gettext_set_language(ln)
uid = getUid(req)
#your account
if isGuestUser(uid):
user = "guest"
accBody = _("""You are logged in as guest. You may want to <A href="../youraccount.py/login?ln=%s">login</A> as a regular user""") % ln + "<BR><BR>"
bask=aler=msgs= _("""The <strong class="headline">guest</strong> users need to <A href="../youraccount.py/login?ln=%s">register</A> first""") % ln
sear= _("No queries found")
else:
user = data[0]
accBody = websession_templates.tmpl_account_body(
ln = ln,
user = user,
)
return websession_templates.tmpl_account_page(
ln = ln,
weburl = weburl,
accBody = accBody,
baskets = bask,
alerts = aler,
searches = sear,
messages = msgs,
administrative = perform_youradminactivities(uid, ln)
)
# template_account() : it is a template for print each of the options from the user's account
def template_account(title, body, ln):
return websession_templates.tmpl_account_template(
ln = ln,
title = title,
body = body
)
# warning_guest_user(): It returns an alert message,showing that the user is a guest user and should log into the system
def warning_guest_user(type, ln=cdslang):
# load the right message language
_ = gettext_set_language(ln)
return websession_templates.tmpl_warning_guest_user(
ln = ln,
type = type,
)
## perform_delete():delete the account of the user, not implement yet
def perform_delete(ln):
return websession_templates.tmpl_account_delete(ln = ln)
## perform_set(email,password): edit your account parameters, email and password.
def perform_set(email,password, ln):
try:
uid = run_sql("SELECT id FROM user where email=%s", (email,))
uid = uid[0][0]
except:
uid = 0
CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL = CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS
prefs = get_user_preferences(uid)
if CFG_EXTERNAL_AUTHENTICATION.has_key(prefs['login_method']) and CFG_EXTERNAL_AUTHENTICATION[prefs['login_method']][1] != True:
CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL = 3
out = websession_templates.tmpl_user_preferences(
ln = ln,
email = email,
email_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL >= 2),
password = password,
password_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS_LOCAL >= 3)
)
if len(CFG_EXTERNAL_AUTHENTICATION) >= 1:
try:
uid = run_sql("SELECT id FROM user where email=%s", (email,))
uid = uid[0][0]
except:
uid = 0
prefs = get_user_preferences(uid)
current_login_method = prefs['login_method']
methods = CFG_EXTERNAL_AUTHENTICATION.keys()
methods.sort()
out += websession_templates.tmpl_user_external_auth(
ln = ln,
methods = methods,
current = current_login_method,
method_disabled = (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4)
)
return out
## create_register_page_box(): register a new account
def create_register_page_box(referer='', ln=cdslang):
return websession_templates.tmpl_register_page(
referer = referer,
ln = ln,
level = CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS,
supportemail = supportemail,
cdsname = cdsname
)
## create_login_page_box(): ask for the user's email and password, for login into the system
def create_login_page_box(referer='', ln=cdslang):
internal = None
for system in CFG_EXTERNAL_AUTHENTICATION.keys():
if not CFG_EXTERNAL_AUTHENTICATION[system][0]:
internal = system
break
register_available = CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS <= 1 and internal
methods = CFG_EXTERNAL_AUTHENTICATION.keys()
methods.sort()
selected = ''
for method in methods:
if CFG_EXTERNAL_AUTHENTICATION[method][1] == True:
selected = method
break
return websession_templates.tmpl_login_form(
ln = ln,
referer = referer,
internal = internal,
register_available = register_available,
methods = methods,
selected_method = selected,
supportemail = supportemail,
)
# perform_logout: display the message of not longer authorized,
def perform_logout(req, ln):
return websession_templates.tmpl_account_logout(ln = ln)
#def perform_lost: ask the user for his email, in order to send him the lost password
def perform_lost(ln):
return websession_templates.tmpl_lost_password_form(
ln = ln,
msg = websession_templates.tmpl_lost_password_message(ln = ln, supportemail = supportemail),
)
# perform_emailSent(email): confirm that the password has been emailed to 'email' address
def perform_emailSent(email, ln):
return websession_templates.tmpl_account_emailSent(ln = ln, email = email)
# peform_emailMessage : display a error message when the email introduced is not correct, and sugest to try again
def perform_emailMessage(eMsg, ln):
return websession_templates.tmpl_account_emailMessage( ln = ln,
msg = eMsg
)
# perform_back(): template for return to a previous page, used for login,register and setting
def perform_back(mess,act,linkname='', ln='en'):
if not linkname:
linkname = act
return websession_templates.tmpl_back_form(
ln = ln,
message = mess,
act = act,
link = linkname,
)
diff --git a/modules/websession/lib/websession.py b/modules/websession/lib/websession.py
index 41518b492..ddd8667f7 100644
--- a/modules/websession/lib/websession.py
+++ b/modules/websession/lib/websession.py
@@ -1,151 +1,151 @@
## $Id$
## CDSware Web Session utilities, implementing persistence.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
Classes necessary for using in CDSware, as a complement of session, which adds persistence to sessions
by using a MySQL table. Consists of the following classes:
- SessionNotInDb: Exception to be raised when a session doesn't exit
- pSession(Session): Specialisation of the class Session which adds persistence to session
- pSessionMapping: Implements only the necessary methods to make it work with the session manager
"""
import cPickle
import time
from UserDict import UserDict
from cdsware.dbquery import run_sql, blob_to_string
from cdsware.session import Session
class SessionNotInDb(Exception):
"""Exception to be raised when a requested session doesn't exist in the DB
"""
pass
class pSession(Session):
"""Specialisation of the class Session which adds persistence to sessions
by using a MySQL table (it pickles itself into the corresponding row of
the table). The class provides methods to save and retrieve an instance
to/from the DB and to access the main session attributes (uid). The
table in the DB must have the following structure:
session_key - text - unique
uid - int
session_object - blob
Attributes:
__tableName -- (string) name of the table in the DB where the
sessions are going to be stored
__uid -- (int) user identifier who initiated the session
__dirty -- (bool) flag indicating whether the session has been
modified (and therefore needs to be saved back to the DB) or not
"""
__tableName = "session"
__ExpireTime = 1050043127
def __init__( self, request, id, uid=-1 ):
Session.__init__( self, request, id )
self.__uid = uid
self.__dirty = 0
def is_dirty( self ):
return self.__dirty
def getUid( self ):
return self.__uid
def setUid( self, newUid ):
self.__uid = int(newUid)
self.__dirty = 1
def retrieve( cls, sessionId ):
"""method for retrieving a session from the DB for the given id. If the
id has no corresponding session an exception is raised
"""
sql = "select session_object from %s where session_key='%s'"%(cls.__tableName, sessionId)
res = run_sql(sql)
if len(res)==0:
raise SessionNotInDb("Session %s doesn't exist"%sessionId)
s = cPickle.loads(blob_to_string(res[0][0]))
return s
retrieve = classmethod( retrieve )
def __getRepr( self ):
return cPickle.dumps( self )
def save( self ):
"""method that tries to insert the session as NEW in the DB. If this
fails (giving an integrity error) it means the session already
exists there and it must be updated, so it performs the
corresponding SQL update
"""
repr = self.__getRepr().replace("'", "\\\'")
repr = repr.replace('"', '\\\"')
try:
sql = 'INSERT INTO %s (session_key, session_expiry, session_object, uid) values ("%s","%s","%s","%s")' % \
(self.__class__.__tableName, self.id, self.get_access_time()+60*60*24*2, repr, int(self.getUid()))
res = run_sql(sql)
# FIXME. WARNING!! it should be "except IntegrityError, e:" but this will
# create a dependency on package MySQL. I'll leave it like this for
# the time being but this can lead to Exception masking
except Exception, e:
sql = 'UPDATE %s SET uid=%s, session_expiry=%s, session_object="%s" WHERE session_key="%s"' % \
(self.__class__.__tableName, int(self.getUid()), self.get_access_time()+60*60*24*2, repr, self.id)
res = run_sql(sql)
self.__dirty=0
class pSessionMapping(UserDict):
"""Only the necessary methods to make it work with the session manager
have been implemented.
"""
def __includeItemFromDB(self, key):
if key not in self.data.keys():
try:
s = pSession.retrieve( key )
self.data[key] = s
except SessionNotInDb, e:
pass
def __setitem__(self, key, v):
"""when a session is added or updated in the dictionary it means it
must be updated within the DB
"""
v.save()
UserDict.__setitem__(self, key, v)
def __getitem__(self, key):
"""in order not to have to load all the sessions in the dictionary
(normally only a single session is needed on each web request) when
a session is requested the object looks to see if it is in the
dictionary (memory) and if not it tries to retrieve it from the
DB, puts it in the dictionary and returns the requested item. If
the session doesn't exist a normal KeyError exception is raised
"""
self.__includeItemFromDB( key )
return UserDict.__getitem__(self, key)
def has_key(self, key):
"""same as for "__getitem__": it checks whether the session exist in the
local dictionary or in the DB.
"""
self.__includeItemFromDB( key )
return UserDict.has_key( self, key )
diff --git a/modules/websession/lib/websession_templates.py b/modules/websession/lib/websession_templates.py
index 1b24f2f4f..97c2908f5 100644
--- a/modules/websession/lib/websession_templates.py
+++ b/modules/websession/lib/websession_templates.py
@@ -1,809 +1,809 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import urllib
import time
import cgi
import gettext
import string
import locale
from cdsware.config import *
from cdsware.messages import gettext_set_language
class Template:
def tmpl_lost_password_message(self, ln, supportemail):
"""
Defines the text that will be displayed on the 'lost password' page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'supportemail' *string* - The email of the support team
"""
# load the right message language
_ = gettext_set_language(ln)
return _("If you have lost password for your CERN Document Server internal account, then please enter your email address below and the lost password will be emailed to you.") +\
"<br /><br />" +\
_("Note that if you have been using an external login system (such as CERN NICE), then we cannot do anything and you have to ask there.") +\
_("Alternatively, you can ask %s to change your login system from external to internal.") % ("""<a href="mailto:%(email)s">%(email)s</a>""" % { 'email' : supportemail }) +\
"<br><br>"
def tmpl_back_form(self, ln, message, act, link):
"""
A standard one-message-go-back-link page.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'message' *string* - The message to display
- 'act' *string* - The action to accomplish when going back
- 'link' *string* - The link text
"""
out = """
<table>
<tr>
<td align=center>%(message)s
<A href="./%(act)s">%(link)s</A></td>
</tr>
</table>
"""% {
'message' : message,
'act' : act,
'link' : link
}
return out
def tmpl_user_preferences(self, ln, email, email_disabled, password, password_disabled):
"""
Displays a form for the user to change his email/password.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'email' *string* - The email of the user
- 'email_disabled' *boolean* - If the user has the right to edit his email
- 'password' *string* - The password of the user
- 'password_disabled' *boolean* - If the user has the right to edit his password
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<p><big><strong class="headline">Edit parameters</strong></big></p>
<form method="post" action="../youraccount.py/change">
<p>%(change_user_pass)s</p>
<table>
<tr><td align="right"><strong>
%(new_email)s:</strong><br/>
<small class="important">(%(mandatory)s)</small>
</td><td>
<input type="text" size="25" name="email" %(email_disabled)s value="%(email)s"><br>
<small><span class="quicknote">%(example)s:</span>
<span class="example">johndoe@example.com</span>
</small>
</td>
<td></td>
</tr>
<tr>
<td align="right"><strong>%(new_password)s:</strong><br>
<small class="quicknote">(%(optional)s)</small>
</td><td align="left">
<input type="password" size="25" name="password" %(password_disabled)s value="%(password)s"><br>
<small><span class=quicknote>%(note)s:</span>
%(password_note)s
</small>
</td>
</tr>
<tr>
<td align="right"><strong>%(retype_password)s:</strong></td>
<td align="left">
<input type="password" size="25" name="password2" %(password_disabled)s value="">
</td>
<td><input type="hidden" name="action" value="edit"></td>
</tr>
<tr><td align="center" colspan="3">
<code class="blocknote"><input class="formbutton" type="submit" value="%(set_values)s"></code>&nbsp;&nbsp;&nbsp;
</td></tr>
</table>
</form>
""" % {
'change_user_pass' : _("If you want to change your email address or password, please set new values in the form below."),
'new_email' : _("New email address"),
'mandatory' : _("mandatory"),
'example' : _("Example"),
'new_password' : _("New password"),
'optional' : _("optional"),
'note' : _("Note"),
'password_note' : _("The password phrase may contain punctuation, spaces, etc."),
'retype_password' : _("Retype password"),
'set_values' : _("Set new values"),
'email' : email,
'email_disabled' : email_disabled and "disabled" or "",
'password' : password,
'password_disabled' : password_disabled and "disabled" or "",
}
return out
def tmpl_user_external_auth(self, ln, methods, current, method_disabled):
"""
Displays a form for the user to change his authentication method.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'methods' *array* - The methods of authentication
- 'method_disabled' *boolean* - If the user has the right to change this
- 'current' *string* - The currently selected method
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<form method="post" action="../youraccount.py/change">
<big><strong class="headline">%(edit_method)s</strong></big>
<p>%(explain_method)s:</p>
<table>
<tr><td valign="top"><b>%(select_method)s:</b></td><td>
""" % {
'edit_method' : _("Edit login method"),
'explain_method' : _("Please select which login method you would like to use to authenticate yourself"),
'select_method' : _("Select method"),
}
for system in methods:
out += """<input type="radio" name="login_method" value="%(system)s" %(disabled)s %(selected)s>%(system)s<br>""" % {
'system' : system,
'disabled' : method_disabled and "disabled" or "",
'selected' : current == system and "disabled" or "",
}
out += """ </td><td></td></tr>
<tr><td></td>
<td><input class="formbutton" type="submit" value="%(select_method)s"></td></tr></table>
</form>""" % {
'select_method' : _("Select method"),
}
return out
def tmpl_lost_password_form(self, ln, msg):
"""
Displays a form for the user to ask for his password sent by email.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'msg' *string* - Explicative message on top of the form.
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<form method="post" action="../youraccount.py/send_email">
%(msg)s
<table>
<tr>
<td align="right"><strong>%(email)s:</strong></td>
<td><input type="text" size="25" name="p_email" value=""></td>
<td><input type="hidden" name="action" value="lost"></td>
</tr>
<tr><td></td>
<td><code class="blocknote"><input class="formbutton" type="submit" value="%(send)s"></code></td>
</tr>
</table>
</form>
""" % {
'msg' : msg,
'email' : _("Email address"),
'send' : _("Send lost password"),
}
return out
def tmpl_account_info(self, ln, uid, guest, cfg_cern_site):
"""
Displays the account information
Parameters:
- 'ln' *string* - The language to display the interface in
- 'uid' *string* - The user id
- 'guest' *boolean* - If the user is guest
- 'cfg_cern_site' *boolean* - If the site is a CERN site
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<P>%(account_offer)s</P>
<blockquote>
<dl>
""" % {
'account_offer' : _("The CDS Search offers you a possibility to personalize the interface, to set up your own personal library of documents, or to set up an automatic alert query that would run periodically and would notify you of search results by email."),
}
if not guest:
out += """
<dt>
<A href="./edit?ln=%(ln)s">%(your_settings)s</A>
<dd>%(change_account)s""" % {
'ln' : ln,
'your_settings' : _("Your Settings"),
'change_account' : _("Set or change your account Email address or password. Specify your preferences about the way the interface looks like.")
}
out += """
<dt><A href="../youralerts.py/display?ln=%(ln)s">%(your_searches)s</A>
<dd>%(search_explain)s
<dt><A href="../yourbaskets.py/display?ln=%(ln)s">%(your_baskets)s</A>
<dd>%(basket_explain)s""" % {
'ln' : ln,
'your_searches' : _("Your Searches"),
'search_explain' : _("View all the searches you performed during the last 30 days."),
'your_baskets' : _("Your Baskets"),
'basket_explain' : _("With baskets you can define specific collections of items, store interesting records you want to access later or share with others."),
}
if guest:
out += self.tmpl_warning_guest_user(ln = ln, type = "baskets")
out += """
<dt><A href="../youralerts.py/list?ln=%s">%(your_alerts)s</A>
<dd>%(explain_alerts)s""" % {
'ln' : ln,
'your_alerts' : _("Your Alerts"),
'explain_alerts' : _("Subscribe to a search which will be run periodically by our service. The result can be sent to you via Email or stored in one of your baskets."),
}
if guest:
out += self.tmpl_warning_guest_user(type="alerts", ln = ln)
if cfg_cern_site:
out += """
<dt><A href="http://weblib.cern.ch/cgi-bin/checkloan?uid=&version=2">%(your_loans)s</A>
<dd>%(explain_loans)s""" % {
'your_loans' : _("Your Loans"),
'explain_loans' : _("Check out book you have on load, submit borrowing requests, etc. Requires CERN ID."),
}
out += """
</dl>
</blockquote>"""
return out
def tmpl_warning_guest_user(self, ln, type):
"""
Displays a warning message about the specified type
Parameters:
- 'ln' *string* - The language to display the interface in
- 'type' *string* - The type of data that will get lost in case of guest account
"""
# load the right message language
_ = gettext_set_language(ln)
msg= _("""You are logged in as a guest user, so your %s will disappear at the end of the current session. If you wish you can
<a href="../youraccount.py/login?ln=%s">login or register here</a>.""") % (type, ln)
return """<table class="errorbox" summary="">
<thead>
<tr>
<th class="errorboxheader">%s</th>
</tr>
</thead>
</table>""" % msg
def tmpl_account_body(self, ln, user):
"""
Displays the body of the actions of the user
Parameters:
- 'ln' *string* - The language to display the interface in
- 'user' *string* - The user name
"""
# load the right message language
_ = gettext_set_language(ln)
return _("""You are logged in as %s. You may want to a) <A href="../youraccount.py/logout?ln=%s">logout</A>; b) edit your <A href="../youraccount.py/edit?ln=%s">account settings</a>.""") % (user, ln, ln) + "<BR><BR>"
def tmpl_account_template(self, title, body, ln):
"""
Displays a block of the your account page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'title' *string* - The title of the block
- 'body' *string* - The body of the block
"""
out =""
out +="""
<table class="searchbox" width="90%%" summary="" >
<thead>
<tr>
<th class="searchboxheader">%s</th>
</tr>
</thead>
<tbody>
<tr>
<td class="searchboxbody">%s</td>
</tr>
</tbody>
</table>""" % (title, body)
return out
def tmpl_account_page(self, ln, weburl, accBody, baskets, alerts, searches, messages, administrative):
"""
Displays the your account page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The URL of cdsware
- 'accBody' *string* - The body of the heading block
- 'baskets' *string* - The body of the baskets block
- 'alerts' *string* - The body of the alerts block
- 'searches' *string* - The body of the searches block
- 'messages' *string* - The body of the messages block
- 'administrative' *string* - The body of the administrative block
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
out += self.tmpl_account_template(_("Your Account"), accBody, ln)
#your baskets
out += self.tmpl_account_template(_("Your Baskets"), baskets, ln)
out += self.tmpl_account_template(_("Your Messages"), messages, ln)
out += self.tmpl_account_template(_("Your Alert Searches"), alerts, ln)
out += self.tmpl_account_template(_("Your Searches"), searches, ln)
out += self.tmpl_account_template(_("Your Submissions"),
_("You can consult the list of %(your_submissions)s and inquire about their status.") % {
'your_submissions' :
"""<a href="%(weburl)s/yoursubmissions.py?ln=%(ln)s">%(your_sub)s</a>""" % {
'ln' : ln,
'weburl' : weburl,
'your_sub' : _("your submissions")
}
}, ln)
out += self.tmpl_account_template(_("Your Approvals"),
_("You can consult the list of %(your_approvals)s with the documents you approved or refereed.") % {
'your_approvals' :
""" <a href="%(weburl)s/yourapprovals.py?ln=%(ln)s">%(your_app)s</a>""" % {
'ln' : ln,
'weburl' : weburl,
'your_app' : _("your approvals"),
}
}, ln)
out += self.tmpl_account_template(_("Your Administrative Activities"), administrative, ln)
return out
def tmpl_account_emailMessage(self, ln, msg):
"""
Displays a link to retrieve the lost password
Parameters:
- 'ln' *string* - The language to display the interface in
- 'msg' *string* - Explicative message on top of the form.
"""
# load the right message language
_ = gettext_set_language(ln)
out =""
out +="""
<body>
%(msg)s <A href="../youraccount.py/lost?ln=%(ln)s">%(try_again)s</A>
</body>
""" % {
'ln' : ln,
'msg' : msg,
'try_again' : _("Try again")
}
return out
def tmpl_account_emailSent(self, ln, email):
"""
Displays a confirmation message for an email sent
Parameters:
- 'ln' *string* - The language to display the interface in
- 'email' *string* - The email to which the message has been sent
"""
# load the right message language
_ = gettext_set_language(ln)
out =""
out += _("Okay, password has been emailed to %s") % email
return out
def tmpl_account_delete(self, ln):
"""
Displays a confirmation message about deleting the account
Parameters:
- 'ln' *string* - The language to display the interface in
"""
# load the right message language
_ = gettext_set_language(ln)
out = "<p>" + _("""Deleting your account""")
return out
def tmpl_account_logout(self, ln):
"""
Displays a confirmation message about logging out
Parameters:
- 'ln' *string* - The language to display the interface in
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
out += _("""You are no longer recognized. If you wish you can <A href="./login?ln=%s">login here</A>.""") % ln
return out
def tmpl_login_form(self, ln, referer, internal, register_available, methods, selected_method, supportemail):
"""
Displays a login form
Parameters:
- 'ln' *string* - The language to display the interface in
- 'referer' *string* - The referer URL - will be redirected upon after login
- 'internal' *boolean* - If we are producing an internal authentication
- 'register_available' *boolean* - If users can register freely in the system
- 'methods' *array* - The available authentication methods
- 'selected_method' *string* - The default authentication method
- 'supportemail' *string* - The email of the support team
"""
# load the right message language
_ = gettext_set_language(ln)
out = "<p>%(please_login)s<br>" % {
'please_login' : _("If you already have an account, please login using the form below.")
}
if register_available:
out += _("""If you don't own an account yet, please <a href="../youraccount.py/register?ln=%s">register</a> an internal account.""") % ln
else:
out += _("""It is not possible to create an account yourself. Contact %s if you want an account.""") % (
"""<a href="mailto:%(email)s">%(email)s</a>""" % { 'email' : supportemail }
)
out += """<form method="post" action="../youraccount.py/login">
<table>
"""
if len(methods) > 1:
# more than one method, must make a select
login_select = """<select name="login_method">"""
for method in methods:
login_select += """<option value="%(method)s" %(selected)s>%(method)s</option>""" % {
'method' : method,
'selected' : (method == selected_method and "selected" or "")
}
login_select += "</select>"
out += """
<tr>
<td align="right">%(login_title)s</td>
<td>%(login_select)s</td>
<td></td>
</tr>""" % {
'login_title' : _("Login via:"),
'login_select' : login_select,
}
else:
# only one login method available
out += """<input type="hidden" name="login_method" value="%s">""" % (methods[0])
out += """<tr>
<td align="right">
<input type="hidden" name="ln" value="%(ln)s">
<input type="hidden" name="referer" value="%(referer)s">
<strong>%(username)s:</strong>
</td>
<td><input type="text" size="25" name="p_email" value=""></td>
<td></td>
</tr>
<tr>
<td align="right"><strong>%(password)s:</strong></td>
<td align="left"><input type="password" size="25" name="p_pw" value=""></td>
<td></td>
</tr>
<tr>
<td></td>
<td align="center" colspan="3"><code class="blocknote"><input class="formbutton" type="submit" name="action" value="%(login)s"></code>""" % {
'ln': ln,
'referer' : cgi.escape(referer),
'username' : _("Username"),
'password' : _("Password"),
'login' : _("login"),
}
if internal:
out += """&nbsp;&nbsp;&nbsp;(<a href="./lost?ln=%(ln)s">%(lost_pass)s</a>)""" % {
'ln' : ln,
'lost_pass' : _("Lost your password?")
}
out += """</td><td></td>
</tr>
</table></form>"""
return out
def tmpl_register_page(self, ln, referer, level, supportemail, cdsname):
"""
Displays a login form
Parameters:
- 'ln' *string* - The language to display the interface in
- 'referer' *string* - The referer URL - will be redirected upon after login
- 'level' *int* - Login level (0 - all access, 1 - accounts activated, 2+ - no self-registration)
- 'supportemail' *string* - The email of the support team
- 'cdsname' *string* - The name of the installation
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if level <= 1:
out += _("""Please enter your email address and desired password:""")
if level == 1:
out += _("The account will not be possible to use before it has been verified and activated.")
out += """
<form method="post" action="../youraccount.py/register">
<input type="hidden" name="referer" value="%(referer)s">
<table>
<tr>
<td align="right"><strong>%(email_address)s:</strong><br><small class="important">(%(mandatory)s)</small></td>
<td><input type="text" size="25" name="p_email" value=""><br>
<small><span class="quicknote">%(example)s:</span>
<span class="example">johndoe@example.com</span></small>
</td>
<td></td>
</tr>
<tr>
<td align="right"><strong>%(password)s:</strong><br><small class="quicknote">(%(optional)s)</small></td>
<td align="left"><input type="password" size="25" name="p_pw" value=""><br>
<small><span class="quicknote">%(note)s:</span> %(password_contain)s</small>
</td>
<td></td>
</tr>
<tr>
<td align="right"><strong>%(retype)s:</strong></td>
<td align="left"><input type="password" size="25" name="p_pw2" value=""></td>
<td></td>
</tr>
<tr>
<td></td>
<td align="left" colspan="3"><code class="blocknote"><input class="formbutton" type="submit" name="action" value="%(register)s"></code></td>
</tr>
</table>
<p><strong>%(note)s:</strong> %(explain_acc)s""" % {
'referer' : cgi.escape(referer),
'email_address' : _("Email address"),
'password' : _("Password"),
'mandatory' : _("mandatory"),
'optional' : _("optional"),
'example' : _("Example"),
'note' : _("Note"),
'password_contain' : _("The password phrase may contain punctuation, spaces, etc."),
'retype' : _("Retype Password"),
'register' : _("register"),
'explain_acc' : _("Please do not use valuable passwords such as your Unix, AFS or NICE passwords with this service. Your email address will stay strictly confidential and will not be disclosed to any third party. It will be used to identify you for personal services of %s. For example, you may set up an automatic alert search that will look for new preprints and will notify you daily of new arrivals by email.") % cdsname,
}
return out
def tmpl_account_adminactivities(self, ln, weburl, uid, guest, roles, activities):
"""
Displays the admin activities block for this user
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The address of the site
- 'uid' *string* - The used id
- 'guest' *boolean* - If the user is guest
- 'roles' *array* - The current user roles
- 'activities' *array* - The user allowed activities
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
# guest condition
if guest:
return _("""You seem to be the guest user. You have to <a href="../youraccount.py/login?ln=%s">login</a> first.""") % ln
# no rights condition
if not roles:
return "<p>" + _("You are not authorized to access administrative functions.") + "</p>"
# displaying form
out += "<p>" + _("You seem to be <em>%s</em>.") % string.join(roles, ", ") + " "
out += _("Here are some interesting web admin links for you:")
# print proposed links:
activities.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
for action in activities:
if action == "cfgbibformat":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibformat/?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibFormat"))
if action == "cfgbibharvest":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibharvest/bibharvestadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibHarvest"))
if action == "cfgbibindex":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibindex/bibindexadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibIndex"))
if action == "cfgbibrank":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/bibrank/bibrankadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure BibRank"))
if action == "cfgwebaccess":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/webaccess/?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebAccess"))
if action == "cfgwebcomment":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/webcomment/webcommentadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebComment"))
if action == "cfgwebsearch":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/websearch/websearchadmin.py?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebSearch"))
if action == "cfgwebsubmit":
out += """<br>&nbsp;&nbsp;&nbsp; <a href="%s/admin/websubmit/?ln=%s">%s</a>""" % (weburl, ln, _("Configure WebSubmit"))
out += "<br>" + _("""For more admin-level activities, see the complete %(admin_area)s""") % {
'admin_area' : """<a href="%s/admin/index.%s.html">%s</a>.""" % (weburl, ln, _("Admin Area"))
}
return out
def tmpl_create_userinfobox(self, ln, weburl, guest, email, submitter, referee, admin):
"""
Displays the user block
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The address of the site
- 'guest' *boolean* - If the user is guest
- 'email' *string* - The user email (if known)
- 'submitter' *boolean* - If the user is submitter
- 'referee' *boolean* - If the user is referee
- 'admin' *boolean* - If the user is admin
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<img src="%s/img/head.gif" border="0" alt="">""" % weburl
if guest:
out += """%(guest_msg)s ::
<a class="userinfo" href="%(weburl)s/youraccount.py/display?ln=%(ln)s">%(session)s</a> ::
<a class="userinfo" href="%(weburl)s/youralerts.py/list?ln=%(ln)s">%(alerts)s</a> ::
<a class="userinfo" href="%(weburl)s/yourbaskets.py/display?ln=%(ln)s">%(baskets)s</a> ::
<a class="userinfo" href="%(weburl)s/youraccount.py/login?ln=%(ln)s">%(login)s</a>""" % {
'weburl' : weburl,
'ln' : ln,
'guest_msg' : _("guest"),
'session' : _("session"),
'alerts' : _("alerts"),
'baskets' : _("baskets"),
'login' : _("login"),
}
else:
out += """%(email)s ::
<a class="userinfo" href="%(weburl)s/youraccount.py/display?ln=%(ln)s">%(account)s</a> ::
<a class="userinfo" href="%(weburl)s/youralerts.py/list?ln=%(ln)s">%(alerts)s</a> ::
<a class="userinfo" href="%(weburl)s/yourmessages.py/display?ln=%(ln)s">%(messages)s</a> ::
<a class="userinfo" href="%(weburl)s/yourbaskets.py/display?ln=%(ln)s">%(baskets)s</a> :: """ % {
'email' : email,
'weburl' : weburl,
'ln' : ln,
'account' : _("account"),
'alerts' : _("alerts"),
'messages': _("messages"),
'baskets' : _("baskets"),
}
if submitter:
out += """<a class="userinfo" href="%(weburl)s/yoursubmissions.py?ln=%(ln)s">%(submission)s</a> :: """ % {
'weburl' : weburl,
'ln' : ln,
'submission' : _("submissions"),
}
if referee:
out += """<a class="userinfo" href="%(weburl)s/yourapprovals.py?ln=%(ln)s">%(approvals)s</a> :: """ % {
'weburl' : weburl,
'ln' : ln,
'approvals' : _("approvals"),
}
if admin:
out += """<a class="userinfo" href="%(weburl)s/youraccount.py/youradminactivities?ln=%(ln)s">%(administration)s</a> :: """ % {
'weburl' : weburl,
'ln' : ln,
'administration' : _("administration"),
}
out += """<a class="userinfo" href="%(weburl)s/youraccount.py/logout?ln=%(ln)s">%(logout)s</a>""" % {
'weburl' : weburl,
'ln' : ln,
'logout' : _("logout"),
}
return out
diff --git a/modules/websession/lib/webuser.py b/modules/websession/lib/webuser.py
index 14a9f8499..878691cfb 100644
--- a/modules/websession/lib/webuser.py
+++ b/modules/websession/lib/webuser.py
@@ -1,602 +1,602 @@
## $Id$
## CDSware User related utilities.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
This file implements all methods necessary for working with users and sessions in cdsware.
Contains methods for logging/registration when a user log/register into the system, checking if it
is a guest user or not.
At the same time this presents all the stuff it could need with sessions managements, working with websession.
It also contains Apache-related user authentication stuff.
"""
from marshal import loads,dumps
from zlib import compress,decompress
import sys
import time
import os
import crypt
import string
import smtplib
import MySQLdb
from cdsware import session, websession
from cdsware.dbquery import run_sql
from cdsware.websession import pSession, pSessionMapping
from cdsware.session import SessionError
from cdsware.config import *
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_findUserRoleActions
from cdsware.access_control_config import *
from cdsware.messages import gettext_set_language
import cdsware.template
tmpl = cdsware.template.load('websession')
def createGuestUser():
"""Create a guest user , insert into user null values in all fields
createGuestUser() -> GuestUserID
"""
if CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0:
return run_sql("insert into user (email, note) values ('', '1')")
elif CFG_ACCESS_CONTROL_LEVEL_GUESTS >= 1:
return run_sql("insert into user (email, note) values ('', '0')")
def page_not_authorized(req, referer='', uid='', text='', navtrail=''):
"""Show error message when account is not activated"""
from cdsware.webpage import page
if not CFG_ACCESS_CONTROL_LEVEL_SITE:
title = cfg_webaccess_msgs[5]
if not uid: uid = getUid(req)
res = run_sql("SELECT email FROM user WHERE id=%s" % uid)
if res and res[0][0]:
if text: body = text
else: body = "%s %s" % (cfg_webaccess_warning_msgs[9] % res[0][0], ("%s %s" % (cfg_webaccess_msgs[0] % referer, cfg_webaccess_msgs[1])))
else:
if text: body = text
else: body = cfg_webaccess_msgs[3]
elif CFG_ACCESS_CONTROL_LEVEL_SITE == 1:
title = cfg_webaccess_msgs[8]
body = "%s %s" % (cfg_webaccess_msgs[7], cfg_webaccess_msgs[2])
elif CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
title = cfg_webaccess_msgs[6]
body = "%s %s" % (cfg_webaccess_msgs[4], cfg_webaccess_msgs[2])
return page(title=title,
uid=getUid(req),
body=body,
navtrail=navtrail)
def getUid (req):
"""It gives the userId taking it from the cookie of the request,also has the control mechanism for the guest users,
inserting in the MySql table when need it, and raise the cookie to the client.
getUid(req) -> userId
"""
if CFG_ACCESS_CONTROL_LEVEL_SITE == 1: return 0
if CFG_ACCESS_CONTROL_LEVEL_SITE == 2: return -1
guest = 0
sm = session.MPSessionManager(pSession, pSessionMapping())
try:
s = sm.get_session(req)
except SessionError,e:
sm.revoke_session_cookie (req)
s = sm.get_session(req)
userId = s.getUid()
if userId == -1: # first time, so create a guest user
s.setUid(createGuestUser())
userId = s.getUid()
guest = 1
sm.maintain_session(req,s)
if guest == 0:
guest = isGuestUser(userId)
if guest:
if CFG_ACCESS_CONTROL_LEVEL_GUESTS == 0:
return userId
elif CFG_ACCESS_CONTROL_LEVEL_GUESTS >= 1:
return -1
else:
res = run_sql("SELECT note FROM user WHERE id=%s" % userId)
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 0:
return userId
elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1 and res and res[0][0] in [1, "1"]:
return userId
else:
return -1
def setUid(req,uid):
"""It sets the userId into the session, and raise the cookie to the client.
"""
sm = session.MPSessionManager(pSession, pSessionMapping())
try:
s = sm.get_session(req)
except SessionError,e:
sm.revoke_session_cookie (req)
s = sm.get_session(req)
s.setUid(uid)
sm.maintain_session(req,s)
return uid
def get_user_info(uid, ln=cdslang):
"""Get infos for a given user.
@param uid: user id (int)
@return tuple: (uid, nickname, display_name)
"""
_ = gettext_set_language(ln)
query = """SELECT id, nickname
FROM user
WHERE id=%i"""
res = run_sql(query%uid)
if res:
if res[0]:
user = list(res[0])
if user[1]:
user.append(user[1])
else:
user[1] = str(user[0])
user.append(_("user #%i")% user[0])
return tuple(user)
return (uid, '', _("N/A"))
def isGuestUser(uid):
"""It Checks if the userId corresponds to a guestUser or not
isGuestUser(uid) -> boolean
"""
out = 1
try:
res = run_sql("select email from user where id=%s", (uid,))
if res:
if res[0][0]:
out = 0
except:
pass
return out
def isUserSubmitter(uid):
u_email = get_email(uid)
res = run_sql("select * from sbmSUBMISSIONS where email=%s",(u_email,))
if len(res) > 0:
return 1
else:
return 0
def isUserReferee(uid):
res = run_sql("select sdocname from sbmDOCTYPE")
for row in res:
doctype = row[0]
categ = "*"
(auth_code, auth_message) = acc_authorize_action(uid, "referee",doctype=doctype, categ=categ)
if auth_code == 0:
return 1
res2 = run_sql("select sname from sbmCATEGORIES where doctype=%s",(doctype,))
for row2 in res2:
categ = row2[0]
(auth_code, auth_message) = acc_authorize_action(uid, "referee",doctype=doctype, categ=categ)
if auth_code == 0:
return 1
return 0
def isUserAdmin(uid):
"Return 1 if the user UID has some admin rights; 0 otherwise."
out = 0
if acc_findUserRoleActions(uid):
out = 1
return out
def checkRegister(user,passw):
"""It checks if the user is register with the correct password
checkRegister(user,passw) -> boolean
"""
query_result = run_sql("select * from user where email=%s and password=%s", (user,passw))
if len(query_result)> 0 :
return 0
return 1
def userOnSystem(user):
"""It checks if the user is registered already on the system
"""
query_register = run_sql("select * from user where email=%s", (user,))
if len(query_register)>0:
return 1
return 0
def checkemail(email):
"""Check whether the EMAIL address supplied by the user is valid.
At the moment we just check whether it contains '@' and
whether it doesn't contain blanks.
checkemail(email) -> boolean
"""
if (string.find(email, "@") <= 0) or (string.find(email, " ") > 0):
return 0
elif CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN:
if not email.endswith(CFG_ACCESS_CONTROL_LIMIT_REGISTRATION_TO_DOMAIN):
return 0
return 1
def getDataUid(req,uid):
"""It takes the email and password from a given userId, from the MySQL database, if don't exist it just returns
guest values for email and password
getDataUid(req,uid) -> [email,password]
"""
email = 'guest'
password = 'none'
query_result = run_sql("select email, password from user where id=%s", (uid,))
if len(query_result)>0:
email = query_result[0][0]
password = query_result[0][1]
if password == None or email =='':
email = 'guest'
list = [email] +[password]
return list
def registerUser(req,user,passw):
"""It registers the user, inserting into the user table of MySQL database, the email and the pasword
of the user. It returns 1 if the insertion is done, 0 if there is any failure with the email
and -1 if the user is already on the data base
registerUser(req,user,passw) -> int
"""
if userOnSystem(user) and user !='':
return -1
if checkRegister(user,passw) and checkemail(user):
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 0:
activated = 1
elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
activated = 0
elif CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
return 0
user_preference = get_default_user_preferences()
setUid(req, run_sql("INSERT INTO user (email, password, note, settings) VALUES (%s,%s,%s,%s)",
(user,passw,activated,serialize_via_marshal(user_preference),)))
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT:
sendNewUserAccountWarning(user, user, passw)
if CFG_ACCESS_CONTROL_NOTIFY_ADMIN_ABOUT_NEW_ACCOUNTS:
sendNewAdminAccountWarning(user, adminemail)
return 1
return 0
def updateDataUser(req,uid,email,password):
"""It updates the data from the user. It is used when a user set his email and password
"""
if email =='guest':
return 0
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
query_result = run_sql("update user set password=%s where id=%s", (password,uid))
else:
query_result = run_sql("update user set email=%s,password=%s where id=%s", (email,password,uid))
return 1
def loginUser(req, p_email,p_pw, login_method):
"""It is a first simple version for the authentication of user. It returns the id of the user,
for checking afterwards if the login is correct
"""
user_prefs = get_user_preferences(emailUnique(p_email))
if user_prefs and login_method != user_prefs["login_method"]:
if CFG_EXTERNAL_AUTHENTICATION.has_key(user_prefs["login_method"]):
return ([], p_email, p_pw, 11)
if not CFG_EXTERNAL_AUTHENTICATION.has_key(login_method):
return ([], p_email, p_pw, 12)
if CFG_EXTERNAL_AUTHENTICATION[login_method][0]:
p_email = CFG_EXTERNAL_AUTHENTICATION[login_method][0].auth_user(p_email, p_pw)
if p_email:
p_pw = givePassword(p_email)
if not p_pw or p_pw < 0:
import random
p_pw = int(random.random() * 1000000)
if not registerUser(req,p_email,p_pw):
return ([], p_email, p_pw, 13)
else:
query_result = run_sql("SELECT id from user where email=%s and password=%s", (p_email,p_pw,))
user_prefs = get_user_preferences(query_result[0][0])
user_prefs["login_method"] = login_method
set_user_preferences(query_result[0][0], user_prefs)
else:
return ([], p_email, p_pw, 10)
query_result = run_sql("SELECT id from user where email=%s and password=%s", (p_email,p_pw,))
if query_result:
prefered_login_method = get_user_preferences(query_result[0][0])['login_method']
else:
return ([], p_email, p_pw, 14)
if login_method != prefered_login_method:
if CFG_EXTERNAL_AUTHENTICATION.has_key(prefered_login_method):
return ([], p_email, p_pw, 11)
return (query_result, p_email, p_pw, 0)
def logoutUser(req):
"""It logout the user of the system, creating a guest user.
"""
uid = getUid(req)
sm = session.MPSessionManager(pSession, pSessionMapping())
try:
s = sm.get_session(req)
except SessionError,e:
sm.revoke_session_cookie (req)
s = sm.get_session(req)
id1 = createGuestUser()
s.setUid(id1)
sm.maintain_session(req,s)
return id1
def userNotExist(p_email,p_pw):
"""Check if the user exists or not in the system
"""
query_result = run_sql("select email from user where email=%s", (p_email,))
if len(query_result)>0 and query_result[0]!='':
return 0
return 1
def emailUnique(p_email):
"""Check if the email address only exists once. If yes, return userid, if not, -1
"""
query_result = run_sql("select id, email from user where email=%s", (p_email,))
if len(query_result) == 1:
return query_result[0][0]
elif len(query_result) == 0:
return 0
return -1
def update_Uid(req,p_email,p_pw):
"""It updates the userId of the session. It is used when a guest user is logged in succesfully in the system
with a given email and password
"""
query_ID = int(run_sql("select id from user where email=%s and password=%s",
(p_email,p_pw))[0][0])
setUid(req,query_ID)
return query_ID
def givePassword(email):
""" It checks in the database the password for a given email. It is used to send the password to the email of the user.It returns
the password if the user exists, otherwise it returns -999
"""
query_pass = run_sql("select password from user where email =%s",(email,))
if len(query_pass)>0:
return query_pass[0][0]
return -999
def sendNewAdminAccountWarning(newAccountEmail, sendTo, ln=cdslang):
"""Send an email to the address given by sendTo about the new account newAccountEmail."""
fromaddr = "From: %s" % supportemail
toaddrs = "To: %s" % sendTo
to = toaddrs + "\n"
sub = "Subject: New account on '%s'" % cdsname
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
sub += " - PLEASE ACTIVATE"
sub += "\n\n"
body = "A new account has been created on '%s'" % cdsname
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS == 1:
body += " and is awaiting activation"
body += ":\n\n"
body += " Username/Email: %s\n\n" % newAccountEmail
body += "You can approve or reject this account request at: %s/admin/webaccess/webaccessadmin.py/manageaccounts\n" % weburl
body += "\n---------------------------------"
body += "\n%s" % cdsname
body += "\nContact: %s" % supportemail
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
return 0
server.quit()
return 1
def sendNewUserAccountWarning(newAccountEmail, sendTo, password, ln=cdslang):
"""Send an email to the address given by sendTo about the new account newAccountEmail."""
fromaddr = "From: %s" % supportemail
toaddrs = "To: %s" % sendTo
to = toaddrs + "\n"
sub = "Subject: Your account created on '%s'\n\n" % cdsname
body = "You have created a new account on '%s':\n\n" % cdsname
body += " Username/Email: %s\n" % newAccountEmail
body += " Password: %s\n\n" % ("*" * len(password))
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1:
body += "This account is awaiting approval by the site administrators and therefore cannot be used as of yet.\nYou will receive an email notification as soon as your account request has been processed.\n"
body += "\n---------------------------------"
body += "\n%s" % cdsname
body += "\nContact: %s" % supportemail
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
return 0
server.quit()
return 1
def get_email(uid):
"""Return email address of the user uid. Return string 'guest' in case
the user is not found."""
out = "guest"
res = run_sql("SELECT email FROM user WHERE id=%s", (uid,), 1)
if res and res[0][0]:
out = res[0][0]
return out
def create_userinfobox_body(uid, language="en"):
"""Create user info box body for user UID in language LANGUAGE."""
out = ""
return tmpl.tmpl_create_userinfobox(
ln = language,
weburl = weburl,
guest = isGuestUser(uid),
email = get_email(uid),
submitter = isUserSubmitter(uid),
referee = isUserReferee(uid),
admin = isUserAdmin(uid),
)
def list_registered_users():
"""List all registered users."""
return run_sql("SELECT id,email FROM user where email!=''")
def list_users_in_role(role):
"""List all users of a given role (see table accROLE)
@param role: role of user (string)
@return list of uids
"""
query = """SELECT uacc.id_user
FROM user_accROLE uacc JOIN accROLE acc
ON uacc.id_accROLE=acc.id
WHERE acc.name='%s'"""
res = run_sql(query% MySQLdb.escape_string(role))
if res:
return map(lambda x: int(x[0]), res)
return []
def list_users_in_roles(role_list):
"""List all users of given roles (see table accROLE)
@param role_list: list of roles [string]
@return list of uids
"""
if not(type(role_list) is list or type(role_list) is tuple):
role_list = [role_list]
params=''
query = """SELECT distinct(uacc.id_user)
FROM user_accROLE uacc JOIN accROLE acc
ON uacc.id_accROLE=acc.id
%s"""
if len(role_list) > 0:
params = 'WHERE '
for role in role_list[:-1]:
params += "acc.name='%s' OR " % MySQLdb.escape_string(role)
params += "acc.name='%s'" % MySQLdb.escape_string(role_list[-1])
res = run_sql(query% params)
if res:
return map(lambda x: int(x[0]), res)
return []
## --- follow some functions for Apache user/group authentication
def auth_apache_user_p(user, password):
"""Check whether user-supplied credentials correspond to valid
Apache password data file. Return 0 in case of failure, 1 in case
of success."""
try:
pipe_input, pipe_output = os.popen2(["/bin/grep", "^" + user + ":", cfg_apache_password_file], 'r')
line = pipe_output.readlines()[0]
password_apache = string.split(string.strip(line),":")[1]
except: # no pw found, so return not-allowed status
return 0
salt = password_apache[:2]
if crypt.crypt(password, salt) == password_apache:
return 1
else:
return 0
def auth_apache_user_in_groups(user):
"""Return list of Apache groups to which Apache user belong."""
out = []
try:
pipe_input,pipe_output = os.popen2(["/bin/grep", user, cfg_apache_group_file], 'r')
for line in pipe_output.readlines():
out.append(string.split(string.strip(line),":")[0])
except: # no groups found, so return empty list
pass
return out
def auth_apache_user_collection_p(user, password, coll):
"""Check whether user-supplied credentials correspond to valid
Apache password data file, and whether this user is authorized to
see the given collections. Return 0 in case of failure, 1 in case
of success."""
from cdsware.search_engine import coll_restricted_p, coll_restricted_group
if not auth_apache_user_p(user, password):
return 0
if not coll_restricted_p(coll):
return 1
if coll_restricted_group(coll) in auth_apache_user_in_groups(user):
return 1
else:
return 0
def get_user_preferences(uid):
pref = run_sql("SELECT id, settings FROM user WHERE id=%s", (uid,))
if pref:
try:
return deserialize_via_marshal(pref[0][1])
except:
return get_default_user_preferences()
return None
def set_user_preferences(uid, pref):
res = run_sql("UPDATE user SET settings='%s' WHERE id=%s" % (serialize_via_marshal(pref),uid))
def get_default_user_preferences():
user_preference = {
'login_method': ''}
for system in CFG_EXTERNAL_AUTHENTICATION.keys():
if CFG_EXTERNAL_AUTHENTICATION[system][1]:
user_preference['login_method'] = system
break
return user_preference
def serialize_via_marshal(obj):
"""Serialize Python object via marshal into a compressed string."""
return MySQLdb.escape_string(compress(dumps(obj)))
def deserialize_via_marshal(string):
"""Decompress and deserialize string into a Python object via marshal."""
return loads(decompress(string))
diff --git a/modules/websession/web/Makefile.am b/modules/websession/web/Makefile.am
index ad6d5157b..26ab167b3 100644
--- a/modules/websession/web/Makefile.am
+++ b/modules/websession/web/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)
webapp_DATA = sessinit.inc.php youraccount.py
EXTRA_DIST = sessinit.inc.php.wml youraccount.py
CLEANFILES = sessinit.inc.php *~ *.tmp
sessinit.inc.php: sessinit.inc.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/websession/web/sessinit.inc.php.wml b/modules/websession/web/sessinit.inc.php.wml
index 7c12a9b38..246795edf 100644
--- a/modules/websession/web/sessinit.inc.php.wml
+++ b/modules/websession/web/sessinit.inc.php.wml
@@ -1,330 +1,330 @@
## $Id$
## Purpose: initializes CDS session management
##
## Note: based on the "PHP4 MySQL Session Handler" code from Ying
## Zhang <ying@zippydesign.com>. His code was modified to
## suit our needs.
##
## Note: for good session management operation, you need to set up in
## the 'php.ini' file the variables `session.gc_maxlifetime'
## (e.g. 86400 to mean 1 day) and `session.cookie_lifetime' to
## zero (session holds until user closes his browser). In
## adddition, the garbage collector should be called explicitely
## via `admin/gc.shtml' if you choose `session.gc_probability'
## to be zero in the `php.ini' file.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
$DBHOST = "<DBHOST>";
$DBUSER = "<DBUSER>";
$DBPASS = "<DBPASS>";
$DBNAME = "<DBNAME>";
$WEBDIR = "<WEBDIR>";
$WEBURL = "<WEBURL>";
$BINDIR = "<BINDIR>";
$ADMINEMAIL = "<ADMINEMAIL>";
$IMAGES = "<WEBURL>/img";
### okay, config read, from now on the script can continue ###
<protect>
$SESS_DBHOST = $DBHOST; /* database server hostname */
$SESS_DBNAME = $DBNAME; /* database name */
$SESS_DBUSER = $DBUSER; /* database user */
$SESS_DBPASS = $DBPASS; /* database password */
$SESS_DBH = "";
## open_db_connection():
function open_db_connection() {
## Open persistent connection to the database.
global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH;
if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) {
echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER";
echo "<li>MySQL Error: ", mysql_error();
die;
}
if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) {
echo "<li>Unable to select database $SESS_DBNAME";
die;
}
return true;
}
## getUid($cookie_string):
function getUid($cookie_string) {
## Read cookie string, look up the session table, and return userID.
## If this cookie is not found, then return 0.
global $SESS_DBH;
$uid = 0;
$query = "SELECT uid FROM session WHERE session_key='$cookie_string'";
$res = mysql_perform_query($query, $SESS_DBH);
if ($row = mysql_fetch_row($res)) {
if ($row[0]) {
$uid = $row[0];
}
}
mysql_free_result($res);
return($uid);
}
## getEmail():
function getEmail($uid) {
## Return user email out of his UID.
global $SESS_DBH;
$uid_email = "guest";
$query = "SELECT email FROM user WHERE id='$uid'";
$res = mysql_perform_query($query, $SESS_DBH);
if ($row = mysql_fetch_row($res)) {
if ($row[0]) {
$uid_email = $row[0];
}
}
mysql_free_result($res);
return($uid_email);
}
function acc_authorize_action($uid, $action) {
## Authorize where $uid can perform $action by calling external
## Python CLI API of WebAccess.
## Return 1 when allowed, 0 otherwise.
global $BINDIR;
$auth = exec($BINDIR."/authaction ". escapeshellarg($uid) . " " . escapeshellarg($action));
return split(" - ",$auth, 2);
}
function authenticate($email,$rule,$doctype="*",$action="*")
{
global $ADMINEMAIL;
if (eregi($ADMINEMAIL,"$email"))
return true;
$res = mysql_query("select id from rules where name='superuser'");
$row = mysql_fetch_row($res);
$id_superuser = $row[0];
$res = mysql_query("select id_user from user_rule where id_rule='${id_superuser}' and (param1='$doctype' or param1='*') and (param2 LIKE '$action' or param2='*')");
while ($row = mysql_fetch_row($res))
{
$iduser = $row[0];
$emailuser = getEmail($iduser);
if (eregi("$email","$emailuser"))
return true;
}
$res = mysql_query("select id from rules where name='$rule'");
if (mysql_num_rows($res) == 0)
return false;
else
{
$row = mysql_fetch_row($res);
$idrule = $row[0];
$res = mysql_query("select id_user from user_rule where id_rule='$idrule' and (param1 LIKE '$doctype' or param1='*') and (param2 LIKE '$action' or param2='*')");
while ($row = mysql_fetch_row($res))
{
$iduser = $row[0];
$emailuser = getEmail($iduser);
if (eregi("$email","$emailuser"))
return true;
}
return false;
}
}
function getRuleID($rule)
{
////////////////////////////
// get the id of the rule //
////////////////////////////
$res = mysql_query("
SELECT id
FROM rules
WHERE name='$rule'");
if (mysql_num_rows($res) == 0)
{
// if it does not exist, attempt to create it
$res = mysql_query("
INSERT
INTO rules (name,description)
VALUES ('$rule','')");
$idrule = mysql_insert_id();
}
else
{
$row = mysql_fetch_row($res);
$idrule = $row[0];
}
return $idrule;
}
function mysql_perform_query($query, $link_identifier, $behaviour="die") {
## Function to call as an alternative to mysql_query. The function
## stops the execution if the query couldn't be executed and
## prints an error message (HTML formatted) (default behaviour). If
## behaviour is set to 'continue', then the function just goes on.
if($behaviour == "continue")
$result = mysql_query($query, $link_identifier);
else {
$result = mysql_query($query, $link_identifier)
or die ("<p>MySQL: could not execute your query<br>$query" .
"<br>Contact the <a href=\"mailto:search.support@cds.cern.ch\">" .
"CDS Support Team</a>.<br>" .
"Error " . mysql_errno($link_identifier) .
": " . mysql_error($link_identifier) . ".</p>");
}
return $result;
}
## displayLoginMenu()
function displayLoginMenu($type) {
global $WEBDIR,$WEBURL,$uid_email,$doctypes;
print '<table width=100% cellpadding=0 cellspacing=0 border=0>';
print '<tr><td>&nbsp;<small><b>PERSONALIZE</b></small></td></tr>';
if ($uid_email != "" && $uid_email != "guest")
{
print '<tr><td>'
. '<form action="'.$WEBURL.'/personalize/youraccount.shtml?action='
. 'logout" method="post"><small>&nbsp;&nbsp;&nbsp;<strong>logged in as:</strong>'
. '<br><font color="green">&nbsp;&nbsp;&nbsp;&nbsp;'.$uid_email.'</font>'
. '</td></tr>';
if (authenticate($uid_email,'superuser'))
{
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;<strong>superuser:&nbsp;</strong>'
. '</font></td></tr>';
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/admin">'
. 'administrative&nbsp;area</A></font></td></tr>';
}
if ($type == "search")
{
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/personalize/youralerts.shtml">'
. 'Your&nbsp;Alerts</A></font></td></tr>';
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/personalize/yourbaskets.shtml">'
. 'Your&nbsp;Baskets</A></font></td></tr>';
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/personalize/yoursearches.shtml">'
. 'Your&nbsp;Searches</A></font></td></tr>';
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/personalize/yoursettings.shtml">'
. 'Your&nbsp;Settings</A></font></td></tr>';
}
if ($type == "submit")
{
$res = mysql_query("
SELECT *
FROM sbmSUBMISSIONS
WHERE email='$uid_email' and
status='pending'");
$numpending = mysql_num_rows($res);
$res = mysql_query("
SELECT *
FROM sbmSUBMISSIONS
WHERE email='$uid_email' and
status='finished'");
$numfinished = mysql_num_rows($res);
if ($doctypes != "account" || $numpending != 0 || $numfinished != 0)
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;<strong>view:&nbsp;</strong>'
. '</font></td></tr>';
if ($doctypes != "account")
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/personalize/youraccount.shtml">your&nbsp;account'
. '</A></font></td></tr>';
if ($numpending != 0)
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/submit/mycds/pending.shtml">your&nbsp;pending'
. '&nbsp;submissions</A></font></td></tr>';
if ($numfinished != 0)
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/submit/mycds/finished.shtml">your&nbsp;completed'
. '&nbsp;submissions</A></font></td></tr>';
$res = mysql_query("
SELECT *
FROM sbmDOCTYPE
WHERE sdocname='$doctypes'");
if ($doctypes != "Main"
&& mysql_num_rows($res) != 0
&& authenticate("$uid_email","canView","$doctypes"))
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/submit/mycds/submitlist.shtml?doctype='.$doctypes.'">'
. 'all&nbsp;completed&nbsp;submissions</A></font></td></tr>';
// Simple approval process
if (authenticate("$uid_email","referee","%","%"))
print '<tr><td><font size="-1">&nbsp;&nbsp;&nbsp;&nbsp;'
. '<A href="'.$WEBURL.'/submit/mycds/simpleapproval.shtml?doctype='
. $doctypes.'">the documents I referee</A></font></td></tr>';
}
print '<tr><td><small><input type="submit" name="action" '
. 'value="logout"></small></form></td></tr>';
}
else
{
if (isset($SuE))
$initialEmail = $SuE;
else
$initialEmail = "$uid_email";
print '<tr><td><form action="'.$WEBURL
. '/personalize/youraccount.shtml?action=login" method="post"><small>'
. '<strong>Email:</strong>';
print '<br><input type="text" size="13" name="p_email" value="'
. $initialEmail.'">';
print '<br><strong>Password:</strong>';
print '<br><input type="password" size="13" name="p_pw" '
. 'value="">';
print '<br><input type="submit" name="action" value="login">';
print ' (<a href="'.$WEBURL.'/personalize/youraccount.shtml?'
. 'action=register">new user?</a>)';
print '</small></form></td></tr>';
}
print '</table>';
}
## okay, helper functions defined, set up user ID variables now...
## do not create new sessions from PHP; only analyze the cookie already set
open_db_connection();
$uid = getUid($_COOKIE["CDSSESSION"]);
$uid_email = getEmail($uid);
</protect>
?>
diff --git a/modules/websession/web/youraccount.py b/modules/websession/web/youraccount.py
index 3ee1aef7b..fb9bde63a 100644
--- a/modules/websession/web/youraccount.py
+++ b/modules/websession/web/youraccount.py
@@ -1,410 +1,410 @@
# -*- coding: utf-8 -*-
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware ACCOUNT HANDLING"""
__lastupdated__ = """$Date$"""
import sys
from mod_python import apache
import smtplib
from cdsware import webuser
from cdsware.config import weburl, cdsname, cdslang, supportemail
from cdsware.webpage import page
from cdsware import webaccount
from cdsware import webbasket
from cdsware import webalert
from cdsware import webuser
from cdsware.webmessage import account_new_mail
from cdsware.access_control_config import *
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE, cfg_webaccess_warning_msgs, CFG_EXTERNAL_AUTHENTICATION
from cdsware.messages import gettext_set_language
import cdsware.template
websession_templates = cdsware.template.load('websession')
def edit(req, ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/set")
data = webuser.getDataUid(req,uid)
email = data[0]
passw = data[1]
return page(title= _("Your Settings"),
body=webaccount.perform_set(email,passw, ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Your Settings",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def change(req,email=None,password=None,password2=None,login_method="",ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/change")
if login_method and CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS < 4:
title = _("Settings edited")
act = "display"
linkname = _("Show account")
prefs = webuser.get_user_preferences(uid)
prefs['login_method'] = login_method
webuser.set_user_preferences(uid, prefs)
mess = _("Login method successfully selected.")
elif login_method and CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 4:
return webuser.page_not_authorized(req, "../youraccount.py/change")
elif email:
uid2 = webuser.emailUnique(email)
if (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2 or (CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS <= 1 and webuser.checkemail(email))) and uid2 != -1 and (uid2 == uid or uid2 == 0) and password == password2:
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS < 3:
change = webuser.updateDataUser(req,uid,email,password)
else:
return webuser.page_not_authorized(req, "../youraccount.py/change")
if change and CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 2:
mess = _("Password successfully edited.")
elif change:
mess = _("Settings successfully edited.")
act = "display"
linkname = _("Show account")
title = _("Settings edited")
elif uid2 == -1 or uid2 != uid and not uid2 == 0:
mess = _("The email address is already in use, please try again.")
act = "edit"
linkname = _("Edit settings")
title = _("Editing settings failed")
elif not webuser.checkemail(email):
mess = _("The email address is not valid, please try again.")
act = "edit"
linkname = _("Edit settings")
title = _("Editing settings failed")
elif password != password2:
mess = _("The passwords do not match, please try again.")
act = "edit"
linkname = _("Edit settings")
title = _("Editing settings failed")
else:
mess = _("Could not update settings.")
act = "edit"
linkname = _("Edit settings")
title = _("Editing settings failed")
return page(title=title,
body=webaccount.perform_back(mess,act, linkname, ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def lost(req, ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/lost")
return page(title=_("Lost your password?"),
body=webaccount.perform_lost(ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def display(req, ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/display")
if webuser.isGuestUser(uid):
return page(title=_("Your Account"),
body=webaccount.perform_info(req, ln),
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
data = webuser.getDataUid(req,uid)
bask = webbasket.account_list_baskets(uid, ln = ln)
aler = webalert.account_list_alerts(uid, ln = ln)
sear = webalert.account_list_searches(uid, ln = ln)
msgs = account_new_mail(uid, ln = ln)
return page(title=_("Your Account"),
body=webaccount.perform_display_account(req,data,bask,aler,sear,msgs,ln),
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def send_email(req, p_email=None, ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/send_email")
user_prefs = webuser.get_user_preferences(webuser.emailUnique(p_email))
if user_prefs:
if CFG_EXTERNAL_AUTHENTICATION.has_key(user_prefs['login_method']) or CFG_EXTERNAL_AUTHENTICATION.has_key(user_prefs['login_method']) and CFG_EXTERNAL_AUTHENTICATION[user_prefs['login_method']][0] != None:
Msg = websession_templates.tmpl_lost_password_message(ln = ln, supportemail = supportemail)
return page(title=_("Your Account"),
body=Msg,
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
passw = webuser.givePassword(p_email)
if passw == -999:
eMsg = _("The entered e-mail address doesn't exist in the database")
return page(title=_("Your Account"),
body=webaccount.perform_emailMessage(eMsg, ln),
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
fromaddr = "From: %s" % supportemail
toaddrs = "To: " + p_email
to = toaddrs + "\n"
sub = "Subject: %s %s\n\n" % (_("Credentials for"), cdsname)
body = "%s %s:\n\n" % (_("Here are your user credentials for"), cdsname)
body += " %s: %s\n %s: %s\n\n" % (_("username"), p_email, _("password"), passw)
body += "%s %s/youraccount.py/login?ln=%s" % (_("You can login at"), weburl, ln)
msg = to + sub + body
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
try:
server.sendmail(fromaddr, toaddrs, msg)
except smtplib.SMTPRecipientsRefused,e:
eMsg = _("The entered email address is incorrect, please check that it is written correctly (e.g. johndoe@example.com).")
return page(title=_("Incorrect email address"),
body=webaccount.perform_emailMessage(eMsg, ln),
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
server.quit()
return page(title=_("Lost password sent"),
body=webaccount.perform_emailSent(p_email, ln),
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def youradminactivities(req, ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/youradminactivities")
return page(title=_("Your Administrative Activities"),
body=webaccount.perform_youradminactivities(uid, ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def delete(req, ln=cdslang):
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/delete")
return page(title=_("Delete Account"),
body=webaccount.perform_delete(ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def logout(req, ln=cdslang):
uid = webuser.logoutUser(req)
# load the right message language
_ = gettext_set_language(ln)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return webuser.page_not_authorized(req, "../youraccount.py/logout")
return page(title=_("Logout"),
body=webaccount.perform_logout(req, ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
def login(req, p_email=None, p_pw=None, login_method=None, action='login', referer='', ln=cdslang):
if CFG_ACCESS_CONTROL_LEVEL_SITE > 0:
return webuser.page_not_authorized(req, "../youraccount.py/login?ln=%s" % ln)
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
#return action+_("login")
if action == "login" or action == _("login"):
if p_email==None or not login_method:
return page(title=_("Login"),
body=webaccount.create_login_page_box(referer, ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
(iden, p_email, p_pw, msgcode) = webuser.loginUser(req,p_email,p_pw, login_method)
if len(iden)>0:
uid = webuser.update_Uid(req,p_email,p_pw)
uid2 = webuser.getUid(req)
if uid2 == -1:
webuser.logoutUser(req)
return webuser.page_not_authorized(req, "../youraccount.py/login?ln=%s" % ln, uid=uid)
# login successful!
if referer:
req.err_headers_out.add("Location", referer)
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
else:
return display(req, ln)
else:
mess = cfg_webaccess_warning_msgs[msgcode] % login_method
if msgcode == 14:
if not webuser.userNotExist(p_email,p_pw) or p_email=='' or p_email==' ':
mess = cfg_webaccess_warning_msgs[15] % login_method
act = "login"
return page(title=_("Login"),
body=webaccount.perform_back(mess,act, _("login"), ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
else:
return "This should have never happened. Please contact %s." % supportemail
def register(req, p_email=None, p_pw=None, p_pw2=None, action='login', referer='', ln=cdslang):
if CFG_ACCESS_CONTROL_LEVEL_SITE > 0:
return webuser.page_not_authorized(req, "../youraccount.py/register?ln=%s" % ln)
uid = webuser.getUid(req)
# load the right message language
_ = gettext_set_language(ln)
if p_email==None:
return page(title=_("Register"),
body=webaccount.create_register_page_box(referer, ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
mess=""
act=""
if p_pw == p_pw2:
ruid = webuser.registerUser(req,p_email,p_pw)
else:
ruid = -2
if ruid == 1:
uid = webuser.update_Uid(req,p_email,p_pw)
mess = _("Your account has been successfully created.")
title = _("Account created")
if CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT == 1:
mess += _(" An email has been sent to the given address with the account information.")
if CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS >= 1:
mess += _(" A second email will be sent when the account has been activated and can be used.")
else:
mess += _(""" You can now access your <a href="%s">account</a>.""") % (
"%s/youraccount.py/display?ln=%s" % (weburl, ln))
elif ruid == -1:
mess = _("The user already exists in the database, please try again.")
act = "register"
title = _("Register failure")
elif ruid == -2:
mess = _("Both passwords must match, please try again.")
act = "register"
title = _("Register failure")
else:
mess = _("The email address given is not valid, please try again.")
act = "register"
title = _("Register failure")
return page(title=title,
body=webaccount.perform_back(mess,act, (act == 'register' and _("register") or ""), ln),
navtrail="""<a class="navtrail" href="%s/youraccount.py/display?ln=%s">""" % (weburl, ln) + _("Your Account") + """</a>""",
description="CDS Personalize, Main page",
keywords="CDS, personalize",
uid=uid,
language=ln,
lastupdated=__lastupdated__)
diff --git a/modules/webstat/Makefile.am b/modules/webstat/Makefile.am
index 1ff3ad5eb..b1bbdeefe 100644
--- a/modules/webstat/Makefile.am
+++ b/modules/webstat/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc etc lib
CLEANFILES = *~
diff --git a/modules/webstat/bin/Makefile.am b/modules/webstat/bin/Makefile.am
index 7b72c5f59..73c9afa7d 100644
--- a/modules/webstat/bin/Makefile.am
+++ b/modules/webstat/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = webstat
EXTRA_DIST = webstat.in
CLEANFILES = *~ *.tmp
diff --git a/modules/webstat/bin/webstat.in b/modules/webstat/bin/webstat.in
index 36a44dbb1..b9ab97e95 100644
--- a/modules/webstat/bin/webstat.in
+++ b/modules/webstat/bin/webstat.in
@@ -1,100 +1,100 @@
#!/bin/sh
## -*- mode: script; coding: utf-8; -*-
##
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## fill config variables:
VERSION='$Id$'
LISPIMAGEDIR=@prefix@/lib/lisp/cdsware
CONFIGDIR=@prefix@/etc/webstat
CLISP=@CLISP@
CMUCL=@CMUCL@
SBCL=@SBCL@
## usage helper function:
usage () {
echo "Usage:" $0 "[options] <httpd-log-file>"
echo "General options:"
echo " -h, --help Print this help."
echo " -V, --version Print version information."
echo "Description: print interesting usage stats from the Apache log file."
echo "Note: Please analyze only moderately-sized logs, e.g. for a day or a week."
}
## looking for version number?
if [ "$1" = "-V" ] || [ "$1" = "--version" ]; then
echo $VERSION
exit 0
fi
## looking for help?
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
usage
exit 0
fi
## do we have enough arguments?
if [ ! -n "$1" ]; then
echo "Error: Not enough arguments."
usage
exit 1
fi
## are input files okay?
FILECFG=${CONFIGDIR}/webstat.cfg
FILELOG=$1
if [ ! -f $FILECFG ]; then
echo "Error: config file ${FILECFG} not found."
exit 1
fi
if [ ! -f $FILELOG ]; then
echo "Error: httpd log file ${FILELOG} not found."
exit 1
fi
## check which Common Lisp implementation to use?
if [ "$LISP" == "" ]; then
LISP=cmucl
if [ ! -s ${LISPIMAGEDIR}/webstat.$LISP.core ]; then
LISP=sbcl
if [ ! -s ${LISPIMAGEDIR}/webstat.$LISP.core ]; then
LISP=clisp
if [ ! -s ${LISPIMAGEDIR}/webstat.$LISP.mem ]; then
echo "Error: no suitable Lisp images found in ${LISPIMAGEDIR}."
exit 1
fi
fi
fi
fi
## okay, try to run the process:
if [ "$LISP" == "cmucl" ]; then
$CMUCL -core ${LISPIMAGEDIR}/webstat.$LISP.core -quiet -batch \
-eval "(progn (analyze-httpd-log-file \"$FILECFG\" \"$FILELOG\")(quit))"
elif [ "$LISP" == "sbcl" ]; then
$SBCL --noinform --core ${LISPIMAGEDIR}/webstat.$LISP.core \
--eval "(progn (analyze-httpd-log-file \"$FILECFG\" \"$FILELOG\")(quit))"
elif [ "$LISP" == "clisp" ]; then
$CLISP -q -M ${LISPIMAGEDIR}/webstat.$LISP.mem \
-x "(progn (analyze-httpd-log-file \"$FILECFG\" \"$FILELOG\")(quit))"
else
echo "Error: $LISP not supported. Please read README."
exit 1
fi
diff --git a/modules/webstat/doc/Makefile.am b/modules/webstat/doc/Makefile.am
index 9ac6a119d..11d00dfa3 100644
--- a/modules/webstat/doc/Makefile.am
+++ b/modules/webstat/doc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
\ No newline at end of file
diff --git a/modules/webstat/doc/admin/Makefile.am b/modules/webstat/doc/admin/Makefile.am
index fe119f959..b02c2b53d 100644
--- a/modules/webstat/doc/admin/Makefile.am
+++ b/modules/webstat/doc/admin/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webstat
doc_DATA = index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webstat/doc/admin/guide.html.wml b/modules/webstat/doc/admin/guide.html.wml
index d60c859c9..b20598bd7 100644
--- a/modules/webstat/doc/admin/guide.html.wml
+++ b/modules/webstat/doc/admin/guide.html.wml
@@ -1,196 +1,196 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebStat Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/webstat/>WebStat Admin</a>" \
navbar_name="admin" \
navbar_select="webstat-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<pre>
CDSware Web usage analyzer
==========================
Purpose:
--------
Walk through the Apache combined log and analyse the usage of the
site with respect to the searching habits, alert/basket pages, etc.
Note: Please analyze only moderately-sized logs, e.g. for a day or a week.
Usage:
------
$ webstat example_access_log
or specify your preferred Common Lisp implementation:
$ LISP=sbcl webstat example_access_log
Supported Common Lisp implementations:
-------------------------------------
CMUCL, SBCL, CLISP.
GCL doesn't work at the moment.
Use CMUCL for fastest results.
Configuration:
--------------
Edit the config file:
$ vim <ETCDIR>/webstat/webstat.cfg
The file is self-explanatory.
Example output:
--------------
** APACHE LOG FILE ANALYSIS
Filename: example_access_log
Excluding search engine hits from (137.138.249.162).
** GENERAL STATS
There were 36109 website hits dating from 20041014 to 20041014.
This makes an average of 36109.0 website hits per day.
There were 1706 unique visitors in 1 days.
Visitor ............................................................ no. of hits
w1.x1.y1.z1 ............................................................... 1844
w2.x2.y2.z2 ............................................................... 1761
w3.x3.y3.z3 ............................................................... 1012
w4.x4.y4.z4 ................................................................ 913
w5.x5.y5.z5 ................................................................ 889
w6.x6.y6.z6 ................................................................ 562
w7.x7.y7.z7 ................................................................ 449
w8.x8.y8.z8 ................................................................ 373
w9.x9.y9.z9 ................................................................ 335
** SEARCH COLLECTIONS USAGE ANALYSIS
There were 9059 visits of search interface pages.
There were 8688 visits of non-Home search interface pages. ( 4.1%)
Collection ....................................................... no. of visits
CERN Document Server ....................................................... 371
Photos ..................................................................... 207
Articles & Preprints ....................................................... 149
HEP Institutes .............................................................. 98
Periodicals ................................................................. 87
Weekly Bulletin ............................................................. 85
Preprints ................................................................... 84
Theses ...................................................................... 80
CERN PhotoLab ............................................................... 78
CERN Yellow Reports ......................................................... 77
Books ....................................................................... 75
ATLAS Photos ................................................................ 72
ATLAS ....................................................................... 68
CERN Archives ............................................................... 68
Academic Training Lectures .................................................. 66
Internet Resources .......................................................... 65
Books & Proceedings ......................................................... 62
Published Articles .......................................................... 60
Summer Student Lectures ..................................................... 60
Standards ................................................................... 59
** SEARCH COLLECTIONS USAGE ANALYSIS
There were 5935 search engine hits.
There were 2586 searches originating from non-Home collections. (56.4%)
Originating collection ......................................... no. of searches
CERN Document Server ...................................................... 3349
News Articles .............................................................. 649
ATLAS eNews ................................................................ 481
Photos ..................................................................... 335
Weekly Bulletin ............................................................ 205
General Information ........................................................ 102
Articles & Preprints ........................................................ 85
CERN PhotoLab ............................................................... 76
CERN Yellow Reports ......................................................... 59
Official News ............................................................... 58
Training and Development .................................................... 50
Staff Association ........................................................... 45
Pension Fund ................................................................ 38
ATLAS Photos ................................................................ 36
CMS Photos .................................................................. 29
Books ....................................................................... 28
Preprints ................................................................... 21
Videos ...................................................................... 18
CERN Committee Documents .................................................... 17
Translation and Minutes ..................................................... 17
** SEARCH ENGINE QUERY PATTERN ANALYSIS
Found 8692 search engine hits.
First search engine hit log is dated 20041014.
Last search engine hit log is dated 20041014.
This makes an average of 8692.0 search engine hits per day.
There were 5424 simple searches out of 8692 search engine hits. (62.4%)
There were 1886 advanced searches out of 8692 search engine hits. (21.7%)
There were 1382 detailed record pages out of 8692 search engine hits. (15.9%)
There are 2523 different query patterns for 8692 search engine hits. (29.0%)
There are 169 empty query pattern searches out of 8692 search engine hits. (1.94%)
There are 1264 phrase searches out of 8692 search engine hits. (14.5%)
There are 263 phrase query patterns out of 2523 query patterns. (10.4%)
There are 1748 one-time event searches out of 8692 search engine hits. (20.1%)
There are 1748 one-time query patterns out of 2523 query patterns. (69.3%)
There are 4276 one-word searches out of 8692 search engine hits. (49.2%)
There are 1602 one-word query patterns out of 2523 query patterns. (63.5%)
There are 223 wildcard searches out of 8692 search engine hits. (2.57%)
There are 35 wildcard query patterns out of 2523 query patterns. (1.39%)
There are 1466 punctuation-like searches out of 8692 search engine hits. (16.9%)
There are 407 punctuation-like query patterns out of 2523 query patterns. (16.1%)
There are 2424 any-field query patterns out of 2523 query patterns. (96.1%)
User query .................................................. no. of occurrences
200409 ..................................................................... 432
........................................................................... 169
"42/2004" ................................................................... 64
"43/2004" ................................................................... 48
"40/2004" ................................................................... 46
internalnote:press internalnote:'Views*' .................................... 44
ALICE ....................................................................... 29
"27/2004" ................................................................... 28
0002235ATLATL ............................................................... 28
"36/2004" ................................................................... 26
"24/2004" ................................................................... 25
internet .................................................................... 24
intranet .................................................................... 24
0021317ADMBUL ............................................................... 23
internalnote:press internalnote:'physics diagrams*' ......................... 23
"19/2004" ................................................................... 22
"39/2004" ................................................................... 22
0005179UDCCER ............................................................... 22
"23/2004" ................................................................... 21
"38/2004" ................................................................... 21
** USER BASKETS STATS
There were 196 user basket page hits.
This makes an average of 196.0 user basket page hits per day.
There were 47 unique basket page users in 1 days.
There were 82 additions to baskets.
There were 114 displays of baskets, out of which 39 public baskets accesses.
** USER ALERTS STATS
There were 7 user alert page hits.
This makes an average of 7.0 user alert page hits per day.
There were 5 unique alert page users in 1 days.
There were 3 displays of user alerts.
There were 4 displays of user searches history.
</pre>
diff --git a/modules/webstat/doc/admin/index.html.wml b/modules/webstat/doc/admin/index.html.wml
index ca01b4c5c..b0bab3eea 100644
--- a/modules/webstat/doc/admin/index.html.wml
+++ b/modules/webstat/doc/admin/index.html.wml
@@ -1,29 +1,29 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebStat Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="webstat"
<dl>
<dt><a href="guide.html">WebStat Admin Guide</a></dt>
<dd>Everything you want to know about configuring and running WebStat.</dd>
</dl>
diff --git a/modules/webstat/doc/hacking/Makefile.am b/modules/webstat/doc/hacking/Makefile.am
index 811477cfb..df783ec89 100644
--- a/modules/webstat/doc/hacking/Makefile.am
+++ b/modules/webstat/doc/hacking/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/hacking/webstat
doc_DATA=
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webstat/etc/Makefile.am b/modules/webstat/etc/Makefile.am
index 718f83566..dd5baa98f 100644
--- a/modules/webstat/etc/Makefile.am
+++ b/modules/webstat/etc/Makefile.am
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
FILESWML=$(wildcard $(srcdir)/*.wml)
etcdir=$(sysconfdir)/webstat
etc_DATA=$(FILESWML:$(srcdir)/%.wml=%)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(wildcard *.cfg) *~ *.tmp
%.cfg: %.cfg.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdspage.wml
$(WML) -o $@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webstat/lib/Makefile.am b/modules/webstat/lib/Makefile.am
index 24c78cd49..de66e2f9b 100644
--- a/modules/webstat/lib/Makefile.am
+++ b/modules/webstat/lib/Makefile.am
@@ -1,54 +1,54 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
lispimagedir = $(libdir)/lisp/cdsware
lispimage_DATA = webstat.clisp.mem webstat.cmucl.core webstat.sbcl.core
FILESLISP = $(wildcard $(srcdir)/*.lisp)
EXTRA_DIST = $(FILESLISP:$(srcdir)/%=%)
CLEANFILES = $(lispimage_DATA) *~ *.tmp *.pyc *.fas *.fasl *.lib *.x86f *.mem *.core
webstat.clisp.mem: $(FILESLISP)
if [ -x "${CLISP}" ]; then \
(cwd=`pwd`; cd $(srcdir) && \
${CLISP} -q -x "(progn (load \"load.lisp\")(saveinitmem \"$${cwd}/webstat.clisp.mem\"))"); \
else \
echo "Warning: cannot find CLISP, hoping you have CMUCL or SBCL instead."; \
touch webstat.clisp.mem; \
fi
webstat.cmucl.core: $(FILESLISP)
if [ -x "${CMUCL}" ]; then \
(cwd=`pwd`; cd $(srcdir) && \
${CMUCL} -quiet -batch -eval "(progn (load \"load.lisp\")(ext:save-lisp \"$${cwd}/webstat.cmucl.core\"))"); \
else \
echo "Warning: cannot find CMUCL, hoping you have CLISP or SBCL instead."; \
touch webstat.cmucl.core; \
fi
webstat.sbcl.core: $(FILESLISP)
if [ -x "${SBCL}" ]; then \
(cwd=`pwd`; cd $(srcdir) && \
${SBCL} --noinform --eval "(progn (load \"load.lisp\")(sb-ext:save-lisp-and-die \"$${cwd}/webstat.sbcl.core\"))"); \
else \
echo "Warning: cannot find SBCL, hoping you have CLISP or CMUCL instead."; \
touch webstat.sbcl.core; \
fi
diff --git a/modules/webstat/lib/load.lisp b/modules/webstat/lib/load.lisp
index c059b2947..92367638b 100644
--- a/modules/webstat/lib/load.lisp
+++ b/modules/webstat/lib/load.lisp
@@ -1,21 +1,21 @@
;;; $Id$
;;;
;;; This file is part of the CERN Document Server Software (CDSware).
-;;; Copyright (C) 2002, 2003, 2004, 2005 CERN.
+;;; Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
;;;
;;; The CDSware 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.
;;;
;;; The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
;;; 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
(proclaim '(optimize (speed 3) (safety 1) (debug 0) (compilation-speed 0) (space 0)))
(load (compile-file "webstatlib.lisp"))
diff --git a/modules/webstat/lib/webstatlib.lisp b/modules/webstat/lib/webstatlib.lisp
index e8ca46bce..c45d30a0f 100644
--- a/modules/webstat/lib/webstatlib.lisp
+++ b/modules/webstat/lib/webstatlib.lisp
@@ -1,806 +1,806 @@
;;; $Id$
;;;
;;; webstatlib.lisp -- library with httpd log file analyzer to gather
;;; CDS usage stats. Another functionality is to parse old Apache log
;;; files and prepare Detailed record page views statistics for
;;; rnkPAGEVIEWS table.
;;;
;;; This file is part of the CERN Document Server Software (CDSware).
-;;; Copyright (C) 2002, 2003, 2004, 2005 CERN.
+;;; Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
;;;
;;; The CDSware 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.
;;;
;;; The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
;;; 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
;;
;; Auxiliary functions come first.
#-gcl (in-package #:cl-user)
(defpackage #:webstatlib
#-gcl (:use #:cl)
(:export #:print-general-stats
#:print-search-interface-stats
#:print-search-collections-stats
#:print-search-pattern-stats
#:print-basket-stats
#:print-alert-stats
#:print-download-stats))
#-gcl (proclaim '(optimize (speed 3) (safety 1) (debug 0) (compilation-speed 0) (space 0)))
(defun parse-integer-or-zero (string)
"Parse integer from STRING and return either the integer, or zero."
(let ((out 0))
(if (string-not-equal string "-")
(setf out (parse-integer string)))
out))
(defun hash-table-keys (hashtable &optional (sort-by-value nil))
"Return list of HASHTABLE keys. Optionally, sort the key list by
hash value."
(let ((keys '()))
(maphash (lambda (key val)
(declare (ignore val))
(push key keys))
hashtable)
(if sort-by-value
(sort keys #'(lambda (x y)
(let ((x-val (gethash x hashtable))
(y-val (gethash y hashtable)))
(if (equalp x-val y-val)
(string< x y) ; when values are equal, test by keys
(> x-val y-val)))))
keys)))
(defun hash-table-values (hashtable)
"Return list of HASHTABLE values."
(let ((vals '()))
(maphash (lambda (key val)
(declare (ignore key))
(push val vals))
hashtable)
vals))
(defun hash-table-key-val-stats (hashtable predicate
&optional (apply-predicate-to-vals nil))
"Return the number of keys in HASHTABLE that satisfy the PREDICATE.
Another returned value is the sum of values for these keys. Suitable
when values are integers, as in histograms."
(declare (type function predicate))
(let ((number-of-keys 0)
(sum-of-values 0))
(declare (type fixnum number-of-keys sum-of-values))
(maphash (lambda (key val)
(if apply-predicate-to-vals
(when (funcall predicate val)
(incf number-of-keys)
(incf sum-of-values val))
(when (funcall predicate key)
(incf number-of-keys)
(incf sum-of-values val))))
hashtable)
(values number-of-keys sum-of-values)))
(defun split-string-by-one-space (string)
"Return list of substrings of STRING divided by *one* space each.
Two consecutive spaces will be seen as if there were an empty string
between them. Taken from Common Lisp Cookbook."
(declare (type simple-base-string string))
(loop for i = 0 then (1+ j)
as j = (position #\Space string :start i)
collect (subseq string i j)
while j))
(defun string-substitute (string substring replacement-string)
"Taken from c.l.l."
(declare (type simple-base-string string substring replacement-string))
(let ((substring-length (length substring))
(last-end 0)
(new-string ""))
(declare (type simple-base-string new-string)
(type integer substring-length last-end))
(do ((next-start
(search substring string)
(search substring string :start2 last-end)))
((null next-start)
(concatenate 'string new-string (subseq string last-end)))
(declare (type (or integer null) next-start))
(setq new-string
(concatenate 'string
new-string
(subseq string last-end next-start)
replacement-string))
(setq last-end (+ next-start substring-length)))))
(defun string-decode-url (string)
"Return string where URL is unquoted, that is %22 is substituted by
a double quote, etc."
(declare (type simple-base-string string))
(setf string (string-substitute string "%20" " "))
(setf string (string-substitute string "+" " "))
(setf string (string-substitute string "%2B" "+"))
(setf string (string-substitute string "%22" "\""))
(setf string (string-substitute string "%23" "#"))
(setf string (string-substitute string "%25" "%"))
(setf string (string-substitute string "%26" "&"))
(setf string (string-substitute string "%27" "'"))
(setf string (string-substitute string "%28" "("))
(setf string (string-substitute string "%29" ")"))
(setf string (string-substitute string "%2A" "*"))
(setf string (string-substitute string "%2C" ","))
(setf string (string-substitute string "%2F" "/"))
(setf string (string-substitute string "%3A" ":"))
(setf string (string-substitute string "%3D" "="))
(setf string (string-substitute string "%3E" ">"))
(setf string (string-substitute string "%3F" "?"))
(setf string (string-substitute string "%5B" "["))
(setf string (string-substitute string "%5C" "\\"))
(setf string (string-substitute string "%5D" "]")))
(defun get-month-number-from-month-name (month-name)
"Return month number for MONTH-NAME."
(declare (type simple-base-string month-name))
(cond ((string= month-name "Jan") 1)
((string= month-name "Feb") 2)
((string= month-name "Mar") 3)
((string= month-name "Apr") 4)
((string= month-name "May") 5)
((string= month-name "Jun") 6)
((string= month-name "Jul") 7)
((string= month-name "Aug") 8)
((string= month-name "Sep") 9)
((string= month-name "Oct") 10)
((string= month-name "Nov") 11)
((string= month-name "Dec") 12)
(t 0)))
(defun get-urlarg-value-from-url-string (url-string url-arg
&optional (return-empty-value nil))
"Return list of values of URL-ARG in the URL-STRING. For example,
if URL-STRING contains 'search.py?p=ellis&f=title', and URL-ARG is
'f', then return list of 'title'. If URL-ARG is not present in
URL-STRING, return list of empty string."
(declare (type simple-base-string url-string url-arg))
(let ((out nil)
(position-pattern-beg nil)
(position-pattern-end nil))
(setf position-pattern-beg (search (concatenate 'string url-arg "=")
url-string))
(if (not position-pattern-beg)
(progn
(when return-empty-value
(push "" out)))
(progn
(setf position-pattern-end (search "&" url-string
:start2 position-pattern-beg))
(if (null position-pattern-end)
(setf position-pattern-end (length url-string)))
(push (string-decode-url (subseq url-string
(+ (length url-arg) 1 position-pattern-beg)
position-pattern-end))
out)))
(if return-empty-value
out
(remove-if #'(lambda (x)
(declare (type simple-base-string x))
(string= "" x))
out))))
(defun get-datetime-from-httpd-log-datetime-string (httpd-log-datetime-string)
"Return request date in numerical format YYYYMMDD from HTTPD-LOG-DATETIME-STRING."
(declare (type simple-base-string httpd-log-datetime-string))
(let ((yyyy (subseq httpd-log-datetime-string 7 11))
(mm-number (get-month-number-from-month-name (subseq httpd-log-datetime-string 3 6)))
(dd (subseq httpd-log-datetime-string 0 2)))
(declare (type fixnum mm-number))
(+ (* 100 100 (parse-integer yyyy))
(* 100 mm-number)
(parse-integer dd))))
(defun get-datetimee-from-httpd-log-datetime-string (httpd-log-datetime-string)
"Return request date in the format YYYY-MM-DD HH:MM:SS from HTTPD-LOG-DATETIME-STRING."
(declare (type simple-base-string httpd-log-datetime-string))
(let ((yyyy (subseq httpd-log-datetime-string 7 11))
(mm (get-month-number-from-month-name (subseq httpd-log-datetime-string 3 6)))
(dd (subseq httpd-log-datetime-string 0 2))
(hms (subseq httpd-log-datetime-string 12 20)))
(format nil "~A-~A-~A ~A" yyyy mm dd hms)))
(defun get-current-collection-from-httpd-log-request-string (httpd-log-request-string)
"Return current collection found in HTTPD-LOG-REQUEST-STRING."
(declare (special *home-collection*))
(let ((out nil)
(url-string (subseq httpd-log-request-string
(position #\space httpd-log-request-string)
(position #\space httpd-log-request-string :from-end t))))
(if (search "?cc=" url-string)
(setf out (get-urlarg-value-from-url-string url-string "cc" t))
(if (search "?c=" url-string)
(setf out (get-urlarg-value-from-url-string url-string "c" t))
(setf out (list *home-collection*))))
(if (string= (car out) "")
(setf out (list *home-collection*)))
out))
(defun get-search-patterns-from-httpd-log-request-string (httpd-log-request-string)
"Return list of search pattern strings (p=,p1=,p2=,p3=) found in
HTTPD-LOG-REQUEST-STRING. As a side effect, increment counters for
*NUMBER-OF-SIMPLE-SEARCHES* and *NUMBER-OF-DETAILED-RECORD-PAGES* when
a simple search or a detailed record page is selected."
(declare (type simple-base-string httpd-log-request-string)
(special *search-engine-url*
*number-of-simple-searches*
*number-of-advanced-searches*
*number-of-detailed-record-pages*))
(let ((out nil)
(url-string (subseq httpd-log-request-string
(position #\space httpd-log-request-string)
(position #\space httpd-log-request-string :from-end t))))
;; url-string now contains URL without leading GET and trailing HTTP/1.1 strings
(when (search *search-engine-url* url-string)
(if (or (search "?id=" url-string)
(search "?recid=" url-string)
(search "?sysno=" url-string)
(search "?sysnb=" url-string))
;; detailed record page happened:
(incf *number-of-detailed-record-pages*)
(if (search "p1=" httpd-log-request-string)
;; advanced search happened:
(progn
(incf *number-of-advanced-searches*)
(setf out (append (get-urlarg-value-from-url-string url-string "p1")
(get-urlarg-value-from-url-string url-string "p2")
(get-urlarg-value-from-url-string url-string "p3"))))
;; simple search happened:
(progn
(incf *number-of-simple-searches*)
(setf out (get-urlarg-value-from-url-string url-string "p" t))))))
out))
(defun wash-httpd-log-line (httpd-log-line)
"Fix eventual problems in HTTPD-LOG-LINE, such as backslash-quote
that some browsers seem to produce. To be called for the input to
wash it out."
(declare (type simple-base-string httpd-log-line))
(string-substitute httpd-log-line "\\\"" "%22"))
;; HTTPD-LOG-ENTRY stucture that will represent Apache log hits, and
;; functions to create it.
(defstruct httpd-log-entry
"Structure representing Apache combined log entry."
(ip "" :type simple-base-string)
(datetime 0 :type integer) ; YYYYMMDD (FIXME: get rid of this)
(datetimee "" :type simple-base-string) ; YYYY-MM-DD HH:MM:SS
(request "" :type simple-base-string)
(status 0 :type integer)
(bytes 0 :type integer)
(referer "" :type simple-base-string)
(browser "" :type simple-base-string))
(defun parse-httpd-log-line-conses-a-lot (line)
"Return list of elements read from Apache combined log LINE. The
elements in line are text strings delimited either by spaces or by
double quotes or brackets. (Spaces within double quotes or brackets
do not take their separator effect. Double quote preceded by a
backslash do not take its effect neither.) WARNING: THIS FUNCTION
CONSES A LOT, A FASTER REWRITE IS AVAILABLE BELOW."
(declare (type simple-base-string line))
(if (string= line "")
nil
(let ((current-char (char line 0))
(position-term-next nil)
(position-term-offset 0))
(declare (type (or fixnum null) position-term-next position-term-offset)
(type character current-char))
(cond ((char= current-char #\")
(setf position-term-next (position #\" line :start 1)
position-term-offset 1))
((char= current-char #\[)
(setf position-term-next (position #\] line :start 1)
position-term-offset 1))
(t (setf position-term-next (position #\Space line :start 1))))
(if (or (null position-term-next)
(>= (+ 1 position-term-next position-term-offset) (length line)))
(list (subseq line position-term-offset))
(append (list (subseq line position-term-offset position-term-next))
(parse-httpd-log-line (subseq line
(+ 1
position-term-next
position-term-offset))))))))
(defun parse-httpd-log-line (line)
"Return list of elements read from Apache combined log LINE. The
elements in line are text strings delimited either by spaces or by
double quotes or brackets. (Spaces within double quotes or brackets
do not take their separator effect. Double quote preceded by a
backslash do not take its effect neither.)"
(declare (type simple-base-string line))
(labels ((get-next-char-to-search (current-char)
(declare (type character current-char))
(cond ((char= current-char #\[) #\])
((char= current-char #\") #\")
(t #\space)))
(get-char-offset (current-char)
(declare (type character current-char))
(cond ((char= current-char #\[) 1)
((char= current-char #\") 1)
(t 0))))
(let* ((out nil)
(position-max (1- (length line)))
(position-term 0)
(position-term-offset (get-char-offset (char line position-term)))
(position-term-next (position (get-next-char-to-search (char line position-term))
line
:start (+ position-term-offset position-term))))
(declare (type (or integer null) position-term position-term-next)
(type integer position-max position-term-offset))
(loop (when (null position-term-next)
(when (< position-term position-max)
(push (subseq line (+ position-term position-term-offset)) out))
(return (nreverse out)))
(push (subseq line (+ position-term position-term-offset) position-term-next) out)
(setf position-term (min (+ 1 position-term-next position-term-offset)
position-max))
(setf position-term-offset (get-char-offset (char line position-term)))
(setf position-term-next (position (get-next-char-to-search (char line position-term))
line
:start (+ position-term position-term-offset)))))))
(defun create-httpd-log-entry (httpd-log-line)
"Create HTTPD-LOG-ENTRY structure from HTTPD-LOG-LINE Apache
combined log line. The line is supposed to be washed already."
(declare (type simple-base-string httpd-log-line))
; firstly parse Apache line according to spaces and quotes into list:
(let ((httpd-log-line-list (parse-httpd-log-line httpd-log-line)))
;; secondly transform into entry:
(make-httpd-log-entry :ip (nth 0 httpd-log-line-list)
:request (nth 4 httpd-log-line-list)
:datetime (get-datetime-from-httpd-log-datetime-string
(nth 3 httpd-log-line-list))
:datetimee (get-datetimee-from-httpd-log-datetime-string
(nth 3 httpd-log-line-list))
:status (parse-integer (nth 5 httpd-log-line-list))
:bytes (parse-integer-or-zero (nth 6 httpd-log-line-list))
:referer (nth 7 httpd-log-line-list)
:browser (nth 8 httpd-log-line-list))))
(defun create-httpd-log-entries (httpd-log-filename
&optional (exclude-ip-list nil))
"Create list of HTTPD-LOG-ENTRY structures from HTTPD-LOG-FILENAME
Apache combined log file. The log file lines are cleaned to make them
valid, if necessary. When EXCLUDE-IP-LIST is set, then lines coming
from those IPs are excluded."
(declare (type simple-base-string httpd-log-filename)
(type list exclude-ip-list))
(let ((httpd-log-entries nil))
(format t "~&** APACHE LOG FILE ANALYSIS")
(format t "~&Filename: ~A" httpd-log-filename)
(unless (null exclude-ip-list)
(format t "~&Excluding search engine hits from ~A." exclude-ip-list))
(with-open-file (input-stream httpd-log-filename :direction :input)
(do ((line (read-line input-stream nil)
(read-line input-stream nil)))
((not line))
(declare (type (or simple-base-string null) line))
(let ((httpd-log-entry-item (create-httpd-log-entry (wash-httpd-log-line line))))
(if (or (null exclude-ip-list)
(not (member (httpd-log-entry-ip httpd-log-entry-item)
exclude-ip-list :test #'equal)))
(push httpd-log-entry-item httpd-log-entries)))))
httpd-log-entries))
(defun filter-httpd-log-entries (httpd-all-log-entries url-substring-pattern
&optional (status-code 200))
"Return only those of HTTPD-ALL-LOG-ENTRIES that satisfy
URL-SUBSTRING-PATTERN and are of status STATUS-CODE."
(remove-if-not #'(lambda (httpd-log-entry-item)
(and (search url-substring-pattern (httpd-log-entry-request httpd-log-entry-item))
(= status-code (httpd-log-entry-status httpd-log-entry-item))))
httpd-all-log-entries))
;; Functions that analyze the files according to the typical use cases.
(defun print-general-stats (httpd-all-log-entries)
"Read HTTPD-LOG-ENTRIES and print some general stats such as
the total number of hits, etc."
(declare (special *nb-histogram-items-to-print*))
(format t "~&~%** GENERAL STATS")
(let ((nb-hits (length httpd-all-log-entries))
(datetime-last (httpd-log-entry-datetime (car httpd-all-log-entries)))
(datetime-first (httpd-log-entry-datetime (car (last httpd-all-log-entries))))
(visitor-histogram (make-hash-table :test #'equalp)))
;; build histogram:
(dolist (httpd-log-entry-item httpd-all-log-entries)
(incf (gethash (httpd-log-entry-ip httpd-log-entry-item)
visitor-histogram 0)))
;; print summary info:
(format t "~&There were ~D website hits dating from ~A to ~A."
nb-hits datetime-first datetime-last)
(format t "~&This makes an average of ~F website hits per day."
(/ nb-hits (1+ (- datetime-last datetime-first))))
(format t "~&There were ~D unique visitors in ~D days."
(length (hash-table-keys visitor-histogram))
(1+ (- datetime-last datetime-first)))
;; print visitors histogram:
(format t "~&~80,1,0,'.<~A ~; ~A~>" "Visitor" "no. of hits")
(let ((visitors-to-print (hash-table-keys visitor-histogram t)))
(if (> (length visitors-to-print) *nb-histogram-items-to-print*)
(setq visitors-to-print (subseq visitors-to-print 0 *nb-histogram-items-to-print*)))
(dolist (visitor visitors-to-print)
(format t "~&~80,1,0,'.<~A ~; ~A~>" visitor
(gethash visitor visitor-histogram))))))
(defun print-search-interface-stats (httpd-all-log-entries)
"Read HTTPD-ALL-LOG-ENTRIES, analyze search interface usage and print
interesting statistics."
(declare (special *search-interface-url*
*home-collection*
*nb-histogram-items-to-print*))
(let ((httpd-log-entries (filter-httpd-log-entries httpd-all-log-entries *search-interface-url*))
(collection-histogram (make-hash-table :test #'equalp)))
;; build histogram:
(dolist (httpd-log-entry httpd-log-entries)
(dolist (current-collection (get-current-collection-from-httpd-log-request-string
(httpd-log-entry-request
httpd-log-entry)))
(incf (gethash current-collection collection-histogram 0))))
;; print summary info:
(format t "~&~%** SEARCH COLLECTIONS USAGE ANALYSIS")
(let ((number-of-interface-visits
(reduce #'+ (hash-table-values collection-histogram))))
(format t "~&There were ~D visits of search interface pages."
number-of-interface-visits)
(format t "~&There were ~D visits of non-Home search interface pages. (~4F\%)"
(- number-of-interface-visits (gethash *home-collection* collection-histogram 0))
(if (zerop number-of-interface-visits)
0
(* 100 (/ (gethash *home-collection* collection-histogram 0)
number-of-interface-visits)))))
;; print histogram:
(format t "~&~80,1,0,'.<~A ~; ~A~>" "Collection" "no. of visits")
(let ((collections-to-print (hash-table-keys collection-histogram t)))
(if (> (length collections-to-print) *nb-histogram-items-to-print*)
(setq collections-to-print (subseq collections-to-print 0 *nb-histogram-items-to-print*)))
(dolist (collection collections-to-print)
(format t "~&~80,1,0,'.<~A ~; ~A~>" collection
(gethash collection collection-histogram))))))
(defun print-search-collections-stats (httpd-all-log-entries)
"Read HTTPD-ALL-LOG-ENTRIES, analyze search engine usage and print
interesting statistics with respect to collections."
(declare (special *search-engine-url*
*home-collection*
*nb-histogram-items-to-print*))
(let ((httpd-log-entries (filter-httpd-log-entries httpd-all-log-entries *search-engine-url*))
(collection-histogram (make-hash-table :test #'equalp)))
;; build histogram:
(dolist (httpd-log-entry httpd-log-entries)
(if (or (search "c=" (httpd-log-entry-request httpd-log-entry))
(search "cc=" (httpd-log-entry-request httpd-log-entry)))
(dolist (current-collection (get-current-collection-from-httpd-log-request-string
(httpd-log-entry-request
httpd-log-entry)))
(incf (gethash current-collection collection-histogram 0)))))
;; print summary info:
(format t "~&~%** SEARCH COLLECTIONS USAGE ANALYSIS")
(let ((number-of-interface-visits
(reduce #'+ (hash-table-values collection-histogram))))
(format t "~&There were ~D search engine hits."
number-of-interface-visits)
(format t "~&There were ~D searches originating from non-Home collections. (~4F\%)"
(- number-of-interface-visits (gethash *home-collection* collection-histogram 0))
(* 100 (/ (gethash *home-collection* collection-histogram 0) number-of-interface-visits))))
;; print histogram:
(format t "~&~80,1,0,'.<~A ~; ~A~>" "Originating collection" "no. of searches")
(let ((collections-to-print (hash-table-keys collection-histogram t)))
(if (> (length collections-to-print) *nb-histogram-items-to-print*)
(setq collections-to-print (subseq collections-to-print 0 *nb-histogram-items-to-print*)))
(dolist (collection collections-to-print)
(format t "~&~80,1,0,'.<~A ~; ~A~>" collection
(gethash collection collection-histogram))))))
(defun print-search-pattern-stats (httpd-all-log-entries)
"Read HTTPD-ALL-LOG-ENTRIES, analyze search patterns and print
interesting statistics."
(declare (special *search-engine-url*
*nb-histogram-items-to-print*
*number-of-simple-searches*
*number-of-advanced-searches*
*number-of-detailed-record-pages*))
(setf *number-of-simple-searches* 0
*number-of-advanced-searches* 0
*number-of-detailed-record-pages* 0)
(let ((httpd-log-entries (filter-httpd-log-entries httpd-all-log-entries *search-engine-url*))
(pattern-histogram (make-hash-table :test #'equalp)))
;; build histogram:
(dolist (httpd-log-entry httpd-log-entries)
(dolist (pattern (get-search-patterns-from-httpd-log-request-string (httpd-log-entry-request
httpd-log-entry)))
(incf (gethash pattern pattern-histogram 0))))
;; print summary info:
(format t "~&~%** SEARCH ENGINE QUERY PATTERN ANALYSIS")
(if (null httpd-log-entries)
(format t "~&No valid search engine hits found. Exiting.")
(let ((number-of-search-engine-hits (length httpd-log-entries))
(number-of-patterns (hash-table-count pattern-histogram))
(day-first (httpd-log-entry-datetime (nth (1- (length httpd-log-entries))
httpd-log-entries)))
(day-last (httpd-log-entry-datetime (first httpd-log-entries))))
(declare (type integer number-of-search-engine-hits
number-of-patterns day-first day-last))
;; a - total number of searches and patterns
(format t "~&Found ~D search engine hits." number-of-search-engine-hits)
(format t "~&First search engine hit log is dated ~A." day-first)
(format t "~&Last search engine hit log is dated ~A." day-last)
(format t "~&This makes an average of ~F search engine hits per day."
(/ number-of-search-engine-hits (1+ (- day-last day-first))))
(format t "~&There were ~D simple searches out of ~D search engine hits. (~4F\%)"
*number-of-simple-searches* number-of-search-engine-hits
(* 100 (/ *number-of-simple-searches* number-of-search-engine-hits)))
(format t "~&There were ~D advanced searches out of ~D search engine hits. (~4F\%)"
*number-of-advanced-searches* number-of-search-engine-hits
(* 100 (/ *number-of-advanced-searches* number-of-search-engine-hits)))
(format t "~&There were ~D detailed record pages out of ~D search engine hits. (~4F\%)"
*number-of-detailed-record-pages* number-of-search-engine-hits
(* 100 (/ *number-of-detailed-record-pages* number-of-search-engine-hits)))
(format t "~&There are ~D different query patterns for ~D search engine hits. (~4F\%)"
number-of-patterns number-of-search-engine-hits
(* 100 (/ number-of-patterns number-of-search-engine-hits)))
;; b - empty searches
(format t "~&There are ~D empty query pattern searches out of ~D search engine hits. (~4F\%)"
(gethash "" pattern-histogram 0)
number-of-search-engine-hits
(* 100 (/ (gethash "" pattern-histogram 0) number-of-search-engine-hits)))
;; c - phrase searches and patterns
(multiple-value-bind (number-of-phrase-patterns number-of-phrase-searches)
(hash-table-key-val-stats pattern-histogram #'(lambda (x)
(declare (type simple-base-string x))
(position #\" x)))
(format t "~&There are ~D phrase searches out of ~D search engine hits. (~4F\%)"
number-of-phrase-searches
number-of-search-engine-hits
(* 100 (/ number-of-phrase-searches number-of-search-engine-hits)))
(format t "~&There are ~D phrase query patterns out of ~D query patterns. (~4F\%)"
number-of-phrase-patterns
number-of-patterns
(* 100 (/ number-of-phrase-patterns number-of-patterns))))
;; d - onetime searches and patterns
(multiple-value-bind (number-of-onetime-patterns number-of-onetime-searches)
(hash-table-key-val-stats pattern-histogram #'(lambda (x)
(declare (integer x))
(= x 1)) t)
(format t "~&There are ~D one-time event searches out of ~D search engine hits. (~4F\%)"
number-of-onetime-searches
number-of-search-engine-hits
(* 100 (/ number-of-onetime-searches number-of-search-engine-hits)))
(format t "~&There are ~D one-time query patterns out of ~D query patterns. (~4F\%)"
number-of-onetime-patterns
number-of-patterns
(* 100 (/ number-of-onetime-patterns number-of-patterns))))
;; e - one-word searches and patterns
(multiple-value-bind (number-of-oneword-patterns number-of-oneword-searches)
(hash-table-key-val-stats pattern-histogram #'(lambda (x)
(declare (type simple-base-string x))
(not (position #\space x))))
(format t "~&There are ~D one-word searches out of ~D search engine hits. (~4F\%)"
number-of-oneword-searches
number-of-search-engine-hits
(* 100 (/ number-of-oneword-searches number-of-search-engine-hits)))
(format t "~&There are ~D one-word query patterns out of ~D query patterns. (~4F\%)"
number-of-oneword-patterns
number-of-patterns
(* 100 (/ number-of-oneword-patterns number-of-patterns))))
;; f - wildcard queries and patterns
(multiple-value-bind (number-of-wildcard-patterns number-of-wildcard-searches)
(hash-table-key-val-stats pattern-histogram #'(lambda (x)
(declare (type simple-base-string x))
(position #\* x)))
(format t "~&There are ~D wildcard searches out of ~D search engine hits. (~4F\%)"
number-of-wildcard-searches
number-of-search-engine-hits
(* 100 (/ number-of-wildcard-searches number-of-search-engine-hits)))
(format t "~&There are ~D wildcard query patterns out of ~D query patterns. (~4F\%)"
number-of-wildcard-patterns
number-of-patterns
(* 100 (/ number-of-wildcard-patterns number-of-patterns))))
;; g - punctuation-like queries and patterns
(multiple-value-bind (number-of-punctuation-patterns number-of-punctuation-searches)
(hash-table-key-val-stats pattern-histogram #'(lambda (x)
(declare (type simple-base-string x))
(or (position #\+ x)
(position #\- x)
(position #\/ x))))
(format t "~&There are ~D punctuation-like searches out of ~D search engine hits. (~4F\%)"
number-of-punctuation-searches
number-of-search-engine-hits
(* 100 (/ number-of-punctuation-searches number-of-search-engine-hits)))
(format t "~&There are ~D punctuation-like query patterns out of ~D query patterns. (~4F\%)"
number-of-punctuation-patterns
number-of-patterns
(* 100 (/ number-of-punctuation-patterns number-of-patterns))))
;; h - anyfield queries and patterns
(multiple-value-bind (number-of-anyfield-patterns number-of-anyfield-searches)
(hash-table-key-val-stats pattern-histogram #'(lambda (x)
(declare (type simple-base-string x))
(not (position #\: x))))
(declare (ignore number-of-anyfield-searches))
(format t "~&There are ~D any-field query patterns out of ~D query patterns. (~4F\%)"
number-of-anyfield-patterns
number-of-patterns
(* 100 (/ number-of-anyfield-patterns number-of-patterns))))
;; print detailed histogram:
(format t "~&~80,1,0,'.<~A ~; ~A~>" "User query" "no. of occurrences")
(let ((patterns-to-print (hash-table-keys pattern-histogram t)))
(if (> (length patterns-to-print) *nb-histogram-items-to-print*)
(setq patterns-to-print (subseq patterns-to-print 0 *nb-histogram-items-to-print*)))
(dolist (pattern patterns-to-print)
(format t "~&~80,1,0,'.<~A ~; ~A~>" pattern
(gethash pattern pattern-histogram))))))))
(defun print-basket-stats (httpd-all-log-entries)
"Read HTTPD-LOG-ENTRIES and print stats related to user baskets."
(declare (special *basket-url*
*add-to-basket-url*
*display-basket-url*
*display-public-basket-url*))
(let ((datetime-first (httpd-log-entry-datetime (car httpd-all-log-entries)))
(datetime-last (httpd-log-entry-datetime (car (last httpd-all-log-entries))))
(httpd-log-entries (filter-httpd-log-entries httpd-all-log-entries *basket-url*))
(basket-user-histogram (make-hash-table :test #'equalp)))
;; build basket users histogram:
(dolist (httpd-log-entry-item httpd-log-entries)
(incf (gethash (httpd-log-entry-ip httpd-log-entry-item)
basket-user-histogram 0)))
(format t "~&~%** USER BASKETS STATS")
;; print basket usage summary info:
(format t "~&There were ~D user basket page hits." (length httpd-log-entries))
(format t "~&This makes an average of ~F user basket page hits per day."
(/ (length httpd-log-entries) (1+ (- datetime-last datetime-first))))
(format t "~&There were ~D unique basket page users in ~D days."
(length (hash-table-keys basket-user-histogram))
(1+ (- datetime-last datetime-first)))
;; add to basket:
(format t "~&There were ~D additions to baskets."
(length (filter-httpd-log-entries httpd-log-entries *add-to-basket-url*)))
;; display baskets:
(format t "~&There were ~D displays of baskets, out of which ~D public baskets accesses."
(length (filter-httpd-log-entries httpd-log-entries *display-basket-url*))
(length (filter-httpd-log-entries httpd-log-entries *display-public-basket-url*)))))
(defun print-alert-stats (httpd-all-log-entries)
"Read HTTPD-LOG-ENTRIES and print stats related to user alerts."
(declare (special *alert-url*
*display-your-alerts-url*
*display-your-searches-url*))
(let ((datetime-first (httpd-log-entry-datetime (car httpd-all-log-entries)))
(datetime-last (httpd-log-entry-datetime (car (last httpd-all-log-entries))))
(httpd-log-entries (filter-httpd-log-entries httpd-all-log-entries *alert-url*))
(alert-user-histogram (make-hash-table :test #'equalp)))
;; build alert users histogram:
(dolist (httpd-log-entry-item httpd-log-entries)
(incf (gethash (httpd-log-entry-ip httpd-log-entry-item)
alert-user-histogram 0)))
(format t "~&~%** USER ALERTS STATS")
;; print alert usage summary info:
(format t "~&There were ~D user alert page hits." (length httpd-log-entries))
(format t "~&This makes an average of ~F user alert page hits per day."
(/ (length httpd-log-entries) (1+ (- datetime-last datetime-first))))
(format t "~&There were ~D unique alert page users in ~D days."
(length (hash-table-keys alert-user-histogram))
(1+ (- datetime-last datetime-first)))
;; display alert:
(format t "~&There were ~D displays of user alerts."
(length (filter-httpd-log-entries httpd-log-entries *display-your-alerts-url*)))
;; display alerts:
(format t "~&There were ~D displays of user searches history."
(length (filter-httpd-log-entries httpd-log-entries *display-your-searches-url*)))))
;; Special-purpose entry points:
(defun print-download-stats (httpd-log-filename file-pattern stats-frequency)
"Read httpd log file HTTPD-LOG-FILENAME, looking for FILE-PATTERN.
Print download stats for intervals of STATS-FREQUENCY, which may be
day, week, or month."
(declare (ignore httpd-log-filename file-pattern stats-frequency))
(format t "~&FIXME: Not implemented yet.")
t)
(defun extract-page-views-events (httpd-log-filename
&optional (exclude-ip-list nil))
"Walk through HTTPD-LOG-FILENAME and extract detailed record page
views events. Useful to input old statistics of page views into
CDSware's rnkPAGEVIEWS table. If EXCLUDE-IP-LIST is set, then do not
count events coming from those IPs."
(declare (type simple-base-string httpd-log-filename)
(type list exclude-ip-list))
(flet ((extract-recid-from-detailed-record-page-url (url)
(declare (type simple-base-string url))
(if (search "GET /search.py?recid=" url)
(or (parse-integer (subseq url 21) :junk-allowed t) 0)
0)))
(format t "-- APACHE LOG FILE ANALYSIS")
(format t "~&-- Filename: ~A" httpd-log-filename)
(unless (null exclude-ip-list)
(format t "~&-- Excluding search engine hits from ~A." exclude-ip-list))
(with-open-file (input-stream httpd-log-filename :direction :input)
(do ((line (read-line input-stream nil)
(read-line input-stream nil)))
((not line))
(declare (type (or simple-base-string null) line))
(let ((httpd-log-entry-item (create-httpd-log-entry (wash-httpd-log-line line))))
(if (and (or (null exclude-ip-list)
(not (member (httpd-log-entry-ip httpd-log-entry-item)
exclude-ip-list :test #'equal)))
(plusp (extract-recid-from-detailed-record-page-url
(httpd-log-entry-request httpd-log-entry-item))))
(format t "~&INSERT INTO rnkPAGEVIEWS (id_bibrec, client_host, view_time) VALUES ('~A', INET_ATON('~A'), '~A');"
(extract-recid-from-detailed-record-page-url
(httpd-log-entry-request httpd-log-entry-item))
(httpd-log-entry-ip httpd-log-entry-item)
(httpd-log-entry-datetimee httpd-log-entry-item)))))))
(format t "~&-- DONE"))
;; Main entry point:
(defun analyze-httpd-log-file (analyzer-config-file httpd-log-file)
"Main function that analyzes HTTPD-LOG-FILE according to
instructions presented in ANALYZER-CONFIG-FILE."
(declare (special *profile*
*nb-histogram-items-to-print*
*exclude-ip-list*
*home-collection*
*search-interface-url*
*search-engine-url*
*basket-url*
*add-to-basket-url*
*display-basket-url*
*display-public-basket-url*
*alert-url*
*display-your-alerts-url*
*display-your-searches-url*))
(load analyzer-config-file :verbose nil :print nil)
(when *profile*
#+cmu (profile:profile-all)
#+fixmeclisp (mon:monitor-all)
#+sbcl (progn
(sb-profile:profile PRINT-SEARCH-PATTERN-STATS)
(sb-profile:profile CREATE-HTTPD-LOG-ENTRIES)
(sb-profile:profile GET-SEARCH-PATTERNS-FROM-HTTPD-LOG-REQUEST-STRING)
(sb-profile:profile PARSE-HTTPD-LOG-LINE)
(sb-profile:profile STRING-DECODE-URL)
(sb-profile:profile CREATE-HTTPD-LOG-ENTRY)
(sb-profile:profile GET-DATETIME-FROM-HTTPD-LOG-DATETIME-STRING)
(sb-profile:profile WASH-HTTPD-LOG-LINE)
(sb-profile:profile GET-MONTH-NUMBER-FROM-MONTH-NAME)
(sb-profile:profile MAKE-HTTPD-LOG-ENTRY)
(sb-profile:profile PARSE-INTEGER-OR-ZERO)
(sb-profile:profile GET-URLARG-VALUE-FROM-URL-STRING)
(sb-profile:profile HASH-TABLE-KEYS)
(sb-profile:profile HASH-TABLE-KEY-VAL-STATS)
(sb-profile:profile STRING-SUBSTITUTE)))
(let ((httpd-all-log-entries (create-httpd-log-entries httpd-log-file *exclude-ip-list*)))
(print-general-stats httpd-all-log-entries)
(print-search-interface-stats httpd-all-log-entries)
(print-search-collections-stats httpd-all-log-entries)
(print-search-pattern-stats httpd-all-log-entries)
(print-basket-stats httpd-all-log-entries)
(print-alert-stats httpd-all-log-entries))
(format t "~&")
(when *profile*
#+cmu (profile:report-time)
#+fixmeclisp (mon:report)
#+sbcl (sb-profile:report)))
diff --git a/modules/webstyle/Makefile.am b/modules/webstyle/Makefile.am
index 76b972612..f1ab30773 100644
--- a/modules/webstyle/Makefile.am
+++ b/modules/webstyle/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = css doc img lib
CLEANFILES = *~
\ No newline at end of file
diff --git a/modules/webstyle/css/Makefile.am b/modules/webstyle/css/Makefile.am
index 1584267d3..73f397ed9 100644
--- a/modules/webstyle/css/Makefile.am
+++ b/modules/webstyle/css/Makefile.am
@@ -1,25 +1,25 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webdir=$(WEBDIR)/img
web_DATA=cds.css
EXTRA_DIST = $(web_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/webstyle/css/cds.css b/modules/webstyle/css/cds.css
index dea1956c2..ed1dea458 100644
--- a/modules/webstyle/css/cds.css
+++ b/modules/webstyle/css/cds.css
@@ -1,1254 +1,1254 @@
/*
* -*- mode: text; coding: utf-8; -*-
$Id$
This file is part of the CERN Document Server Software (CDSware).
- Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
The CDSware 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.
The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
body {
color: #000;
background: #fff;
margin: 0px;
padding: 0px;
}
h1 {
font-size: 173%;
font-weight: 700;
margin-top: 5px;
margin-left: 0px;
color: #36c;
background: transparent;
}
.h1 {
font-size: 173%;
font-weight: 700;
margin-left: 0px;
color: #36c;
background: transparent;
}
h2 {
font-size: 144%;
font-weight: 650;
margin-left: 0px;
color: #36c;
background: transparent;
}
h3 {
font-size: 120%;
font-weight: 600;
font-variant: small-caps;
margin-top: 40px;
margin-left: 0px;
margin-bottom: 10px;
color: #36c;
background: transparent;
border-bottom: dotted 2px #36c;
width: 50%;
}
h4 {
font-size: 110%;
font-weight: 600;
font-style: italic;
color: #36c;
margin-left: 0px;
background: transparent;
}
h5 {
font-size: 110%;
font-weight: 400;
color: #36c;
margin-left: 0px;
background: transparent;
}
h6 {
font-size: 110%;
font-weight: 200;
font-style: italic;
color: #36c;
margin-left: 0px;
background: transparent;
}
a:link {
color: #00c;
background: transparent;
}
a:visited {
color: #006;
background: transparent;
}
a:active {
color: #00c;
background: transparent;
}
a:hover {
color: #00c;
background: transparent;
}
a.moreinfo:link {
color: #060;
background: transparent;
}
a.moreinfo:visited {
color: #060;
background: transparent;
}
a.moreinfo:active {
color: #060;
background: transparent;
}
a.moreinfo:hover {
color: #060;
background: transparent;
}
a.img:hover {
color: #00c;
background: transparent;
}
a.img:active {
color: #00c;
background: transparent;
font-weight: normal;
}
a.note:link {
color: #666;
background: transparent;
}
a.note:visited {
color: #666;
background: transparent;
}
a.note:active {
color: #666;
background: transparent;
}
a.note:hover {
color: #666;
background: transparent;
}
.headerbox {
color: #000;
background: transparent;
width: 100%;
padding: 0px;
margin-top: 0px;
margin-bottom: 0px;
border-collapse: collapse;
border-bottom: 2px solid #3366cc;
}
.headerboxbody {
color: #000;
padding: 0px;
margin: 0px;
}
.headerboxbodylogo {
width: 200px;
padding-left: 5px;
color: #36c;
font-size: 20px;
font-weight: bold;
font-variant: small-caps;
letter-spacing: 6px;
}
.headermodulebox {
color: #fff;
background: transparent;
border-collapse: collapse;
margin: 0px;
padding: 0px;
}
.headermoduleboxbody {
color: #000;
background: #36c;
font-size: x-small;
font-weight: bold;
text-align: center;
margin: 0px;
padding: 0px;
width: 75px;
}
.headermoduleboxbodyblank {
width: 12px;
padding: 0px;
margin: 0px;
}
.headermoduleboxbodyselected {
color: #000;
background: #fff;
font-size: x-small;
font-weight: bold;
text-align: center;
border-left: 2px solid #36c;
border-right: 2px solid #36c;
border-top: 2px solid #36c;
margin: 5px;
padding: 0px;
width: 75px;
}
a.header:link {
color: #fff;
background: #36c;
text-decoration: none;
}
a.header:visited {
color: #fff;
background: #36c;
text-decoration: none;
}
a.header:active {
color: #fff;
background: #36c;
text-decoration: none;
}
a.header:hover {
color: #fff;
background: #36c;
text-decoration: none;
}
a.headerselected:link {
color: #36c;
background: #fff;
text-decoration: none;
}
a.headerselected:visited {
color: #36c;
background: #fff;
text-decoration: none;
}
a.headerselected:active {
color: #36c;
background: #fff;
text-decoration: none;
}
a.headerselected:hover {
color: #36c;
background: #fff;
text-decoration: none;
}
.navtrailbox {
color: #36c;
background: #fff;
padding: 0px;
margin-top: 7px;
border-spacing: 0px;
border-collapse: collapse;
font-size: x-small;
}
.navtrailboxbody {
color: #36c;
padding: 0px 0px 0px 10px;
border-spacing: 0px;
background: #fff;
font-size: x-small;
}
a.navtrail:link {
color: #36c;
background: transparent;
}
a.navtrail:visited {
color: #36c;
background: transparent;
}
a.navtrail:active {
color: #36c;
background: transparent;
}
a.navtrail:hover {
color: #36c;
background: transparent;
}
.info {
color: #060;
background: transparent;
}
.snapshot {
color: #000;
background: transparent;
border: 2px solid #999;
margin: 10px 10px 0px 40px;
}
.pageheader {
color: #999;
font-size: x-small;
background: transparent;
padding: 0px;
margin: 0px;
width: 100%;
}
.pagebody {
color: #000;
background: transparent;
margin:0px;
padding: 20px;
}
.pagebodystripeleft {
color: #000;
background: #fff;
font-size: x-small;
width: 120px;
margin: 0px;
padding-left: 10px;
float: left;
}
.pagebodystripemiddle {
color: #000;
background: #fff;
padding: 0px;
margin: 0px;
width: 100%;
}
.pagebodystriperight {
color: #000;
background: #fff;
font-size: x-small;
width: 120px;
float: right;
}
.pageboxlefttop {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxlefttopadd {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxleftbottom {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxleftbottomadd {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxrighttop {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxrighttopadd {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxrightbottom {
color: #000;
background: transparent;
font-size: x-small;
}
.pageboxrightbottomadd {
color: #000;
background: transparent;
font-size: x-small;
}
.pagefooter {
color: #666;
background: #fff;
font-size: x-small;
margin-top: 50px;
padding: 0px;
border-top: 1px solid #666;
width: 100%;
clear: both;
}
.pagefooterstripeleft {
color: #666;
background: #fff;
font-size: x-small;
margin-left: 5px;
width: 60%;
float: left;
text-align: left;
}
.pagefooterstriperight {
color: #666;
background: #fff;
margin-right: 5px;
font-size: x-small;
text-align: right;
}
a.footer:link {
color: #666;
background: transparent;
}
a.footer:visited {
color: #666;
background: transparent;
}
a.footer:active {
color: #666;
background: transparent;
}
a.footer:hover {
color: #666;
background: transparent;
}
.errorbox {
color: #000;
background: #ffcccc;
padding: 1px;
margin: 5px 30px 5px 30px;
border-collapse: collapse;
border: 2px solid #900;
}
.errorboxheader {
color: #000;
background: #ffcccc;
padding: 3px;
border-spacing: 0px;
font-weight: bold;
text-align: left;
}
.errorboxbody {
color: #000;
background: #ffcccc;
padding: 3px;
}
.searchbox {
color: #000;
background: #fff;
padding: 1px;
margin: 5px 0px 5px 0px;
border-collapse: collapse;
border-top: 1px solid #36c;
}
.searchboxheader {
color: #000;
background: #f1f1f1;
padding: 3px;
border-spacing: 0px;
font-size: small;
text-align: left;
}
.searchboxbody {
color: #000;
background: #fff;
padding: 3px;
}
.narrowsearchbox {
color: #000;
background: #fff;
padding: 1px;
margin: 20px 20px 5px 0px;
border-collapse: collapse;
border-top: 1px solid #36c;
}
.narrowsearchboxheader {
color: #000;
background: #f1f1f1;
padding: 3px;
border-spacing: 0px;
font-size: small;
text-align: left;
}
.narrowsearchboxbody {
color: #000;
background: #fff;
padding: 3px;
}
.latestadditionsbox {
color: #000;
background: #fff;
padding: 5px;
margin: 5px 20px 5px 0px;
border-spacing: 5px;
}
.latestadditionsboxtimebody {
color: #000;
background: #fff;
padding: 3px;
white-space: nowrap;
text-align: right;
vertical-align: top;
font-size: xx-small;
}
.latestadditionsboxrecordbody {
color: #000;
background: #fff;
padding: 3px;
text-align: left;
vertical-align: top;
font-size: small;
}
.portalbox {
color: #000;
background: #fff;
margin: 0px 0px 15px 0px;
border-collapse: collapse;
border-top: 1px solid #abb;
font-size: x-small;
width: 100%;
}
.portalboxheader {
color: #000;
background: #f1f1f1;
padding: 2px;
border-spacing: 0px;
border-bottom: 1px solid #999;
text-align: left;
font-size: x-small;
}
.portalboxbody {
color: #000;
background: #fff;
padding: 2px;
font-size: x-small;
}
.admin_wvar, .admin_w200, .admin_wvar_nomargin {
color: #000;
background: white;
padding: 1px;
margin: 0px 0px 5px 20px;
border-spacing: 0px;
border-top: 1px solid #36c;
}
.admin_w200 {
width: 250px;
}
.admin_wvar_nomargin {
margin: 0px;
}
.adminlabel {
width: 100px;
font-size: small;
background: #f1f1f1;
vertical-align: top;
}
.adminheader, .adminheaderleft, .adminheadercenter, .adminheaderright {
color: #000;
background: #f1f1f1;
border-spacing: 0px;
font-size: small;
padding: 3px 5px;
text-align: center;
}
.adminheaderleft {
text-align: left;
}
.adminheaderright {
text-align: right;
}
.adminbutton {
color: #fff;
background: #36c;
font-weight: bold;
margin: 5px 10px 5px 10px;
border-collapse: collapse;
border-top: 1px solid #36c;
}
.admintd, .admintdleft, .admintdright {
font-size: small;
padding: 0px 10px;
text-align: center;
vertical-align: top;
}
.admintdleft {
text-align: left;
}
.admintdright {
text-align: right;
}
a.google:link {
color: #333;
background: transparent;
}
a.google:visited {
color: #333;
background: transparent;
}
a.google:active {
color: #333;
background: transparent;
}
a.google:hover {
color: #333;
background: transparent;
}
.googlebox {
color: #333;
background: #fff;
text-align: left;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
padding: 10px;
font-size: small;
border-collapse: collapse;
border-top: 1px solid #fc0;
}
.googleboxheader {
color: #333;
background: #ffc;
font-weight: normal;
font-size: small;
vertical-align: top;
}
.googleboxbody {
color: #333;
background: #fff;
padding: 0px 5px 0px 5px;
font-size: small;
text-align: left;
vertical-align: top;
}
.adminbox {
color: #000;
background: #f1f1f1;
margin: 0px;
padding: 0px;
width: 120px;
}
.adminboxheader {
color: #000;
background: #f1f1f1;
font-size: x-small;
text-align: left;
}
.adminboxbody {
color: #000;
background: #f1f1f1;
font-size: x-small;
}
.formbutton {
color: #fff;
background: #36c;
font-weight: bold;
}
.headline {
color: #36c;
background: transparent;
}
.quicknote {
color: #603;
background: transparent;
}
.important {
color: #f00;
background: transparent;
}
.popupselected {
color: #fff;
background: #006;
}
.searchresultsbox {
color: #000;
background: #ffe;
padding: 0px;
margin-top: 15px;
border-collapse: collapse;
border-top: 1px solid #fc0;
width: 100%;
}
.searchresultsboxheader {
color: #000;
background: #ffc;
padding: 2px;
border-spacing: 0px;
text-align: left;
font-weight: normal;
}
.searchresultsboxbody {
color: #000;
background: #ffe;
border-top: 1px dotted #fc0;
border-bottom: 1px dotted #fc0;
padding: 2px;
}
.searchresultsboxrecords {
color: #000;
background: transparent;
margin-left: 0px;
margin-right: 20px;
}
.nearesttermsbox {
color: #603;
background: #ffe;
padding: 0px;
border-collapse: collapse;
}
.nearesttermsboxheader {
color: #603;
background: #ffc;
padding: 0px;
border-spacing: 0px;
text-align: left;
font-weight: normal;
}
.nearesttermsboxbody {
color: #603;
background: #fff;
padding: 0px;
}
a.nearestterms:link {
color: #603;
background: transparent;
}
a.nearestterms:visited {
color: #603;
background: transparent;
}
a.nearestterms:active {
color: #603;
background: transparent;
}
a.nearestterms:hover {
color: #603;
background: transparent;
}
.nearesttermsboxbodyselected {
color: #999;
background: #fff;
padding: 0px;
}
a.nearesttermsselected:link {
color: #999;
background: transparent;
}
a.nearesttermsselected:visited {
color: #999;
background: transparent;
}
a.nearesttermsselected:active {
color: #999;
background: transparent;
}
a.nearesttermsselected:hover {
color: #999;
background: transparent;
}
.moreinfo {
color: #060;
font-size: small;
background: transparent;
}
.rankscoreinfo {
color: #666;
font-size: x-small;
background: transparent;
}
.userinfobox {
color: #039;
font-size: x-small;
width: 150px;
margin-bottom: 15px;
}
.userinfoboxheader {
color: #039;
font-size: x-small;
font-weight: bold;
border-top: 1px solid #060;
border-bottom: 1px solid #060;
}
.userinfoboxbody {
color: #039;
padding: 0px 5px 2px 0px;
font-size: x-small;
font-weight: normal;
}
a.userinfo:link {
color: #039;
background: transparent;
}
a.userinfo:visited {
color: #039;
background: transparent;
}
a.userinfo:active {
color: #039;
background: transparent;
}
a.userinfo:hover {
color: #039;
background: transparent;
}
a.langinfo:link {
color: #666;
background: transparent;
}
a.langinfo:visited {
color: #666;
background: transparent;
}
a.langinfo:active {
color: #666;
background: transparent;
}
a.langinfo:hover {
color: #666;
background: transparent;
}
.faq {
margin-left: 12%;
margin-right: 3%;
}
.faqq {
margin-left: 18%;
margin-right: 3%;
}
.exampleleader {
color: #060;
background: transparent;
}
.example {
color: #039;
background: transparent;
}
.blocknote {
color: #000;
background: #ccc;
}
.blocknotebis {
color: #000;
background: #999;
}
.devel {
color: #600;
background: #fff;
border-color: #600;
border-left-width: medium;
border-left-style: solid;
font-size: 90%;
}
.normal {
color: #000;
background: #fff;
}
.address {
font-style: normal;
font-size: x-small;
}
.note {
color: #666;
background: transparent;
}
.warning {
color: #603;
background: transparent;
}
.light {
color: #ccc;
background: transparent;
}
.nbdoccoll {
color: #666;
background: transparent;
}
hr {
width: 100%;
height: 1px;
color: #999;
background-color: #999;
border-width: 0;
}
input,select {
color: #000;
background: #fff;
}
.wsactionbutton {
width: 150px;
height: 25px;
color: #039;
margin: 0px;
background-color: #fff;
border: 2px solid #039;
vertical-align: middle;
font-size: small;
padding: 5px 5px 0px 5px;
}
.wsactionbuttonh {
width: 150px;
height: 25px;
color: #039;
margin: 0px;
background-color: #9cf;
border: 2px solid #039;
vertical-align: middle;
font-size: small;
padding: 5px 5px 0px 5px;
}
.textbutton {
color: #039;
font-weight: bold;
text-decoration: none;
}
.submitBody {
color: #000;
background: #9cf;
}
.submitHeader {
color: #fff;
background: #006;
}
.submitCurrentPage {
color: #000;
background: #9cf;
border-top: 1px solid #039;
border-left: 1px solid #039;
border-right: 1px solid #039;
}
.submitEmptyPage {
color: #fff;
background: #fff;
border-bottom: 1px solid #039;
}
.submitPage {
color: #000;
background: #fff;
border-top: 1px solid #039;
border-left: 1px solid #039;
border-right: 1px solid #039;
}
.mycdscell {
border-right: 1px solid #fff;
}
.guideimg {
border: 2px dotted #777;
padding: 5px;
margin: 5px;
}
.guideheader {
font-size: 120%;
font-weight: 600;
font-variant: small-caps;
color: #36c;
margin-left: 10px;
background: transparent;
}
.recordlastmodifiedbox {
text-align: left;
font-size: small;
color: #603;
background: #fff;
}
.commentbox {
color: #000;
width: 100%;
padding: 0px 10px 10px 10px;
border-left: 2px solid #36c;
}
.warninggreen {
color: #060;
background: transparent;
}
.warningred {
color: #f00;
background: transparent;
}
.reportabuse {
color: #000;
background: #fff;
font-size: small;
vertical-align: bottom;
}
/* WebMessage module */
.mailbox{
border-collapse: collapse;
color: #000;
margin-top: 15px;
padding: 0px;
width: auto;
}
.mailboxheader tr{
background: #ffc;
}
.inboxheader {
text-align:center;
padding: 5px 30px 5px 30px;
border-top: 1px solid #fc0;
border-bottom: 1px solid #fc0;
}
.messageheader{
width: 100%;
padding: 0px;
border: 0px;
}
.mailboxinput{
width: 100%;
}
.mailboxlabel{
white-space: nowrap;
padding-right: 15px;
}
.mailboxbody{
background: #ffe;
}
.mailboxrecord{
/* each record */
}
.mailboxrecord td{
/* each cell of a record */
padding: 4px 30px 4px 30px;
border-top: 1px dashed #fff;
}
.mailboxfooter{
background-color: #fff;
}
.mailboxfooter td{
padding: 10px 0px 0px 0px;
border-top: 1px solid #fc0;
border-bottom: none;
border-left: none;
border-right: none;
}
.mailboxsearch td {
padding-top: 10px;
padding-bottom: 10px;
}
.mailboxresults td {
padding-bottom: 5px;
border-bottom: 1px solid #fc0;
}
.nonsubmitbutton {
color: #000;
background: #fc0;
font-weight: bold;
}
.confirmoperation{
margin: auto;
width: 400px;
height: 100px;
background-color: #ddf;
}
.confirmmessage{
font-weight: bold;
text-align: center;
}
.infobox{
background-color: #ffc;
padding: 7px;
border-collapse: collapse;
border: 1px solid #fc0;
}
.warningbox{
background-color: #cff;
padding: 7px;
border-collapse: collapse;
border: 1px solid #ccff00;
}
.quotabox{
background-color: #ffc;
width: 200px;
height: 15px;
border: 1px solid #fc0;
margin: 3px 0px 3px 0px;
}
.quotabar{
background-color: #fc0;
border: 0px none black;
height: 15px;
}
/* WebBasket module */
#bskcontainer{
float: left;
background: transparent;
}
#bsktabs{
float: left;
width: 100%;
background:transparent;
padding: 0px;
margin: 0px;
text-align: center;
}
.bsktab{
float: left;
vertical-align: center;
margin: 0px 20px 0px 20px;
padding: 4px 10px 5px 5px;
background-repeat: no-repeat;
background-position: top-left;
background-color: #ffe;
}
#bsktab_selected{
background-color: #ffc;
font-weight: bold;
/* border-left: 1px solid #fc0;
border-top: 1px solid #fc0;
border-right: 1px solid #fc0;*/
border-bottom: hidden;
}
.bsktab a{
color: #000;
text-decoration: none;
}
.bsktab a:hover{
text-decoration: underline;
}
.bsktab img{
margin: 0px 5px 0px 0px;
}
#bskcontent{
float: left;
border-collapse: collapse;
background: #ffe;
border: none;
}
#bsktopics{
background-color: #ffc;
padding: 10px;
width: 100%;
}
.bsktopic{
white-space: nowrap;
font-weight: bold;
margin: 0px 20px 0px 20px;
}
.bsktopic a{
font-weight: normal;
text-decoration: none;
color: #000;
}
.bsktopic a:hover{
text-decoration: underline;
}
#bskbaskets{
padding: 10px;
}
#bskinfos{
background-color: transparent;
}
.bskbasket{
width: auto;
margin-bottom: 20px;
border-collapse: collapse;
border: 1px solid #fc0;
background-color:white;
}
.bskbasketheader{
background-color: #ffc;
}
.bskbasketheader td{
padding: 5px;
border-bottom: 1px solid #fc0;
border-collapse: collapse;
vertical-align: top;
}
.bskbasketfooter{
border-top: 1px solid #fc0;
background-color: #ffc;
padding: 3px;
}
.bskbasketheaderactions{
text-align: center;
white-space: nowrap;
}
.bskbasketheaderactions td{
border: none;
}
.bskbasketheaderactions img{
border: 0px;
margin: 2px;
}
.bskbasketheaderactions a{
font-size: small;
color: #000;
}
.bskbasketfooter td{
padding: 5px 0px 5px 0px;
}
.bskactions{
text-align: center;
white-space: nowrap;
border-bottom: 1px solid #fc0;
}
.bskactions td{
border: none;
}
.bskactions img{
border: 0px;
margin: 2px;
}
.bskactions a{
font-size: x-small;
}
.bsktitle {
width: 100%;
}
.bskcmtcol{
white-space: nowrap;
text-align: right;
}
.bskcontentcol{
border-bottom: 1px solid #fc0;
padding: 5px;
}
.bskcontentcol a{
font-size: small;
}
.bskcomment {
padding: 15px 10px 15px 10px;
margin-bottom: 5px;
border-bottom: 1px solid #fc0;
}
.bsklabel{
font-size: small;
font-weight: bold;
white-space: nowrap;
padding-right: 15px;
}
.bsk_create_link{
padding-top: 5px;
padding-bottom: 10px;
background-color: transparent;
}
.bsk_create_link a{
color: black;
}
.bsk_create_link img{
border: none;
}
dd{
margin-bottom: 10px;
}
/* end of WebBasket module */
/* WebSubmit module */
form.hyperlinkform {
/* used in form tag for a form that should be hidden, but contains a button styled like a hyperlink */
display: inline;
padding: 0;
margin: 0;
height: 0;
width: 0;
}
input.hyperlinkformHiddenInput {
/* used in a hidden input tag for a form that should be hidden, but contains a button styled like a hyperlink */
display: inline;
padding: 0;
margin: 0;
height: 0;
width: 0;
}
input.hyperlinkformSubmitButton {
/* used in a submit input tag for a form that should be hidden, but contains a button styled like a hyperlink */
display: inline;
padding: 0;
margin: 0;
border: 0;
background-color: transparent;
font-size: 1em;
line-height: 1em;
text-decoration: underline;
cursor: pointer;
color: blue;
}
/* end of WebSubmit module */
/* end of cds.css */
diff --git a/modules/webstyle/doc/Makefile.am b/modules/webstyle/doc/Makefile.am
index f9de00106..4beb41039 100644
--- a/modules/webstyle/doc/Makefile.am
+++ b/modules/webstyle/doc/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
CLEANFILES = *~
diff --git a/modules/webstyle/doc/admin/Makefile.am b/modules/webstyle/doc/admin/Makefile.am
index 9d937268c..e6491487a 100644
--- a/modules/webstyle/doc/admin/Makefile.am
+++ b/modules/webstyle/doc/admin/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/webstyle
doc_DATA=index.html guide.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp
%.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py en $@
\ No newline at end of file
diff --git a/modules/webstyle/doc/admin/guide.html.wml b/modules/webstyle/doc/admin/guide.html.wml
index 76200f22b..28604ce60 100644
--- a/modules/webstyle/doc/admin/guide.html.wml
+++ b/modules/webstyle/doc/admin/guide.html.wml
@@ -1,53 +1,53 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebStyle Admin Guide" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/webstyle/>WebStyle Admin</a>" \
navbar_name="admin" \
navbar_select="webstyle-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h2>Compile-time Configuration of Page Layout</h2>
<p>The style of the CDSware installation is defined largely also
during the configuration time, as explained in the <a
href="http://cdsware.cern.ch/download/INSTALL">INSTALL</a> guide. You
can modify page header, footer, general portalboxes, etc. See the
installation guide for more details.
<h2>Run-time Configuration of Page Layout</h2>
<p>During runtime you most probably want to modify mostly the <a
href="<WEBURL>/img/cds.css">CDS style sheet</a> and <a
href="<WEBURL>/img/">images</a>.
<p>The look of the search interface pages may be modify to a very
large extent in the <a href="<WEBURL>/admin/websearch">WebSearch Admin
Interface</a> by adding portalboxes on various places on the page.
<h2>Advanced Page Layout Changes</h2>
<p>More advanced changes to the web page layout have to be carried out
on the programming level. For example, most mod_python dynamic pages
are using the <code>page()</code> function defined in the
<code>webpage.py</code> file.
diff --git a/modules/webstyle/doc/admin/index.html.wml b/modules/webstyle/doc/admin/index.html.wml
index 87b6d893c..c7e4a3e79 100644
--- a/modules/webstyle/doc/admin/index.html.wml
+++ b/modules/webstyle/doc/admin/index.html.wml
@@ -1,34 +1,34 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "cdspage.wml" \
title="WebStyle Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="webstyle"
<p>
This is the gate to the admin area for WebStyle. You need to
<a href="<WEBURL>/youraccount.py/login?referer=<WEBURL>/admin/webstyle/">login</a> to enter.
</p>
<dl>
<dt><a href="guide.html">WebStyle Admin Guide</a></dt>
<dd>Everything you want to know about WebStyle administration</dd>
</dl>
diff --git a/modules/webstyle/img/Makefile.am b/modules/webstyle/img/Makefile.am
index 8cac432fe..f4dc12d70 100644
--- a/modules/webstyle/img/Makefile.am
+++ b/modules/webstyle/img/Makefile.am
@@ -1,28 +1,28 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
gifsdir=$(WEBDIR)/img
GIFS = $(wildcard $(srcdir)/*.gif $(srcdir)/*.jpg $(srcdir)/*.png)
gifs_DATA = $(GIFS:$(srcdir)/%=%)
EXTRA_DIST = $(gifs_DATA)
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/webstyle/lib/Makefile.am b/modules/webstyle/lib/Makefile.am
index 6f81fa827..e985bcdab 100644
--- a/modules/webstyle/lib/Makefile.am
+++ b/modules/webstyle/lib/Makefile.am
@@ -1,25 +1,25 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir=$(libdir)/python/cdsware
pylib_DATA=webpage.py template.py webstyle_templates.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp *.pyc
diff --git a/modules/webstyle/lib/template.py b/modules/webstyle/lib/template.py
index 0a6250bd4..0a370924d 100644
--- a/modules/webstyle/lib/template.py
+++ b/modules/webstyle/lib/template.py
@@ -1,46 +1,46 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware templating framework."""
__version__ = "$Id$"
from cdsware.config import cfg_template_skin
def load(module=''):
""" Load and returns a template class, given a module name (like
'websearch', 'webbasket',...). The module corresponding to
the currently selected template model (see config.wml,
variable CFG_TEMPLATE_SKIN) is tried first. In case it does
not exist, it returns the default template for that module.
"""
local = {}
# load the right template based on the cfg_template_skin and the specified module
if cfg_template_skin == "default":
mymodule = __import__("cdsware.%s_templates" % (module), local, local,
["cdsware.templates.%s" % (module)])
else:
try:
mymodule = __import__("cdsware.%s_templates_%s" % (module, cfg_template_skin), local, local,
["cdsware.templates.%s_%s" % (module, cfg_template_skin)])
except ImportError:
mymodule = __import__("cdsware.%s_templates" % (module), local, local,
["cdsware.templates.%s" % (module)])
return mymodule.Template()
diff --git a/modules/webstyle/lib/webpage.py b/modules/webstyle/lib/webpage.py
index 0208839d0..7a0ba80cf 100644
--- a/modules/webstyle/lib/webpage.py
+++ b/modules/webstyle/lib/webpage.py
@@ -1,172 +1,172 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Web Page Functions"""
import re
import string
import sys
import time
import traceback
import urllib
from cdsware.config import *
from cdsware.messages import gettext_set_language
from cdsware.webuser import create_userinfobox_body
from cdsware.errorlib import get_msgs_for_code_list, register_errors
import cdsware.template
webstyle_templates = cdsware.template.load('webstyle')
def create_navtrailbox_body(title,
previous_links,
prolog="",
separator=""" &gt; """,
epilog="",
language=cdslang):
"""Create navigation trail box body
input: title = page title;
previous_links = the trail content from site title until current page (both ends exlusive).
output: text containing the navtrail
"""
return webstyle_templates.tmpl_navtrailbox_body(weburl = weburl,
ln = language,
title = title,
previous_links = previous_links,
separator = separator,
prolog = prolog,
epilog = epilog)
def page(title, body, navtrail="", description="", keywords="", uid=0, cdspageheaderadd="", cdspageboxlefttopadd="", cdspageboxleftbottomadd="", cdspageboxrighttopadd="", cdspageboxrightbottomadd="", cdspagefooteradd="", lastupdated="", language=cdslang, urlargs="", verbose=1, titleprologue="", titleepilogue="", req=None, errors=[], warnings=[]):
"""page(): display CDS web page
input: title of the page
body of the page in html format
description goes to the metadata in the header of the HTML page
keywords goes to the metadata in the header of the html page
cdspageheaderadd is a message to be displayed just under the page header
cdspageboxlefttopadd is a message to be displayed in the page body on left top
cdspageboxleftbottomadd is a message to be displayed in the page body on left bottom
cdspageboxrighttopadd is a message to be displayed in the page body on right top
cdspageboxrightbottomadd is a message to be displayed in the page body on right bottom
cdspagefooteradd is a message to be displayed on the top of the page footer
lastupdated is a text containing the info on last update (optional)
language is the language version of the page
urlargs are the URL arguments of the page to display (useful to affect languages)
verbose is verbosity of the page (useful for debugging)
titleprologue is to be printed right before page title
titleepilogue is to be printed right after page title
req is the mod_python request
errors is the list of error codes as defined in the moduleName_config.py file of the calling module
log is the string of data that should be appended to the log file (errors automatically logged)
output: the final cds page with header, footer, etc.
"""
_ = gettext_set_language(language)
if title == cdsnameintl[language]:
headerstitle = _("Home")
else:
headerstitle = title
# if there are event
if warnings:
warnings = get_msgs_for_code_list(warnings, 'warning', language)
register_errors(warnings, 'warning')
# if there are errors
if errors:
errors = get_msgs_for_code_list(errors, 'error', language)
register_errors(errors, 'error', req)
body = create_error_box(req, errors=errors, ln=language)
return webstyle_templates.tmpl_page(weburl = weburl,
ln = language,
headertitle = headerstitle,
sitename = cdsnameintl[language],
supportemail = supportemail,
description = description,
keywords = keywords,
userinfobox = create_userinfobox_body(uid, language),
navtrailbox = create_navtrailbox_body(title, navtrail, language=language),
uid = uid,
# pageheader = cdspageheader,
pageheaderadd = cdspageheaderadd,
boxlefttop = cdspageboxlefttop,
boxlefttopadd = cdspageboxlefttopadd,
boxleftbottomadd = cdspageboxleftbottomadd,
boxleftbottom = cdspageboxleftbottom,
boxrighttop = cdspageboxrighttop,
boxrighttopadd = cdspageboxrighttopadd,
boxrightbottomadd = cdspageboxrightbottomadd,
boxrightbottom = cdspageboxrightbottom,
titleprologue = titleprologue,
title = title,
titleepilogue = titleepilogue,
body = body,
# pagefooter = cdspagefooter,
languagebox = webstyle_templates.tmpl_language_selection_box(urlargs, language),
version = version,
lastupdated = lastupdated,
pagefooteradd = cdspagefooteradd)
def pageheaderonly(title, navtrail="", description="", keywords="", uid=0, cdspageheaderadd="", language=cdslang, urlargs="", verbose=1):
"""Return just the beginning of page(), with full headers.
Suitable for the search results page and any long-taking scripts."""
return webstyle_templates.tmpl_pageheader(weburl = weburl,
ln = language,
headertitle = title,
sitename = cdsnameintl[language],
supportemail = supportemail,
description = description,
keywords = keywords,
userinfobox = create_userinfobox_body(uid, language),
navtrailbox = create_navtrailbox_body(title, navtrail, language=language),
uid = uid,
# pageheader = cdspageheader,
pageheaderadd = cdspageheaderadd,
languagebox = webstyle_templates.tmpl_language_selection_box(urlargs, language))
def pagefooteronly(cdspagefooteradd="", lastupdated="", language=cdslang, urlargs="", verbose=1):
"""Return just the ending of page(), with full footer.
Suitable for the search results page and any long-taking scripts."""
return webstyle_templates.tmpl_pagefooter(weburl = weburl,
ln = language,
sitename = cdsnameintl[language],
supportemail = supportemail,
# pagefooter = cdspagefooter,
languagebox = webstyle_templates.tmpl_language_selection_box(urlargs, language),
version = version,
lastupdated = lastupdated,
pagefooteradd = cdspagefooteradd)
def create_error_box(req, title=None, verbose=1, ln=cdslang, errors=None):
"""Analyse the req object and the sys traceback and return a text
message box with internal information that would be suitful to
display when something bad has happened.
"""
_ = gettext_set_language(ln)
return webstyle_templates.tmpl_error_box(title = title,
ln = ln,
verbose = verbose,
req = req,
supportemail = supportemail,
errors = errors)
diff --git a/modules/webstyle/lib/webstyle_templates.py b/modules/webstyle/lib/webstyle_templates.py
index d7079df82..cfc70d3e4 100644
--- a/modules/webstyle/lib/webstyle_templates.py
+++ b/modules/webstyle/lib/webstyle_templates.py
@@ -1,592 +1,592 @@
## $Id$
## CDSware WebStyle templates.
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import urllib
import time
import cgi
import gettext
import traceback
import sre
import urllib
import sys
from cdsware.config import *
from cdsware.messages import gettext_set_language, language_list_long
class Template:
def tmpl_navtrailbox_body(self, weburl, ln, title, previous_links, separator, prolog, epilog):
"""Create navigation trail box body
Parameters:
- 'weburl' *string* - The base URL for the site
- 'ln' *string* - The language to display
- 'title' *string* - page title;
- 'previous_links' *string* - the trail content from site title until current page (both ends exlusive)
- 'prolog' *string* - HTML code to prefix the navtrail item with
- 'epilog' *string* - HTML code to suffix the navtrail item with
- 'separator' *string* - HTML code that separates two navtrail items
Output:
- text containing the navtrail
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if title != cdsnameintl[ln]:
out += """<a class="navtrail" href="%(weburl)s?ln=%(ln)s">%(msg_home)s</a>""" % {
'weburl' : weburl,
'ln' : ln,
'msg_home' : _("Home")}
if previous_links:
if out:
out += separator
out += previous_links
if title:
if out:
out += separator
if title == cdsnameintl[ln]: # hide site name, print Home instead
out += _("Home")
else:
out += title
return prolog + out + epilog
def tmpl_page(self, weburl, ln, headertitle, sitename = "", supportemail = "", description = "", keywords = "",
userinfobox = "", navtrailbox = "",
pageheaderadd = "", boxlefttop = "", boxlefttopadd = "",
boxleftbottom = "", boxleftbottomadd = "", boxrighttop = "", boxrighttopadd = "",
boxrightbottom = "", boxrightbottomadd = "", titleprologue = "", title = "", titleepilogue = "", body = "",
version = "", lastupdated = None, languagebox = "",
pagefooteradd = "",
uid = 0,
):
"""Creates a complete page
Parameters:
- 'weburl' *string* - The base URL for the site
- 'ln' *string* - The language to display
- 'sitename' *string* - the first part of the page HTML title
- 'headertitle' *string* - the second part of the page HTML title
- 'supportemail' *string* - email of the support team
- 'description' *string* - description goes to the metadata in the header of the HTML page
- 'keywords' *string* - keywords goes to the metadata in the header of the HTML page
- 'userinfobox' *string* - the HTML code for the user information box
- 'navtrailbox' *string* - the HTML code for the navigation trail box
- 'pageheaderadd' *string* - additional page header HTML code
- 'boxlefttop' *string* - left-top box HTML code
- 'boxlefttopadd' *string* - additional left-top box HTML code
- 'boxleftbottom' *string* - left-bottom box HTML code
- 'boxleftbottomadd' *string* - additional left-bottom box HTML code
- 'boxrighttop' *string* - right-top box HTML code
- 'boxrighttopadd' *string* - additional right-top box HTML code
- 'boxrightbottom' *string* - right-bottom box HTML code
- 'boxrightbottomadd' *string* - additional right-bottom box HTML code
- 'title' *string* - the title of the page
- 'body' *string* - the body of the page
- 'version' *string* - the version number of CDSware
- 'lastupdated' *string* - when the page was last updated
- 'languagebox' *string* - the HTML code for the language box
- 'pagefooteradd' *string* - additional page footer HTML code
Output:
- HTML code of the page
"""
# load the right message language
_ = gettext_set_language(ln)
if lastupdated:
msg_lastupdated = _("Last updated:") + " " + lastupdated
else:
msg_lastupdated = ""
out = self.tmpl_pageheader(
weburl = weburl,
ln = ln,
headertitle = headertitle,
sitename = sitename,
supportemail = supportemail,
description = description,
keywords = keywords,
userinfobox = userinfobox,
navtrailbox = navtrailbox,
pageheaderadd = pageheaderadd,
languagebox = languagebox,
) + """
<div class="pagebody">
<div class="pagebodystripeleft">
<div class="pageboxlefttop">%(boxlefttop)s</div>
<div class="pageboxlefttopadd">%(boxlefttopadd)s</div>
<div class="pageboxleftbottomadd">%(boxleftbottomadd)s</div>
<div class="pageboxleftbottom">%(boxleftbottom)s</div>
</div>
<div class="pagebodystriperight">
<div class="pageboxrighttop">%(boxrighttop)s</div>
<div class="pageboxrighttopadd">%(boxrighttopadd)s</div>
<div class="pageboxrightbottomadd">%(boxrightbottomadd)s</div>
<div class="pageboxrightbottom">%(boxrightbottom)s</div>
</div>
<div class="pagebodystripemiddle">
<h1 class="headline">%(title)s</h1>
%(body)s
</div>
</div>
""" % {
'boxlefttop' : boxlefttop,
'boxlefttopadd' : boxlefttopadd,
'boxleftbottom' : boxleftbottom,
'boxleftbottomadd' : boxleftbottomadd,
'boxrighttop' : boxrighttop,
'boxrighttopadd' : boxrighttopadd,
'boxrightbottom' : boxrightbottom,
'boxrightbottomadd' : boxrightbottomadd,
'title' : title,
'body' : body,
} + self.tmpl_pagefooter(
weburl = weburl,
ln = ln,
sitename = sitename,
supportemail = supportemail,
version = version,
lastupdated = lastupdated,
languagebox = languagebox,
pagefooteradd = pagefooteradd
)
return out
def tmpl_pageheader(self, weburl, ln, headertitle = "", sitename = "", supportemail = "", description = "", keywords = "",
userinfobox = "", navtrailbox = "",
pageheaderadd = "", languagebox = "",
uid = 0,
):
"""Creates a page header
Parameters:
- 'weburl' *string* - The base URL for the site
- 'ln' *string* - The language to display
- 'sitename' *string* - the first part of the page HTML title
- 'headertitle' *string* - the second part of the page HTML title
- 'supportemail' *string* - email of the support team
- 'description' *string* - description goes to the metadata in the header of the HTML page
- 'keywords' *string* - keywords goes to the metadata in the header of the HTML page
- 'userinfobox' *string* - the HTML code for the user information box
- 'navtrailbox' *string* - the HTML code for the navigation trail box
- 'pageheaderadd' *string* - additional page header HTML code
- 'languagebox' *string* - the HTML code for the language box
Output:
- HTML code of the page headers
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<!-- DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware SOURCES. LOOK THERE FOR THE COPYRIGHT INFO. -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>%(sitename)s: %(headertitle)s</title>
<link rev="made" href="mailto:%(supportemail)s">
<link rel="stylesheet" href="%(weburl)s/img/cds.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="%(description)s">
<meta name="keywords" content="%(keywords)s">
</head>
<body>
<div class="pageheader">
<!-- replaced page header -->
<div style="background-image: url(%(weburl)s/img/header_background.gif);">
<table class="headerbox">
<tr>
<td rowspan="2" class="headerboxbodylogo">
%(sitename)s
</td>
<td align="right" class="userinfoboxbody">
%(userinfobox)s
</td>
</tr>
<tr>
<td class="headerboxbody" valign="bottom" align="left">
<table class="headermodulebox">
<tr>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="%(weburl)s/?ln=%(ln)s">%(msg_search)s</a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="%(weburl)s/submit.py?ln=%(ln)s">%(msg_submit)s</a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="%(weburl)s/youraccount.py/display?ln=%(ln)s">%(msg_personalize)s</a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
<td class="headermoduleboxbody">
<a class=header href="%(weburl)s/help/index.%(ln)s.html">%(msg_help)s</a>
</td>
<td class="headermoduleboxbodyblank">
&nbsp;
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<table class="navtrailbox">
<tr>
<td class="navtrailboxbody">
%(navtrailbox)s
</td>
</tr>
</table>
<!-- end replaced page header -->
%(pageheaderadd)s
</div>
""" % {
'weburl' : weburl,
'ln' : ln,
'sitename' : sitename,
'headertitle' : headertitle,
'supportemail' : supportemail,
'description' : description,
'keywords' : keywords,
'userinfobox' : userinfobox,
'navtrailbox' : navtrailbox,
'pageheaderadd' : pageheaderadd,
'msg_search' : _("Search"),
'msg_submit' : _("Submit"),
'msg_personalize' : _("Personalize"),
'msg_help' : _("Help"),
'languagebox' : languagebox,
}
return out
def tmpl_pagefooter(self, weburl, ln, sitename = "", supportemail = "",
version = "", lastupdated = None, languagebox = "",
pagefooteradd = ""
):
"""Creates a page footer
Parameters:
- 'weburl' *string* - The base URL for the site
- 'ln' *string* - The language to display
- 'sitename' *string* - the first part of the page HTML title
- 'supportemail' *string* - email of the support team
- 'version' *string* - the version number of CDSware
- 'lastupdated' *string* - when the page was last updated
- 'languagebox' *string* - the HTML code for the language box
- 'pagefooteradd' *string* - additional page footer HTML code
Output:
- HTML code of the page headers
"""
# load the right message language
_ = gettext_set_language(ln)
if lastupdated:
msg_lastupdated = _("Last updated:") + " " + lastupdated
else:
msg_lastupdated = ""
out = """
<div class="pagefooter">
%(pagefooteradd)s
<!-- replaced page footer -->
<div class="pagefooterstripeleft">
%(sitename)s&nbsp;::&nbsp;<a class="footer" href="%(weburl)s/?ln=%(ln)s">%(msg_search)s</a>&nbsp;::&nbsp;<a class="footer" href="%(weburl)s/submit.py?ln=%(ln)s">%(msg_submit)s</a>&nbsp;::&nbsp;<a class="footer" href="%(weburl)s/youraccount.py/display?ln=%(ln)s">%(msg_personalize)s</a>&nbsp;::&nbsp;<a class="footer" href="%(weburl)s/help/index.%(ln)s.html">%(msg_help)s</a>
<br>
%(msg_poweredby)s <a class="footer" href="http://cdsware.cern.ch/">CDSware</a> v%(version)s
<br>
%(msg_maintainedby)s <a class="footer" href="mailto:%(supportemail)s">%(supportemail)s</a>
<br>
%(msg_lastupdated)s
</div>
<div class="pagefooterstriperight">
%(languagebox)s
</div>
<!-- replaced page footer -->
</div>
</body>
</html>
""" % {
'weburl' : weburl,
'ln' : ln,
'sitename' : sitename,
'supportemail' : supportemail,
'msg_search' : _("Search"),
'msg_submit' : _("Submit"),
'msg_personalize' : _("Personalize"),
'msg_help' : _("Help"),
'msg_poweredby' : _("Powered by"),
'msg_maintainedby' : _("Maintained by"),
'msg_lastupdated' : msg_lastupdated,
'languagebox' : languagebox,
'version' : version,
'pagefooteradd' : pagefooteradd,
}
return out
def tmpl_language_selection_box(self, urlargs="", language="en"):
"""Take URLARGS and LANGUAGE and return textual language
selection box for the given page.
Parameters:
- 'urlargs' *string* - The url args that helped produce this page
- 'language' *string* - The selected language
"""
# load the right message language
_ = gettext_set_language(language)
out = ""
for (lang, lang_namelong) in language_list_long():
if lang == language:
out += """ <span class="langinfo">%s</span> &nbsp; """ % lang_namelong
else:
if urlargs:
urlargs = sre.sub(r'ln=.*?(&|$)', '', urlargs)
if urlargs:
if urlargs.endswith('&'):
urlargs += "ln=%s" % lang
else:
urlargs += "&ln=%s" % lang
else:
urlargs = "ln=%s" % lang
out += """ <a class="langinfo" href="?%s">%s</a> &nbsp; """ % (urlargs, lang_namelong)
return _("This site is also available in the following languages:") + "<br>" + out
def tmpl_error_box(self, ln, title, verbose, req, supportemail, errors):
"""Produces an error box.
Parameters:
- 'title' *string* - The title of the error box
- 'ln' *string* - The selected language
- 'verbose' *bool* - If lots of information should be displayed
- 'req' *object* - the request object
- 'supportemail' *string* - the supportemail for this installation
- 'errors' list of tuples (error_code, error_message)
- #! todo
"""
# load the right message language
_ = gettext_set_language(ln)
info_not_available = _("N/A")
if title == None:
if errors:
title = _("Error: %s") % errors[0][1]
else:
title = _("Internal Error")
browser_s = _("Browser")
if req:
try:
if req.headers_in.has_key('User-Agent'):
browser_s += ': ' + req.headers_in['User-Agent']
else:
browser_s += ': ' + info_not_available
host_s = req.hostname
page_s = req.unparsed_uri
client_s = req.connection.remote_ip
except:
pass
else:
browser_s += ': ' + info_not_available
host_s = page_s = client_s = info_not_available
error_s = ''
sys_error_s = ''
traceback_s = ''
if verbose >= 1:
if sys.exc_info()[0]:
sys_error_s = _("System Error: %s %s\n") % (sys.exc_info()[0], sys.exc_info()[1])
if errors:
errs = ''
for error_tuple in errors:
try:
errs += "%s%s : %s\n " % (' '*6, error_tuple[0], error_tuple[1])
except:
errs += "%s%s\n" % (' '*6, error_tuple)
errs = errs[6:-2] # get rid of trainling ','
error_s = _("Error: %s")% errs + "\n"
else:
error_s = _("Error") + ': ' + info_not_available
if verbose >= 9:
traceback_s = _("Traceback: \n%s") % string.join(traceback.format_tb(sys.exc_info()[2]),"\n")
out = """
<table class="errorbox">
<thead>
<tr>
<th class="errorboxheader">
<p> %(title)s %(sys1)s %(sys2)s</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td class="errorboxbody">
<p>%(contact)s</p>
<blockquote><pre>
URI: http://%(host)s%(page)s
%(time_label)s: %(time)s
%(browser)s
%(client_label)s: %(client)s
%(error)s%(sys_error)s%(traceback)s
</pre></blockquote>
</td>
</tr>
<tr>
<td>
<form action="%(weburl)s/error.py/send_report" method="POST">
%(send_error_label)s
<input class="adminbutton" type="submit" value="%(send_label)s" />
<input type="hidden" name="header" value="%(title)s %(sys1)s %(sys2)s" />
<input type="hidden" name="url" value="URI: http://%(host)s%(page)s" />
<input type="hidden" name="time" value="Time: %(time)s" />
<input type="hidden" name="browser" value="%(browser)s" />
<input type="hidden" name="client" value="Client: %(client)s" />
<input type="hidden" name="error" value="%(error)s" />
<input type="hidden" name="sys_error" value="%(sys_error)s" />
<input type="hidden" name="traceback" value="%(traceback)s" />
<input type="hidden" name="referer" value="%(referer)s" />
</form>
</td>
</tr>
</tbody>
</table>
""" % {
'title' : title,
'time_label': _("Time"),
'client_label': _("Client"),
'send_error_label': _("Please send an error report to the Administrator"),
'send_label': _("Send error report"),
'sys1' : sys.exc_info()[0] or '',
'sys2' : sys.exc_info()[1] or '',
'contact' : _("Please contact <a href=\"mailto:%s\">%s</a> quoting the following information:") % (urllib.quote(supportemail), supportemail),
'host' : host_s,
'page' : page_s,
'time' : time.strftime("%d/%b/%Y:%H:%M:%S %z"),
'browser' : browser_s,
'client' : client_s,
'error' : error_s,
'traceback' : traceback_s,
'sys_error' : sys_error_s,
'weburl' : weburl,
'referer' : page_s!=info_not_available and ("http://" + host_s + page_s) or info_not_available
}
return out
diff --git a/modules/websubmit/Makefile.am b/modules/websubmit/Makefile.am
index 7d1da12dd..816210984 100644
--- a/modules/websubmit/Makefile.am
+++ b/modules/websubmit/Makefile.am
@@ -1,22 +1,22 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bin doc etc lib web
CLEANFILES = *~
diff --git a/modules/websubmit/bin/Makefile.am b/modules/websubmit/bin/Makefile.am
index 6841cf0c4..9adbe1a0b 100644
--- a/modules/websubmit/bin/Makefile.am
+++ b/modules/websubmit/bin/Makefile.am
@@ -1,24 +1,24 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
bin_SCRIPTS = thumbmaker
EXTRA_DIST = thumbmaker.in
CLEANFILES = *~ *.tmp
diff --git a/modules/websubmit/bin/thumbmaker.in b/modules/websubmit/bin/thumbmaker.in
index df126be42..a7889ca4d 100644
--- a/modules/websubmit/bin/thumbmaker.in
+++ b/modules/websubmit/bin/thumbmaker.in
@@ -1,210 +1,210 @@
#!@PHP@ -q
<?
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
$__version__ = '$Id$';
########################################################
#
# Description: Creates GIF thumbnails of bigger size x pixels
# Works for both gif and jpeg pictures
# This scripts needs many local programs to work: jpegsize,
# djpeg, pnmscale, ppmtogif, ppmquant, gifrsize, convert
# The path to these programs are stored in the config_XXX.php
# Creator: T.Baron
#
# INPUT: $1->Path to picture file
# $2->Path to resulting thumbnail
# $3->largest size (in pixels)
#
# OUTPUT: thumbnail file at $2
#
########################################################
$DJPEG="@DJPEG@";
$CONVERT="@CONVERT@";
$GIFTEXT="@GIFTEXT@";
$JPEGSIZE="@JPEGSIZE@";
$PNMSCALE="@PNMSCALE@";
$PPMQUANT="@PPMQUANT@";
$PPMTOGIF="@PPMTOGIF@";
$GIFINTER="@GIFINTER@";
$GIFRSIZE="@GIFRSIZE@";
foreach($argv as $value)
{
if ($value == "-V" || $value == "--version") {
print $__version__."\n";
exit();
}
if ($value == "-h" || $value == "--help") {
print "usage : thumbmaker <path_to_picture> <path_to_thumbnail> "
. "<max_thumbnail_size>\n";
exit();
}
}
if ($DJPEG == "")
{
print "\nthumbmaker: Cannot find djpeg\n";
exit;
}
if ($CONVERT == "")
{
print "\nthumbmaker: Cannot find convert\n";
exit;
}
if ($GIFTEXT == "")
{
print "\nthumbmaker: Cannot find giftext\n";
exit;
}
if ($JPEGSIZE == "")
{
print "\nthumbmaker: Cannot find jpegsize\n";
exit;
}
if ($PNMSCALE == "")
{
print "\nthumbmaker: Cannot find pnmscale\n";
exit;
}
if ($PPMQUANT == "")
{
print "\nthumbmaker: Cannot find ppmquant\n";
exit;
}
if ($PPMTOGIF == "")
{
print "\nthumbmaker: Cannot find ppmtogif\n";
exit;
}
if ($GIFINTER == "")
{
print "\nthumbmaker: Cannot find gifinter\n";
exit;
}
if ($GIFRSIZE == "")
{
print "\nthumbmaker: Cannot find gifrsize\n";
exit;
}
if ( count($argv) != 4 )
{
print "usage : thumbmaker <path_to_picture> <path_to_thumbnail> "
. "<max_thumbnail_size>\n";
exit;
}
else
{
$picture=$argv[1];
$thumbnail=$argv[2];
$maxsize=$argv[3];
}
#######################################################
#
# Main script
#
#######################################################
#get extension
$extension = ereg_replace(".*\.","",$picture);
$ext = strtolower($extension);
if ($ext != "gif"
&& $ext != "jpeg"
&& $ext != "jpg"
&& $ext != "pdf"
&& $ext != "ps" )
{
print "$0: works only with GIF, PDF, PS or JPEG formats!!!\n";
exit;
}
if ( $ext == "pdf" )
{
$newname = str_replace(".pdf",".gif",$picture);
$isPDF = TRUE;
system("$CONVERT pdf:$picture gif:$newname");
$picture = $newname;
$ext = "gif";
}
elseif ( $ext == "ps" )
{
$newname = str_replace(".ps",".gif",$picture);
$isPDF = TRUE;
system("$CONVERT ps:$picture gif:$newname");
$picture = $newname;
$ext = "gif";
}
else
$isPDF = FALSE;
#get picture size
if ($ext == "gif")
{
$imagesize=`$GIFTEXT $picture | grep "Image Size"`;
$imagesize = ereg_replace("\n.*","",$imagesize);
$width = ereg_replace(".*Width = ","",$imagesize);
$width = ereg_replace(" Height.*","",$width);
$height = ereg_replace(".*Height = ","",$imagesize);
$height = ereg_replace("\..*","",$height);
}
else
{
$imagesize=`$JPEGSIZE $picture`;
$width = ereg_replace(" .*","",$imagesize);
chop($width);
$height = ereg_replace(".* ","",$imagesize);
chop($height);
}
#process scale factor
if ( $width > $height )
$originalmaxsize = $width;
else
$originalmaxsize = $height;
$scale = $maxsize/$originalmaxsize;
#create gif picture if jpeg + transform interlaced gif
$basename = ereg_replace("\.$extension","",$picture);
if ( $ext == "jpg" || $ext == "jpeg" )
system("$DJPEG $picture | $PNMSCALE"
. " $scale | $PPMQUANT 256 | "
. "$PPMTOGIF > $thumbnail");
else
{
system("$GIFINTER $picture > ${basename}_TMfinal.gif");
#create final thumbnail
system("$GIFRSIZE -s $scale ${basename}_TMfinal.gif "
. "> $thumbnail");
system("rm -r ${basename}_TMfinal.gif");
}
if ($isPDF == TRUE)
system("rm $picture");
?>
diff --git a/modules/websubmit/doc/Makefile.am b/modules/websubmit/doc/Makefile.am
index 0b3edfc65..998c68d84 100644
--- a/modules/websubmit/doc/Makefile.am
+++ b/modules/websubmit/doc/Makefile.am
@@ -1,68 +1,68 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin hacking
docdir = $(WEBDIR)/help/submit
doc_DATA=access.en.html access.fr.html access.de.html access.es.html access.ca.html access.pl.html access.pt.html access.it.html access.ja.html access.ru.html access.sk.html access.cs.html access.no.html access.sv.html access.el.html access.uk.html \
actions.en.html actions.fr.html actions.de.html actions.es.html actions.ca.html actions.pl.html actions.pt.html actions.it.html actions.ja.html actions.ru.html actions.sk.html actions.cs.html actions.no.html actions.sv.html actions.el.html actions.uk.html \
approval.en.html approval.fr.html approval.de.html approval.pl.html approval.pt.html approval.es.html approval.ca.html approval.it.html approval.ja.html approval.ru.html approval.sk.html approval.cs.html approval.no.html approval.sv.html approval.el.html approval.uk.html \
bibliographic_fields.en.html bibliographic_fields.fr.html bibliographic_fields.de.html bibliographic_fields.es.html bibliographic_fields.ca.html bibliographic_fields.pl.html bibliographic_fields.pt.html bibliographic_fields.it.html bibliographic_fields.ja.html bibliographic_fields.ru.html bibliographic_fields.sk.html bibliographic_fields.cs.html bibliographic_fields.no.html bibliographic_fields.sv.html bibliographic_fields.el.html bibliographic_fields.uk.html \
description.en.html description.fr.html description.de.html description.pl.html description.pt.html description.es.html description.ca.html description.it.html description.ja.html description.ru.html description.sk.html description.cs.html description.no.html description.sv.html description.el.html description.uk.html \
file_transfer.en.html file_transfer.fr.html file_transfer.de.html file_transfer.es.html file_transfer.ca.html file_transfer.pl.html file_transfer.pt.html file_transfer.it.html file_transfer.ja.html file_transfer.ru.html file_transfer.sk.html file_transfer.cs.html file_transfer.no.html file_transfer.sv.html file_transfer.el.html file_transfer.uk.html \
index.en.html index.fr.html index.de.html index.pl.html index.pt.html index.es.html index.ca.html index.it.html index.ja.html index.ru.html index.sk.html index.cs.html index.no.html index.sv.html index.el.html index.uk.html \
introduction.en.html introduction.fr.html introduction.de.html introduction.es.html introduction.ca.html introduction.pl.html introduction.pt.html introduction.it.html introduction.ja.html introduction.ru.html introduction.sk.html introduction.cs.html introduction.no.html introduction.sv.html introduction.el.html introduction.uk.html \
login.en.html login.fr.html login.de.html login.pl.html login.pt.html login.es.html login.ca.html login.it.html login.ja.html login.ru.html login.sk.html login.cs.html login.no.html login.sv.html login.el.html login.uk.html \
modification.en.html modification.fr.html modification.de.html modification.es.html modification.ca.html modification.pl.html modification.pt.html modification.it.html modification.ja.html modification.ru.html modification.sk.html modification.cs.html modification.no.html modification.sv.html modification.el.html modification.uk.html \
password.en.html password.fr.html password.de.html password.es.html password.ca.html password.pl.html password.pt.html password.it.html password.ja.html password.ru.html password.sk.html password.cs.html password.no.html password.sv.html password.el.html password.uk.html \
pending.en.html pending.fr.html pending.de.html pending.es.html pending.ca.html pending.pl.html pending.pt.html pending.it.html pending.ja.html pending.ru.html pending.sk.html pending.cs.html pending.no.html pending.sv.html pending.el.html pending.uk.html \
approvals.en.html approvals.fr.html approvals.de.html approvals.es.html approvals.ca.html approvals.pl.html approvals.pt.html approvals.it.html approvals.ja.html approvals.ru.html approvals.sk.html approvals.cs.html approvals.no.html approvals.sv.html approvals.el.html approvals.uk.html \
revised_version.en.html revised_version.fr.html revised_version.de.html revised_version.es.html revised_version.ca.html revised_version.pl.html revised_version.pt.html revised_version.it.html revised_version.ja.html revised_version.ru.html revised_version.sk.html revised_version.cs.html revised_version.no.html revised_version.sv.html revised_version.el.html revised_version.uk.html \
submission.en.html submission.fr.html submission.de.html submission.es.html submission.ca.html submission.pl.html submission.pt.html submission.it.html submission.ja.html submission.ru.html submission.sk.html submission.cs.html submission.no.html submission.sv.html submission.el.html submission.uk.html \
subnumber.en.html subnumber.fr.html subnumber.de.html subnumber.es.html subnumber.ca.html subnumber.pl.html subnumber.pt.html subnumber.it.html subnumber.ja.html subnumber.ru.html subnumber.sk.html subnumber.cs.html subnumber.no.html subnumber.sv.html subnumber.el.html subnumber.uk.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp *.php
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.en.html %.fr.html %.de.html %.es.html %.ca.html %.pl.html %.pt.html %.it.html %.ja.html %.ru.html %.sk.html %.cs.html %.no.html %.sv.html %.el.html %.uk.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(MO)
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$*.en.html \
-o\(ALL-LANG_*\)+LANG_FR:$*.fr.html \
-o\(ALL-LANG_*\)+LANG_DE:$*.de.html \
-o\(ALL-LANG_*\)+LANG_ES:$*.es.html \
-o\(ALL-LANG_*\)+LANG_CA:$*.ca.html \
-o\(ALL-LANG_*\)+LANG_PL:$*.pl.html \
-o\(ALL-LANG_*\)+LANG_PT:$*.pt.html \
-o\(ALL-LANG_*\)+LANG_IT:$*.it.html \
-o\(ALL-LANG_*\)+LANG_JA:$*.ja.html \
-o\(ALL-LANG_*\)+LANG_RU:$*.ru.html \
-o\(ALL-LANG_*\)+LANG_SK:$*.sk.html \
-o\(ALL-LANG_*\)+LANG_CS:$*.cs.html \
-o\(ALL-LANG_*\)+LANG_NO:$*.no.html \
-o\(ALL-LANG_*\)+LANG_SV:$*.sv.html \
-o\(ALL-LANG_*\)+LANG_EL:$*.el.html \
-o\(ALL-LANG_*\)+LANG_UK:$*.uk.html $<
for lang in $(LINGUAS); do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.$${lang}.html" ; \
done
diff --git a/modules/websubmit/doc/access.html.wml b/modules/websubmit/doc/access.html.wml
index fbd37e500..560ccc1e3 100644
--- a/modules/websubmit/doc/access.html.wml
+++ b/modules/websubmit/doc/access.html.wml
@@ -1,45 +1,45 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Access Pages" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<BLOCKQUOTE>
<span class="guideheader">T</span>here is one <a href="<WEBURL>/submit.py">main access page</a> for
CDSware Submit.<br><br>
<span class="guideheader">T</span>here, you should choose the type of document which interests you by clicking
on its name.<br><br>
<span class="guideheader">O</span>nce here, you can find the list of all the possible actions for this type of
document (blue buttons), and sometimes a list of categories. If there is a list of categories, you should first choose
one before clicking on an action.<br><br>
<span class="guideheader">A</span>t the bottom of the page you will find the input box in which you can enter
your <a href="subnumber.<lang:star: *>.html">submission number</a>.<br><br>
<span class="guideheader">A</span>n action can be either open to anybody worldwide or restricted to a given
list of people. In any case you should login before using the tool:<br>
<IMG src="<WEBURL>/img/sbm_guide_login.png" class="guideimg" ALT="">
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="password.<lang:star: *>.html">protection and passwords</A><BR>
<li><A HREF="subnumber.<lang:star: *>.html">submission numbers</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/actions.html.wml b/modules/websubmit/doc/actions.html.wml
index c5cbff63f..a35ebf9b0 100644
--- a/modules/websubmit/doc/actions.html.wml
+++ b/modules/websubmit/doc/actions.html.wml
@@ -1,58 +1,58 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Available Actions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<span class="guideheader">T</span>his tool currently allows you to make 4 actions.
Here is a list of the actions:
<BLOCKQUOTE>
<CENTER>
<TABLE>
<TR>
<TD align=right><SMALL><A HREF="submission.<lang:star: *>.html">Submit New Record</A></SMALL></TD>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;</TD>
<TD><IMG SRC="<WEBURL>/img/sbm_guide_submit_button.png" ALT="" class="guideimg"></TD>
</TR>
<TR>
<TD align=right><SMALL><A HREF="revised_version.<lang:star: *>.html">Submit New File</A></SMALL></TD>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;</TD>
<TD><IMG SRC="<WEBURL>/img/sbm_guide_revise_button.png" ALT="" class="guideimg"></TD>
</TR>
<TR>
<TD align=right><SMALL><A HREF="modification.<lang:star: *>.html">Modify Record</A></SMALL></TD>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;</TD>
<TD><IMG SRC="<WEBURL>/img/sbm_guide_modify_button.png" ALT="" class="guideimg"></TD>
</TR>
<TR>
<TD align=right><SMALL><A HREF="approval.<lang:star: *>.html">Approve Record</A></SMALL></TD>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;</TD>
<TD><IMG SRC="<WEBURL>/img/sbm_guide_approve_button.png" ALT="" class="guideimg"></TD>
</TR>
</TABLE>
</CENTER>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/Makefile.am b/modules/websubmit/doc/admin/Makefile.am
index 1e8b75a26..61668b8d9 100644
--- a/modules/websubmit/doc/admin/Makefile.am
+++ b/modules/websubmit/doc/admin/Makefile.am
@@ -1,75 +1,75 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
docdir = $(WEBDIR)/admin/websubmit/guide
doc_DATA=actionimplement.en.html actionimplement.fr.html actionimplement.de.html actionimplement.es.html actionimplement.ca.html actionimplement.pl.html actionimplement.pt.html actionimplement.it.html actionimplement.ja.html actionimplement.ru.html actionimplement.sk.html actionimplement.cs.html actionimplement.no.html actionimplement.sv.html actionimplement.el.html actionimplement.uk.html \
actionmodify.en.html actionmodify.fr.html actionmodify.de.html actionmodify.es.html actionmodify.ca.html actionmodify.pl.html actionmodify.pt.html actionmodify.it.html actionmodify.ja.html actionmodify.ru.html actionmodify.sk.html actionmodify.cs.html actionmodify.no.html actionmodify.sv.html actionmodify.el.html actionmodify.uk.html \
actionnew.en.html actionnew.fr.html actionnew.de.html actionnew.es.html actionnew.ca.html actionnew.pl.html actionnew.pt.html actionnew.it.html actionnew.ja.html actionnew.ru.html actionnew.sk.html actionnew.cs.html actionnew.no.html actionnew.sv.html actionnew.el.html actionnew.uk.html \
actionremove.en.html actionremove.fr.html actionremove.de.html actionremove.es.html actionremove.ca.html actionremove.pl.html actionremove.pt.html actionremove.it.html actionremove.ja.html actionremove.ru.html actionremove.sk.html actionremove.cs.html actionremove.no.html actionremove.sv.html actionremove.el.html actionremove.uk.html \
actions.en.html actions.fr.html actions.de.html actions.es.html actions.ca.html actions.pl.html actions.pt.html actions.it.html actions.ja.html actions.ru.html actions.sk.html actions.cs.html actions.no.html actions.sv.html actions.el.html actions.uk.html \
catalogues.en.html catalogues.fr.html catalogues.de.html catalogues.es.html catalogues.ca.html catalogues.pl.html catalogues.pt.html catalogues.it.html catalogues.ja.html catalogues.ru.html catalogues.sk.html catalogues.cs.html catalogues.no.html catalogues.sv.html catalogues.el.html catalogues.uk.html \
description.en.html description.fr.html description.de.html description.es.html description.ca.html description.pl.html description.pt.html description.it.html description.ja.html description.ru.html description.sk.html description.cs.html description.no.html description.sv.html description.el.html description.uk.html \
documentmodify.en.html documentmodify.fr.html documentmodify.de.html documentmodify.es.html documentmodify.ca.html documentmodify.pl.html documentmodify.pt.html documentmodify.it.html documentmodify.ja.html documentmodify.ru.html documentmodify.sk.html documentmodify.cs.html documentmodify.no.html documentmodify.sv.html documentmodify.el.html documentmodify.uk.html \
documentnew.en.html documentnew.fr.html documentnew.de.html documentnew.es.html documentnew.ca.html documentnew.pl.html documentnew.pt.html documentnew.it.html documentnew.ja.html documentnew.ru.html documentnew.sk.html documentnew.cs.html documentnew.no.html documentnew.sv.html documentnew.el.html documentnew.uk.html \
documentremove.en.html documentremove.fr.html documentremove.de.html documentremove.es.html documentremove.ca.html documentremove.pl.html documentremove.pt.html documentremove.it.html documentremove.ja.html documentremove.ru.html documentremove.sk.html documentremove.cs.html documentremove.no.html documentremove.sv.html documentremove.el.html documentremove.uk.html \
documents.en.html documents.fr.html documents.de.html documents.es.html documents.ca.html documents.pl.html documents.pt.html documents.it.html documents.ja.html documents.ru.html documents.sk.html documents.cs.html documents.no.html documents.sv.html documents.el.html documents.uk.html \
example.en.html example.fr.html example.de.html example.es.html example.ca.html example.pl.html example.pt.html example.it.html example.ja.html example.ru.html example.sk.html example.cs.html example.no.html example.sv.html example.el.html example.uk.html \
faq.en.html faq.fr.html faq.de.html faq.es.html faq.ca.html faq.pl.html faq.pt.html faq.it.html faq.ja.html faq.ru.html faq.sk.html faq.cs.html faq.no.html faq.sv.html faq.el.html faq.uk.html \
functiondelete.en.html functiondelete.fr.html functiondelete.de.html functiondelete.es.html functiondelete.ca.html functiondelete.pl.html functiondelete.pt.html functiondelete.it.html functiondelete.ja.html functiondelete.ru.html functiondelete.sk.html functiondelete.cs.html functiondelete.no.html functiondelete.sv.html functiondelete.el.html functiondelete.uk.html \
functionedit.en.html functionedit.fr.html functionedit.de.html functionedit.es.html functionedit.ca.html functionedit.pl.html functionedit.pt.html functionedit.it.html functionedit.ja.html functionedit.ru.html functionedit.sk.html functionedit.cs.html functionedit.no.html functionedit.sv.html functionedit.el.html functionedit.uk.html \
functiondescription.en.html functiondescription.fr.html functiondescription.de.html functiondescription.es.html functiondescription.ca.html functiondescription.pl.html functiondescription.pt.html functiondescription.it.html functiondescription.ja.html functiondescription.ru.html functiondescription.sk.html functiondescription.cs.html functiondescription.no.html functiondescription.sv.html functiondescription.el.html functiondescription.uk.html \
functionnew.en.html functionnew.fr.html functionnew.de.html functionnew.es.html functionnew.ca.html functionnew.pl.html functionnew.pt.html functionnew.it.html functionnew.ja.html functionnew.ru.html functionnew.sk.html functionnew.cs.html functionnew.no.html functionnew.sv.html functionnew.el.html functionnew.uk.html \
functions.en.html functions.fr.html functions.de.html functions.es.html functions.ca.html functions.pl.html functions.pt.html functions.it.html functions.ja.html functions.ru.html functions.sk.html functions.cs.html functions.no.html functions.sv.html functions.el.html functions.uk.html \
implementfunctions.en.html implementfunctions.fr.html implementfunctions.de.html implementfunctions.es.html implementfunctions.ca.html implementfunctions.pl.html implementfunctions.pt.html implementfunctions.it.html implementfunctions.ja.html implementfunctions.ru.html implementfunctions.sk.html implementfunctions.cs.html implementfunctions.no.html implementfunctions.sv.html implementfunctions.el.html implementfunctions.uk.html \
implementwebform.en.html implementwebform.fr.html implementwebform.de.html implementwebform.es.html implementwebform.ca.html implementwebform.pl.html implementwebform.pt.html implementwebform.it.html implementwebform.ja.html implementwebform.ru.html implementwebform.sk.html implementwebform.cs.html implementwebform.no.html implementwebform.sv.html implementwebform.el.html implementwebform.uk.html \
index.en.html index.fr.html index.de.html index.es.html index.ca.html index.pl.html index.pt.html index.it.html index.ja.html index.ru.html index.sk.html index.cs.html index.no.html index.sv.html index.el.html index.uk.html \
philosophy.en.html philosophy.fr.html philosophy.de.html philosophy.es.html philosophy.ca.html philosophy.pl.html philosophy.pt.html philosophy.it.html philosophy.ja.html philosophy.ru.html philosophy.sk.html philosophy.cs.html philosophy.no.html philosophy.sv.html philosophy.el.html philosophy.uk.html \
protection.en.html protection.fr.html protection.de.html protection.es.html protection.ca.html protection.pl.html protection.pt.html protection.it.html protection.ja.html protection.ru.html protection.sk.html protection.cs.html protection.no.html protection.sv.html protection.el.html protection.uk.html \
bibconvert.en.html bibconvert.fr.html bibconvert.de.html bibconvert.es.html bibconvert.ca.html bibconvert.pl.html bibconvert.pt.html bibconvert.it.html bibconvert.ja.html bibconvert.ru.html bibconvert.sk.html bibconvert.cs.html bibconvert.no.html bibconvert.sv.html bibconvert.el.html bibconvert.uk.html \
introduction.en.html introduction.fr.html introduction.de.html introduction.es.html introduction.ca.html introduction.pl.html introduction.pt.html introduction.it.html introduction.ja.html introduction.ru.html introduction.sk.html introduction.cs.html introduction.no.html introduction.sv.html introduction.el.html introduction.uk.html
FILESWML = $(wildcard $(srcdir)/*.wml)
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%)
CLEANFILES = $(doc_DATA) *~ *.tmp *.php
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.en.html %.fr.html %.de.html %.es.html %.ca.html %.pl.html %.pt.html %.it.html %.ja.html %.ru.html %.sk.html %.cs.html %.no.html %.sv.html %.el.html %.uk.html: %.html.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml $(MO) \
$(top_srcdir)/config/cdsnavbar.wml
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$*.en.html \
-o\(ALL-LANG_*\)+LANG_FR:$*.fr.html \
-o\(ALL-LANG_*\)+LANG_DE:$*.de.html \
-o\(ALL-LANG_*\)+LANG_ES:$*.es.html \
-o\(ALL-LANG_*\)+LANG_CA:$*.ca.html \
-o\(ALL-LANG_*\)+LANG_PL:$*.pl.html \
-o\(ALL-LANG_*\)+LANG_PT:$*.pt.html \
-o\(ALL-LANG_*\)+LANG_IT:$*.it.html \
-o\(ALL-LANG_*\)+LANG_JA:$*.ja.html \
-o\(ALL-LANG_*\)+LANG_RU:$*.ru.html \
-o\(ALL-LANG_*\)+LANG_SK:$*.sk.html \
-o\(ALL-LANG_*\)+LANG_CS:$*.cs.html \
-o\(ALL-LANG_*\)+LANG_NO:$*.no.html \
-o\(ALL-LANG_*\)+LANG_SV:$*.sv.html \
-o\(ALL-LANG_*\)+LANG_EL:$*.el.html \
-o\(ALL-LANG_*\)+LANG_UK:$*.uk.html $<
for lang in $(LINGUAS); do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.$${lang}.html" ; \
done
diff --git a/modules/websubmit/doc/admin/actionimplement.html.wml b/modules/websubmit/doc/admin/actionimplement.html.wml
index e75561825..0063c91d6 100644
--- a/modules/websubmit/doc/admin/actionimplement.html.wml
+++ b/modules/websubmit/doc/admin/actionimplement.html.wml
@@ -1,96 +1,96 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Implement an action over a document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">I</span>mplement an action over a document type. Create the web forms
and the treatment process.
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">F</span>rom the main page of the manager, click on the title of the
relevant document type.<br>Then click on the "Add a New Submission" button.
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">J</span>ust select the name of the action you want to implement. When you
select an action, the list of document which already implement this action appears. Then you can select from
this list the document from which you want to clone the implementation, or just choose "No Clone" if you want
to build this implementation from scratch.<br><br>
&nbsp;<span class="guideheader">A</span>fter selecting the correct fields, click on the "Add Submission"
button.<br><br>
&nbsp;<span class="guideheader">Y</span>ou then go back to the document type manager page where you
can see that in the bottom array your newly implemented action appears (check the acronym in the first
column).<br><br>
<img src="<WEBURL>/img/sbm_admin_guide_implement.png" class="guideimg"><br><br>
<ul>
<li>Clicking on the action acronym will allow you to modify the general data about the action (remember
in this case that all the other implementations of this particular action will also be changed).
<li>The second column indicates whether the button representing this action will appear on the submission page.
<li>The third column shows you the number of pages composing the web form for this implementation.
(see <A HREF="implementwebform.<lang:star: *>.html">create and maintain the web form</A>).
<li>The 4th and 5th columns indicate the creation and last modification dates for this implementation.
<li>In the 6th column, you can find the order in which the button will be displayed on the submission page
of this document type.<br>
<li>The following 4 columns (level, score, stpage, endtxt) deal with the insertion of this action in an action
set.<br><br>
<TABLE border=0 bgcolor="eeeeff"><TR><TD><small><br>
An action set is a succession of actions which should be done in a given order when a user starts.<br>
For example the submission of a document is usually composed of two actions: Submission of Bibliographic
Information (SBI) and Fulltext Transfer (FTT) which should be done one after the other.<BR>
When the user starts the submission, we want CDS Submit to get him first in SBI and when he finishes SBI to
carry him to FTT.<BR>
SBI and FTT are in this case in the same action set.<BR>
They will both have a level of 1 ("level" is a bad name, it should be "action set number"), SBI will have a
score of 1, and FTT a score of 2 (which means it will be started after SBI). If you set the stpage of FTT to 2,
the user will be directly carried to the 2nd page of the FTT web form. This value is usually set to 1.<br>
The endtxt field contains the text which will be display to the user at the end of the first action (here
it could be "you now have to transfer your files")
<br><br>
A single action like "Modify Bibliographic Information" should have the 3 columns to 0,0 and 1.<BR>&nbsp;
</small></TD></TR></TABLE>
<br><br>
<li>Click on the icon in the 12th column ("Edit Submission Pages") to
<A HREF="implementwebform.<lang:star: *>.html">create or edit the web form</A>.
<li>Click on the icon in the 13th column ("Edit Functions") to
<A HREF="implementfunctions.<lang:star: *>.html">create or edit the function list</A>.
<li>The "Edit Submission" column allows you to modify the data (level, status text...) for this implementation.
<li> Finally the last column allows you to delete this implementation.<BR>&nbsp;
</UL><br>
&nbsp;<span class="guideheader">I</span>f you chose to clone the implementation from an existing one,
the web form as well as the functions list will already be defined. Else you will have to create them from scratch.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="implementwebform.<lang:star: *>.html">create and maintain the web form</A><BR>
<li><A HREF="implementfunctions.<lang:star: *>.html">create and maintain the data treatment</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/actionmodify.html.wml b/modules/websubmit/doc/admin/actionmodify.html.wml
index c64902085..4e3305f97 100644
--- a/modules/websubmit/doc/admin/actionmodify.html.wml
+++ b/modules/websubmit/doc/admin/actionmodify.html.wml
@@ -1,59 +1,59 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Modify an existing action" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">T</span>his page is about how to modify the general data about an
action - for modifying the implementation of an action over a document type, see
<A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A>
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "View Actions" link in the right menu of the websubmit
admin, then on the title of the action you want to modify...
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">Y</span>ou may modify 3 fields:<br>
<UL>
<li><b>Action Description</b>: This is a short description of the new action.
<li><b>dir</b>: This is the name of the directory in which the submission data will be stored temporarily.
See the meaning of this parameter in <A HREF="actionnew.<lang:star: *>.html">create an action</A>.
<li><b>statustext</b>: text displayed in the status bar of the browser when the user moves his mouse
upon the action button.
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="actionremove.<lang:star: *>.html">remove an action</A><BR>
<li><A HREF="actionnew.<lang:star: *>.html">create an action</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/actionnew.html.wml b/modules/websubmit/doc/admin/actionnew.html.wml
index 88c77bad1..56b6d5adb 100644
--- a/modules/websubmit/doc/admin/actionnew.html.wml
+++ b/modules/websubmit/doc/admin/actionnew.html.wml
@@ -1,58 +1,58 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Add a new action" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "Available Actions" link in the websubmit right menu,
then on the "Add an Action" button.
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">A</span> new action is defined by 6 fields:<br><br>
<UL>
<li><b>Creation Date</b> and <b>Modification Dates</b> are generated and modified automatically.<br>
<li><b>Action Code</b>: This is the acronym for your new action. We usually use a 3 letters acronym.
<li><b>Action Description</b>: This is a short description of the new action.
<li><b>dir</b>: This is the name of the directory in which the submission data will be stored temporarily. If
the dir value is "running" as for the "Submit New Record" action (SBI), then the submission data for a
Text Document (document acronym "TEXT") will be stored in the
<CFG_SUBMIT_DIR>/running/TEXT/9089760_90540 directory (where 9089760_90540 is what we call
the submission number. It is a string automatically generated at the beginning of each submission). Once
finished, the submission data will be moved to the
<CFG_SUBMIT_DIR>/done/running/TEXT/ directory by the "Move_to_Done" function.
<li><b>statustext</b>: text displayed in the status bar of the browser when the user moves his mouse upon
the action button.
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="actionremove.<lang:star: *>.html">remove an action</A><BR>
<li><A HREF="actionmodify.<lang:star: *>.html">modify an action</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/actionremove.html.wml b/modules/websubmit/doc/admin/actionremove.html.wml
index d0d6f1c32..55383f5d5 100644
--- a/modules/websubmit/doc/admin/actionremove.html.wml
+++ b/modules/websubmit/doc/admin/actionremove.html.wml
@@ -1,45 +1,45 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Remove an Action" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">R</span>emoving the implementation of an action over a document type -
Please note the removal of the action itself is not allowed with this tool.
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">F</span>rom the websubmit admin main page, click on the title of the
relevant document type. Then click on the red cross corresponding to the line of the action you want to remove.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="actionnew.<lang:star: *>.html">create an action</A><BR>
<li><A HREF="actionmodify.<lang:star: *>.html">modify an action</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/actions.html.wml b/modules/websubmit/doc/admin/actions.html.wml
index 3979c82c4..232d42cee 100644
--- a/modules/websubmit/doc/admin/actions.html.wml
+++ b/modules/websubmit/doc/admin/actions.html.wml
@@ -1,47 +1,47 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Actions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<BLOCKQUOTE>
&nbsp;<span class="guideheader">I</span>n webSubmit you can create several actions (for example
"Submit New Record", "Submit a New File", "Send to a Distribution List", etc. in fact any action you can imagine
to perform on a document stored in your database). The creation of an action is very simple and consists in
filling in a name, description and associating a directory to this action. The directory parameter indicates where
the collected data will be stored when the action is carried on.<br><br>
&nbsp;<span class="guideheader">O</span>nce an action is created, you have to implement it over a document
type. Implementing an action means defining the web form which will be displayed to a user, and defining the
treatment (set of functions) applied to the data which have been gathered. The implementation of the same action
over two document types can be very different. The fields in the web form can be different as well as the functions
applied at the end of this action.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="actionnew.<lang:star: *>.html">create a new action</A><BR>
<li><A HREF="actionremove.<lang:star: *>.html">remove an action</A><BR>
<li><A HREF="actionmodify.<lang:star: *>.html">modify an action</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/bibconvert.html.wml b/modules/websubmit/doc/admin/bibconvert.html.wml
index 9e70f7fd6..5840c0c27 100644
--- a/modules/websubmit/doc/admin/bibconvert.html.wml
+++ b/modules/websubmit/doc/admin/bibconvert.html.wml
@@ -1,42 +1,42 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="BibConvert" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">W</span>ebSubmit stores the data gathered during a submission in a
directory. In this directory each file corresponds to a field saved during the submission. <br>
&nbsp;<span class="guideheader">B</span>ibConvert is used to create a formatted file which will be easy to
upload in the bibliographical database from this directory.<br>
&nbsp;<span class="guideheader">T</span>his bibConvert program is called from the
<a href="functiondescription.<lang:star: *>.html?#Make_Record">Make_Record</a> and
<a href="functiondescription.<lang:star: *>.html?#Make_Modify_Record">Make_Modify_Record</a> functions
from the <a href="functions.<lang:star: *>.html">end script</a> system of webSubmit.<br>
&nbsp;<span class="guideheader">T</span>he bibConvert configuration files used by webSubmit are in the
<ETCDIR>/bibconvert/config directory.<br><br>
&nbsp;<span class="guideheader">F</span>or more info about bibconvert, please see the dedicated
<a href="<WEBURL>/admin/bibconvert">guide</a>.
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/catalogues.html.wml b/modules/websubmit/doc/admin/catalogues.html.wml
index 6863710ec..6bf445548 100644
--- a/modules/websubmit/doc/admin/catalogues.html.wml
+++ b/modules/websubmit/doc/admin/catalogues.html.wml
@@ -1,67 +1,67 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Catalogues organisation" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">T</span>his feature allows you to organise the way webSubmit main page
will look like. You will be able to group document types inside catalogues and order the catalogues the way you
wish.
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "Organisation" link in the websubmit admin right menu.
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">O</span>nce on the "Edit Catalogues page", you will find the currently
defined organisation chart in the middle of the page. To the right, one form allows you to create a new catalogue
("Add a Catalogue") and one to add a document type to an existing catalogue ("Add a document type").
<BR>&nbsp;<br>
<UL>
<LI><FONT color=green>To add a catalogue:</FONT> Enter the name of your new catalogue in the
"Catalogue Name" free text field then choose to which existing catalogue this one will be attached to. If you
attach the new one to an already existing catalogue, you can create a sub-catalogue. To actually create it,
click on "ADD".
<LI><FONT color=green>To add a document type to a catalogue:</FONT> Choose in the list of existing
"Document type names" the one you want to add to the chart. Then choose to which catalogue the document
type will be associated. Click on "ADD" to finalise this action.
<LI><FONT color=green>To withdraw a document type or a catalogue from the chart:</FONT> Click on the
red cross next to the item you want to withdraw. If you withdraw a catalogue all document types attached to
it will be withdrawn also (of course the actual document types in webSubmit won't be destroyed!).
<LI><FONT color=green>To move a document type or a catalogue in the chart:</FONT> Use the small up
and down arrows next to the document type/catalogue title.
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="newtype.<lang:star: *>.html">Create a New Document Type</A><BR>
<li><A HREF="documents.<lang:star: *>.html">document types</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/description.html.wml b/modules/websubmit/doc/admin/description.html.wml
index 87e96fcdf..3f15f992a 100644
--- a/modules/websubmit/doc/admin/description.html.wml
+++ b/modules/websubmit/doc/admin/description.html.wml
@@ -1,57 +1,57 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Interface Description" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>Welcome to webSubmit Management tool:</h3>
<BLOCKQUOTE>
<UL>
&nbsp;<span class="guideheader">o</span>n the websubmit admin <a href="<WEBURL>/admin/websubmit/">main page</a> you will find:<br><br>
<IMG src="<WEBURL>/img/sbm_admin_guide_mainpage.png" class="guideimg"><br><br>
<UL>
<LI>The list of all existing document type in the middle of the page. Click on one line in the list to have
access to the main document modification panel</SMALL>
<LI>The right menu panel with the following links inside:
<UL>
<LI>"<b>webSubmit Admin</b>": This links leads you back to the main page of the manager.
<LI>"<b>New Doctype</b>": Click here if you wish to create a new document type.
<LI>"<b>Remove Doctype</b>": Click here if you want to remove an existing document type.
<LI>"<b>Available Actions</b>": Lists all existing actions
<LI>"<b>Available Javascript Checks</b>": Lists all existing Javascript checking functions.
<LI>"<b>Available Element Description</b>": Lists all existing html form element descriptions.
<LI>"<b>Available Functions</b>": Lists all existing functions in CDS Submit.
<LI>"<b>Organise Main Page</b>": Allows you to manage the appearance and order of the list of document
types on CDS Submit User main page.
</UL>
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<A HREF="description.<lang:star: *>.html">interface description</A><BR>
<A HREF="actions.<lang:star: *>.html">actions</A><BR>
<A HREF="documents.<lang:star: *>.html">document types</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/documentmodify.html.wml b/modules/websubmit/doc/admin/documentmodify.html.wml
index e7a341a34..85a2a39fa 100644
--- a/modules/websubmit/doc/admin/documentmodify.html.wml
+++ b/modules/websubmit/doc/admin/documentmodify.html.wml
@@ -1,56 +1,56 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Modify an existing type of document" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">M</span>odifying a document type in webSubmit - this will modify its
general data description, not the implementations of
the actions on this document type. For the later, please see <A HREF="actionimplement.<lang:star: *>.html">
implement an action over a type of document</A>.
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">F</span>rom the main page of the manager, click on the title of the
document type you want to modify, then click on the "Edit Document Type Details".
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">O</span>nce here, you can modify 2 fields:<br>
<li><b>Document Type Name</b>: This is the full name of your new document. This is the text which will appear
on the list of available documents and catalogues on webSubmit main page.
<li><b>Document Type Description</b>: This is the text which will appear on the right of the screen when the user
moves the mouse over the document type title and on the document type submission page. This can be pure
text or html.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="documentremove.<lang:star: *>.html">remove a type of document</A><BR>
<li><A HREF="documentnew.<lang:star: *>.html">create a type of document</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/documentnew.html.wml b/modules/websubmit/doc/admin/documentnew.html.wml
index 36b7e7330..d5f66e90a 100644
--- a/modules/websubmit/doc/admin/documentnew.html.wml
+++ b/modules/websubmit/doc/admin/documentnew.html.wml
@@ -1,56 +1,56 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Add a new type of document" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "New Doctype" link in the webSubmit right menu.
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">A</span> new document type is defined by 6 fields:<br>
<UL>
<li><b>Creation Date</b> and <b>Modification Dates</b> are generated and modified automatically.<br>
<li><b>Document Type ID</b>: This is the acronym for your new document type. We usually use a 3 letters
acronym.
<li><b>Document Type Name</b>: This is the full name of your new document. This is the text which will
appear on the list of available documents and catalogues on webSubmit main page.
<li><b>Document Type Description</b>: This is the text which will appear on the document type submission
page. This can be pure text or html.
<li><b>Doctype to clone</b>: Here you can choose to create your document type as a clone of another
existing document type. If so, the new document type will implement all actions implemented by the chosen
one. The web forms will be the same, and the functions also, as well as the values of the parameters for
these functions. Of course once cloned, you will be able to modify the implemented actions.
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="documentremove.<lang:star: *>.html">remove a type of document</A><BR>
<li><A HREF="documentmodify.<lang:star: *>.html">modify a type of document</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/documentremove.html.wml b/modules/websubmit/doc/admin/documentremove.html.wml
index ef85e2fc6..8de9fcf35 100644
--- a/modules/websubmit/doc/admin/documentremove.html.wml
+++ b/modules/websubmit/doc/admin/documentremove.html.wml
@@ -1,45 +1,45 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Remove a type of document" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "Remove Doctype" link in the
webSubmit admin right menu
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">S</span>elect the document type to delete then click on the "Remove Doctype" button. Remember by doing this, you
will delete this document type as well as all the implementation of actions for this document type!
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="documentnew.<lang:star: *>.html">create a type of document</A><BR>
<li><A HREF="documentmodify.<lang:star: *>.html">modify a type of document</A><BR>
<li><A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/documents.html.wml b/modules/websubmit/doc/admin/documents.html.wml
index 671fab453..d076f3c24 100644
--- a/modules/websubmit/doc/admin/documents.html.wml
+++ b/modules/websubmit/doc/admin/documents.html.wml
@@ -1,50 +1,50 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Document Types" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<BLOCKQUOTE>
<UL>
&nbsp;<span class="guideheader">W</span>ebSubmit can propose several actions on different document
types. Each of these document type may or may not implement all possible actions. The main difference
between each document type is the metadata which define each of them, and may also be the kind of fulltext
files attached to one record. <br><br>
&nbsp;<span class="guideheader">A</span> document type can be one of "Thesis", "Photos", "Videotapes"...
or whatever type of document you may invent. A document type is always defined by its metadata. It may or
may not have a fulltext file attached to it.<br><br>
&nbsp;<span class="guideheader">T</span>his tool leaves you free to create the web forms adapted to whatever type of document you want to
create (see "<a href=implementwebform.<lang:star: *>.html>Create and Maintain the Web Form</a>") as well as free
to determine what treatment you wish to apply to the collected data (see
"<a href=implementfunctions.<lang:star: *>.html>Create and Maintain the Data Treatment</a>").
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<A HREF="documentnew.<lang:star: *>.html">add a new type of document</A><BR>
<A HREF="documentremove.<lang:star: *>.html">remove a type of document</A><BR>
<A HREF="documentmodify.<lang:star: *>.html">modify a type of document</A><BR>
<A HREF="actionimplement.<lang:star: *>.html">implement an action over a type of document</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/example.html.wml b/modules/websubmit/doc/admin/example.html.wml
index 1e1ad1334..18db370fb 100644
--- a/modules/websubmit/doc/admin/example.html.wml
+++ b/modules/websubmit/doc/admin/example.html.wml
@@ -1,87 +1,87 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Using the manager through an example" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>what is this?</h3>
<BLOCKQUOTE>
<UL>
This page presents you the typical situations a user could meet using WebSubmit, and for each situation how to use the manager to configure it.
</UL>
</BLOCKQUOTE>
<h3>The user reaches WebSubmit main page.</h3>
<IMG src="<WEBURL>/img/sbm_admin_guide_mainmenu.png" alt="Main Page" class="guideimg" align="left">
&nbsp;<span class="guideheader">T</span>o add a document type to WebSubmit, you should go to the <a target=top href="<WEBURL>/admin/websubmit/index.php">main page</a>
and click on "New Doctype" in the left blue panel.<br><br>
&nbsp;<span class="guideheader">E</span>ven once created, a document type will not appear automatically on this page. To configure the list of catalogues and document
types displayed on this page, the administrator shall go to the <a target=top href="<WEBURL>/admin/websubmit/editCatalogues.php">edit catalogues</a>
page. (see the <a href=catalogues.<lang:star: *>.html>guide section</a>)<br>
<h3>The user can then click on the document type he is interested in.</h3>
<IMG src="<WEBURL>/img/sbm_admin_guide_menudoc.png" alt="Document type Page" class="guideimg" align="left">
&nbsp;<span class="guideheader">T</span>he text appearing under the header containing the name of the document
can be configured by going to the <a target=top href="<WEBURL>/admin/websubmit/">main page</a>, click on
the title of the document type then on the "Edit Document Types Details" button.<br><br>
&nbsp;<span class="guideheader">Y</span>ou can associate several categories to a document type which can be defined by going to the
<a target=top href="<WEBURL>/admin/websubmit/">main page</a>, click on the title of the document type
then on the "View Categories" button. The selected category will be saved in a file named "comboXXX"
(where XXX is the short name of the document type) in the submission directory.<br><br>
&nbsp;<span class="guideheader">T</span>o add an action button to this page, first implement this action by going to the
<a target=top href="<WEBURL>/admin/websubmit/">main page</a>, click on the title of the document type then
on the "Add a new submission" button. If the action is already implemented and the button still does not appear
on the submision page, then you should edit the details of this implementation: go to the
<a target=top href="<WEBURL>/admin/websubmit">main page</a>, click on the title of the document type then
on the icon in the "Edit Submission" column and in the line of the desired action. There you should set the
"Displayed" form field to "YES".<br><br>
&nbsp;<span class="guideheader">Y</span>ou can also change the order of the buttons, by going to the <a target=top href="<WEBURL>/admin/websubmit/">
main page</a>, click on the title of the document type then on the icon in the "Edit Submission" column and in the
line of the desired action. There you can set the "buttonorder" form field.<br><br>
<h3>The user now may choose a category, then click on the action button he wishes.<br>The submission starts, the first page of the web form appears.</h3>
<IMG src="<WEBURL>/img/sbm_admin_guide_form.png" alt="Document type Page" class="guideimg" align="left">
&nbsp;<span class="guideheader">T</span>his web form is composed of several pages, on each of these
pages form fields can be found. To modify the number of pages, add or withdraw form fields and modify
the texts before each form field, you shall go to the <a target=top href="<WEBURL>/admin/websubmit">main page</a>,
click on the title of the document type then on the icon in the "Edit Submission Pages" column and in the line of the
desired action. (see the <a href=actionimplement.<lang:star: *>.html>guide section</a>)<br><br>
<h3>On the last page of the submission, there should be a button like in the following image which will
trigger the end script</h3>
<IMG src="<WEBURL>/img/sbm_admin_guide_endaction.png" alt="Document type End Page" class="guideimg" align="left">
&nbsp;<span class="guideheader">T</span>his button is defined like any other form field. Its definition should include
a <i> onclick="finish();"</i> javascript attribute.<br><br>
&nbsp;<span class="guideheader">A</span>fter clicking this button, WebSubmit will apply the end script functions
to the gathered data. To modify the end script, you shall go to the <a target=top href="<WEBURL>/admin/websubmit/">
main page</a>, click on the title of the document type then on the icon in the "Edit Functions" column and in the line
of the desired action. (see the <a href="implementfunctions.<lang:star: *>.html">guide section</a>)<br>
<h3>See also:</h3>
<BLOCKQUOTE>
<A HREF="description.<lang:star: *>.html">interface description</A><BR>
<A HREF="actions.<lang:star: *>.html">actions</A><BR>
<A HREF="documents.<lang:star: *>.html">document types</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/faq.html.wml b/modules/websubmit/doc/admin/faq.html.wml
index 35f20ecdc..95474fb8a 100644
--- a/modules/websubmit/doc/admin/faq.html.wml
+++ b/modules/websubmit/doc/admin/faq.html.wml
@@ -1,77 +1,77 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="WebSubmit Admin FAQ" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
&nbsp;<span class="guideheader">Q</span>1. <a href="#Q1">I'd like to be warned each time there is an error, or an important
action is made through the manager. Is this possible?
</a><br>
&nbsp;<span class="guideheader">Q</span>2. <a href="#Q2">Where are all the files stored in this system?
</a><br>
&nbsp;<span class="guideheader">Q</span>3. <a href="#Q3">How is the documents archive organised?
</a><br><br><br><br>
<a name="Q1"></a>
<i>&nbsp;<span class="guideheader">Q</span>1. I'd like to be warned each time there is an error, or an important
action is made through the manager. Is this possible?
</i>
<BLOCKQUOTE>
Yes, it is. Edit the config.wml file in CDSware distribution, find the "ADMINEMAIL" definition and set it to your email
address. You will then receive all the warning emails issued by the manager.
</BLOCKQUOTE>
<a name="Q2"></a>
<i>&nbsp;<span class="guideheader">Q</span>2. Where are all the files stored in this system?
</i>
<BLOCKQUOTE>
<li>the counter files are here: <CFG_SUBMIT_COUNTER>. There are used by the
<a href="functiondescription.<lang:star: *>.html#Report_Number_Generation">Report_Number_Generation</a>
function.
<li>all running and completed submissions are stored here: <CFG_SUBMIT_DIR>.
<li>all the document files attached to records are stored here: <CFG_FILE_DIR>.
<li>all python functions used by webSubmit are stored here: <LIBDIR>/python/cdsware/websubmit_functions
</BLOCKQUOTE>
<a name="Q3"></a>
<i>&nbsp;<span class="guideheader">Q</span>3. How is the documents archive organised?
</i>
<BLOCKQUOTE>
First of all, the documents files attached to records are stored here: <CFG_FILE_DIR>. <br><br>
The <a href="functiondescription.<lang:star: *>.html#Upload_Files">Upload_Files</a> webSubmit function is used
to link a document with a record.<br><br>
All documents get an id from the system and are stored in the "bibdoc" table in the database. The link between a
document and a record is stored using the "bibdoc_bibrec" table.<br><br>
The document id is used to determine where the files are stored. For example the files of document #14 will be
stored here: <CFG_FILE_DIR>/g0/14<br><br>
The subdirectory g0 is used to split the documents accross the filesystem. The CFG_FILE_DIR_SIZE variable from
config.wml determines how many documents will be stored under one subdirectory.<br><br>
Several files may be stored under the same document directory: they are the different formats and versions of the
same document. Versions are indicated by a string of the form ";1.0" concatenated to the name of the file.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
notes
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/functiondelete.html.wml b/modules/websubmit/doc/admin/functiondelete.html.wml
index 5b41418f8..ae6d759ff 100644
--- a/modules/websubmit/doc/admin/functiondelete.html.wml
+++ b/modules/websubmit/doc/admin/functiondelete.html.wml
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Remove a function" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>Note</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">T</span>here are currently no way of deleting a function through this
interface. Use the direct MySQL command line interface for this.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="functionedit.<lang:star: *>.html">edit a function</A><BR>
<li><A HREF="functionnew.<lang:star: *>.html">create a function</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/functiondescription.html.wml b/modules/websubmit/doc/admin/functiondescription.html.wml
index bc2eba7db..699f3aa9e 100644
--- a/modules/websubmit/doc/admin/functiondescription.html.wml
+++ b/modules/websubmit/doc/admin/functiondescription.html.wml
@@ -1,1042 +1,1042 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="All functions explained" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>Description:</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">T</span>his page lists and explains all the functions used in the demo
provided with CDSWare package. This list is not exhaustive since you can add any new function you need.<br>
&nbsp;<span class="guideheader">C</span>lick on one function name to get its description.<br>
&nbsp;<span class="guideheader">P</span>lease note in this page when we refer to [param] this means the
value of the parameter 'param' for a given document type.<br><br>
<table cellspacing=5><tr>
<td valign="top">
<a HREF="#CaseEDS">CaseEDS</A><br>
<a HREF="#Create_Modify_Interface">Create_Modify_Interface</A><br>
<a HREF="#Create_Recid">Create_Recid</A><br>
<a HREF="#Finish_Submission">Finish_Submission</A><br>
<a HREF="#Get_Info">Get_Info</A><br>
<a HREF="#Get_Report_Number">Get_Report_Number</A><br>
<a HREF="#Get_Sysno">Get_Sysno</A><br>
<a HREF="#Get_TFU_Files">Get_TFU_Files</A><br>
<a HREF="#Insert_Modify_Record">Insert_Modify_Record</A><br>
<a HREF="#Insert_Record">Insert_Record</A><br>
</td>
<td valign="top">
<a HREF="#Is_Original_Submitter">Is_Original_Submitter</A><br>
<a HREF="#Is_Referee">Is_Referee</A><br>
<a HREF="#Mail_Submitter">Mail_Submitter</A><br>
<a HREF="#Make_Modify_Record">Make_Modify_Record</A><br>
<a HREF="#Make_Record">Make_Record</A><br>
<a HREF="#Move_From_Pending">Move_From_Pending</A><br>
<a HREF="#Move_to_Done">Move_to_Done</A><br>
<a HREF="#Move_to_Pending">Move_to_Pending</A><br>
<a HREF="#Print_Success">Print_Success</A><br>
<a HREF="#Print_Success_APP">Print_Success_APP</A><br>
</td>
<td valign="top">
<a HREF="#Print_Success_MBI">Print_Success_MBI</A><br>
<a HREF="#Print_Success_SRV">Print_Success_SRV</A><br>
<a HREF="#Report_Number_Generation">Report_Number_Generation</A><br>
<a HREF="#Send_Approval_Request">Send_Approval_Request</A><br>
<a HREF="#Send_APP_Mail">Send_APP_Mail</A><br>
<a HREF="#Send_Modify_Mail">Send_Modify_Mail</A><br>
<a HREF="#Send_SRV_Mail">Send_SRV_Mail</A><br>
<a HREF="#Test_Status">Test_Status</A><br>
<a HREF="#Update_Approval_DB">Update_Approval_DB</A><br>
<a HREF="#Upload_Files">Upload_Files</A><br>
</td>
</tr></table>
</BLOCKQUOTE>
<br><br><A NAME="CaseEDS">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>CaseEDS</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function may be used if the treatment to be done after a submission depends on a field entered by
the user. Typically this is used in an approval interface. If the referee approves then we do this. If he rejects,
then we do other thing.<br>
More specifically, the function gets the value from the file named [casevariable] and compares it with the
values stored in [casevalues]. If a value matches, the function directly goes to the corresponding step stored
in [casesteps]. If no value is matched, it goes to step [casedefault].
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>casevariable</b></SMALL></TD>
<TD><SMALL>
This parameters contains the name of the file in which the function will get the chosen value.<br>
Eg: "decision"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>casevalues</b></SMALL></TD>
<TD><SMALL>
Contains the list of recognized values to match with the chosen value. Should be a comma separated list of words.<br>
Eg: "approve,reject"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>casesteps</b></SMALL></TD>
<TD><SMALL>
Contains the list of steps corresponding to the values matched in [casevalue]. It should be a comma
separated list of numbers<br>
Eg: "2,3"<br>
<i>In this example, if the value stored in the file named "decision" is "approved", then the function launches
step 2 of this action. If it is "reject", then step 3 is launched.</i>
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>casedefault</b></SMALL></TD>
<TD><SMALL>
Contains the step number to go by default if no match is found.<br>
Eg: "4"<br>
<i>In this example, if the value stored in the file named "decision" is not "approved" nor "reject", then
step 4 is launched.</i>
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Create_Modify_Interface">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Create_Modify_Interface</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
To be used in the MBI-Modify Record action.
It displays a web form allowing the user to modify the fields he chose. The fields are prefilled with the existing
values extracted from the documents database.
This functions takes the values stored in the [fieldnameMBI] file. This file contains a list of field name separated
with "+" (it is usually generated from a multiple select form field). Then the function retrieves the corresponding
tag name (marc-21) stored in the element definition. Finally it displays the web form and fills it with the existing
values found in the documents database.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>fieldnameMBI</b></SMALL></TD>
<TD><SMALL>
Contains the name of the file in which the function will find the list of fields the user wants to modify. Depends
on the web form configuration.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Create_Recid">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Create_Recid</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function retrieves a new record id from the records database. This record id will then be used to create the
XML record afterwards, or to link with the fulltext files. The created id is stored in a file named "SN".
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Finish_Submission">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Finish_Submission</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function stops the data treatment process even if further steps exist. This is used for example in the
approval action. In the first step, the program determines whether the user approved or rejected the
document (see <A href="#CaseEDS">CaseEDS</a> function description). Then depending on the result, it
executes step 2 or step 3. If it executes step 2, then it should continue with step 3 if nothing stopped it. The
Finish_Submission function plays this role.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Get_Info">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Get_Info</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function tries to retrieve in the "pending" directory or directly in the documents database, some information
about the document: title, original submitter's email and author(s).<br>
If found, this information is stored in 3 global variables: $emailvalue, $titlevalue, $authorvalue to be used
in other functions.<br>
If not found, an error message is displayed.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>authorFile</b></SMALL></TD>
<TD><SMALL>
Name of the file in which the author may be found if the document has not yet been integrated (in this case
it is still in the "pending" directory).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>emailFile</b></SMALL></TD>
<TD><SMALL>
Name of the file in which the email of the original submitter may be found if the document has not yet been
integrated (in this case it is still in the "pending" directory).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>titleFile</b></SMALL></TD>
<TD><SMALL>
Name of the file in which the title may be found if the document has not yet been integrated (in this case it is
still in the "pending" directory).
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Get_Report_Number">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Get_Report_Number</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function gets the value contained in the [edsrn] file and stores it in the reference global variable.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>edsrn</b></SMALL></TD>
<TD><SMALL>
Name of the file which stores the reference.<br>
This value depends on the web form configuration you did. It should contain the name of the form element used for storing the reference of the document.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Get_Sysno">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Get_Sysno</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This functions searches for the document in the database and stores the system number of this document in the "SN" file and in a global variable.<br>
"Get_Report_Number" should be called before.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Insert_Modify_Record">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Insert_Modify_Record</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function gets the output of bibconvert and uploads it into the MySQL bibliographical database.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Insert_Record">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Insert_Record</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function gets the output of bibFormat and uploads it into the MySQL bibliographical database.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Is_Original_Submitter">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Is_Original_Submitter</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
If the authentication module (login) is active in webSubmit, this function compares the current login with the email of the original submitter. If it is the same (or if the current user has superuser rights), we go on. If it differs, an error message is issued.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Is_Referee">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Is_Referee</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function checks whether the currently logged user is a referee for this document.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Mail_Submitter">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Mail_Submitter</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function send an email to the submitter to warn him the document he has just submitted has been
correctly received.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>authorfile</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the authors of the document<br>
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>titleFile</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the title of the document<br>
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>emailFile</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the email of the submitter of the document<br>
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>status</b></SMALL></TD>
<TD><SMALL>
Depending on the value of this parameter, the function adds an additional text to the email.<br>
This parameter can be one of:<br>
<b>ADDED</b>: The file has been integrated in the database.<br>
<b>APPROVAL</b>: The file has been sent for approval to a referee.<br>
or can stay empty.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>edsrn</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the reference of the document<br>
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>newrnin</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the 2nd reference of the document (if any)<br>
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Make_Modify_Record">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Make_Modify_Record</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function creates the record file formatted for a direct insertion in the documents database. It uses the
<a href="bibconvert.<lang:star: *>.html">bibConvert</a> tool.<br>
The main difference between all the Make_..._Record functions are the parameters.<br>
As its name says, this particular function should be used for the modification of a record. (MBI- Modify
Record action).
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>modifyTemplate</b></SMALL></TD>
<TD><SMALL>
Name of bibconvert's configuration file used for creating the mysql record.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>sourceTemplate</b></SMALL></TD>
<TD><SMALL>
Name of bibconvert's source file.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Make_Record">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Make_Record</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function creates the record file formatted for a direct insertion in the documents database. It uses the
<a href="bibconvert.<lang:star: *>.html">bibConvert</a> tool.<br>
The main difference between all the Make_..._Record functions are the parameters.<br>
As its name does not say :), this particular function should be used for the submission of a document.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>createTemplate</b></SMALL></TD>
<TD><SMALL>
Name of bibconvert's configuration file used for creating the mysql record.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>sourceTemplate</b></SMALL></TD>
<TD><SMALL>
Name of bibconvert's source file.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Move_From_Pending">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Move_From_Pending</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function retrieves the data of a submission which was temporarily stored in the "pending" directory
(waiting for an approval for example), and moves it to the current action directory.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Move_to_Done">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Move_to_Done</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function moves the existing submission directory to the <CFG_SUBMIT_DIR>/done directory. If the
Then it tars and gzips the directory.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Move_to_Pending">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Move_to_Pending</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function moves the existing submission directory to the <CFG_SUBMIT_DIR>/pending directory. It is
used to store temporarily this data until it is approved or...
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Print_Success">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Print_Success</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function simply displays a text on the screen, telling the user the submission went fine. To be used in
the "Submit New Record" action.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>status</b></SMALL></TD>
<TD><SMALL>
Depending on the value of this parameter, the function adds an additional text to the email.<br>
This parameter can be one of:<br>
<b>ADDED</b>: The file has been integrated in the database.<br>
<b>APPROVAL</b>: The file has been sent for approval to a referee.<br>
or can stay empty.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>edsrn</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the reference of the document<br>
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>newrnin</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the 2nd reference of the document (if any)<br>
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Print_Success_APP">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Print_Success_APP</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function simply displays a text on the screen, telling the referee his decision has been taken into account.
To be used in the Approve (APP) action.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Print_Success_MBI">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Print_Success_MBI</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function simply displays a text on the screen, telling the user the modification went fine. To be used in
the Modify Record (MBI) action.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Print_Success_SRV">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Print_Success_SRV</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function simply displays a text on the screen, telling the user the revision went fine. To be used in the
Submit New File (SRV) action.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL>none</TD>
</TR>
</TABLE>
<br><br><A NAME="Report_Number_Generation">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Report_Number_Generation</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function is used to automatically generate a reference number.<br>
After generating the reference, the function saves it into the [newrnin] file and sets the global variable
containing this reference.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>autorngen</b></SMALL></TD>
<TD><SMALL>
If set to "<b>Y</b>": The reference number is generated.<br>
If set to "<b>N</b>": The reference number is read from a file ([newrnin])<br>
If set to "<b>A</b>": The reference number will be the access number of the submission.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>counterpath</b></SMALL></TD>
<TD><SMALL>
indicates the file in which the program will find the counter for this reference generation.<br>
The value of this parameter may contain one of:<BR>
"<b>&lt;PA&gt;categ&lt;/PA&gt;</b>": in this case this string is replaced with the content of the file [altrnin]<br>
"<b>&lt;PA&gt;yy&lt;/PA&gt;</b>": in this case this string is replaced by the current year (4 digits) if [altyeargen]
is set to "AUTO", or by the content of the [altyeargen] file in any other case. (this content should be formatted
as a date (dd/mm/yyyy).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>rnformat</b></SMALL></TD>
<TD><SMALL>
This is the format used by the program to create the reference. The program computes the value of the
parameter and appends a "-" followed by the current value of the counter increased by 1.<br>
The value of this parameter may contain one of:<BR>
"<b>&lt;PA&gt;categ&lt;/PA&gt;</b>": in this case this string is replaced with the content of the file [altrnin]<br>
"<b>&lt;PA&gt;yy&lt;/PA&gt;</b>": in this case this string is replaced by the current year (4 digits) if [altyeargen]
is set to "AUTO", or by the content of the [altyeargen] file in any other case. (this content should be formatted
as a date (dd/mm/yyyy).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>rnin</b></SMALL></TD>
<TD><SMALL>
This parameter contains the name of the file in which the program will find the category if needed. The content
of thif file will then replace the string &lt;PA&gt;categ&lt;/PA&gt; in the reference format or in the counter
path.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>yeargen</b></SMALL></TD>
<TD><SMALL>
This parameter can be one of:<br>
"<b>AUTO</b>": in this case the program takes the current 4 digit year.<br>
"<b>&lt;filename&gt;</b>": in this case the program extract the year from the file which name is
&lt;filename&gt;. This file should contain a date (dd/mm/yyyy).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>edsrn</b></SMALL></TD>
<TD><SMALL>
Name of the file in which the created reference will be stored.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Send_Approval_Request">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Send_Approval_Request</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function sends an email to the referee in order to start the simple approval process.<br>
This function is very CERN-specific and should be changed in case of external use.<br>
Must be called after the <a href=#Get_Report_Number>Get_Report_Number</a> function.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>addressesDAM</b></SMALL></TD>
<TD><SMALL>
email addresses of the people who will receive this email (comma separated list). this parameter may contain the <b>&lt;CATEG&gt;</b> string. In which case the variable computed from the [categformatDAM] parameter replaces this string.<br>
eg.: "&lt;CATEG&gt;-email@cern.ch"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>categformatDAM</b></SMALL></TD>
<TD><SMALL>
contains a regular expression used to compute the category of the document given the reference of the document.<br>
eg.: if [categformatAFP]="TEST-&lt;CATEG&gt;-.*" and the reference of the document is "TEST-CATEGORY1-2001-001", then the computed category equals "CATEGORY1"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>authorfile</b></SMALL></TD>
<TD><SMALL>
name of the file in which the authors are stored
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>titlefile</b></SMALL></TD>
<TD><SMALL>
name of the file in which the title is stored.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>directory</b></SMALL></TD>
<TD><SMALL>
parameter used to create the URL to access the files.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Send_APP_Mail">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Send_APP_Mail</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
Sends an email to warn people that a document has been approved.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>addressesAPP</b></SMALL></TD>
<TD><SMALL>
email addresses of the people who will receive this email (comma separated list). this parameter may contain
the <b>&lt;CATEG&gt;</b> string. In which case the variable computed from the [categformatAFP] parameter
replaces this string.<br>
eg.: "&lt;CATEG&gt;-email@cern.ch"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>categformatAPP</b></SMALL></TD>
<TD><SMALL>
contains a regular expression used to compute the category of the document given the reference of the
document.<br>
eg.: if [categformatAFP]="TEST-&lt;CATEG&gt;-.*" and the reference of the document is
"TEST-CATEGORY1-2001-001", then the computed category equals "CATEGORY1"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>newrnin</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the 2nd reference of the approved document (if any).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>edsrn</b></SMALL></TD>
<TD><SMALL>
Name of the file containing the reference of the approved document.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Send_Modify_Mail">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Send_Modify_Mail</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function sends an email to warn people a document has been modified and the user his modifications
have been taken into account..
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>addressesMBI</b></SMALL></TD>
<TD><SMALL>
email addresses of the people who will receive this email (comma separated list).
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>fieldnameMBI</b></SMALL></TD>
<TD><SMALL>
name of the file containing the modified fields.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>sourceDoc</b></SMALL></TD>
<TD><SMALL>
Long name for the type of document. This name will be displayed in the mail.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>emailfile</b></SMALL></TD>
<TD><SMALL>
name of the file in which the email of the modifier will be found.
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Send_SRV_Mail">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Send_SRV_Mail</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function sends an email to warn people a revision has been carried out.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>notefile</b></SMALL></TD>
<TD><SMALL>
name of the file in which the note can be found
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>emailfile</b></SMALL></TD>
<TD><SMALL>
name of the file containing the submitter's email
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>addressesSRV</b></SMALL></TD>
<TD><SMALL>
email addresses of the people who will receive this email (comma separated list). this parameter may contain the <b>&lt;CATEG&gt;</b> string. In which case the variable computed from the [categformatDAM] parameter replaces this string.<br>
eg.: "&lt;CATEG&gt;-email@cern.ch"
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>categformatDAM</b></SMALL></TD>
<TD><SMALL>
contains a regular expression used to compute the category of the document given the reference of the
document.<br>
eg.: if [categformatAFP]="TEST-&lt;CATEG&gt;-.*" and the reference of the document is
"TEST-CATEGORY1-2001-001", then the computed category equals "CATEGORY1"
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Test_Status">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Test_Status</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function checks whether the considered document has been requested for approval and is still waiting
for approval. It also checks whether the password stored in file "password" of the submission directory
corresponds to the password associated with the document..
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top" colspan="2"><SMALL><b>none</b></SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Update_Approval_DB">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Update_Approval_DB</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function updates the approval database when a document has just been approved or rejected. It uses
the [categformatDAM] parameter to compute the category of the document.<br>
Must be called after the <a href=#Get_Report_Number>Get_Report_Number</a> function.
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>categformatDAM</b></SMALL></TD>
<TD><SMALL>
It contains the regular expression which allows the retrieval of the category from the reference number.<br>
Eg: if [categformatDAM]="TEST-&lt;CATEG&gt;-.*" and the reference is "TEST-CATEG1-2001-001" then the
category will be recognized as "CATEG1".
</SMALL></TD>
</TR>
</TABLE>
<br><br><A NAME="Upload_Files">
<table border="1" width="80%">
<TR><TD colspan="2" bgcolor="#ddddff"><SMALL><b>Upload_Files</b></SMALL></TD></TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>description</SMALL></TD></TR>
<TR>
<TD colspan="2">
<SMALL>
This function displays the list of already transfered files (main and additional ones), and also outputs an html
form for uploading other files (pictures or fulltexts).
</SMALL>
</TD>
</TR>
<TR><TD colspan="2" bgcolor="#eeeeff" align="center"><SMALL>parameters</SMALL></TD></TR>
<TR>
<TD valign="top"><SMALL><b>maxsize</b></SMALL></TD>
<TD><SMALL>
Maximum allowed size for the transfered files (size in bits)
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>minsize</b></SMALL></TD>
<TD><SMALL>
Minimum allowed size for the transfered files (size in bits)
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>iconsize</b></SMALL></TD>
<TD><SMALL>
In case the transfered files are pictures (jpg, gif or pdf), the function will automatically try to create icons from them.
This parameter indicates the size in pixel of the created icon.
</SMALL></TD>
</TR>
<TR>
<TD valign="top"><SMALL><b>type</b></SMALL></TD>
<TD><SMALL>
This can be one of "fulltext" or "picture". If the type is set to "picture" then the function will try to create icons
(uses the ImageMagick's "convert" tool)
</SMALL></TD>
</TR>
</TABLE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="functionnew.<lang:star: *>.html">create a new function</A><BR>
<li><A HREF="functiondelete.<lang:star: *>.html">delete a function</A><BR>
<li><A HREF="functionedit.<lang:star: *>.html">edit a function</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/functionedit.html.wml b/modules/websubmit/doc/admin/functionedit.html.wml
index 58678bf2f..1c605e640 100644
--- a/modules/websubmit/doc/admin/functionedit.html.wml
+++ b/modules/websubmit/doc/admin/functionedit.html.wml
@@ -1,57 +1,57 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Edit a function" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">E</span>dit a function, add parameters to it...
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "Available Functions" link in the websubmit admin
right menu.
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">O</span>n this page appears a list of all functions defined into the system.
Two columns give you access to some features:
<UL>
<LI><FONT color=green>View function usage</FONT> Click here to have access to the list of all document
types and all actions in which this function is used. Then by clicking on one of the items, you will be given a
chance to modify the parameters value for the given document type.
<LI><FONT color=green>View/Edit function details</FONT> There you will be able to modify the function
description, as well as add/withdraw parameters for this function.
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="functionnew.<lang:star: *>.html">create a new function</A><BR>
<li><A HREF="functiondelete.<lang:star: *>.html">delete a function</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/functionnew.html.wml b/modules/websubmit/doc/admin/functionnew.html.wml
index 313ded3b9..50d8a3608 100644
--- a/modules/websubmit/doc/admin/functionnew.html.wml
+++ b/modules/websubmit/doc/admin/functionnew.html.wml
@@ -1,70 +1,70 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Create a new function" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "Available Functions" link in the websubmit admin right
menu. Then click on the "Add New Function" button.
</BLOCKQUOTE>
<h3>How to do this?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">E</span>nter the name of the new function as well as a text description if
you wish.<br>
&nbsp;<span class="guideheader">Y</span>ou will then reach a page where you can add parameters to your
new function.<br><br>
&nbsp;<span class="guideheader">D</span>on't forget to add the function file inside the
<LIBDIR>/python/cdsware/websubmit_functions directory and to name the file after the function. Functions must
be written in Python. Here is an example implementation of a function:<BR><BR>
<LIBDIR>/python/cdsware/websubmit_functions/Get_Report_Number.py:</SMALL>
<TABLE border=0 width=75% bgcolor="eeeeff"><TR><TD><small><pre><br>
def Get_Report_Number (parameters,curdir,form):
global rn
#Path of file containing report number
if os.path.exists("%s/%s" % (curdir,parameters['edsrn'])):
fp = open("%s/%s" % (curdir,parameters['edsrn']),"r")
rn = fp.read()
rn = rn.replace("/","_")
rn = re.sub("[\n\r ]+","",rn)
else:
rn = ""
return ""
<pre></small></TD></TR></TABLE>
<br>
The function parameters are passed to the function through the parameters dictionary.<br>
The curdir parameter contains the current submission directory path.<br>
The form parameter contains the form passed to the current web page for possible reference from inside the
function.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="functionedit.<lang:star: *>.html">edit a function</A><BR>
<li><A HREF="functiondelete.<lang:star: *>.html">delete a function</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/functions.html.wml b/modules/websubmit/doc/admin/functions.html.wml
index f73546c6f..d45cb7eab 100644
--- a/modules/websubmit/doc/admin/functions.html.wml
+++ b/modules/websubmit/doc/admin/functions.html.wml
@@ -1,51 +1,51 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Functions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>Description:</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">I</span>n webSubmit, each action process is divided into two phases: the
gathering of data (through a web form) and the treatment of the data.<br><br>
&nbsp;<span class="guideheader">T</span>he treatment is organised in a succession of functions, each of
which has its own input and output.<BR><BR>
&nbsp;<span class="guideheader">T</span>he functions themselves are stored in separate files (one per
function) in the <LIBDIR>/python/cdsware/websubmit_functions directory. A file containing a function MUST
be named after the function name itself. For example, a function called "Move_to_Done" MUST be stored in a
file called Move_to_Done.py. The case is important here.<br><BR>
&nbsp;<span class="guideheader">F</span>or a description of what should be inside the file, have a look to
the "create a new function" page of this guide.<br><br>
&nbsp;<span class="guideheader">T</span>o each function you can associate one or several parameters,
which may have different values according to the document type the function is used for. One parameter may
be used for different functions. For example one standard parameter used in several functions is called "edsrn".
It contains the name of the file in which the reference of the document is stored.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="functionnew.<lang:star: *>.html">create a new function</A><BR>
<li><A HREF="functiondelete.<lang:star: *>.html">delete a function</A><BR>
<li><A HREF="functionedit.<lang:star: *>.html">edit a function</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/implementfunctions.html.wml b/modules/websubmit/doc/admin/implementfunctions.html.wml
index 10acd3f04..548e8e3f0 100644
--- a/modules/websubmit/doc/admin/implementfunctions.html.wml
+++ b/modules/websubmit/doc/admin/implementfunctions.html.wml
@@ -1,76 +1,76 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Setup the Data Treatment" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">A</span>t the end of a submission, we have to tell webSubmit what to do
with the data it has gathered. This is expressed through one or several lists of functions (we call this the
"end script").
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">F</span>rom the main page of the manager, click on the title of the relevant
document type.<br>Then click on the icon in the "Edit Functions" column of the relevant line.
</BLOCKQUOTE>
<h3>List of functions</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">H</span>ere is what you may see then (this is the end script list of functions
for a document type named "TEST" and action "FTT" - Fulltext Transfer):<br><br>
<IMG src="<WEBURL>/img/sbm_admin_guide_listfunctions.png" class="guideimg"><br><br>
&nbsp;<span class="guideheader">Y</span>ou can see the ordered list of all the functions in the end script.
This end script is composed of 2 steps (see the "step" column). The functions composing the first step are called,
then there should be action from the user which would trigger step 2 - in the present case the
<a href="functiondescription.<lang:star: *>.html#Upload_Files">Upload_Files</a> function (last of step 1) allows
the user to upload additional files by creating a web form, then when the user finishes, he presses another
button created by the function, which ends the process. Functions of step 2 are then called.<br><br>
&nbsp;<span class="guideheader">W</span>hy implement multiple steps? The reason can vary with the task
you want to accomplish. For example with the example above (Fulltext Transfer), we use the first step to allow
the upload of multiple additional files (dynamic action) which could not be done in the
<a href="implementwebform.<lang:star: *>.html">static web form</a>. In the case of the
"Modify Bibliographic Information" action, the first step is used to display the fields the user wants to modify,
prefilled with the existing values. The reason is once again that the task we want to realise is dynamic.<br><br>
&nbsp;<span class="guideheader">T</span>he "score" column is used to order the functions. The function
which has the smallest score will be called first, and the largest score will be called last.<br><br>
&nbsp;<span class="guideheader">Y</span>ou can then:
<ul>
<li> View and edit the parameters of each function by clicking on the name of the function.
<li> Move one function up and down, by using the small blue arrows.
<li> Suppress one function by clicking on the relevant red cross.
<li> Add a function to the list by clicking the "ADD FUNCTION" button.
<li> Go back to the document main page ("FINISHED" button).
</ul>
&nbsp;<span class="guideheader">P</span>lease note: To pass one function from one step to another,
you have to delete it then add it again in the proper step.
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="functions.<lang:star: *>.html">all about functions</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/implementwebform.html.wml b/modules/websubmit/doc/admin/implementwebform.html.wml
index a72428a5f..b012aeb5f 100644
--- a/modules/websubmit/doc/admin/implementwebform.html.wml
+++ b/modules/websubmit/doc/admin/implementwebform.html.wml
@@ -1,165 +1,165 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Create and maintain the web form" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>What is it?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>reate and define the web form used during an action.
</BLOCKQUOTE>
<h3>How to get there?</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">F</span>rom the main page of the manager, click on the title of the relevant
document type. Then click on the icon in the "Edit Submission Pages" column of the relevant line.
</BLOCKQUOTE>
<h3>List of the form pages</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">A</span> web form can be split over several pages. This is a matter
of easiness for the user: he will have an overview of all form fields present on the page without having to scroll it.
Moreover, each time the user goes from one page to the other, all entered data are saved. If he wants to stop
then come back later (or if the browser crashes!) he will be able to get back to the submission at the exact
moment he left it.<br><br>
&nbsp;<span class="guideheader">O</span>nce here:<br><br>
<IMG src="<WEBURL>/img/sbm_admin_guide_menupage.png" class="guideimg"><br><br>
you can see the ordered list of already existing pages in the web form. In this example there are 4 pages.
You can then:
<ul>
<li> Move one page from one place to an other, using the small blue arrows under each page number.
<li>Suppress one page by clicking on the relevant red cross.
<li>Add a page, by clicking the "ADD A PAGE" button!
<li><a href="#onepage">Edit the content of one page</a> by clicking on the page number.
<li>Go back to the document main page.
</ul>
</BLOCKQUOTE>
<a name="onepage"></a>
<h3>Edit one form page</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on a page number, you then arrive to a place where you can
edit this form page.<br><br>
&nbsp;<span class="guideheader">A</span> form page is composed of a list of form elements. Each of these
form elements is roughly made of an html template and a text displayed before the form field.<br><br>
&nbsp;<span class="guideheader">I</span>n the first part of the page, you have a preview of what the form
will look like to the user:<br>
<IMG src="<WEBURL>/img/sbm_admin_guide_preview.png" class="guideimg"><br><br>
&nbsp;<span class="guideheader">T</span>hen the second table shows you the list of the form elements
present on the page:<br>
<IMG src="<WEBURL>/img/sbm_admin_guide_elements.png" class="guideimg"><br><br>
&nbsp;<span class="guideheader">Y</span>ou can then:
<ul>
<li>Move one element from one place to another using the drop-down menus in the first
column ("Item No") of the table, or the little blue arrows in the second column.
<li><a href="#edittemplate">Edit the html template of one form element</a> by clicking on the name of the
template in the 3rd column ("Name").
<li><a href="#editelement">Edit one of the form elements</a> by clicking on the icon in the 10th column.
<li>delete one form element by clicking on the relevant red cross.
<li><a href="#addelement">Add an element to the page</a> by clicking the "ADD ELEMENT TO PAGE" button.
</UL>
</BLOCKQUOTE>
<a name="edittemplate"></a>
<h3>Edit the html template of one form element</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">I</span>n the html template edition page, you can modify the following values:
<UL>
<LI><b>Element type</b>: indicates which html form element to create
<li><b>Aleph code</b>: <font color=red>Aleph users only!</font> - This indicates in which field of the Aleph
document database to retrieve the original value when modifying this information (function
Create_Modify_Interface of action MBI).
<li><b>Marc Code</b>: <font color=red>MySQL users only!</font> - This indicates in which field of the MySQL
document database to retrieve the original value when modifying this information (function
Create_Modify_Interface of action MBI).
<LI><b>Cookies</b>: indicates whether webSubmit will set a cookie on the value filled in by the user. If yes,
next time the user will come to this submission, the value he has entered last time will be filled in automatically.
<LI><b>other fields</b>: The other fields help defining the html form element.
</UL>
<font color=red>Important warning!</font> Please remember this is a template! This means it can be used in
many different web forms/implementations. When you modify this template the modification will take place in
each of the implementations this template has been used.
</BLOCKQUOTE>
<a name="editelement"></a>
<h3>Edit one form element</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">I</span>n the form element edition page, you may modify the following values:
<UL>
<li><b>element label</b>: This is the text displayed before the actual form field.
<li><b>level</b>: can be one of "mandatory" or "optional". If mandatory, the user won't be able to leave
this page before filling this field in.
<li><b>short desc</b>: This is the text displayed in the summary window when it is opened.
<li><b>Check</b>: Select here the <a href="#addcheck">javascript checking function</a> to be applied to
the submitted value of this field
<li><b>Modify Text</b>: This text will be displayed before the form field when modifying the value (action
"Modify Record", function "Create_Modify_Interface")
</ul>
</BLOCKQUOTE>
<a name="addelement"></a>
<h3>Add one form element</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "ADD ELEMENT TO PAGE" button. There you will have
to decide which <a href="#addtemplate">html template field</a> to use ("Element Description code"), and
also the field mentioned <a href="#editelement">above</a>.
</BLOCKQUOTE>
<a name="addtemplate"></a>
<h3>Create a new html template</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">Y</span>ou have access to the list of all existing html templates by clicking
on the "View element descriptions" link in the websubmit admin right menu.<br>
By clicking on one of them, you will have access to its description.<br>
If no template corresponds to the one you seek, click on the "ADD NEW ELEMENT DESCRIPTION" button to
create one.<br>
&nbsp;<span class="guideheader">T</span>he fields you have to enter in the creation form are the one
described in the <a href="#edittemplate">Edit the html template of one form element</a> section.<br>
You also have to choose a name for this new element.<br>
<font color=red>IMPORTANT!</font> The name you choose for your html element is also the name of the file
in which webSubmit will save the value entered in this field. This is also the one you will use in your
"<a href=bibconvert.<lang:star: *>.html>bibConvert</a>" configuration. Bibconvert is the program which will
convert the data gathered in webSubmit in a formatted XML file for insertion in the documents database.
<br>
&nbsp;<span class="guideheader">T</span>ips:
<li>Elements of type "select box" which are used as a mandatory field in a form must start with "&lt;option&gt;Select:&lt;/option&gt;"
</BLOCKQUOTE>
<a name="addcheck"></a>
<h3>Create and edit a checking function.</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">C</span>lick on the "View Checks" link in the websubmit admin right menu.
You then have access to a list of all the defined javascript functions.<br>
You can then click on the name of the function you want to modify, or click on the "ADD NEW CHECK" button
to create a new javascript function.<br>
These functions are inserted in the web page when the user is doing his submission. When he clicks on
"next page", this function will be called with the value entered by the user as a parameter. If the function returns
false, the page does not change and an error message should be output. If the function returns true, everything
is correct, so page can be changed.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="implementfunctions.<lang:star: *>.html">create and maintain the data treatment</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/index.html.wml b/modules/websubmit/doc/admin/index.html.wml
index e4a60693e..7810453f5 100644
--- a/modules/websubmit/doc/admin/index.html.wml
+++ b/modules/websubmit/doc/admin/index.html.wml
@@ -1,75 +1,75 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="_(Guide)_" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<p>Version <: print generate_pretty_revision_date_string('$Id$'); :>
<h3>Table of Contents</STRONG></h3>
<UL>
<LI><B>Introduction</B>
<UL>
<LI><A HREF="introduction.<lang:star: *>.html">General Overview of the Manager Tool</A>
<LI><A HREF="example.<lang:star: *>.html">Using the manager through an example</A>
<LI><A HREF="philosophy.<lang:star: *>.html">Philosophy behind the document submission system</A>
</UL>
<LI><B>The Interface</B>
<UL>
<LI><A HREF="description.<lang:star: *>.html">Description</A>
</UL>
<LI><B><A HREF="documents.<lang:star: *>.html">Types of Document</A></B>
<UL>
<LI><A HREF="documentnew.<lang:star: *>.html">Add a New Type of Document</A>
<LI><A HREF="documentremove.<lang:star: *>.html">Remove a type of document</A>
<LI><A HREF="documentmodify.<lang:star: *>.html">Modify an Existing Type of Document</A>
</UL>
<LI><B><A HREF="actions.<lang:star: *>.html">Actions</A></B>
<UL>
<LI><A HREF="actionnew.<lang:star: *>.html">Add a New Action</A>
<LI><A HREF="actionremove.<lang:star: *>.html">Remove an Action</A>
<LI><A HREF="actionmodify.<lang:star: *>.html">Modify an Existing Action</A>
<LI><A HREF="actionimplement.<lang:star: *>.html">Implement an Action over a Document Type</A>
<UL>
<LI><A HREF="implementwebform.<lang:star: *>.html">Create and Maintain the Web Form</A>
<LI><A HREF="implementfunctions.<lang:star: *>.html">Create and Maintain the Data Treatment</A>
</UL>
</UL>
<LI><B><A HREF="functions.<lang:star: *>.html">Functions</A></B>
<UL>
<LI><A HREF="functionnew.<lang:star: *>.html">Create a New Function</A>
<LI><A HREF="functiondelete.<lang:star: *>.html">Remove a Function</A>
<LI><A HREF="functionedit.<lang:star: *>.html">Edit a Function</A>
<LI><A HREF="functiondescription.<lang:star: *>.html">All Functions Explained</A>
</UL>
<LI><B><A HREF="protection.<lang:star: *>.html">Protection</A></B>
<LI><B><A HREF="catalogues.<lang:star: *>.html">Catalogues Organisation</A></B>
<LI><B><A HREF="bibconvert.<lang:star: *>.html">bibConvert</A></B>
<LI><B>Notes</B>
<UL>
</UL>
<LI><B><A HREF="faq.<lang:star: *>.html">FAQ</a></B>
</UL>
diff --git a/modules/websubmit/doc/admin/introduction.html.wml b/modules/websubmit/doc/admin/introduction.html.wml
index d6b4988c7..f95931396 100644
--- a/modules/websubmit/doc/admin/introduction.html.wml
+++ b/modules/websubmit/doc/admin/introduction.html.wml
@@ -1,56 +1,56 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="General overview of the manager tool" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>Things to know before using the Manager:</h3>
<BLOCKQUOTE>
<UL>
&nbsp;<span class="guideheader">T</span>his manager tool allows you to administrate all the WebSubmit
interface. With it, you will be able to create new actions, new types of documents and edit the existing ones.
<br><br>
&nbsp;<span class="guideheader">T</span>he main objects in webSubmit are the "action" (such as
"Submit New Record", "Submit New File", "Modify Record"...) and the "type of document" (such as "preprint",
"photo"...).<br><br>
&nbsp;<span class="guideheader">T</span>o one given type of document can be attached several actions.
An action is the addition of two processes:
<UL>
<LI>The first one is the <a href="implementwebform.<lang:star: *>.html">data gathering</a>. The manager
will allow you to create new web forms corresponding to the fields the user will have to fill in when using
webSubmit.
<LI>The second one is the <a href="implementfunctions.<lang:star: *>.html">data treatement</a>.
Basically, what the program will do with the data gathered during the first phase. The treatment appears
in this tool as a sequence of functions. This manager will allow you to add functions to an action, edit the
existing functions, and reorder the functions.
</UL>
</UL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="example.<lang:star: *>.html">using the manager through an example</A><BR>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="actions.<lang:star: *>.html">actions</A><BR>
<li><A HREF="documents.<lang:star: *>.html">document types</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/philosophy.html.wml b/modules/websubmit/doc/admin/philosophy.html.wml
index b0e7e858a..0fa7e84a6 100644
--- a/modules/websubmit/doc/admin/philosophy.html.wml
+++ b/modules/websubmit/doc/admin/philosophy.html.wml
@@ -1,102 +1,102 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Philosophy behind the document submission system" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<p>This page will explain some philosophical issues behind the document submission system.
<h3>On the relation between a search collection and a submission doctype:</h3>
<BLOCKQUOTE>
<UL>
&nbsp;<span class="guideheader">T</span>he relation
between a search collection and a submission document
type may be prone to certain confusion for CDSware
administrators. This comes from the fact that there is
no one-to-one direct mapping between them, as is usual
elsewhere. The relation is more flexible than that.<br><br>
&nbsp;<span class="guideheader">A</span> search
collection in CDSware is defined through a search
query. For example, "all records where field F
contains the value V belong to collection C". Several
assertions can be deduced from this definition:<br>
&nbsp;1/ A single record can appear in several collections.<br>
&nbsp;2/ There is no limitation to the number of
collections in which a record can appear.<br>
&nbsp;3/ Any query can be used to build a
collection. The query can also be a complex one using
logical operators, hence can rely on the value of
several fields.<br><br>
&nbsp;(In addition, a search collection can be defined
via a set of its subcollections in the hierarchy tree.
Refer to the <a
href="<WEBURL>/admin/websearch/guide.html">WebSearch
Admin Guide</a> for that matter.)<br><br>
&nbsp;<span class="guideheader">T</span>he submission
system basically creates an XML MARC record and stores
it in the database. To which collection this new
record belongs depends exclusively on the content of
the XML MARC record. This XML MARC record is created
by the <a href="functiondescription.<lang:star:
*>.html#Make_Record">Make_Record</a> function. So the
secret of the matching of a submitted record to a
particular collection lies in the configuration of
this function. Some examples will clarify this
point:<br><br>
&nbsp;<span class="guideheader">E</span>xample 1:
Let's consider a "Preprints" collection which is
defined by this query: "980__a:PREPRINT". We want to
create a submission document type from which all
records will go to this "Preprints" collection. For
this, the Make_Record function should be configured so
that a 980__a field containing "PREPRINT" will always
be created.<br>
&nbsp;<span class="guideheader">E</span>xample 2:
Let's still consider the same "Preprints" collection,
and an additional "Theses" collection based on a
slightly different query "980__a:THESIS". We want to
create a single submission type from which the records
will go in the "Preprints" or "Theses" collections
depending on a field chosen by the submitter. In this
case, the Make_Record function should be configured so
that a 980__a field will contain either "PREPRINT" or
"THESIS" depending on the value entered by
the submitter.<br><br>
&nbsp;<span class="guideheader">T</span>he apparent
disconnection between a submission document type and a
search collection allows a great flexibility, allowing
administrators to create 1 to 1, 1 to n, n to 1 or
even 1 to 0 (not very useful!) relations.
</UL>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/admin/protection.html.wml b/modules/websubmit/doc/admin/protection.html.wml
index 47b72b745..fbe5d165d 100644
--- a/modules/websubmit/doc/admin/protection.html.wml
+++ b/modules/websubmit/doc/admin/protection.html.wml
@@ -1,43 +1,43 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Protection" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a> &gt; <a class=navtrail href=<lang:star: index.*.html>>_(Guide)_</a>" \
navbar_name="admin" \
navbar_select="websubmit-admin-guide"
<h3>Description:</h3>
<BLOCKQUOTE>
&nbsp;<span class="guideheader">I</span>n webSubmit, you can restrict the use of some actions on a given
document type to a list of users. You can use the <a href="<WEBURL>/admin/webaccess">webAccess</a>
manager for this.<br><br>
&nbsp;<span class="guideheader">L</span>et's say you want to restrict the submission of new TEXT documents
to a given user. You should then create a role in webAccess which will authorize the action "submit" over doctype
"TEXT" and act "SBI" (Submit new record). You can call this role "submitter_TEXT_SBI" for example.
Then link the role to the proper users.<br>
&nbsp;<span class="guideheader">A</span>nother example: if you wish to authorize a user to Modify the
bibliographic data of PICT documents, you have to create a role which authorize the action "submit" over doctype
"PICT" and act "MBI". This role can be called "submitter_PICT_MBI" or whatever you want.<br><br>
&nbsp;<span class="guideheader">I</span>f no role is defined for a given action and a given document type,
then all users will be allowed to use it.
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/approval.html.wml b/modules/websubmit/doc/approval.html.wml
index 2c4b755a3..89a7f3c53 100644
--- a/modules/websubmit/doc/approval.html.wml
+++ b/modules/websubmit/doc/approval.html.wml
@@ -1,43 +1,43 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Approval" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his action allows you to approve a document which has been submitted to
the document server. The request is usually sent to you through an email.
Once you have made your decision, you will also receive a confirmation email.<br><br>
<span class="guideheader">T</span>he document should appear on the
<A HREF="<WEBURL>/publiline.py">Documents Status list</A> and on your personal
<a href="approvals.<lang:star: *>.html">approvals page</a>.
There you will be able to send a new request if you lost the first one.
</BLOCKQUOTE>
<h3>Delay:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he document should appear in the server after you have approved it
before <b>1 day</b>. Past this delay, please <a href="mailto:<ADMINEMAIL>">contact us</a>.
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/approvals.html.wml b/modules/websubmit/doc/approvals.html.wml
index 301863800..c682ae498 100644
--- a/modules/websubmit/doc/approvals.html.wml
+++ b/modules/websubmit/doc/approvals.html.wml
@@ -1,43 +1,43 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="View List of refereed Documents" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his feature allows you to have access to the list of all the documents you are
a referee for. <br><br>
<span class="guideheader">T</span>o access this feature, you must first
<a href="login.<lang:star: *>.html">login</a>, then click on the "approvals" link in the personal panel:<br>
<IMG src="<WEBURL>/img/sbm_guide_approvals.png" class="guideimg" ALT=""><br>
This link will appear only if you currently referee at least one document.<br><br>
<span class="guideheader">B</span>y clicking on an item in this list, you can directly access the documents
you referee and start the approval process.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="login.<lang:star: *>.html">login mechanism</A><BR>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="password.<lang:star: *>.html">protection and passwords</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/bibliographic_fields.html.wml b/modules/websubmit/doc/bibliographic_fields.html.wml
index f9eb37861..8a274f1ee 100644
--- a/modules/websubmit/doc/bibliographic_fields.html.wml
+++ b/modules/websubmit/doc/bibliographic_fields.html.wml
@@ -1,53 +1,53 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Notes on Bibliographic Fields" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Authors:</h3>
<BLOCKQUOTE>
<span class="guideheader">I</span>f you have problem with authors, make sure you chose the right format
("Initial. Name" or "Name, Initial") and that the first part is ALWAYS followed by a white space. Make sure also
that you have entered one author per line. <B>Warning</B>! In all cases, an empty line in the list of authors can
result in an error. Be careful, and do not put an empty line for example at the end of the list.
</BLOCKQUOTE>
<h3>Special characters in Titles/Abstracts:</h3>
<BLOCKQUOTE>
<span class="guideheader">I</span>f your document is in TeX/LaTeX, do not forget to use the
"Copy&amp;Paste" option. You may need to use special characters, like accented characters or formula. Using
accented characters from your keyboard should not be a problem as the system is UTF-8 based. Anyway, you
should always check the quality and correctness of the information in your record once it has been
inserted in the database. If there is a problem, please <a href="mailto:<ADMINEMAIL>">contact us</a>.
</BLOCKQUOTE>
<h3>keywords:</h3>
<BLOCKQUOTE>
<span class="guideheader">M</span>ake sure you put one keyword per line in the input box. If you enter
"muon decay" on a single line and try to search for "muon" afterwards, the report will not be found, whereas
if you put "muon" on one line and "decay" on the next, your report will be found.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="submission.<lang:star: *>.html">submit new record</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/description.html.wml b/modules/websubmit/doc/description.html.wml
index 95acbb39e..ef6436cfd 100644
--- a/modules/websubmit/doc/description.html.wml
+++ b/modules/websubmit/doc/description.html.wml
@@ -1,67 +1,67 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Interface Description" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Interface:</h3>
<BLOCKQUOTE>
<span class="guideheader">H</span>ere is the description of the main CDS Submit interface:<BR>
<IMG src="<WEBURL>/img/sbm_guide_description.png" class="guideimg" ALT="">
<BR>
<span class="guideheader">T</span>his example shows the second page of the submission of a text document.
The user will have to fill all the fields ("language", "number of pages", "date of creation" and "keywords"), and
then click on the "next page" button to go to page 3. You can see here that this particular submission is
composed of 4 pages.
</BLOCKQUOTE>
<h3>Cancelling the action:</h3>
<BLOCKQUOTE>
<span class="guideheader">A</span>t any time, you can click the "main menu" button to cancel and leave the
submission. You will then be able to continue this submission if you want by using the "submissions" link in the
personal options panel:<br>
<IMG src="<WEBURL>/img/sbm_guide_submissions.png" class="guideimg" ALT="">
</BLOCKQUOTE>
<h3>Navigating through the pages:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>o go from one page to another, you can use the "previous page"/
"next page" buttons, or directly click on the page numbers at the top of the interface. Another solution to
navigate through the pages, is to open the summary window.
</BLOCKQUOTE>
<h3>Using the summary window:</h3>
<BLOCKQUOTE>
<span class="guideheader">B</span>y clicking the "SUMMARY" link, you can open the summary window for
the current action:<BR>
<IMG src="<WEBURL>/img/sbm_guide_summary.png" class="guideimg" ALT="" align="left">
<span class="guideheader">T</span>his window presents you the list of all the fields of the submission, together with
the values you already entered.<br><br>
<span class="guideheader">C</span>licking on one of the field names will bring you directly to the submission
page containing this field.<br><br><br><br><br><br><br><br>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="subnumber.<lang:star: *>.html">submission numbers</A><BR>
<li><A HREF="login.<lang:star: *>.html">login</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/file_transfer.html.wml b/modules/websubmit/doc/file_transfer.html.wml
index a1ddcc670..0db1283d9 100644
--- a/modules/websubmit/doc/file_transfer.html.wml
+++ b/modules/websubmit/doc/file_transfer.html.wml
@@ -1,74 +1,74 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Notes on File Transfers" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>File Formats:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he formats which are accepted in general are: PostScript (.ps), PDF (.pdf),
Word (.doc), Tex/LaTex (.tex). The prefered format is PDF. We have an automatic conversion process which
allows us to propose both PostScript and PDF online. The conversion PostScript<->PDF is made on-the-fly which
means the files are accesible as soon as the submission is finished. In general, <B>you should always check your
files (and the converted ones)</B> once you have finished the submission and your report as been integrated
in our database.
</BLOCKQUOTE>
<h3>Picture File Formats:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he prefered format for picture files is JPEG (preferably 144 dpi and not
a too small picture ~A4). We also accept PDF encapsulated pictures. In both case a gif icon is created on-the-fly
for every transfered picture.
</BLOCKQUOTE>
<h3>File Names:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he file names should not contain any white space, nor any special
characters.<BR>
<span class="guideheader">T</span>he extension of the file should be more or less standard (the check is
case-insensitive): .ps fo PostScript, .pdf for PDF etc.
</BLOCKQUOTE>
<h3>File Sizes:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he size of the files you transfer to us is controlled and restricted. If the
size of your file is too big, consider that somebody with a poor network connection will never be able to download
and thus read it. A possible solution in this case is to split your file into several chapters for example and transfer
the next chapters as <B> additional files</B>.
</BLOCKQUOTE>
<h3>File Uploads:</h3>
<BLOCKQUOTE>
<span class="guideheader">Y</span>ou always have to use the "browse" button when uploading a file. A dialog
box will then pop-up and you will be able to indicate your file. Then click on "OK", the dialog closes, and the path
to your file will appear in the input box, at the left of the button. The file will then be transfered the next time you
change page. <B>Please NEVER type the path to your file by hand in the input box!</B> If the path you typed in
is wrong, you will not notice it and the file will not be transfered. You avoid errors like this by using the "browse"
button.<br>
<img src="<WEBURL>/img/sbm_guide_browse.png" class="guideimg" alt="">
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="submission.<lang:star: *>.html">submit new record</A><BR>
<li><A HREF="revised_version.<lang:star: *>.html">submit new file</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/index.html.wml b/modules/websubmit/doc/index.html.wml
index 3ff9aec10..64930f232 100644
--- a/modules/websubmit/doc/index.html.wml
+++ b/modules/websubmit/doc/index.html.wml
@@ -1,58 +1,58 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="_(Submit Help)_" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a>"
<h3>Table of Contents</h3>
<UL>
<LI>Introduction
<UL>
<LI><A HREF="<lang:star: introduction.*.html>">Use and scope of the tool</A>
</UL>
<LI>The Interface
<UL>
<LI><A HREF="<lang:star: description.*.html>">Description</A>
<LI><A HREF="<lang:star: access.*.html>">Access pages</A>
<LI><A HREF="<lang:star: password.*.html>">Protection and passwords</A>
<LI><A HREF="<lang:star: subnumber.*.html>">Submission numbers</A>
<LI><A HREF="<lang:star: login.*.html>">Login</A>
<LI>Personal Services
<UL>
<LI><A HREF="<lang:star: pending.*.html>">View pending submissions</A>
<LI><A HREF="<lang:star: approvals.*.html>">View refereed documents</A>
</UL>
</UL>
<LI><A HREF="<lang:star: actions.*.html>">Actions</A>
<UL>
<LI><A HREF="<lang:star: submission.*.html>">Submit New Record</A>
<LI><A HREF="<lang:star: modification.*.html>">Modify Record</A>
<LI><A HREF="<lang:star: revised_version.*.html>">Submit New File</A></SMALL>
<LI><A HREF="<lang:star: approval.*.html>">Approve Record</A></SMALL>
</UL>
<LI>Notes
<UL>
<LI><A HREF="<lang:star: file_transfer.*.html>">Notes on file transfers</A>
<LI><A HREF="<lang:star: bibliographic_fields.*.html>">Notes on bibliographic fields</A>
</UL>
<LI>FAQ
</UL>
diff --git a/modules/websubmit/doc/introduction.html.wml b/modules/websubmit/doc/introduction.html.wml
index 613443a9e..d8cd56e7f 100644
--- a/modules/websubmit/doc/introduction.html.wml
+++ b/modules/websubmit/doc/introduction.html.wml
@@ -1,48 +1,48 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Introduction" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Please note:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his tool can be used on all platforms (Sun, Mac and PC), with all known
web browsers.
</BLOCKQUOTE>
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">C</span>DS Submit is the main entry point for all documents stored in
<a href="<WEBURL>"><CDSNAME></a>. But it is more than simply a submission tool...<br><br>
<span class="guideheader">T</span>his tool offers the opportunity to the users not only to submit a document
(of many possible types), but also allows different manipulations on these documents.<br><br>
<span class="guideheader">A</span>mong other possibilities, CDS Submit allows you to modify your documents,
submit revised versions, referee some documents, keep track of all the past submissions you did...
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="<lang:star: description.*.html>">interface description</A><BR>
<li><A HREF="<lang:star: actions.*.html>">actions</A><BR>
<li><A HREF="<lang:star: documents.*.html>">document types</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/login.html.wml b/modules/websubmit/doc/login.html.wml
index 42464ad9a..23d9100c6 100644
--- a/modules/websubmit/doc/login.html.wml
+++ b/modules/websubmit/doc/login.html.wml
@@ -1,58 +1,58 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Login" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">Y</span>ou have to login before using the tool. You should use your email address
as your user name. This strictly identifies a unique user, and if you loose or forget your password we will send it
to you at this email address.<br>
<IMG src="<WEBURL>/img/sbm_guide_login.png" class="guideimg" ALT=""><br>
<span class="guideheader">O</span>nce you are logged in, you will stay logged until you close your browser,
or explicitely request a logout.<br>
<IMG src="<WEBURL>/img/sbm_guide_logout.png" class="guideimg" ALT=""><br>
</BLOCKQUOTE>
<h3>Why a login mechanism?</h3>
<BLOCKQUOTE>
<span class="guideheader">A</span>s it ensures privacy, this login mechanism also allows us to offer new
personal services to you: <a href="pending.<lang:star: *>.html">access your pending submissions</a>, or the
<a href="approvals.<lang:star: *>.html">documents you referee</a> for example.
</BLOCKQUOTE>
<h3>Important note:</h3>
<BLOCKQUOTE>
<span class="guideheader">E</span>ven if an empty password is authorized, it would mean anybody could
potentially access your private services, so unless you don't mind this, choose a non empty password!
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="pending.<lang:star: *>.html">view pending submissions</A><BR>
<li><A HREF="completed.<lang:star: *>.html">view completed submissions</A><BR>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="password.<lang:star: *>.html">protection and passwords</A><BR>
<li><A HREF="subnumber.<lang:star: *>.html">submission numbers</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/modification.html.wml b/modules/websubmit/doc/modification.html.wml
index 97c6e0e30..4da22b2fb 100644
--- a/modules/websubmit/doc/modification.html.wml
+++ b/modules/websubmit/doc/modification.html.wml
@@ -1,55 +1,55 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Modify Record" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his action allows you, once you have submitted a document and it has
been integrated into this server, to modify the bibliographic information (title, authors...) you entered at submission
time.<BR><BR>
<span class="guideheader">Y</span>ou are proposed a list of fields that you can modify. You can select one
or several of these fields. The way of doing a multiple selection depends on the platform you are working on.
<BR>
For Netscape users:<BR>
<li>On MacOS: keep the "apple" key pressed while selectioning multiple fields.<BR>
<li>On Windows: keep the "control" key pressed<BR>
<li>On Linux/UNIX: simply click on several fields!<BR><BR>
<span class="guideheader">O</span>nce you have selected the fields and pressed the "finish selection"
button, input boxes will be displayed in which you will find the old values of the fields. You can then modify these
values, and don't forget to click on the "end submission" button once you have finished. Else your changes
will not be taken into account.<BR>
</BLOCKQUOTE>
<h3>Delay:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he maximum delay for taking into account a modification is <B>1 day</B>.
After this time, if you still do not notice any change, please <A HREF="<ADMINEMAIL>">contact us</A>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="revised_version.<lang:star: *>.html">submit new file</A><BR>
<li><A HREF="bibliographic_fields.<lang:star: *>.html">notes on the bibliographic fields</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/password.html.wml b/modules/websubmit/doc/password.html.wml
index e1813d86f..c1211c964 100644
--- a/modules/websubmit/doc/password.html.wml
+++ b/modules/websubmit/doc/password.html.wml
@@ -1,39 +1,39 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Protection and Passwords" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<BLOCKQUOTE>
<span class="guideheader">A</span>n action can be either open to anybody worldwide or restricted to some
users.<br><br>
<span class="guideheader">F</span>or a given document type, different actions can be protected differently.
If you need and do not have the access rights for an action, try contacting the <a href="mailto:<ADMINEMAIL>">
administrator</a>.<br><br>
<span class="guideheader">I</span>n any case you should login before using the tool:<br>
<IMG src="<WEBURL>/img/sbm_guide_login.png" class="guideimg" ALT="">
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="login.<lang:star: *>.html">login</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/pending.html.wml b/modules/websubmit/doc/pending.html.wml
index 0daa9b944..4cc148b5e 100644
--- a/modules/websubmit/doc/pending.html.wml
+++ b/modules/websubmit/doc/pending.html.wml
@@ -1,44 +1,44 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="View Pending Submissions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his feature allows you to have access to the list of all the actions you
started with the tool. <br><br>
<span class="guideheader">T</span>o access this feature, you must first
<a href="login.<lang:star: *>.html">login</a>, then click on the "submissions" link in the personal panel:<br>
<IMG src="<WEBURL>/img/sbm_guide_submissions.png" class="guideimg" ALT=""><br>
This link will appear only after you have first used the CDS Submit tool.<br><br>
<span class="guideheader">B</span>y clicking on an item in this list, you have the opportunity to complete this
action if it had not been finished.
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="login.<lang:star: *>.html">login mechanism</A><BR>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="password.<lang:star: *>.html">protection and passwords</A><BR>
<li><A HREF="subnumber.<lang:star: *>.html">submission numbers</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/revised_version.html.wml b/modules/websubmit/doc/revised_version.html.wml
index c531d6463..a31aa3226 100644
--- a/modules/websubmit/doc/revised_version.html.wml
+++ b/modules/websubmit/doc/revised_version.html.wml
@@ -1,46 +1,46 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Submit New File" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his action allows you, once you have submitted a paper and its
associated files, to submit a revision of the document or to add a new format of the document.<BR>
<span class="guideheader">T</span>he prefered format for the files are PostScript or PDF.<BR>
<span class="guideheader">T</span>he old version will still appear online with a version number appended to its name.<BR>
<span class="guideheader">F</span>inally, an email is sent to the original author to notify the change.</SMALL>
</BLOCKQUOTE>
<h3>Delay:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he revised version should appear online right after the end of its submission. If you still do not find the revised version online, please <A HREF="mailto:support@documents.cern.ch">contact us</A></SMALL>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE><SMALL>
<li><A HREF="modification.<lang:star: *>.html">modification of bibliographic information</A><BR>
<li><A HREF="file_transfer.<lang:star: *>.html">notes on file transfers</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/submission.html.wml b/modules/websubmit/doc/submission.html.wml
index b94441f5d..184234de6 100644
--- a/modules/websubmit/doc/submission.html.wml
+++ b/modules/websubmit/doc/submission.html.wml
@@ -1,58 +1,58 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Submit New Record" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<h3>Description:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>his action is used to submit a document (of any kind) to our server.
A submission is usually divided into several steps, which are:
<UL>
<LI><b>Submission of bibliographic information</b><br> in this part of the submission, which usually comes first
you are asked to enter bibliographic fields such as title, author, etc. When a special formatting is requested,
it is written in the notice and an automatic checking is applied. You are then asked to modify your entry when
it is mistyped.<BR><BR>
<LI><b>File Upload</B><BR>This should be used if your file is accessible from your local machine file system
(either the file is on your local disk, or it is reachable through a remote file system connection).
</UL>
</BLOCKQUOTE>
<h3>Important Notices:</h3>
<BLOCKQUOTE>
<LI>As documents will be available worldwide, only final versions - including all figures - should be submitted.
<LI>Users are encouraged to submit their papers in PDF rather than any other file formats.
</BLOCKQUOTE>
<h3>Delay:</h3>
<BLOCKQUOTE>
<span class="guideheader">T</span>he maximum delay between the end of a submission and the appearance
of the submitted document on the server is <B>1 day</B>. After this time, if you still do not find the document,
please <A HREF="mailto:<ADMINEMAIL>">contact us</A>
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="bibliographic_fields.<lang:star: *>.html">notes on the bibliographic fields</A><BR>
<li><A HREF="file_transfer.<lang:star: *>.html">notes on file transfers</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/doc/subnumber.html.wml b/modules/websubmit/doc/subnumber.html.wml
index 01b773dc7..d2b55243f 100644
--- a/modules/websubmit/doc/subnumber.html.wml
+++ b/modules/websubmit/doc/subnumber.html.wml
@@ -1,49 +1,49 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#include "configbis.wml"
#include "cdspage.wml" \
title="Submission Number" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/help/<lang:star: index.*.html>>_(Help Central)_</a> &gt; <a class=navtrail href=<WEBURL>/help/submit/<lang:star: index.*.html>>_(Submit Help)_</a>"
<BLOCKQUOTE>
<span class="guideheader">T</span>he submission numbers are used to uniquely identify a submission. When
you start a submission, you are given a submission number which appears at the bottom of the interface:<br>
<IMG src="<WEBURL>/img/sbm_guide_subnumber.png" class="guideimg" ALT=""><br>
<span class="guideheader">Y</span>ou can note this number at the beginning of the submission. If your browser
crashes during the submission (it happens!), you will be able to retrieve the data you had already entered using this
submission number.
In order to do so, please go to the access page of the proper type of document, enter the submission number
(also called "access number") at the bottom of the page and click on "go!":<br>
<IMG src="<WEBURL>/img/sbm_guide_accessnumber.png" class="guideimg" ALT=""><br>
If the system does not find your submission, make sure you are on the correct access page.<BR><BR>
<span class="guideheader">O</span>nce an action has been fully completed, you will not be able to use this
feature anymore.
<BR><BR>
<span class="guideheader">A</span>nother way of continuing a submission which was previously stopped is to use
the personal service "submissions" tool:<br>
<IMG src="<WEBURL>/img/sbm_guide_submissions.png" class="guideimg" ALT="">
</BLOCKQUOTE>
<h3>See also:</h3>
<BLOCKQUOTE>
<li><A HREF="description.<lang:star: *>.html">interface description</A><BR>
<li><A HREF="access.<lang:star: *>.html">access pages</A><BR>
<li><A HREF="pending.<lang:star: *>.html">pending submissions</A><BR>
</BLOCKQUOTE>
diff --git a/modules/websubmit/etc/Makefile.am b/modules/websubmit/etc/Makefile.am
index 26dee07a6..03fb9804b 100644
--- a/modules/websubmit/etc/Makefile.am
+++ b/modules/websubmit/etc/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = bibconvert
\ No newline at end of file
diff --git a/modules/websubmit/etc/bibconvert/KB/Makefile.am b/modules/websubmit/etc/bibconvert/KB/Makefile.am
index e44b0815b..b3d8dbc0b 100644
--- a/modules/websubmit/etc/bibconvert/KB/Makefile.am
+++ b/modules/websubmit/etc/bibconvert/KB/Makefile.am
@@ -1,25 +1,25 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir=$(sysconfdir)/bibconvert/KB
etc_DATA=Month.KB
EXTRA_DIST = $(etc_DATA)
CLEANFILES = *~ *.tmp
\ No newline at end of file
diff --git a/modules/websubmit/etc/bibconvert/Makefile.am b/modules/websubmit/etc/bibconvert/Makefile.am
index 17fd57c6f..7fb8b360e 100644
--- a/modules/websubmit/etc/bibconvert/Makefile.am
+++ b/modules/websubmit/etc/bibconvert/Makefile.am
@@ -1,20 +1,20 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = KB config
\ No newline at end of file
diff --git a/modules/websubmit/etc/bibconvert/config/Makefile.am b/modules/websubmit/etc/bibconvert/config/Makefile.am
index 828e79448..c7fe5a5e4 100644
--- a/modules/websubmit/etc/bibconvert/config/Makefile.am
+++ b/modules/websubmit/etc/bibconvert/config/Makefile.am
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
etcdir = $(sysconfdir)/bibconvert/config
etc_DATA = EDSPICT.tpl EDSPICTmodify.tpl EDSRPICT.tpl EDSRPICTmodify.tpl \
EDSRTEXT.tpl EDSRTEXTmodify.tpl EDSTEXT.tpl EDSTEXTmodify.tpl \
EDSPICTcreate.tpl EDSRPICTcreate.tpl EDSRTEXTcreate.tpl EDSTEXTcreate.tpl
EXTRA_DIST = EDSPICT.tpl EDSPICTmodify.tpl EDSRPICT.tpl EDSRPICTmodify.tpl \
EDSRTEXT.tpl EDSRTEXTmodify.tpl EDSTEXT.tpl EDSTEXTmodify.tpl \
EDSPICTcreate.tpl.in EDSRPICTcreate.tpl.in EDSRTEXTcreate.tpl.in EDSTEXTcreate.tpl.in
CLEANFILES = *~ *.tmp
diff --git a/modules/websubmit/lib/Makefile.am b/modules/websubmit/lib/Makefile.am
index ba54ffc51..02dcea367 100644
--- a/modules/websubmit/lib/Makefile.am
+++ b/modules/websubmit/lib/Makefile.am
@@ -1,33 +1,33 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = functions
pylibdir = $(libdir)/python/cdsware
pylib_DATA = websubmit_config.py websubmit_engine.py file.py \
websubmit_templates.py \
websubmitadmin_config.py \
websubmitadmin_dblayer.py \
websubmitadmin_engine.py \
websubmitadmin_templates.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/websubmit/lib/file.py b/modules/websubmit/lib/file.py
index 3ad955781..d7353b492 100644
--- a/modules/websubmit/lib/file.py
+++ b/modules/websubmit/lib/file.py
@@ -1,551 +1,551 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
import mimetypes
import shutil
import md5
import urllib
from xml.sax.saxutils import quoteattr
from mod_python import apache
from cdsware.config import *
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email
from cdsware.dbquery import run_sql
from cdsware.websubmit_config import *
from cdsware.messages import gettext_set_language
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
archivepath = filedir
archivesize = filedirsize
# sort compressed file extensions list to get lengthy ones first:
cfg_compressed_file_extensions_sorted = cfg_compressed_file_extensions
cfg_compressed_file_extensions_sorted.sort()
class BibRecDocs:
"""this class represents all the files attached to one record"""
def __init__(self,recid):
self.id = recid
self.bibdocs = []
self.buildBibDocList()
def buildBibDocList(self):
self.bibdocs = []
res = run_sql("select id_bibdoc,type from bibrec_bibdoc,bibdoc where id=id_bibdoc and id_bibrec=%s and status!='deleted'", (self.id,))
for row in res:
self.bibdocs.append(BibDoc(bibdocid=row[0],recid=self.id))
def listBibDocs(self,type=""):
tmp=[]
for bibdoc in self.bibdocs:
if type=="" or type == bibdoc.getType():
tmp.append(bibdoc)
return tmp
def getBibDocNames(self,type="Main"):
names = []
for bibdoc in self.listBibDocs(type):
names.append(bibdoc.getDocName())
return names
def getBibDoc(self,bibdocid):
for bibdoc in self.bibdocs:
if bibdoc.getId() == bibdocid:
return bibdoc
return None
def deleteBibDoc(self,bibdocid):
for bibdoc in self.bibdocs:
if bibdoc.getId() == bibdocid:
bibdoc.delete()
self.buildBibDocList()
def addBibDoc(self,type="Main",docname="file"):
while docname in self.getBibDocNames(type):
match = re.match("(.*_)([^_]*)",docname)
if match:
try:
docname = match.group(1)+str(int(match.group(2)) + 1)
except:
docname = docname + "_2"
else:
docname = docname + "_2"
bibdoc = BibDoc(recid=self.id,type=type,docname=docname)
if bibdoc != None:
self.bibdocs.append(bibdoc)
return bibdoc
def addNewFile(self,fullpath,type="Main"):
filename = re.sub("\..*","",re.sub(r".*[\\/:]", "", fullpath))
bibdoc = self.addBibDoc(type,filename)
if bibdoc != None:
bibdoc.addFilesNewVersion(files=[fullpath])
return bibdoc
return None
def addNewVersion(self,fullpath,bibdocid):
bibdoc = self.getBibDoc(bibdocid)
if bibdoc != None:
bibdoc.addFilesNewVersion(files=[fullpath])
docname = re.sub("\..*","",re.sub(r".*[\\/:]", "", fullpath))
if docname != bibdoc.getDocName():
while docname in self.getBibDocNames(bibdoc.getType()):
match = re.match("(.*_)([^_]*)",docname)
if match:
try:
docname = match.group(1)+str(int(match.group(2)) + 1)
except:
docname = docname + "_2"
else:
docname = docname + "_2"
bibdoc.changeName(docname)
return bibdoc
return None
def addNewFormat(self,fullpath,bibdocid):
bibdoc = self.getBibDoc(bibdocid)
if bibdoc != None:
bibdoc.addFilesNewFormat(files=[fullpath])
return bibdoc
return None
def listLatestFiles(self,type=""):
docfiles = []
for bibdoc in self.listBibDocs(type):
for docfile in bibdoc.listLatestFiles():
docfiles.append(docfile)
return docfiles
def checkFileExists(self,fullpath,type=""):
if os.path.exists(fullpath):
docfiles = self.listLatestFiles(type)
for docfile in docfiles:
if md5.new(readfile(fullpath)).digest() == md5.new(readfile(docfile.getPath())).digest():
return docfile.getBibDocId()
else:
return 0
def display(self,bibdocid="",version="",type="", ln = cdslang):
t=""
bibdocs = []
if bibdocid!="":
for bibdoc in self.bibdocs:
if bibdoc.getId() == bibdocid:
bibdocs.append(bibdoc)
else:
bibdocs = self.listBibDocs(type)
if len(bibdocs) > 0:
types = listTypesFromArray(bibdocs)
fulltypes = []
for mytype in types:
fulltype = {
'name' : mytype,
'content' : [],
}
for bibdoc in bibdocs:
if mytype == bibdoc.getType():
fulltype['content'].append(bibdoc.display(version, ln = ln))
fulltypes.append(fulltype)
t = websubmit_templates.tmpl_bibrecdoc_filelist(
ln = ln,
types = fulltypes,
)
return t
class BibDoc:
"""this class represents one file attached to a record
there is a one to one mapping between an instance of this class and
an entry in the bibdoc db table"""
def __init__ (self,bibdocid="",recid="",docname="file",type="Main"):
# bibdocid is known, the document already exists
if bibdocid != "":
if recid == "":
res = run_sql("select id_bibrec,type from bibrec_bibdoc where id_bibdoc=%s",(bibdocid,))
if len(res) > 0:
recid = res[0][0]
self.type = res[0][1]
else:
recid = None
self.type = ""
else:
res = run_sql("select type from bibrec_bibdoc where id_bibrec=%s and id_bibdoc=%s",(recid,bibdocid,))
self.type = res[0][0]
# gather the other information
res = run_sql("select * from bibdoc where id=%s", (bibdocid,))
self.cd = res[0][3]
self.md = res[0][4]
self.recid = recid
self.docname = res[0][2]
self.id = bibdocid
group = "g"+str(int(int(self.id)/archivesize))
self.basedir = "%s/%s/%s" % (archivepath,group,self.id)
# else it is a new document
else:
if docname == "" or type == "":
return None
else:
self.recid = recid
self.type = type
self.docname = docname
self.id = run_sql("insert into bibdoc (docname,creation_date,modification_date) values(%s,NOW(),NOW())", (docname,))
if self.id != None:
#we link the document to the record if a recid was specified
if self.recid != "":
run_sql("insert into bibrec_bibdoc values(%s,%s,%s)", (recid,self.id,self.type,))
else:
return None
group = "g"+str(int(int(self.id)/archivesize))
self.basedir = "%s/%s/%s" % (archivepath,group,self.id)
# we create the corresponding storage directory
if not os.path.exists(self.basedir):
os.makedirs(self.basedir)
# and save the father record id if it exists
if self.recid!="":
fp = open("%s/.recid" % self.basedir,"w")
fp.write(str(self.recid))
fp.close()
# build list of attached files
self.docfiles = {}
self.BuildFileList()
# link with relatedFiles
self.relatedFiles = {}
self.BuildRelatedFileList()
def addFilesNewVersion(self,files=[]):
"""add a new version of a file to an archive"""
latestVersion = self.getLatestVersion()
if latestVersion == "0":
myversion = "1"
else:
myversion = str(int(latestVersion)+1)
for file in files:
if os.path.exists(file):
filename = re.sub(r".*[\\/:]", "", file)
shutil.copy(file,"%s/%s;%s" % (self.basedir,filename,myversion))
self.BuildFileList()
def addFilesNewFormat(self,files=[],version=""):
"""add a new format of a file to an archive"""
if version == "":
version = self.getLatestVersion()
for file in files:
if os.path.exists(file):
filename = re.sub(r".*[\\/:]", "", file)
shutil.copy(file,"%s/%s;%s" % (self.basedir,filename,version))
self.BuildFileList()
def getIcon(self):
if self.relatedFiles.has_key('Icon'):
return self.relatedFiles['Icon'][0]
else:
return None
def addIcon(self,file):
"""link an icon with the bibdoc object"""
#first check if an icon already exists
existingIcon = self.getIcon()
if existingIcon != None:
existingIcon.delete()
#then add the new one
filename = re.sub("\..*","",re.sub(r".*[\\/:]", "", file))
newicon = BibDoc(type='Icon',docname=filename)
if newicon != None:
newicon.addFilesNewVersion(files=[file])
run_sql("insert into bibdoc_bibdoc values(%s,%s,'Icon')", (self.id,newicon.getId(),))
if os.path.exists(newicon.getBaseDir()):
fp = open("%s/.docid" % newicon.getBaseDir(),"w")
fp.write(str(self.id))
fp.close()
self.BuildRelatedFileList()
def deleteIcon(self):
existingIcon = self.getIcon()
if existingIcon != None:
existingIcon.delete()
self.BuildRelatedFileList()
def display(self,version="", ln = cdslang):
t=""
if version == "all":
docfiles = self.listAllFiles()
elif version != "":
docfiles = self.listVersionFiles(version)
else:
docfiles = self.listLatestFiles()
existingIcon = self.getIcon()
if existingIcon != None:
imagepath = "%s/getfile.py?docid=%s&name=%s&format=gif" % (weburl,existingIcon.getId(),urllib.quote(existingIcon.getDocName()))
else:
imagepath = "%s/smallfiles.gif" % images
versions = []
for version in listVersionsFromArray(docfiles):
currversion = {
'version' : version,
'previous' : 0,
'content' : []
}
if version == self.getLatestVersion() and version != "1":
currversion['previous'] = 1
for docfile in docfiles:
if docfile.getVersion() == version:
currversion['content'].append(docfile.display(ln = ln))
versions.append(currversion)
t = websubmit_templates.tmpl_bibdoc_filelist(
ln = ln,
weburl = weburl,
versions = versions,
imagepath = imagepath,
docname = self.docname,
id = self.id,
)
return t
def changeName(self,newname):
run_sql("update bibdoc set docname=%s where id=%s",(newname,self.id,))
self.docname = newname
def getDocName(self):
"""retrieve bibdoc name"""
return self.docname
def getBaseDir(self):
"""retrieve bibdoc base directory"""
return self.basedir
def getType(self):
"""retrieve bibdoc type"""
return self.type
def getRecid(self):
"""retrieve bibdoc recid"""
return self.recid
def getId(self):
"""retrieve bibdoc id"""
return self.id
def getFile(self,name,format,version):
if version == "":
docfiles = self.listLatestFiles()
else:
docfiles = self.listVersionFiles(version)
for docfile in docfiles:
if docfile.getName()==name and docfile.getFormat()==format:
return docfile
return None
def listVersions(self):
versions = []
for docfile in self.docfiles:
if not docfile.getVersion() in versions:
versions.append(docfile.getVersion())
return versions
def delete(self):
"""delete the current bibdoc instance"""
run_sql("update bibdoc set status='deleted' where id=%s",(self.id,))
def BuildFileList(self):
"""lists all files attached to the bibdoc"""
self.docfiles = []
if os.path.exists(self.basedir):
for fil in os.listdir(self.basedir):
if fil != ".recid" and fil != ".docid" and fil != "." and fil != "..":
filepath = "%s/%s" % (self.basedir,fil)
fileversion = re.sub(".*;","",fil)
fullname = fil.replace(";%s" % fileversion,"")
# detect fullname's basename and extension:
fullname_lowercase = fullname.lower()
fullname_extension_postition = -1
# first try to detect compressed file extensions:
for compressed_file_extension in cfg_compressed_file_extensions_sorted:
if fullname_lowercase.endswith("." + compressed_file_extension):
fullname_extension_postition = fullname[:-len(compressed_file_extension)-1].rfind(".")
break
if fullname_extension_postition == -1:
# okay, no compressed extension found, so try to find last dot:
fullname_extension_postition = fullname.rfind(".")
# okay, fullname_extension_postition should now indicate where extension starts (incl. compressed ones)
if fullname_extension_postition == -1:
fullname_basename = fullname
fullname_extension = ""
else:
fullname_basename = fullname[:fullname_extension_postition]
fullname_extension = fullname[fullname_extension_postition+1:]
# we can append file:
self.docfiles.append(BibDocFile(filepath,self.type,fileversion,fullname_basename,fullname_extension,self.id))
def BuildRelatedFileList(self):
res = run_sql("select ln.id_bibdoc2,ln.type from bibdoc_bibdoc as ln,bibdoc where id=ln.id_bibdoc2 and ln.id_bibdoc1=%s and status!='deleted'",(self.id,))
for row in res:
bibdocid = row[0]
type = row[1]
if not self.relatedFiles.has_key(type):
self.relatedFiles[type] = []
self.relatedFiles[type].append(BibDoc(bibdocid=bibdocid))
def listAllFiles(self):
return self.docfiles
def listLatestFiles(self):
return self.listVersionFiles(self.getLatestVersion())
def listVersionFiles(self,version):
tmp = []
for docfile in self.docfiles:
if docfile.getVersion() == version:
tmp.append(docfile)
return tmp
def getLatestVersion(self):
if len(self.docfiles) > 0:
self.docfiles.sort(orderFilesWithVersion)
return self.docfiles[0].getVersion()
else:
return 0
def getFileNumber(self):
return len(self.files)
def registerDownload(self,addressIp,version,format,userid=0):
return run_sql("INSERT INTO rnkDOWNLOADS (id_bibrec,id_bibdoc,file_version,file_format,id_user,client_host,download_time) VALUES (%s,%s,%s,%s,%s,INET_ATON(%s),NOW())",
(self.recid,self.id,version,string.upper(format),userid,addressIp,))
class BibDocFile:
"""this class represents a physical file in the CDSware filesystem"""
def __init__(self,fullpath,type,version,name,format,bibdocid):
self.fullpath = fullpath
self.type = type
self.bibdocid = bibdocid
self.version = version
self.size = os.path.getsize(fullpath)
self.md = os.path.getmtime(fullpath)
try:
self.cd = os.path.getctime(fullpath)
except:
self.cd = self.md
self.name = name
self.format = format
self.dir = os.path.dirname(fullpath)
if format == "":
self.mime = "text/plain"
self.encoding = ""
self.fullname = name
else:
self.fullname = "%s.%s" % (name,format)
(self.mime,self.encoding) = mimetypes.guess_type(self.fullname)
if self.mime == None:
self.mime = "text/plain"
def display(self, ln = cdslang):
if self.format != "":
format = ".%s" % self.format
else:
format = ""
return websubmit_templates.tmpl_bibdocfile_filelist(
ln = ln,
weburl = weburl,
id = self.bibdocid,
selfformat = self.format,
version = self.version,
name = self.name,
format = format,
size = self.size,
)
def getType(self):
return self.type
def getPath(self):
return self.fullpath
def getBibDocId(self):
return self.bibdocid
def getName(self):
return self.name
def getFormat(self):
return self.format
def getSize(self):
return self.size
def getVersion(self):
return self.version
def getRecid(self):
return run_sql("select id_bibrec from bibrec_bibdoc where id_bibdoc=%s",(self.bibdocid,))[0][0]
def stream(self,req):
if os.path.exists(self.fullpath):
req.content_type = self.mime
req.encoding = self.encoding
req.filename = self.fullname
req.headers_out["Content-Disposition"] = "file; filename=%s" % quoteattr(self.fullname)
req.send_http_header()
fp = file(self.fullpath,"r")
content = fp.read()
fp.close()
return content
def readfile(path):
if os.path.exists(path):
fp = open(path,"r")
content = fp.read()
fp.close()
return content
def listTypesFromArray(bibdocs):
types = []
for bibdoc in bibdocs:
if not bibdoc.getType() in types:
types.append(bibdoc.getType())
return types
def listVersionsFromArray(docfiles):
versions = []
for docfile in docfiles:
if not docfile.getVersion() in versions:
versions.append(docfile.getVersion())
return versions
def orderFilesWithVersion(docfile1,docfile2):
"""order docfile objects according to their version"""
version1 = int(docfile1.getVersion())
version2 = int(docfile2.getVersion())
return cmp(version2,version1)
diff --git a/modules/websubmit/lib/functions/Add_Files.py b/modules/websubmit/lib/functions/Add_Files.py
index 3e6aca305..ffab79206 100644
--- a/modules/websubmit/lib/functions/Add_Files.py
+++ b/modules/websubmit/lib/functions/Add_Files.py
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.file import *
def Add_Files(parameters,curdir,form):
if os.path.exists("%s/files" % curdir):
bibrecdocs = BibRecDocs(sysno)
for file in os.listdir("%s/files" % curdir):
fullpath = "%s/files/%s" % (curdir,file)
bibdoc = None
if not bibrecdocs.checkFileExists(fullpath,"Main"):
bibdoc = bibrecdocs.addNewFile(fullpath,"Main")
return ""
diff --git a/modules/websubmit/lib/functions/CaseEDS.py b/modules/websubmit/lib/functions/CaseEDS.py
index 11266b232..16f185882 100644
--- a/modules/websubmit/lib/functions/CaseEDS.py
+++ b/modules/websubmit/lib/functions/CaseEDS.py
@@ -1,63 +1,63 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function CaseEDS
## This function compares the content of a file to different
## values and directly goes to a different step in the action
## according to the value.
## Author: T.Baron
## PARAMETERS: casevariable: name of the file containing the value
## casevalues: comma-separated list of values
## casesteps: comma-separated list of steps
## casedefault: default step if no value is mapped
def CaseEDS(parameters,curdir,form):
casevariable = parameters['casevariable']
casevalue = parameters['casevalues']
casevalues = casevalue.split(",")
casestep = parameters['casesteps']
casesteps = casestep.split(",")
cases = {}
for a, b in map(None, casevalues, casesteps):
cases[a] = b
casedefault = parameters['casedefault']
nextstep = ""
if not os.path.exists("%s/%s" % (curdir,casevariable)):
nextstep = casedefault
else:
fp = open("%s/%s" % (curdir,casevariable), "r")
value = fp.read()
fp.close()
if cases.has_key(value):
nextstep = cases[value]
else:
nextstep = casedefault
if nextstep != "":
t="<b>Please wait...</b>"
t ="""
<SCRIPT LANGUAGE="JavaScript1.1">
document.forms[0].action="submit.py";
document.forms[0].step.value=%s;
document.forms[0].submit();
</SCRIPT>""" % nextstep
raise functionStop(t)
else:
raise functionError("Case function: Could not determine next action step")
return ""
diff --git a/modules/websubmit/lib/functions/Create_Modify_Interface.py b/modules/websubmit/lib/functions/Create_Modify_Interface.py
index 2d29634d3..b4b38f7a9 100644
--- a/modules/websubmit/lib/functions/Create_Modify_Interface.py
+++ b/modules/websubmit/lib/functions/Create_Modify_Interface.py
@@ -1,191 +1,191 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Create_Modify_Interface
## This function creates the html form allowing the user to
## some bibliographic fields
## Author: T.Baron
## PARAMETERS: fieldnameMBI: name of the file containing the
## "+"-separated list of fields to modify
execfile("%s/cdsware/websubmit_functions/Retrieve_Data.py" % pylibdir)
import re,os
def Create_Modify_Interface_getfieldval_fromfile(cur_dir, fld=""):
"""Read a field's value from its corresponding text file in 'cur_dir' (if it exists) into memory.
Delete the text file after having read-in its value.
This function is called on the reload of the modify-record page. This way, the field in question
can be populated with the value last entered by the user (before reload), instead of always being
populated with the value still found in the DB.
"""
fld_val = ""
if len(fld) > 0 and os.access("%s/%s" % (cur_dir,fld), os.R_OK|os.W_OK):
fp = open( "%s/%s" % (cur_dir,fld), "r" )
fld_val = fp.read()
fp.close()
try:
os.unlink("%s/%s"%(cur_dir,fld))
except OSError:
# Cannot unlink file - ignore, let websubmit main deal with this
pass
fld_val = fld_val.strip()
return fld_val
def Create_Modify_Interface_getfieldval_fromDBrec(fieldcode, recid):
"""Read a field's value from the record stored in the DB.
This function is called when the Create_Modify_Interface function is called for the first time
when modifying a given record, and field values must be retrieved from the database.
"""
fld_val = ""
if fieldcode != "":
fld_val = Get_Field(fieldcode,recid)
return fld_val
def Create_Modify_Interface_transform_date(fld_val):
"""Accept a field's value as a string. If the value is a date in one of the following formats:
DD Mon YYYY (e.g. 23 Apr 2005)
YYYY-MM-DD (e.g. 2005-04-23)
...transform this date value into "DD/MM/YYYY" (e.g. 23/04/2005).
"""
if re.search("^[0-9]{2} [a-z]{3} [0-9]{4}$",fld_val,re.IGNORECASE) is not None:
try:
fld_val = time.strftime("%d/%m/%Y",time.strptime(fld_val,"%d %b %Y"))
except (ValueError,TypeError):
# bad date format:
pass
elif re.search("^[0-9]{4}-[0-9]{2}-[0-9]{2}$",fld_val,re.IGNORECASE) is not None:
try:
fld_val = time.strftime("%d/%m/%Y",time.strptime(fld_val,"%Y-%m-%d"))
except (ValueError,TypeError):
# bad date format:
pass
return fld_val
def Create_Modify_Interface(parameters,curdir,form):
"""Create an interface for the modification of a document, based on the fields that the user has
chosen to modify
"""
global sysno,rn
t=""
# variables declaration
fieldname = parameters['fieldnameMBI']
# Path of file containing fields to modify
if os.path.exists("%s/%s" % (curdir,fieldname)):
fp = open( "%s/%s" % (curdir,fieldname), "r" )
fieldstext = fp.read()
fp.close()
else:
raise functionError("cannot find fields to modify")
fieldstext = re.sub("\+","\n",fieldstext)
fields = fieldstext.split("\n")
#output some text
t=t+"<CENTER bgcolor=\"white\">The document <B>%s</B> has been found in the database.</CENTER><BR>Please modify the following fields:<BR>Then press the 'END' button at the bottom of the page<BR>\n" % rn
for field in fields:
subfield = ""
value = ""
marccode = ""
text = ""
# retrieve and display the modification text
t=t+"<FONT color=\"darkblue\">\n"
res = run_sql("SELECT modifytext FROM sbmFIELDDESC WHERE name=%s", (field,))
if len(res)>0:
t=t+"<small>%s</small> </FONT>\n" % res[0][0]
# retrieve the marc code associated with the field
res = run_sql("SELECT marccode FROM sbmFIELDDESC WHERE name=%s", (field,))
if len(res) > 0:
marccode = res[0][0]
# then retrieve the previous value of the field
if os.path.exists("%s/%s" % (curdir,"Create_Modify_Interface_DONE")):
# Page has been reloaded - get field value from text file on server, not from DB record
value = Create_Modify_Interface_getfieldval_fromfile(curdir,field)
else:
# First call to page - get field value from DB record
value = Create_Modify_Interface_getfieldval_fromDBrec(marccode, sysno)
# If field is a date value, transform date into format DD/MM/YYYY:
value = Create_Modify_Interface_transform_date(value)
res = run_sql("SELECT * FROM sbmFIELDDESC WHERE name=%s", (field,))
if len(res) > 0:
type = res[0][3]
numcols = res[0][6]
numrows = res[0][5]
size = res[0][4]
maxlength = res[0][7]
val = res[0][8]
fidesc = res[0][9]
if type == "T":
text="<TEXTAREA name=\"%s\" rows=%s cols=%s wrap>%s</TEXTAREA>" % (field,numrows,numcols,value)
elif type == "F":
text="<INPUT TYPE=\"file\" name=\"%s\" size=%s maxlength=%s>" % (field,size,maxlength)
elif type == "I":
# JY correction, 15.6.01
value = re.sub("[\n\r\t]+","",value)
text="<INPUT name=\"%s\" size=%s value=\"%s\"> " % (field,size,val)
text= text + "<SCRIPT>document.forms[0].%s.value=\"%s\";</SCRIPT>" % (field,value)
elif type == "H":
text="<INPUT type=\"hidden\" name=\"%s\" value=\"%s\">" % (field,val)
text=text+"<SCRIPT>document.forms[0].%s.value=\"%s\";</SCRIPT>" % (field,value)
elif type == "S":
values = re.split("[\n\r]+",value)
text=fidesc
if re.search("%s\[\]" % field,fidesc):
multipletext = "[]"
else:
multipletext = ""
if len(values) > 0 and not(len(values) == 1 and values[0] == ""):
text += "<SCRIPT>\n"
text += "var i = 0;\n"
text += "el = document.forms[0].elements['%s%s'];\n" % (field,multipletext)
text += "max = el.length;\n"
for val in values:
text += "var found = 0;\n"
text += "var i=0;\n"
text += "while (i != max) {\n"
text += " if (el.options[i].value == \"%s\" || el.options[i].text == \"%s\") {\n" % (val,val)
text += " el.options[i].selected = true;\n"
text += " found = 1;\n"
text += " }\n"
text += " i=i+1;\n"
text += "}\n"
#text += "if (found == 0) {\n"
#text += " el[el.length] = new Option(\"%s\", \"%s\", 1,1);\n"
#text += "}\n"
text += "</SCRIPT>\n"
elif type == "D":
text=fidesc
elif type == "R":
co = compile(fidesc.replace("\r\n","\n"),"<string>","exec")
exec(co)
else:
text="%s: unknown field type" % field
t = t+"<small>%s</small>" % text
# output some more text
t=t+"<BR><BR><CENTER><small><INPUT type=\"button\" width=400 height=50 name=\"End\" value=\"END\" onClick=\"document.forms[0].step.value = 2;document.forms[0].submit();\"></small></CENTER></H4>"
# Flag File to be written if first call to page, which tells function that if page is reloaded,
# it should get field values from text files in curdir, instead of from DB record:
if not os.path.exists("%s/%s" % (curdir,"Create_Modify_Interface_DONE")):
# Write flag file:
try:
fp = open( "%s/%s" % (curdir,"Create_Modify_Interface_DONE"), "w")
fp.write("DONE\n")
fp.flush()
fp.close()
except IOError, e:
# Can't open flag file for writing
pass
return t
diff --git a/modules/websubmit/lib/functions/Create_Recid.py b/modules/websubmit/lib/functions/Create_Recid.py
index c5c48912b..adfe80130 100644
--- a/modules/websubmit/lib/functions/Create_Recid.py
+++ b/modules/websubmit/lib/functions/Create_Recid.py
@@ -1,32 +1,32 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
def Create_Recid(parameters,curdir,form):
global sysno
if not os.path.exists("%s/SN" % curdir):
recid = run_sql("insert into bibrec (creation_date,modification_date) values(NOW(),NOW())")
fp = open("%s/SN" % curdir,"w")
fp.write(str(recid))
sysno = recid
else:
fp = open("%s/SN" % curdir,"r")
sysno = fp.read()
fp.close()
return ""
diff --git a/modules/websubmit/lib/functions/Finish_Submission.py b/modules/websubmit/lib/functions/Finish_Submission.py
index ac1706aa9..15fa4ab19 100644
--- a/modules/websubmit/lib/functions/Finish_Submission.py
+++ b/modules/websubmit/lib/functions/Finish_Submission.py
@@ -1,36 +1,36 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
##
## Name: Finish_Submission
## Description: function Finish_Submission
## This function sets some global variables so that even if
## we are not in the last step of an action, the action stops
## anyway.
## Author: T.Baron
## PARAMETERS: -
## OUTPUT: HTML
##
def Finish_Submission(parameters,curdir,form):
global last_step,action_score
last_step = 1
action_score = "-1"
return ""
diff --git a/modules/websubmit/lib/functions/Format_Record.py b/modules/websubmit/lib/functions/Format_Record.py
index ebe9f193f..f611eb8f3 100644
--- a/modules/websubmit/lib/functions/Format_Record.py
+++ b/modules/websubmit/lib/functions/Format_Record.py
@@ -1,21 +1,21 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
def Format_Record(parameters,curdir,form):
os.system("%s < %s/recmysql > %s/recmysqlfmt" % (bibformat,curdir,curdir))
return ""
diff --git a/modules/websubmit/lib/functions/Get_Info.py b/modules/websubmit/lib/functions/Get_Info.py
index dd1c0ba71..d20c7016d 100644
--- a/modules/websubmit/lib/functions/Get_Info.py
+++ b/modules/websubmit/lib/functions/Get_Info.py
@@ -1,100 +1,100 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
##
## Name: Get_Info.py
## Description: function Get_Info
## This function retrieves some bibliographic data (title,
## submitter email, author and sets global variables with
## the values, so that other functions may use them.
## Author: T.Baron
## PARAMETERS: authorFile: name of the file in which the author is stored
## emailFile: name of the file in which the email is stored
## titleFile: name of the file in which the title is stored
## OUTPUT: HTML
##
execfile("%s/cdsware/websubmit_functions/Retrieve_Data.py" % pylibdir)
titlevalue = ""
emailvalue = ""
authorvalue = ""
def Get_Info(parameters,curdir,form):
global titlevalue,emailvalue,authorvalue,rn
doctype = form['doctype']
titlefile = parameters["titleFile"]
emailfile = parameters["emailFile"]
authorfile = parameters["authorFile"]
if not Get_Info_In_Curdir(rn,titlefile,emailfile,authorfile,doctype):
if not Get_Info_In_DB(rn,parameters,curdir):
DocumentNotFound(rn)
return ""
def Get_Info_In_Curdir(repno,titlefile,emailfile,authorfile,doctype):
global titlevalue,emailvalue,authorvalue
if not os.path.exists("%s/%s" % (curdir,titlefile)):
return 0
else:
if os.path.exists("%s/%s" % (curdir,titlefile)):
fp = open("%s/%s" % (curdir,titlefile),"r")
titlevalue = fp.read()
fp.close()
else :
titlevalue = "-"
if os.path.exists("%s/%s" % (curdir,emailfile)):
fp = open("%s/%s" % (curdir,emailfile),"r")
emailvalue = fp.read()
fp.close()
else :
emailvalue = "-"
if os.path.exists("%s/%s" % (curdir,authorfile)):
fp = open("%s/%s" % (curdir,authorfile),"r")
authorvalue = fp.read()
fp.close()
else :
authorvalue = "-"
return 1
def Get_Info_In_DB(rn,parameters,curdir):
global titlevalue,emailvalue,authorvalue,sysno
if sysno != "":
titlevalue = Get_Field('245__a',sysno)
emailvalue = Get_Field('8560_f',sysno)
authorvalue = Get_Field('100__a',sysno)
authorvalue += "\n%s" % Get_Field('700__a',sysno)
# save result
fp = open("%s/SN" % curdir,"w")
fp.write(sysno)
fp.close()
return 1
else:
return 0
def DocumentNotFound(repno):
raise functionStop("""
<SCRIPT>
document.forms[0].action="submit.py";
document.forms[0].curpage.value = 1;
document.forms[0].step.value = 0;
document.forms[0].submit();
alert('The document %s cannot be found in our database.\\nAnyway, you can still choose another document if you wish.');
</SCRIPT>""" % repno)
return 0
diff --git a/modules/websubmit/lib/functions/Get_Report_Number.py b/modules/websubmit/lib/functions/Get_Report_Number.py
index 3c31fe755..8232fce3e 100644
--- a/modules/websubmit/lib/functions/Get_Report_Number.py
+++ b/modules/websubmit/lib/functions/Get_Report_Number.py
@@ -1,42 +1,42 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
##
## Name: Get_Report_Number.py
## Description: function Get_Report_Number
## This function retrieves the reference of the document from
## the name of the file it is stored in.
## Author: T.Baron
## PARAMETERS: edsrn: name of the file in which the reference is stored
## OUTPUT: HTML
##
def Get_Report_Number (parameters,curdir,form):
global rn
#Path of file containing report number
if os.path.exists("%s/%s" % (curdir,parameters['edsrn'])):
fp = open("%s/%s" % (curdir,parameters['edsrn']),"r")
rn = fp.read()
rn = rn.replace("/","_")
rn = re.sub("[\n\r ]+","",rn)
else:
rn = ""
return ""
diff --git a/modules/websubmit/lib/functions/Get_Sysno.py b/modules/websubmit/lib/functions/Get_Sysno.py
index c847e9876..a0ab8c484 100644
--- a/modules/websubmit/lib/functions/Get_Sysno.py
+++ b/modules/websubmit/lib/functions/Get_Sysno.py
@@ -1,53 +1,53 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
##
## Name: Get_Sysno.py
## Description: function Get_Sysno
## This function retrieves the system number of a document
## given its reference
## Author: T.Baron
## PARAMETERS: -
## OUTPUT: HTML
##
from cdsware.search_engine import search_pattern
def Get_Sysno(parameters,curdir,form):
global rn,sysno
# initialize sysno variable
sysno = ""
if os.path.exists("%s/SN" % curdir):
fp = open("%s/SN" % curdir,"r")
sysno = fp.read()
fp.close()
else:
searchresults = search_pattern(req=None, p=rn, f="reportnumber").items().tolist()
if len(searchresults) == 0:
raise functionStop("<SCRIPT>document.forms[0].action=\"submit.py\";document.forms[0].curpage.value=1;document.forms[0].step.value=0;document.forms[0].submit();alert('The report %s cannot be found in our database.\\nPerhaps it has not been integrated yet?\\nAnyway, you can choose another report number if you wish.\\n Or retry this action in a few minutes.');</SCRIPT>" % rn)
elif len(searchresults) > 1:
raise functionStop("<SCRIPT>document.forms[0].action=\"submit.py\";document.forms[0].curpage.value=1;document.forms[0].step.value=0;document.forms[0].submit();alert('Multiple documents have been found with report number %s\\nYou can try with another report number if you wish.\\n Or retry this action in a few minutes.');</SCRIPT>" % rn)
else:
sysno = searchresults[0]
# save resultin a file
fp = open("%s/SN" % curdir,"w")
fp.write(str(sysno))
fp.close()
return ""
diff --git a/modules/websubmit/lib/functions/Insert_Modify_Record.py b/modules/websubmit/lib/functions/Insert_Modify_Record.py
index 7fba53d2d..2659c9b18 100644
--- a/modules/websubmit/lib/functions/Insert_Modify_Record.py
+++ b/modules/websubmit/lib/functions/Insert_Modify_Record.py
@@ -1,32 +1,32 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
def Insert_Modify_Record(parameters,curdir,form):
global rn
if os.path.exists("%s/recmysqlfmt" % curdir):
recfile = "recmysqlfmt"
elif os.path.exists("%s/recmysql" % curdir):
recfile = "recmysql"
else:
raise functionError("Could not find record file")
initialfile = "%s/%s" % (curdir,recfile)
finalfile = "%s/%s_%s" % (tmpdir,rn,time.strftime("%Y-%m-%d_%H:%M:%S"))
shutil.copy(initialfile,finalfile)
os.system("%s -c %s" % (bibupload,finalfile))
return ""
diff --git a/modules/websubmit/lib/functions/Insert_Record.py b/modules/websubmit/lib/functions/Insert_Record.py
index 1516e2918..f255489fa 100644
--- a/modules/websubmit/lib/functions/Insert_Record.py
+++ b/modules/websubmit/lib/functions/Insert_Record.py
@@ -1,32 +1,32 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import shutil
def Insert_Record(parameters,curdir,form):
global rn
if os.path.exists("%s/recmysql" % curdir):
recfile = "recmysql"
else:
raise functionError("Could not find record file")
initialfile = "%s/%s" % (curdir,recfile)
finalfile = "%s/%s_%s" % (tmpdir,rn,time.strftime("%Y-%m-%d_%H:%M:%S"))
shutil.copy(initialfile,finalfile)
os.system("%s -r -i %s" % (bibupload,finalfile))
return ""
diff --git a/modules/websubmit/lib/functions/Is_Original_Submitter.py b/modules/websubmit/lib/functions/Is_Original_Submitter.py
index 8b293f9f3..f88ad4efa 100644
--- a/modules/websubmit/lib/functions/Is_Original_Submitter.py
+++ b/modules/websubmit/lib/functions/Is_Original_Submitter.py
@@ -1,57 +1,57 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
##
## Name: Is_Original_Submitter
## Description: function Is_Original_Submitter
## This function compares the email of the current logged
## user with the original submitter of the document, then
## check whether the user has special rights.
## Author: T.Baron
##
## PARAMETERS: -
## OUTPUT: HTML
##
execfile("%s/cdsware/websubmit_functions/Retrieve_Data.py" % pylibdir)
def Is_Original_Submitter(parameters,curdir,form):
global uid_email,sysno,uid
doctype = form['doctype']
act = form['act']
email = Get_Field("8560_f",sysno)
email = re.sub("[\n\r ]+","",email)
uid_email = re.sub("[\n\r ]+","",uid_email)
(auth_code, auth_message) = acc_authorize_action(uid, "submit",verbose=0,doctype=doctype, act=act)
if re.search(uid_email,email,re.IGNORECASE) == None and auth_code != 0:
raise functionStop("""
<SCRIPT>
document.forms[0].action="submit.py";
document.forms[0].curpage.value = 1;
document.forms[0].step.value = 0;
document.forms[0].submit();
alert('Only the submitter of this document has the right to do this action. \\nYour login (%s) is different from the one of the submitter (%s).');
</SCRIPT>""" % (uid_email,email))
elif re.search(uid_email,email,re.IGNORECASE) == None and auth_code == 0:
return ("""
<SCRIPT>
alert('Only the submitter of this document has the right to do this action. \\nYour login (%s) is different from the one of the submitter (%s).\\n\\nAnyway, as you have a special authorization for this type of documents,\\nyou are allowed to proceed! Watch out your actions!');
</SCRIPT>""" % (uid_email,email))
return ""
diff --git a/modules/websubmit/lib/functions/Is_Referee.py b/modules/websubmit/lib/functions/Is_Referee.py
index 9472725a2..7c580c6be 100644
--- a/modules/websubmit/lib/functions/Is_Referee.py
+++ b/modules/websubmit/lib/functions/Is_Referee.py
@@ -1,41 +1,41 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
def Is_Referee(parameters,curdir,form):
global uid_email,sysno,rn,uid
doctype = form['doctype']
# Get document category
res = run_sql("SELECT categ FROM sbmAPPROVAL WHERE rn=%s", (rn,))
if len(res) >0:
categ = res[0][0]
else:
categ=""
# Try to retrieve the referee's email from the referee's database
(auth_code, auth_message) = acc_authorize_action(uid, "referee",doctype=doctype, categ=categ)
if auth_code != 0:
raise functionStop("""
<SCRIPT>
document.forms[0].action="submit.py";
document.forms[0].curpage.value = 1;
document.forms[0].step.value = 0;
document.forms[0].submit();
alert('Sorry you (%s) have not been recognized as a referee for this type of document.\\nIf you think this is an error, please contact %s');
</SCRIPT>""" % (uid_email,supportemail))
return ""
diff --git a/modules/websubmit/lib/functions/Mail_Submitter.py b/modules/websubmit/lib/functions/Mail_Submitter.py
index 5be14a04d..72debfda1 100644
--- a/modules/websubmit/lib/functions/Mail_Submitter.py
+++ b/modules/websubmit/lib/functions/Mail_Submitter.py
@@ -1,104 +1,104 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
##
## Name: Mail_Submitter.py
## Description: function Mail_Submitter
## This function sends a confirmation email to the submitter
## of the document
## Author: T.Baron
##
## PARAMETERS: authorfile: name of the file containing the author
## titleFile: name of the file containing the title
## emailFile: name of the file containing the email
## status: one of "ADDED" (the document has been integrated
## into the database) or "APPROVAL" (an email has
## been sent to a referee - simple approval)
## edsrn: name of the file containing the reference
## newrnin: name of the file containing the 2nd reference
## (if any)
## OUTPUT: HTML
##
from cdsware.websubmit_config import cfg_websubmit_copy_mails_to_admin
execfile("%s/cdsware/websubmit_functions/mail.py" % pylibdir)
def Mail_Submitter (parameters,curdir,form):
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
# retrieve report number
edsrn = parameters['edsrn']
newrnin = parameters['newrnin']
fp = open("%s/%s" % (curdir,edsrn),"r")
rn = fp.read()
fp.close()
rn = re.sub("[\n\r]+","",rn)
if newrnin != "" and os.path.exists("%s/%s" % (curdir,newrnin)):
fp = open("%s/%s" % (curdir,newrnin),"r")
additional_rn = read()
fp.close()
additional_rn = re.sub("[\n\r]+","",additional_rn)
fullrn = "%s and %s" % (additional_rn,rn)
else:
fullrn = rn
fullrn = fullrn.replace("\n"," ")
# The title is read from the file specified by 'titlefile'
try:
fp = open("%s/%s" % (curdir,parameters['titleFile']),"r")
m_title = fp.read().replace("\n"," ")
fp.close()
except:
m_title = "-"
# The name of the author is read from the file specified by 'authorfile'
try:
fp = open("%s/%s" % (curdir,parameters['authorfile']),"r")
m_author = fp.read().replace("\n"," ")
fp.close()
except:
m_author = "-"
# The submitters email address is read from the file specified by 'emailFile'
try:
fp = open("%s/%s" % (curdir,parameters['emailFile']),"r")
m_recipient = fp.read().replace ("\n"," ")
fp.close()
except:
m_recipient = ""
# create email body
email_txt = "The document %s\nTitle: %s\nAuthor(s): %s\n\nhas been correctly received\n\n" % (fullrn,m_title,m_author)
# The user is either informed that the document has been added to the database, or sent for approval
if parameters['status'] == "APPROVAL":
email_txt = email_txt + "An email has been sent to the referee. You will be warned by email as soon as the referee takes his/her decision regarding your document.\n\n"
elif parameters['status'] == "ADDED":
email_txt = email_txt + "It will be soon added to our Document Server.\n\nOnce inserted, you will be able to check the bibliographic information and the quality of the electronic documents at this URL:\n<%s/search.py?recid=%s>\nIf you detect an error please let us know by sending an email to %s. \n\n" % (htdocsurl,sysno,supportemail)
email_txt = email_txt + "Thank you for using %s Submission Interface.\n" % cdsname
# send the mail
tostring = m_recipient.strip()
if cfg_websubmit_copy_mails_to_admin:
# Copy mail to admins:
if len(tostring) > 0:
tostring += ",%s" % (adminemail,)
else:
tostring = adminemail
body = forge_email(FROMADDR,m_recipient,"","%s: Document Received" % fullrn,email_txt)
tolist = tostring.split(",")
if len(tolist[0]) > 0:
send_email(FROMADDR,tolist,body,0)
return ""
diff --git a/modules/websubmit/lib/functions/Make_Modify_Record.py b/modules/websubmit/lib/functions/Make_Modify_Record.py
index ad4f6bd63..7118a10a7 100644
--- a/modules/websubmit/lib/functions/Make_Modify_Record.py
+++ b/modules/websubmit/lib/functions/Make_Modify_Record.py
@@ -1,63 +1,63 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Make_Modify_Record
## This function creates the bibliographic record
## using bibConvert and the configuration files passed as
## parameters
## Author: T.Baron
##
## PARAMETERS: sourceModify: source description file
## mysqlModify: template description file
## OUTPUT: HTML
def Make_Modify_Record(parameters,curdir,form):
# Get rid of "invisible" white spaces
source = parameters['sourceTemplate'].replace(" ","")
modify = parameters['modifyTemplate'].replace(" ","")
# We use bibconvert to create the xml record
call_uploader_txt = "%s -l1 -d'%s' -Cs'%s/%s' -Ct'%s/%s' > %s/recmysql" % (bibconvert,curdir,bibconvertconf,source,bibconvertconf,modify,curdir)
os.system(call_uploader_txt)
# Then we have to format this record (turn & into &amp; and < into &lt;
# After all we know nothing about the text entered by the users at submission time
if os.path.exists("%s/recmysql" % curdir):
fp = open("%s/recmysql" % curdir,"r")
rectext = fp.read()
fp.close()
else:
raise functionError("Cannot create database record")
# First of all the &
rectext = rectext.replace("&amp;","&")
rectext = rectext.replace("&","&amp;")
# Then the < - More difficult!
rectext = rectext.replace("<","&lt;")
rectext = rectext.replace("&lt;record","<record")
rectext = rectext.replace("&lt;/record","</record")
rectext = rectext.replace("&lt;datafield","<datafield")
rectext = rectext.replace("&lt;/datafield","</datafield")
rectext = rectext.replace("&lt;controlfield","<controlfield")
rectext = rectext.replace("&lt;/controlfield","</controlfield")
rectext = rectext.replace("&lt;subfield","<subfield")
rectext = rectext.replace("&lt;/subfield","</subfield")
# Save the record back
fp = open("%s/recmysql" % curdir,"w")
fp.write(rectext)
fp.close()
return ""
diff --git a/modules/websubmit/lib/functions/Make_Record.py b/modules/websubmit/lib/functions/Make_Record.py
index 2026cbcc8..bc0a7a952 100644
--- a/modules/websubmit/lib/functions/Make_Record.py
+++ b/modules/websubmit/lib/functions/Make_Record.py
@@ -1,61 +1,61 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Make_Weblib_Record
## This function creates the bibliographic record
## using bibConvert and the configuration files passed as
## parameters
## Author: T.Baron
##
## PARAMETERS: sourceSubmit: source description file
## mysqlInsert: template description file
def Make_Record(parameters,curdir,form):
# Get rid of "invisible" white spaces
source = parameters['sourceTemplate'].replace(" ","")
create = parameters['createTemplate'].replace(" ","")
# We use bibconvert to create the xml record
call_uploader_txt = "%s -l1 -d'%s' -Cs'%s/%s' -Ct'%s/%s' > %s/recmysql" % (bibconvert,curdir,bibconvertconf,source,bibconvertconf,create,curdir)
os.system(call_uploader_txt)
# Then we have to format this record (turn & into &amp; and < into &lt;
# After all we know nothing about the text entered by the users at submission time
if os.path.exists("%s/recmysql" % curdir):
fp = open("%s/recmysql" % curdir,"r")
rectext = fp.read()
fp.close()
else:
raise functionError("Cannot create database record")
# First of all the &
rectext = rectext.replace("&amp;","&")
rectext = rectext.replace("&","&amp;")
# Then the < - More difficult!
rectext = rectext.replace("<","&lt;")
rectext = rectext.replace("&lt;record","<record")
rectext = rectext.replace("&lt;/record","</record")
rectext = rectext.replace("&lt;datafield","<datafield")
rectext = rectext.replace("&lt;/datafield","</datafield")
rectext = rectext.replace("&lt;controlfield","<controlfield")
rectext = rectext.replace("&lt;/controlfield","</controlfield")
rectext = rectext.replace("&lt;subfield","<subfield")
rectext = rectext.replace("&lt;/subfield","</subfield")
# Save the record back
fp = open("%s/recmysql" % curdir,"w")
fp.write(rectext)
fp.close()
return ""
diff --git a/modules/websubmit/lib/functions/Makefile.am b/modules/websubmit/lib/functions/Makefile.am
index 1e45c7637..f84bdca9c 100644
--- a/modules/websubmit/lib/functions/Makefile.am
+++ b/modules/websubmit/lib/functions/Makefile.am
@@ -1,60 +1,60 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
pylibdir=$(libdir)/python/cdsware/websubmit_functions
pylib_DATA = Add_Files.py \
CaseEDS.py \
Create_Modify_Interface.py \
Create_Recid.py \
Finish_Submission.py \
Format_Record.py \
Get_Info.py \
Get_Report_Number.py \
Get_Sysno.py \
Insert_Modify_Record.py \
Insert_Record.py \
Is_Original_Submitter.py \
Is_Referee.py \
Mail_Submitter.py \
Make_Modify_Record.py \
Make_Record.py \
Move_Files_Archive.py \
Move_From_Pending.py \
Move_to_Done.py \
Move_to_Pending.py \
Print_Success.py \
Print_Success_APP.py \
Print_Success_DEL.py \
Print_Success_MBI.py \
Print_Success_SRV.py \
Report_Number_Generation.py \
Retrieve_Data.py \
Send_APP_Mail.py \
Send_Approval_Request.py \
Send_Modify_Mail.py \
Send_SRV_Mail.py \
Test_Status.py \
Update_Approval_DB.py \
Upload_Files.py \
mail.py
EXTRA_DIST = $(pylib_DATA)
CLEANFILES = *~ *.tmp
diff --git a/modules/websubmit/lib/functions/Move_Files_Archive.py b/modules/websubmit/lib/functions/Move_Files_Archive.py
index 2959f9d41..8f110fccb 100644
--- a/modules/websubmit/lib/functions/Move_Files_Archive.py
+++ b/modules/websubmit/lib/functions/Move_Files_Archive.py
@@ -1,51 +1,51 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.file import *
def Move_Files_Archive(parameters,curdir,form):
MainDir = "%s/files/MainFiles" % curdir
IncludeDir = "%s/files/AdditionalFiles" %curdir
watcheddirs = {'Main':MainDir, 'Additional':IncludeDir}
for type in watcheddirs.keys():
dir = watcheddirs[type]
if os.path.exists(dir):
formats = {}
files = os.listdir(dir):
files.sort()
for file in files:
extension = re.sub("^[^\.]*\.","",file)
if extension == file:
extension = ""
filename = re.sub("\..*","",file)
if not formats.has_key(filename):
formats[filename] = []
formats[filename].append(extension)
# first delete all missing files
bibarchive = BibRecDocs(sysno)
existingBibdocs = bibarchive.listBibDocs(type)
if existingBibdocs != None:
for existingBibdoc in existingBibdocs:
if not formats.has_key(existingBibdoc.getFileName()):
existingBibdoc.delete()
# then create/update the new ones
for key in formats.keys():
# instanciate bibdoc object
bibarchive.addFile(path=dir, type=type,filename=key,formats=formats[key])
return ""
diff --git a/modules/websubmit/lib/functions/Move_From_Pending.py b/modules/websubmit/lib/functions/Move_From_Pending.py
index cbc013531..10dad89cb 100644
--- a/modules/websubmit/lib/functions/Move_From_Pending.py
+++ b/modules/websubmit/lib/functions/Move_From_Pending.py
@@ -1,40 +1,40 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Move_From_Pending
## This function retrieves an old submisison directory which
## had been saved in /pending and moves all the data files
## in the current working directory
## Author: T.Baron
## PARAMETERS: -
def Move_From_Pending(parameters,curdir,form):
global rn
doctype = form['doctype']
srcdir = "%s/pending/%s/%s" % (storage,doctype,rn)
if os.path.exists(srcdir):
if rn != "":
files = os.listdir(srcdir)
for file in files:
os.rename("%s/%s" % (srcdir,file), "%s/%s" % (curdir,file))
os.rmdir(srcdir)
else:
raise functionError("Move_From_Pending: Cannot retrieve reference information %s" % srcdir)
return ""
diff --git a/modules/websubmit/lib/functions/Move_to_Done.py b/modules/websubmit/lib/functions/Move_to_Done.py
index 1dd338497..33e3d3ec0 100644
--- a/modules/websubmit/lib/functions/Move_to_Done.py
+++ b/modules/websubmit/lib/functions/Move_to_Done.py
@@ -1,50 +1,50 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Move_to_Done
## This function move the current working directory to the
## /done directory and compress it
## Author: T.Baron
## PARAMETERS: -
def Move_to_Done(parameters,curdir,form):
global rn
data = re.search(".*/([^/]*)/([^/]*)/[^/]*$",curdir)
dir = data.group(1)
doctype = data.group(2)
DONEDIR = "%s/done/%s/%s" % (storage,dir,doctype)
if not os.path.exists(DONEDIR):
try:
os.makedirs(DONEDIR)
except:
raise functionError("Cannot create done directory %s" % DONEDIR)
# Moves the files to the done diectory and creates an archive
rn = rn.replace("/","-")
namedir = "%s_%s" % (rn,time.strftime("%Y%m%d%H%M%S"))
FINALDIR = "%s/%s" % (DONEDIR,namedir)
os.rename(curdir,FINALDIR)
if tar != "" and gzip != "":
os.chdir(DONEDIR)
tar_txt = "%s -cf - %s > %s.tar" % (tar,namedir,namedir)
os.system(tar_txt)
zip_txt = "%s %s.tar" % (gzip,namedir)
os.system(zip_txt)
rm_txt = "rm -R %s" % namedir
os.system(rm_txt)
return ""
diff --git a/modules/websubmit/lib/functions/Move_to_Pending.py b/modules/websubmit/lib/functions/Move_to_Pending.py
index 88491e354..2695f7700 100644
--- a/modules/websubmit/lib/functions/Move_to_Pending.py
+++ b/modules/websubmit/lib/functions/Move_to_Pending.py
@@ -1,41 +1,41 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Move_to_Pending
## This function moves the current working directory to
## /pending (usually the document is then waiting for
## approval)
## Author: T.Baron
## PARAMETERS: -
def Move_to_Pending(parameters,curdir,form):
global rn
doctype = form['doctype']
PENDIR = "%s/pending/%s" % (storage,doctype)
if not os.path.exists(PENDIR):
try:
os.makedirs(PENDIR)
except:
raise functionError("Cannot create pending directory %s" % PENDIR)
# Moves the files to the pending directory
rn = rn.replace("/","-")
namedir = rn
FINALDIR = "%s/%s" % (PENDIR,namedir)
os.rename(curdir,FINALDIR)
return ""
diff --git a/modules/websubmit/lib/functions/Print_Success.py b/modules/websubmit/lib/functions/Print_Success.py
index 871c8bc45..90e8b9375 100644
--- a/modules/websubmit/lib/functions/Print_Success.py
+++ b/modules/websubmit/lib/functions/Print_Success.py
@@ -1,42 +1,42 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
def Print_Success(parameters,curdir,form):
t=""
edsrn = parameters['edsrn']
newrnin = parameters['newrnin']
status = parameters['status']
fp = open("%s/%s" % (curdir,edsrn),"r")
rn = fp.read()
fp.close()
if newrnin != "" and os.path.exists("%s/%s" % (curdir,newrnin)):
fp = open("%s/%s" % (curdir,newrnin),"r")
additional_rn = fp.read()
fp.close()
additional_rn = " and %s" % additional_rn
else:
additional_rn = ""
t=t+Request_Print("A", "<br><br><B>Submission Complete!</B><br><BR>")
t=t+Request_Print("A", "Your document has the following reference(s): <b>%s%s</b><br><br>" % (rn,additional_rn))
if status == "APPROVAL":
t=t+Request_Print("A", "An email has been sent to the referee. You will be warned by email as soon as the referee takes his/her decision regarding your document.<br><br>\n")
if status == "ADDED":
t=t+Request_Print("A", "It will soon appear on our server.<br><br>\n")
t=t+Request_Print("A", "Thank you for using %s!" % cdsname)
t=t+Request_Print("A", "<br><br><br><br>")
return t
diff --git a/modules/websubmit/lib/functions/Print_Success_APP.py b/modules/websubmit/lib/functions/Print_Success_APP.py
index 7811ae36a..ddf18556d 100644
--- a/modules/websubmit/lib/functions/Print_Success_APP.py
+++ b/modules/websubmit/lib/functions/Print_Success_APP.py
@@ -1,39 +1,39 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Print_Success_APP
## This function outputs a message telling the user his/her
## decision was taken into account.
## Author: T.Baron
## PARAMETERS: -
def Print_Success_APP(parameters,curdir,form):
global rn
# the field containing the decision of the referee must be called "decision".
if not os.path.exists("%s/decision" % curdir):
raise functionError("Could not find decision file")
else:
fp = open("%s/decision" % curdir,"r")
decision = fp.read()
fp.close()
t="<br><br><B>Your decision has been taken into account!</B><br><BR>"
if decision == "approve":
t+="The document will be soon available with the following reference: <b>%s</b><BR>" % rn
return t
diff --git a/modules/websubmit/lib/functions/Print_Success_DEL.py b/modules/websubmit/lib/functions/Print_Success_DEL.py
index de007b14f..4d1ea96a6 100644
--- a/modules/websubmit/lib/functions/Print_Success_DEL.py
+++ b/modules/websubmit/lib/functions/Print_Success_DEL.py
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Print_Success_DEL
## This function displays a message telling the user the
## record has actually been deleted
## Author: T.Baron
## PARAMETERS: -
def Print_Success_DEL(parameters,curdir,form):
global rn
t="<br><br><b>Document %s was successfully deleted.</b>" % rn
return t
diff --git a/modules/websubmit/lib/functions/Print_Success_MBI.py b/modules/websubmit/lib/functions/Print_Success_MBI.py
index 33b513694..7e937873a 100644
--- a/modules/websubmit/lib/functions/Print_Success_MBI.py
+++ b/modules/websubmit/lib/functions/Print_Success_MBI.py
@@ -1,31 +1,31 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Print_Success_MBI
## This function displays a message telling the user the
## modification has been taken into account
## Author: T.Baron
## PARAMETERS: -
def Print_Success_MBI(parameters,curdir,form):
global rn
t="<B>Modification completed!</B><br><BR>"
t+="These modifications on document %s will be processed as quickly as possible and made <br>available on the %s Server</b>" % (rn,cdsname)
return t
diff --git a/modules/websubmit/lib/functions/Print_Success_SRV.py b/modules/websubmit/lib/functions/Print_Success_SRV.py
index bede662e4..fffddef23 100644
--- a/modules/websubmit/lib/functions/Print_Success_SRV.py
+++ b/modules/websubmit/lib/functions/Print_Success_SRV.py
@@ -1,30 +1,30 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Print_Success_SRV
## This function displays a message telling the user the
## revised files have been correctly received
## Author: T.Baron
## PARAMETERS: -
def Print_Success_SRV(parameters,curdir,form):
global rn
t="<br><br><b>Document %s was successfully revised.</b>" % rn
return t
diff --git a/modules/websubmit/lib/functions/Report_Number_Generation.py b/modules/websubmit/lib/functions/Report_Number_Generation.py
index ba3309bbb..6ce7af31c 100644
--- a/modules/websubmit/lib/functions/Report_Number_Generation.py
+++ b/modules/websubmit/lib/functions/Report_Number_Generation.py
@@ -1,132 +1,132 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Report_Number_Generation
## This function creates a reference for the submitted
## document and saves it in the specified file.
## Author: T.Baron
##
## PARAMETERS: edsrn: name of the file in which the reference is saved
## autorngen: one of "A", "N", "Y"
## "A": The reference is the submission number
## "N": The reference is taken from a file [edsrn]
## "Y": The reference is generated
## rnin: name of the file containing the category
## counterpath: path to the counter file
## rnformat: format for the generated reference
## yeargen: if "AUTO", current year, else the year is
## extracted from the file [yeargen]
def Report_Number_Generation(parameters,curdir,form):
global doctype,access,act,dir,rn
# The program must automatically generate the report number
# Generate Year
if parameters['autorngen'] == "Y":
if parameters['yeargen'] == "AUTO":
# Current year is used
yy = time.strftime("%Y")
else :
# If yeargen != auto then the contents of the file named 'yeargen' is used
# Assumes file uses DD-MM-YYYY format
fp = open("%s/%s" % (curdir,parameters['yeargen']),"r")
mydate = fp.read()
fp.close()
yy = re.sub("^......","",mydate)
# Evaluate category - Category is read from the file named 'rnin
if os.path.exists("%s/%s" % (curdir,parameters['rnin'])):
fp = open("%s/%s" % (curdir,parameters['rnin']),"r")
category = fp.read()
category = category.replace("\n","")
else:
category = ""
# The counter and report number formats are evaluated.
# All data is considered as a string literal except that enclosed
# in the <PA></PA> brackets. The category replaces <PA>categ</PA>
# and the 4 digits year replaces <PA>yy</PA>
counter_path = parameters['counterpath'].replace("<PA>categ</PA>",category)
counter_path = counter_path.replace ("<PA>yy</PA>",yy)
counter_path = counter_path.replace(" ","")
counter_path = counter_path.replace("\n","")
rn_format = parameters['rnformat'].replace ("<PA>categ</PA>",category)
rn_format = rn_format.replace ("<PA>yy</PA>",yy)
# Check if the report number does not already exists
if os.path.exists("%s/%s" % (curdir,parameters['edsrn'])):
fp = open("%s/%s" % (curdir,parameters['edsrn']),"r")
oldrn = fp.read()
fp.close()
if oldrn != "" and not re.search("\?\?\?",oldrn):
rn = oldrn
return ""
# create it
rn = Create_Reference(counter_path,rn_format)
rn = rn.replace("\n","")
rn = rn.replace("\r","")
rn = rn.replace("\015","")
rn = rn.replace("\013","")
rn = rn.replace("\012","")
# The file edsrn is created in the submission directory, and it stores the report number
fp = open("%s/%s" % (curdir,parameters['edsrn']),"w")
fp.write(rn)
fp.close()
# The report number is just read from a specified file
elif parameters['autorngen'] == "N":
fp = open("%s/%s" % (curdir,parameters['edsrn']),"r")
rn = fp.read()
fp.close()
# Some documents are really annoying and insist on a totally different way of doing things
# This code is for documents which have the access number in the report
# number (instead of using a counter)
elif parameters['autorngen'] == "A":
rn = parameters['rnformat'].replace ("<PA>access</PA>",access)
# The file accessno/edsrn is created, and it stores the report number
fp = open("%s/%s" % (curdir,parameters['edsrn']),"w")
fp.write(rn)
fp.close()
return ""
def Create_Reference(counter_path,ref_format):
# test if the counters directory exists, if not attempts to create it
if not os.path.exists(counters):
try:
os.mkdir(counters)
except:
raise functionError("File System: Cannot create counters directory %s" % counters)
if not os.path.exists("%s/%s" % (counters,counter_path)):
try:
fp = open("%s/%s" % (counters,counter_path),"w")
except:
raise functionError("File System: no permission to write in counters directory %s" % counters)
fp.write ("0")
fp.close()
# retrieve current counter value
fp = open("%s/%s" % (counters,counter_path),"r")
id = fp.read()
fp.close()
if id == "":
id=0
# increment the counter
id = int(id)+1
# store new value
fp = open("%s/%s" % (counters,counter_path),"w")
fp.write (str(id))
fp.close()
# create final value
reference = "%s-%03d" % (ref_format,id)
# Return the report number prelude with the id concatenated on at the end
return reference
diff --git a/modules/websubmit/lib/functions/Retrieve_Data.py b/modules/websubmit/lib/functions/Retrieve_Data.py
index c793e6710..6c94e3d1d 100644
--- a/modules/websubmit/lib/functions/Retrieve_Data.py
+++ b/modules/websubmit/lib/functions/Retrieve_Data.py
@@ -1,33 +1,33 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Get_Field
## This function returns the value of the specified field
## from the specified document
## Author: T.Baron
##
## PARAMETERS: fieldname: marc21 code
## bibrec: system number of the bibliographic record
from cdsware.search_engine import search_pattern, perform_request_search, print_record
def Get_Field(fieldname,bibrec):
value = string.strip(print_record(int(bibrec),'tm',fieldname))
return value
diff --git a/modules/websubmit/lib/functions/Send_APP_Mail.py b/modules/websubmit/lib/functions/Send_APP_Mail.py
index a2de68fc4..c8d8bb987 100644
--- a/modules/websubmit/lib/functions/Send_APP_Mail.py
+++ b/modules/websubmit/lib/functions/Send_APP_Mail.py
@@ -1,121 +1,121 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Send_APP_Mail
## This function send an email informing the original
## submitter of a document that the referee has approved/
## rejected the document. The email is also sent to the
## referee for checking.
## Author: T.Baron
## PARAMETERS:
## newrnin: name of the file containing the 2nd reference
## addressesAPP: email addresses to which the email will
## be sent (additionally to the author)
## categformatAPP: variable needed to derive the addresses
## mentioned above
from cdsware.access_control_admin import acc_getRoleUsers,acc_getRoleId
from cdsware.websubmit_config import cfg_websubmit_copy_mails_to_admin
execfile("%s/cdsware/websubmit_functions/mail.py" % pylibdir)
def Send_APP_Mail (parameters,curdir,form):
global emailvalue,titlevalue,authorvalue,sysno,rn
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
doctype = form['doctype']
emailvalue = emailvalue.replace("\n","")
titlevalue = titlevalue.replace("\n","")
authorvalue = authorvalue.replace("\n","")
# variables declaration
categformat = parameters['categformatAPP']
otheraddresses = parameters['addressesAPP']
newrnpath = parameters['newrnin']
# retrieve values stored into files
if os.path.exists("%s/COM" % curdir):
fp = open("%s/COM" % curdir, "r")
comment = fp.read()
fp.close()
else:
comment = ""
if os.path.exists("%s/decision" % curdir):
fp = open("%s/decision" % curdir,"r")
decision = fp.read()
fp.close()
else:
decision = ""
if os.path.exists("%s/%s" % (curdir,newrnpath)):
fp = open("%s/%s" % (curdir,newrnpath) , "r")
newrn = fp.read()
fp.close()
else:
newrn = ""
# Document name
res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
docname = res[0][0]
# retrieve category
categformat = categformat.replace("<CATEG>","([^-]*)")
categs = re.match(categformat,rn)
if categs != None:
category = categs.group(1)
else:
category = "unknown"
# Build referee's email address
refereeaddress = ""
# Try to retrieve the referee's email from the referee's database
for user in acc_getRoleUsers(acc_getRoleId("referee_%s_%s" % (doctype,category))):
refereeaddress += user[1] + ","
# And if there is a general referee
for user in acc_getRoleUsers(acc_getRoleId("referee_%s_*" % doctype)):
refereeaddress += user[1] + ","
refereeaddress = re.sub(",$","",refereeaddress)
# Creation of the mail for the referee
otheraddresses = otheraddresses.replace("<CATEG>",category)
addresses = ""
if refereeaddress != "":
addresses = refereeaddress + ","
if otheraddresses != "":
addresses += otheraddresses
else:
addresses = re.sub(",$","",addresses)
if decision == "approve":
mailtitle = "%s has been approved" % rn
mailbody = "The %s %s has been approved." % (docname,rn)
mailbody += "\nIt will soon be accessible here:\n<%s/search.py?recid=%s>" % (htdocsurl,sysno)
else:
mailtitle = "%s has been rejected" % rn
mailbody = "The %s %s has been rejected." % (docname,rn)
if rn != newrn and decision == "approve" and newrn != "":
mailbody += "Its new reference number is: %s" % newrn
mailbody += "\n\nTitle: %s\n\nAuthor(s): %s\n\n" % (titlevalue,authorvalue)
if comment != "":
mailbody += "Comments from the referee:\n%s\n" % comment
mailbody += "---------------------------------------------\nBest regards.\nThe submission team.\n"
#Send mail to referee
tostring = addresses.strip()
if cfg_websubmit_copy_mails_to_admin:
# Copy mail to admins:
if len(tostring) > 0:
tostring += ",%s" % (adminemail,)
else:
tostring = adminemail
body = forge_email(FROMADDR,addresses,"",mailtitle,mailbody)
tolist = re.split(",",tostring)
if len(tolist[0]) > 0:
send_email(FROMADDR,tolist,body,0)
return ""
diff --git a/modules/websubmit/lib/functions/Send_Approval_Request.py b/modules/websubmit/lib/functions/Send_Approval_Request.py
index 194242c78..1b1010ecd 100644
--- a/modules/websubmit/lib/functions/Send_Approval_Request.py
+++ b/modules/websubmit/lib/functions/Send_Approval_Request.py
@@ -1,112 +1,112 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Send_Approval_Request
## This function sends an email to the referee asking him/her
## to approve/reject a document
## Author: T.Baron
## PARAMETERS: directory: parameter to the link manager program
## addressesDAM: address of the referee(s)
## categformatDAM: variable needed to extract the category
## of the document and use it to derive the
## address.
## authorfile: name of the file containing the author list
## titleFile: name of the file containing the title
from cdsware.access_control_admin import acc_getRoleUsers,acc_getRoleId
from cdsware.websubmit_config import cfg_websubmit_copy_mails_to_admin
execfile("%s/cdsware/websubmit_functions/mail.py" % pylibdir)
def Send_Approval_Request (parameters,curdir,form):
global rn,sysno
# variables declaration
doctype = re.search(".*/([^/]*)/([^/]*)/[^/]*$",curdir).group(2)
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
otheraddresses = parameters['addressesDAM']
categformat = parameters['categformatDAM']
# retrieve category
categformat = categformat.replace("<CATEG>","([^-]*)")
categs = re.match(categformat,rn)
if categs != None:
category = categs.group(1)
else:
category = "unknown"
# create TI
if os.path.exists("%s/date" % curdir):
fp = open("%s/date" % curdir, "r")
date = fp.read()
fp.close()
else:
date = ""
if os.path.exists("%s/%s" % (curdir,parameters['titleFile'])):
fp = open("%s/%s" % (curdir,parameters['titleFile']),"r")
title = fp.read()
fp.close()
title = title.replace("\n","")
else:
title = ""
title += " - %s" % date
# create AU
if os.path.exists("%s/%s" % (curdir,parameters['authorfile'])):
fp = open("%s/%s" % (curdir,parameters['authorfile']), "r")
author = fp.read()
fp.close()
else:
author = ""
# we get the referee password
sth = run_sql("SELECT access FROM sbmAPPROVAL WHERE rn=%s", (rn,))
if len(sth) >0:
access = sth[0][0]
# Build referee's email address
refereeaddress = ""
# Try to retrieve the referee's email from the referee's database
for user in acc_getRoleUsers(acc_getRoleId("referee_%s_%s" % (doctype,category))):
refereeaddress += user[1] + ","
# And if there are general referees
for user in acc_getRoleUsers(acc_getRoleId("referee_%s_*" % doctype)):
refereeaddress += user[1] + ","
refereeaddress = re.sub(",$","",refereeaddress)
# Creation of the mail for the referee
addresses = ""
if refereeaddress != "":
addresses = refereeaddress + ","
if otheraddresses != "":
addresses += otheraddresses
else:
addresses = re.sub(",$","",addresses)
title_referee = "Request for approval of %s" % rn
mail_referee = "The document %s has been submitted to the %s Server..\nYour approval is requested on it.\n\n" % (rn,cdsname)
mail_referee +="Title: %s\n\nAuthor(s): %s\n\n" % (title,author)
mail_referee +="To access the document(s), select the file(s) from the location:<%s/getfile.py?recid=%s>\n\n" % (htdocsurl,sysno)
mail_referee +="To approve/reject the document, you should go to this URL:\n<%s/approve.py?%s>\n" % (urlpath,access)
mail_referee +="---------------------------------------------\nBest regards.\nThe submission team.\n"
#Send mail to referee
tostring = addresses.strip()
if cfg_websubmit_copy_mails_to_admin:
# Copy mail to admins:
if len(tostring) > 0:
tostring += ",%s" % (adminemail,)
else:
tostring = adminemail
body = forge_email(FROMADDR,addresses,"",title_referee,mail_referee)
tolist = re.split(",",tostring)
if len(tolist[0]) > 0:
send_email(FROMADDR,tolist,body,0)
return ""
diff --git a/modules/websubmit/lib/functions/Send_Modify_Mail.py b/modules/websubmit/lib/functions/Send_Modify_Mail.py
index bcd203be2..a96202756 100644
--- a/modules/websubmit/lib/functions/Send_Modify_Mail.py
+++ b/modules/websubmit/lib/functions/Send_Modify_Mail.py
@@ -1,83 +1,83 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Send_Modify_Mail
## This function sends an email saying the document has been
## correctly updated
## Author: T.Baron
## PARAMETERS: addressesMBI: email addresses to which the mail is sent
## fieldnameMBI: name of the file containing the modified
## fields
## sourceDoc: name of the type of document
## emailFile: name of the file containing the email of the
## user
from cdsware.websubmit_config import cfg_websubmit_copy_mails_to_admin
execfile("%s/cdsware/websubmit_functions/mail.py" % pylibdir)
def Send_Modify_Mail (parameters,curdir,form):
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
global sysno,rn
if parameters['emailFile']!= None and parameters['emailFile']!= "" and os.path.exists("%s/%s" % (curdir,parameters['emailFile'])):
fp = open("%s/%s" % (curdir,parameters['emailFile']),"r")
sub = fp.read()
fp.close()
sub = sub.replace ("\n","")
else:
sub = ""
# Copy mail to:
addresses = parameters['addressesMBI']
addresses = addresses.strip()
m_fields = parameters['fieldnameMBI']
type = parameters['sourceDoc']
rn = re.sub("[\n\r ]+","",rn)
if os.path.exists("%s/%s" % (curdir,m_fields)):
fp = open("%s/%s" % (curdir,m_fields),"r")
fields = fp.read()
fp.close()
fields = fields.replace ("\n"," | ")
fields = re.sub("[| \n\r]+$","",fields)
else:
fields = ""
email_txt = "Dear Sir or Madam, \n%s %s has just been modified.\nModified fields: %s\n\n" % (type,rn,fields)
if accessurl != "" and sysno != "":
email_txt += "You can check the modified document here:\n"
email_txt += "<%s?id=%s>\n\n" % (accessurl,sysno)
email_txt += "Please note that the modifications will be taken into account in a couple of minutes.\n\nBest regards,\nThe %s Server support Team" % cdsname
# send the mail
tostring = sub.strip()
if len(addresses) > 0:
if len(tostring) > 0:
tostring += ",%s" % (addresses,)
else:
tostring = addresses
if cfg_websubmit_copy_mails_to_admin:
# Copy mail to admins:
if len(tostring) > 0:
tostring += ",%s" % (adminemail,)
else:
tostring = adminemail
body = forge_email(FROMADDR,sub,"","%s modified" % rn,email_txt)
tolist = tostring.split(",")
if len(tolist[0]) > 0:
send_email(FROMADDR,tolist,body,0)
return ""
diff --git a/modules/websubmit/lib/functions/Send_SRV_Mail.py b/modules/websubmit/lib/functions/Send_SRV_Mail.py
index c251ba690..4a8d32935 100644
--- a/modules/websubmit/lib/functions/Send_SRV_Mail.py
+++ b/modules/websubmit/lib/functions/Send_SRV_Mail.py
@@ -1,80 +1,80 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Send_SRV_Mail
## This function sends an email confirming the revision
## has been carried on with success
## Author: T.Baron
## PARAMETERS: addressesSRV: list of addresses to send this email to.
## categformatDAM: variable used to derive the category of
## the document from its reference. This value might then
## be used to derive the list of addresses
## emailFile: name of the file in which the user's email is
## noteFile: name of the file containing a note from the user
from cdsware.websubmit_config import cfg_websubmit_copy_mails_to_admin
execfile("%s/cdsware/websubmit_functions/mail.py" % pylibdir)
execfile("%s/cdsware/websubmit_functions/Retrieve_Data.py" % pylibdir)
def Send_SRV_Mail(parameters,curdir,form):
global rn,doctype,sysno
# variables declaration
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
addresses = parameters['addressesSRV']
addresses = addresses.strip()
if parameters['emailFile']!=None and parameters['emailFile']!="" and os.path.exists("%s/%s" % (curdir,parameters['emailFile'])):
fp = open("%s/%s" % (curdir,parameters['emailFile']), "r")
SuE = fp.read()
fp.close()
else:
SuE = ""
SuE = SuE.replace("\n",",")
if parameters['noteFile']!=None and parameters['noteFile']!= "" and os.path.exists("%s/%s" % (curdir,parameters['noteFile'])):
fp = open("%s/%s" % (curdir,parameters['noteFile']), "r")
note = fp.read()
fp.close()
else:
note = ""
title = Get_Field("245__a",sysno)
author = Get_Field('100__a',sysno)
author += Get_Field('700__a',sysno)
# create message
message = "A revised version of document %s has been submitted.\n\nTitle: %s\nAuthor(s): %s\nURL: <%s?id=%s>%s" % (rn,title,author,accessurl,sysno,note)
# send the email
tostring = SuE.strip()
if len(addresses) > 0:
if len(tostring) > 0:
tostring += ",%s" % (addresses,)
else:
tostring = addresses
if cfg_websubmit_copy_mails_to_admin:
# Copy mail to admins:
if len(tostring) > 0:
tostring += ",%s" % (adminemail,)
else:
tostring = adminemail
body = forge_email(FROMADDR,SuE,"","%s revised" % rn,message)
tolist = re.split(",",tostring)
if len(tolist[0]) > 0:
send_email(FROMADDR,tolist,body,0)
return ""
diff --git a/modules/websubmit/lib/functions/Test_Status.py b/modules/websubmit/lib/functions/Test_Status.py
index 5cbfd3a67..3ef721809 100644
--- a/modules/websubmit/lib/functions/Test_Status.py
+++ b/modules/websubmit/lib/functions/Test_Status.py
@@ -1,71 +1,71 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Test_Status
## This function checks whether the document is still waiting
## for approval or not.
## Author: T.Baron
##
## PARAMETERS: -
def Test_Status(parameters,curdir,form):
global rn
res = run_sql("SELECT status, access FROM sbmAPPROVAL WHERE rn=%s", (rn,))
if len(res) == 0:
raise functionStop(printNotRequested(rn))
else:
if res[0][0] == "approved":
raise functionStop(printApproved(rn))
elif res[0][0] == "rejected":
raise functionStop(printRejected(rn))
return ""
def printNotRequested(rn):
t="""
<SCRIPT>
document.forms[0].action="submit.py";
document.forms[0].curpage.value = 1;
document.forms[0].step.value = 0;
document.forms[0].submit();
alert('The document %s has never been asked for approval.\\nAnyway, you can still choose another document if you wish.');
</SCRIPT>""" % rn
return t
def printApproved(rn):
t="""
<SCRIPT>
document.forms[0].action="submit.py";
document.forms[0].curpage.value = 1;
document.forms[0].step.value = 0;
document.forms[0].submit();
alert('The document %s has already been approved.\\nAnyway, you can still choose another document if you wish.');
</SCRIPT>""" % rn
return t
def printRejected(rn):
t="""
<SCRIPT>
document.forms[0].action="submit.py";
document.forms[0].curpage.value = 1;
document.forms[0].step.value = 0;
document.forms[0].submit();
alert('The document %s has already been rejected.\\nAnyway, you can still choose another document if you wish.');
</SCRIPT>""" % rn
return t
diff --git a/modules/websubmit/lib/functions/Update_Approval_DB.py b/modules/websubmit/lib/functions/Update_Approval_DB.py
index 3e24d4228..4e31e2c9e 100644
--- a/modules/websubmit/lib/functions/Update_Approval_DB.py
+++ b/modules/websubmit/lib/functions/Update_Approval_DB.py
@@ -1,66 +1,66 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## Description: function Update_Approval_DB
## This function updates the approval database with the
## decision of the referee
## Author: T.Baron
## PARAMETERS: categformatDAM: variable used to compute the category
## of the document from its reference
def Update_Approval_DB(parameters,curdir,form):
global rn
doctype = form['doctype']
act = form['act']
categformat = parameters['categformatDAM']
access = "%s%s" % (time.time(),os.getpid())
if act != "APP":
# retrieve category
if re.search("<FILE:",categformat):
filename = categformat.replace("<FILE:","")
filename = filename.replace(">","")
if os.path.exists("%s/%s" % (curdir,filename)):
fp = open("%s/%s" % (curdir,filename))
category = fp.read()
fp.close()
else:
category=""
category = category.replace("\n","")
else:
categformat = categformat.replace("<CATEG>","([^-]*)")
category = re.match(categformat,rn).group(1)
if category == "":
category = "unknown"
sth = run_sql("SELECT status,dFirstReq,dLastReq,dAction FROM sbmAPPROVAL WHERE doctype=%s and categ=%s and rn=%s", (doctype,category,rn,))
if len(sth) == 0:
run_sql("INSERT INTO sbmAPPROVAL values(%s,%s,%s,'waiting',NOW(),NOW(),'',%s)", (doctype,category,rn,access,))
else:
run_sql("UPDATE sbmAPPROVAL SET dLastReq=NOW(), status='waiting' WHERE doctype=%s and categ=%s and rn=%s", (doctype,category,rn,))
else:
if os.path.exists("%s/decision" % curdir):
fp = open("%s/decision" % curdir, "r")
decision = fp.read()
fp.close()
else:
decision = ""
if decision == "approve":
run_sql("UPDATE sbmAPPROVAL SET dAction=NOW(),status='approved' WHERE rn=%s", (rn,))
else:
run_sql("UPDATE sbmAPPROVAL SET dAction=NOW(),status='rejected' WHERE rn=%s", (rn,))
return ""
diff --git a/modules/websubmit/lib/functions/Upload_Files.py b/modules/websubmit/lib/functions/Upload_Files.py
index 2dbc01576..9b1abcb0f 100644
--- a/modules/websubmit/lib/functions/Upload_Files.py
+++ b/modules/websubmit/lib/functions/Upload_Files.py
@@ -1,256 +1,256 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
from cdsware.file import *
def Upload_Files(parameters,curdir,form):
global doctype,access,act,dir
minsize=parameters['minsize']
maxsize=parameters['maxsize']
iconsize=parameters['iconsize']
type=parameters['type']
t=""
bibrecdocs = BibRecDocs(sysno)
# first check if a file has been requested for deletion
if form.has_key("deleted"):
deleted = form['deleted']
else:
deleted = "no"
if form.has_key("deletedfile"):
deletedfile = form['deletedfile']
else:
deletedfile = ""
if form.has_key("mybibdocid"):
mybibdocid = form['mybibdocid']
else:
mybibdocid = ""
if form.has_key("fileAction"):
fileAction = form['fileAction']
else:
fileAction = ""
if deleted == "yes":
bibrecdocs.deleteBibDoc(int(deletedfile))
# then check if a file has been requested for addition
if os.path.exists("%s/myfile" % curdir):
fp = open("%s/myfile" % curdir,"r")
myfile=fp.read()
fp.close()
extension = re.sub("^[^\.]*\.","",myfile)
filename = re.sub("\..*","",os.path.basename(myfile))
fullpath = "%s/files/myfile/%s" % (curdir,myfile)
if os.path.getsize(fullpath) < int(minsize):
os.unlink("%s/myfile" % curdir)
os.unlink(fullpath)
t+= """<script>alert("your file was too small (<%s o) and was deleted");</script>""" % minsize
elif os.path.getsize(fullpath) > int(maxsize):
os.unlink("%s/myfile" % curdir)
os.unlink(fullpath)
t+= """<script>alert("your file was too big (>%s o) and was deleted");</script>""" % maxsize
else:
bibdoc = None
if fileAction == "AddMain":
if not bibrecdocs.checkFileExists(fullpath,"Main"):
bibdoc = bibrecdocs.addNewFile(fullpath,"Main")
if fileAction == "AddAdditional":
if not bibrecdocs.checkFileExists(fullpath,"Additional"):
bibdoc = bibrecdocs.addNewFile(fullpath,"Additional")
if fileAction == "ReviseAdditional" and mybibdocid != "":
if not bibrecdocs.checkFileExists(fullpath,"Additional"):
bibdoc = bibrecdocs.addNewVersion(fullpath,int(mybibdocid))
if fileAction == "AddAdditionalFormat" and mybibdocid != "":
bibdoc = bibrecdocs.addNewFormat(fullpath,int(mybibdocid))
if type == "fulltext" and fileAction != "AddMainFormat" and fileAction != "AddAdditionalFormat":
additionalformats = createRelatedFormats(fullpath)
if len(additionalformats) > 0 and bibdoc != None:
bibdoc.addFilesNewFormat(additionalformats)
if type == "picture" and fileAction != "AddMainFormat" and fileAction != "AddAdditionalFormat":
iconpath = createIcon(fullpath,iconsize)
if iconpath != None and bibdoc != None:
bibdoc.addIcon(iconpath)
os.unlink(iconpath)
elif bibdoc !=None:
bibdoc.deleteIcon()
bibrecdocs.buildBibDocList()
os.unlink(fullpath)
os.unlink("%s/myfile" % curdir)
t+="<form>"
t=t+Display_Form(bibrecdocs)
t=t+Display_File_List(bibrecdocs)
t=t+ "<br><CENTER><small><INPUT TYPE=\"button\" HEIGHT=35 WIDTH=250 NAME=\"Submit\" VALUE=\"End Submission\" onClick=\"step2();\"></small></CENTER>"
t+="</form>"
return t
def Display_File_List(bibrecdocs):
t="""<br><br><table cellpadding=0 cellspacing=0 border=0 bgcolor=#dddddd width=80% align=center><tr><td>"""
bibdocs = bibrecdocs.listBibDocs()
if len(bibdocs) > 0:
types = listTypesFromArray(bibdocs)
for mytype in types:
if len(bibrecdocs.listBibDocs(mytype)) > 1:
plural = "s"
else:
plural = ""
t+="<small><b>%s</b> document%s:</small>" % (mytype,plural)
for bibdoc in bibdocs:
if mytype == bibdoc.getType():
t+="<table cellpadding=0 cellspacing=1 border=0><tr><td bgcolor=\"white\">"
t+="<center><input type=radio name=mybibdocid value=%s><br><br><A href=\"\" onClick=\"if (confirm('Are you sure you want to delete this file?')) { document.forms[0].deletedfile.value='%s';document.forms[0].deleted.value='yes';document.forms[0].submit();return false;} else { return false; }\"><IMG src=%s/smallbin.gif border=0 align=center></a><br></small></center>" % (bibdoc.getId(),bibdoc.getId(),images)
t+="</td><td>"
t+=bibdoc.display()
t+="</td></tr></table>"
t+="""</td></tr></table>"""
return t
def Display_Form(bibrecdocs):
#output the upload files form.
t=""
t=t+"""
<B>Don't forget to click on the \"End Submission\" button when you have finished managing the files.</b><br><br>
<TABLE cellpadding=0 cellspacing=0 border=0 bgcolor=#dddddd width=80% align=center>
<TR>
<TD>
<SMALL>Please complete the form below to upload a new file:</SMALL>
</TD></TR>
<TR><TD>
<INPUT name=deletedfile value=\"\" type=hidden>
<TABLE>
<TR>
<TD ALIGN=center bgcolor=white width=20>
<small><B>1</B></small>
</TD>
<TD>
<small><SELECT name=fileAction>
<option selected> Select:"""
if len(bibrecdocs.listBibDocs("Main")) == 0:
t+="\n<option value=AddMain> Add Main Document"
t+= "<option value=AddAdditional> Add Additional Document"
if len(bibrecdocs.listBibDocs()) != 0:
t+="\n<option value=ReviseAdditional> Revise Document"
t+="\n<option value=AddAdditionalFormat> Add new Format to Document"
t+="""
</SELECT></small>
</TD>
<TD></TD>
</TR>
<TR>
<TD ALIGN=center bgcolor=white width=20>
<small><b>2</B></small>
</TD>
<TD>
<small><INPUT NAME=myfile TYPE="file"> </small>
</TD>
</TR>
<TR>
<TD ALIGN=center bgcolor=white width=20>
<small><B>3</B></small>
</TD>
<TD ALIGN=LEFT>
<small><INPUT TYPE="Submit" WIDTH=150 VALUE="Click to send file" onClick="return checkAdd();"></small>
</TD>
</TR>
</TABLE>
</TD></TR></TABLE>
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
function checkAdd()
{
if (document.forms[0].fileAction.value == "ReviseAdditional" || document.forms[0].fileAction.value =="AddAdditionalFormat")
{
if (getRadioValue(document.forms[0].mybibdocid) == null) {
alert("please choose the document you wish to modify");
return false;
}
else
return true;
}
else if (document.forms[0].fileAction.value == "Select:")
{
alert("please select the type of action (form field #1)");
return false;
}
else
{
return true;
}
}
function getRadioValue (radioButtonOrGroup) {
var value = null;
if (radioButtonOrGroup.length) { // group
for (var b = 0; b < radioButtonOrGroup.length; b++)
if (radioButtonOrGroup[b].checked)
value = radioButtonOrGroup[b].value;
}
else if (radioButtonOrGroup.checked)
value = radioButtonOrGroup.value;
return value;
}
function step2()
{
if(confirm(\"You are about to submit the files and end the upload process.\"))
{
document.forms[0].step.value = 2;
document.forms[0].submit();
}
return true;
}
</SCRIPT> """
return t
def createRelatedFormats(fullpath):
createdpaths = []
filename = re.sub("\..*","",os.path.basename(fullpath))
extension = re.sub("^[^\.]*.","",os.path.basename(fullpath)).lower()
basedir = os.path.dirname(fullpath)
if extension == "pdf":
# Create PostScript
os.system("%s -toPostScript %s" % (acroread,fullpath))
if os.path.exists("%s/%s.ps" % (basedir,filename)):
os.system("%s %s/%s.ps" % (gzip,basedir,filename))
createdpaths.append("%s/%s.ps.gz" % (basedir,filename))
if extension == "ps":
# Create PDF
os.system("%s %s %s/%s.pdf" % (distiller,fullpath,basedir,filename))
if os.path.exists("%s/%s.pdf" % (basedir,filename)):
createdpaths.append("%s/%s.pdf" % (basedir,filename))
if extension == "ps.gz":
#gunzip file
os.system("%s %s" % (gunzip,fullpath))
# Create PDF
os.system("%s %s/%s.ps %s/%s.pdf" % (distiller,basedir,filename,basedir,filename))
if os.path.exists("%s/%s.pdf" % (basedir,filename)):
createdpaths.append("%s/%s.pdf" % (basedir,filename))
#gzip file
os.system("%s %s/%s.ps" % (gzip,basedir,filename))
return createdpaths
def createIcon(fullpath,iconsize):
global convert
basedir = os.path.dirname(fullpath)
filename = os.path.basename(fullpath)
extension = re.sub("^[^\.]*\.","",filename)
if extension == filename:
extension == ""
iconpath = "%s/icon-%s.gif" % (basedir,re.sub("\..*","",filename))
if os.path.exists(fullpath) and extension.lower() in ['pdf','gif','jpg','jpeg','ps']:
os.system("%s -scale %s %s %s" % (convert,iconsize,fullpath,iconpath))
if os.path.exists(iconpath):
return iconpath
else:
return None
diff --git a/modules/websubmit/lib/websubmit_config.py b/modules/websubmit/lib/websubmit_config.py
index 9396bc064..518999fc6 100644
--- a/modules/websubmit/lib/websubmit_config.py
+++ b/modules/websubmit/lib/websubmit_config.py
@@ -1,57 +1,57 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""CDSware Submission Web Interface config file."""
## import config variables defined from config.wml:
from cdsware.config import adminemail, \
supportemail, \
images, \
urlpath, \
accessurl, \
counters, \
storage, \
filedir, \
filedirsize, \
gfile, \
gzip, \
tar, \
gunzip, \
acroread, \
distiller, \
convert, \
tmpdir, \
bibupload, \
bibformat, \
bibwords, \
bibconvert, \
bibconvertconf, \
htdocsurl
## test:
test = "FALSE"
## CC all action confirmation mails to administrator? (0 == NO; 1 == YES)
cfg_websubmit_copy_mails_to_admin = 0
## known compressed file extensions:
cfg_compressed_file_extensions = ["z", "gz", "tar", "tgz", "tar", "tar.gz",
"zip", "rar", "arj", "arc", "pak", "lha", "lhz",
"sit", "sea", "sitx", "cpt", "hqx", "uu", "uue",
"bz", "bz2", "bzip", "tbz", "tbz2", "tar.bz", "tar.bz2"]
diff --git a/modules/websubmit/lib/websubmit_engine.py b/modules/websubmit/lib/websubmit_engine.py
index 9ba997399..63603abac 100644
--- a/modules/websubmit/lib/websubmit_engine.py
+++ b/modules/websubmit/lib/websubmit_engine.py
@@ -1,1161 +1,1161 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
import MySQLdb
import shutil
from mod_python import apache
from cdsware.config import *
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email
from cdsware.websubmit_config import *
from cdsware.file import *
from cdsware.messages import gettext_set_language, wash_language
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
def interface(req,c=cdsname,ln=cdslang, doctype="", act="", startPg=1, indir="", access="",mainmenu="",fromdir="",file="",nextPg="",nbPg="",curpage=1):
ln = wash_language(ln)
# load the right message language
_ = gettext_set_language(ln)
sys.stdout = req
# get user ID:
try:
uid = getUid(req)
uid_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value,req, c, ln)
# variable initialisation
t = ""
field = []
fieldhtml = []
level = []
fullDesc = []
text = []
check = []
select = []
radio = []
upload = []
txt = []
noPage = []
# Preliminary tasks
# check that the user is logged in
if uid_email == "" or uid_email == "guest":
return warningMsg(websubmit_templates.tmpl_warning_message(
ln = ln,
msg = _("Sorry, you must log in to perform this action. Please use the top right menu to do so.")
), req, ln)
# warningMsg("""<center><font color="red"></font></center>""",req, ln)
# check we have minimum fields
if doctype=="" or act=="" or access=="":
return errorMsg(_("invalid parameter"),req, c, ln)
# retrieve the action and doctype data
if indir == "":
res = run_sql("select dir from sbmACTION where sactname=%s",(act,))
if len(res) == 0:
return errorMsg(_("cannot find submission directory"),req, c, ln)
else:
row = res[0]
indir = row[0]
res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s",(doctype,))
if len(res) == 0:
return errorMsg(_("unknown document type"),req, c, ln)
else:
docname = res[0][0]
docname = string.replace(docname," ","&nbsp;")
res = run_sql("SELECT lactname FROM sbmACTION WHERE sactname=%s",(act,))
if len(res) == 0:
return errorMsg(_("unknown action"),req, c, ln)
else:
actname = res[0][0]
actname = string.replace(actname," ","&nbsp;")
subname = "%s%s" % (act,doctype)
res = run_sql("SELECT nbpg FROM sbmIMPLEMENT WHERE subname=%s", (subname,))
if len(res) == 0:
return errorMsg(_("can't figure number of pages"),req, c, ln)
else:
nbpages = res[0][0]
#Get current page
if startPg != "" and (curpage=="" or curpage==0):
curpage = startPg
# retrieve the name of the file in which the reference of
# the submitted document will be stored
res = run_sql("SELECT value FROM sbmPARAMETERS WHERE doctype=%s and name='edsrn'", (doctype,))
if len(res) == 0:
edsrn = ""
else:
edsrn = res[0][0]
# This defines the path to the directory containing the action data
curdir = "%s/%s/%s/%s" % (storage,indir,doctype,access)
# if this submission comes from another one ($fromdir is then set)
# We retrieve the previous submission directory and put it in the proper one
if fromdir != "":
olddir = "%s/%s/%s/%s" % (storage,fromdir,doctype,access)
if os.path.exists(olddir):
os.rename(olddir,curdir)
# If the submission directory still does not exist, we create it
if not os.path.exists(curdir):
try:
os.makedirs(curdir)
except:
return errorMsg(_("can't create submission directory"),req, c, ln)
# retrieve the original main menu url ans save it in the "mainmenu" file
if mainmenu != "":
fp = open("%s/mainmenu" % curdir,"w")
fp.write(mainmenu)
fp.close()
# and if the file containing the URL to the main menu exists
# we retrieve it and store it in the $mainmenu variable
if os.path.exists("%s/mainmenu" % curdir):
fp = open("%s/mainmenu" % curdir,"r");
mainmenu = fp.read()
fp.close()
else:
mainmenu = "%s/submit.py" %urlpath
# various authentication related tasks...
if uid_email != "guest" and uid_email != "":
#First save the username (email address) in the SuE file. This way bibconvert will be able to use it if needed
fp = open("%s/SuE" % curdir,"w")
fp.write(uid_email)
fp.close()
# is user authorized to perform this action?
(auth_code, auth_message) = acc_authorize_action(uid, "submit",verbose=0,doctype=doctype, act=act)
if acc_isRole("submit",doctype=doctype,act=act) and auth_code != 0:
return warningMsg("<center><font color=red>%s</font></center>" % auth_message, req)
# then we update the "journal of submission"
res = run_sql("SELECT * FROM sbmSUBMISSIONS WHERE doctype=%s and action=%s and id=%s and email=%s", (doctype,act,access,uid_email,))
if len(res) == 0:
run_sql("INSERT INTO sbmSUBMISSIONS values (%s,%s,%s,'pending',%s,'',NOW(),NOW())", (uid_email,doctype,act,access,))
else:
run_sql("UPDATE sbmSUBMISSIONS SET md=NOW() WHERE doctype=%s and action=%s and id=%s and email=%s", (doctype,act,access,uid_email,))
# Save the form fields entered in the previous submission page
# If the form was sent with the GET method
form = req.form
value = ""
# we parse all the form variables
for key in form.keys():
formfields = form[key]
if re.search("\[\]",key):
filename = key.replace("[]","")
else:
filename = key
# the field is an array
if isinstance(formfields,types.ListType):
fp = open("%s/%s" % (curdir,filename),"w")
for formfield in formfields:
#stripslashes(value)
value = specialchars(formfield)
fp.write(value+"\n")
fp.close()
# the field is a normal string
elif isinstance(formfields,types.StringTypes) and formfields != "":
value = formfields
fp = open("%s/%s" % (curdir,filename),"w")
fp.write(specialchars(value))
fp.close()
# the field is a file
elif hasattr(formfields,"filename"):
if not os.path.exists("%s/files/%s" % (curdir,key)):
try:
os.makedirs("%s/files/%s" % (curdir,key))
except:
return errorMsg(_("can't create submission directory"),req, c, ln)
filename = formfields.filename
if filename != "":
# This may be dangerous if the file size is bigger than the available memory
data = formfields.file.read()
fp = open("%s/files/%s/%s" % (curdir,key,filename),"w")
fp.write(data)
fp.close()
fp = open("%s/lastuploadedfile" % curdir,"w")
fp.write(filename)
fp.close()
fp = open("%s/%s" % (curdir,key),"w")
fp.write(filename)
fp.close()
# if the found field is the reference of the document
# we save this value in the "journal of submissions"
if uid_email != "" and uid_email != "guest":
if key == edsrn:
run_sql("UPDATE sbmSUBMISSIONS SET reference=%s WHERE doctype=%s and id=%s and email=%s", (value,doctype,access,uid_email,))
# Now deal with the cookies
# If the fields must be saved as a cookie, we do so
# In this case, the value of the field will be retrieved and
# displayed as the default value of the field next time the user
# does a submission
if value!="":
res = run_sql("SELECT cookie FROM sbmFIELDDESC WHERE name=%s", (key,))
if len(res) > 0:
if res[0][0] == 1:
setCookie(key,value,uid)
# create interface
# For each field to be displayed on the page
subname = "%s%s" % (act,doctype)
res = run_sql("SELECT * FROM sbmFIELD WHERE subname=%s and pagenb=%s ORDER BY fieldnb,fieldnb", (subname,curpage,))
full_fields = []
values = []
for arr in res:
full_field = {}
# We retrieve its HTML description
res3 = run_sql("SELECT * FROM sbmFIELDDESC WHERE name=%s", (arr[3],))
arr3 = res3[0]
if arr3[8]==None:
val=""
else:
val=arr3[8]
# we also retrieve and add the javascript code of the checking function, if needed
full_field['javascript'] = ''
if arr[7] != '':
res2 = run_sql("SELECT chdesc FROM sbmCHECKS WHERE chname=%s", (arr[7],))
full_field['javascript'] = res2[0][0]
full_field['type'] = arr3[3]
full_field['name'] = arr[3]
full_field['rows'] = arr3[5]
full_field['cols'] = arr3[6]
full_field['val'] = val
full_field['size'] = arr3[4]
full_field['maxlength'] = arr3[7]
full_field['htmlcode'] = arr3[9]
full_field['typename'] = arr[1]
# The 'R' fields must be executed in the engine's environment,
# as the runtime functions access some global and local
# variables.
if full_field ['type'] == 'R':
co = compile (full_field ['htmlcode'].replace("\r\n","\n"),"<string>","exec")
exec(co)
else:
text = websubmit_templates.tmpl_submit_field (ln = ln, field = full_field)
# we now determine the exact type of the created field
if full_field['type'] not in [ 'D','R']:
field.append(full_field['name'])
level.append(arr[5])
fullDesc.append(arr[4])
txt.append(arr[6])
check.append(arr[7])
# If the field is not user-defined, we try to determine its type
# (select, radio, file upload...)
# check whether it is a select field or not
if re.search("SELECT",text,re.IGNORECASE) != None:
select.append(1)
else:
select.append(0)
# checks whether it is a radio field or not
if re.search(r"TYPE=[\"']?radio",text,re.IGNORECASE) != None:
radio.append(1)
else:
radio.append(0)
# checks whether it is a file upload or not
if re.search(r"TYPE=[\"']?file",text,re.IGNORECASE) != None:
upload.append(1)
else:
upload.append(0)
# if the field description contains the "<COMBO>" string, replace
# it by the category selected on the document page submission page
combofile = "combo%s" % doctype
if os.path.exists("%s/%s" % (curdir,combofile)):
f = open("%s/%s" % (curdir,combofile),"r")
combo = f.read()
f.close()
else:
combo=""
text = text.replace("<COMBO>",combo)
# if there is a <YYYY> tag in it, replace it by the current year
year = time.strftime("%Y");
text = text.replace("<YYYY>",year)
# if there is a <TODAY> tag in it, replace it by the current year
today = time.strftime("%d/%m/%Y");
text = text.replace("<TODAY>",today)
fieldhtml.append(text)
else:
select.append(0)
radio.append(0)
upload.append(0)
# field.append(value) - initial version, not working with JS, taking a submitted value
field.append(arr[3])
level.append(arr[5])
txt.append(arr[6])
fullDesc.append(arr[4])
check.append(arr[7])
fieldhtml.append(text)
full_field['fullDesc'] = arr[4]
full_field['text'] = text
# If a file exists with the name of the field we extract the saved value
text = ''
if os.path.exists("%s/%s" % (curdir,full_field['name'])):
file = open("%s/%s" % (curdir,full_field['name']),"r");
text = file.read()
text = re.compile("[\n\r]*$").sub("",text)
text = re.compile("\n").sub("\\n",text)
text = re.compile("\r").sub("",text)
file.close()
# Or if a cookie is set
# If a cookie is found corresponding to the name of the current
# field, we set the value of the field to the cookie's value
elif getCookie(full_field['name'],uid) != None:
value = getCookie(full_field['name'],uid)
value = re.compile("\r").sub("",value)
value = re.compile("\n").sub("\\n",value)
text = value
values.append(text)
full_fields.append(full_field)
returnto = {}
if int(curpage) == int(nbpages):
subname = "%s%s" % (act,doctype)
res = run_sql("SELECT * FROM sbmFIELD WHERE subname=%s and pagenb!=%s", (subname,curpage,))
nbFields = 0
message = ""
fullcheck_select = []
fullcheck_radio = []
fullcheck_upload = []
fullcheck_field = []
fullcheck_level = []
fullcheck_txt = []
fullcheck_noPage = []
fullcheck_check = []
for arr in res:
if arr[5] == "M":
res2 = run_sql("SELECT * FROM sbmFIELDDESC WHERE name=%s", (arr[3],));
row2 = res2[0]
if row2[3] in ['D','R']:
if row2[3] == "D":
text = row2[9]
else:
text = eval(row2[9])
formfields = text.split(">")
for formfield in formfields:
match = re.match("name=([^ <>]+)",formfield,re.IGNORECASE)
if match != None:
names = match.groups
for value in names:
if value != "":
value = re.compile("[\"']+").sub("",value)
fullcheck_field.append(value)
fullcheck_level.append(arr[5])
fullcheck_txt.append(arr[6])
fullcheck_noPage.append(arr[1])
fullcheck_check.append(arr[7])
nbFields = nbFields+1
else:
fullcheck_noPage.append(arr[1])
fullcheck_field.append(arr[3])
fullcheck_level.append(arr[5])
fullcheck_txt.append(arr[6])
fullcheck_check.append(arr[7])
nbFields = nbFields+1
# tests each mandatory field
fld = 0
res = 1
for i in range (0,nbFields):
res = 1
if not os.path.exists("%s/%s" % (curdir,fullcheck_field[i])):
res=0
else:
file = open("%s/%s" % (curdir,fullcheck_field[i]),"r")
text = file.read()
if text == '':
res=0
else:
if text == "Select:":
res=0
if res == 0:
fld = i
break
if not res:
returnto = {
'field' : fullcheck_txt[fld],
'page' : fullcheck_noPage[fld],
}
t += websubmit_templates.tmpl_page_interface(
ln = ln,
docname = docname,
actname = actname,
curpage = curpage,
nbpages = nbpages,
file = file,
nextPg = nextPg,
access = access,
nbPg = nbPg,
doctype = doctype,
act = act,
indir = indir,
fields = full_fields,
javascript = websubmit_templates.tmpl_page_interface_js(
ln = ln,
upload = upload,
field = field,
fieldhtml = fieldhtml,
txt = txt,
check = check,
level = level,
curdir = curdir,
values = values,
select = select,
radio = radio,
curpage = curpage,
nbpages = nbpages,
images = images,
returnto = returnto,
),
images = images,
mainmenu = mainmenu,
)
# start display:
req.content_type = "text/html"
req.send_http_header()
p_navtrail = """<a href="submit.py">%(submit)s</a>&nbsp;>&nbsp;<a href="submit.py?doctype=%(doctype)s\">%(docname)s</a>&nbsp;""" % {
'submit' : _("Submit"),
'doctype' : doctype,
'docname' : docname,
}
return page(title= actname,
body = t,
navtrail = p_navtrail,
description = "submit documents in CDSWare",
keywords = "submit, CDSWare",
uid = uid,
language = ln,
urlargs = req.args)
def endaction(req,c=cdsname,ln=cdslang, doctype="", act="", startPg=1, indir="", access="",mainmenu="",fromdir="",file="",nextPg="",nbPg="",curpage=1,step=1,mode="U"):
global rn,sysno,dismode,curdir,uid,uid_email,last_step,action_score
# load the right message language
_ = gettext_set_language(ln)
try:
rn
except NameError:
rn = ""
dismode = mode
ln = wash_language(ln)
sys.stdout = req
t=""
# get user ID:
try:
uid = getUid(req)
uid_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value, req, c, ln)
# Preliminary tasks
# check that the user is logged in
if uid_email == "" or uid_email == "guest":
return warningMsg(websubmit_templates.tmpl_warning_message(
ln = ln,
msg = _("Sorry, you must log in to perform this action. Please use the top right menu to do so.")
), req, ln)
# check we have minimum fields
if doctype=="" or act=="" or access=="":
return errorMsg(_("invalid parameter"),req, c, ln)
# retrieve the action and doctype data
if indir == "":
res = run_sql("select dir from sbmACTION where sactname=%s", (act,))
if len(res) == 0:
return errorMsg(_("cannot find submission directory"),req, c, ln)
else:
row = res[0]
indir = row[0]
# The following words are reserved and should not be used as field names
reserved_words = ["stop","file","nextPg","startPg","access","curpage","nbPg","act","indir","doctype","mode","step","deleted","file_path","userfile_name"]
# This defines the path to the directory containing the action data
curdir = "%s/%s/%s/%s" % (storage,indir,doctype,access)
# If the submission directory still does not exist, we create it
if not os.path.exists(curdir):
try:
os.makedirs(curdir)
except:
return errorMsg(_("can't create submission directory"),req, c, ln)
# retrieve the original main menu url ans save it in the "mainmenu" file
if mainmenu != "":
fp = open("%s/mainmenu" % curdir,"w")
fp.write(mainmenu)
fp.close()
# and if the file containing the URL to the main menu exists
# we retrieve it and store it in the $mainmenu variable
if os.path.exists("%s/mainmenu" % curdir):
fp = open("%s/mainmenu" % curdir,"r");
mainmenu = fp.read()
fp.close()
else:
mainmenu = "%s/submit.py" % urlpath
# retrieve the name of the file in which the reference of
# the submitted document will be stored
res = run_sql("SELECT value FROM sbmPARAMETERS WHERE doctype=%s and name='edsrn'",(doctype,))
if len(res) == 0:
edsrn = ""
else:
edsrn = res[0][0]
# Now we test whether the user has already completed the action and
# reloaded the page (in this case we don't want the functions to be called
# once again
# reloaded = Test_Reload(uid_email,doctype,act,access)
# if the action has been completed
#if reloaded:
# return warningMsg("<b> Sorry, this action has already been completed. Please go back to the main menu to start a new action.</b>",req)
# We must determine if the action is finished (ie there is no other steps after the current one
res = run_sql("SELECT step FROM sbmFUNCTIONS WHERE action=%s and doctype=%s and step > %s", (act,doctype,step,))
if len(res) == 0:
finished = 1
else:
finished = 0
# Save the form fields entered in the previous submission page
# If the form was sent with the GET method
form = req.form
value = ""
# we parse all the form variables
for key in form.keys():
formfields = form[key]
if re.search("\[\]",key):
filename = key.replace("[]","")
else:
filename = key
# the field is an array
if isinstance(formfields,types.ListType):
fp = open("%s/%s" % (curdir,filename),"w")
for formfield in formfields:
#stripslashes(value)
value = specialchars(formfield)
fp.write(value+"\n")
fp.close()
# the field is a normal string
elif isinstance(formfields,types.StringTypes) and formfields != "":
value = formfields
fp = open("%s/%s" % (curdir,filename),"w")
fp.write(specialchars(value))
fp.close()
# the field is a file
elif hasattr(formfields,"filename"):
if not os.path.exists("%s/files/%s" % (curdir,key)):
try:
os.makedirs("%s/files/%s" % (curdir,key))
except:
return errorMsg("can't create submission directory",req,cdsname,ln)
filename = formfields.filename
if filename != "":
# This may be dangerous if the file size is bigger than the available memory
data = formfields.file.read()
fp = open("%s/files/%s/%s" % (curdir,key,filename),"w")
fp.write(data)
fp.close()
fp = open("%s/lastuploadedfile" % curdir,"w")
fp.write(filename)
fp.close()
fp = open("%s/%s" % (curdir,key),"w")
fp.write(filename)
fp.close()
# if the found field is the reference of the document
# we save this value in the "journal of submissions"
if uid_email != "" and uid_email != "guest":
if key == edsrn:
run_sql("UPDATE sbmSUBMISSIONS SET reference=%s WHERE doctype=%s and id=%s and email=%s", (value,doctype,access,uid_email,))
# Now deal with the cookies
# If the fields must be saved as a cookie, we do so
# In this case, the value of the field will be retrieved and
# displayed as the default value of the field next time the user
# does a submission
if value!="":
res = run_sql("SELECT cookie FROM sbmFIELDDESC WHERE name=%s", (key,))
if len(res) > 0:
if res[0][0] == 1:
setCookie(key,value,uid)
# Get document name
res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
if len(res) > 0:
docname = res[0][0]
else:
return errorMsg(_("unknown type of document"),req,cdsname,ln)
# Get action name
res = run_sql("SELECT lactname FROM sbmACTION WHERE sactname=%s", (act,))
if len(res) > 0:
actname = res[0][0]
else:
return errorMsg(_("unknown action"),req,cdsname,ln)
# Get number of pages
subname = "%s%s" % (act,doctype)
res = run_sql("SELECT nbpg FROM sbmIMPLEMENT WHERE subname=%s",(subname,))
if len(res) > 0:
nbpages = res[0][0]
else:
return errorMsg(_("this action does not apply on this type of document"),req,cdsname,ln)
# we specify here whether we are in the last step of the action or not
res = run_sql("SELECT step FROM sbmFUNCTIONS WHERE action=%s and doctype=%s and step>%s", (act,doctype,step,))
if len(res) == 0:
last_step = 1
else:
last_step = 0
# Prints the action details, returning the mandatory score
action_score = action_details(doctype,act)
current_level = get_level(doctype, act)
# Calls all the function's actions
function_content = ''
try:
function_content = print_function_calls(doctype, act, step, form)
except functionError,e:
return errorMsg(e.value,req, c, ln)
except functionStop,e:
if e.value != None:
function_content = e.value
else:
function_content = e
# If the action was mandatory we propose the next mandatory action (if any)
next_action = ''
if action_score != -1 and last_step == 1:
next_action = Propose_Next_Action(doctype,action_score,access,current_level,indir)
# If we are in the last step of an action, we can update the "journal of submissions"
if last_step == 1:
if uid_email != "" and uid_email != "guest" and rn != "":
res = run_sql("SELECT * FROM sbmSUBMISSIONS WHERE doctype=%s and action=%s and id=%s and email=%s", (doctype,act,access,uid_email,))
if len(res) == 0:
run_sql("INSERT INTO sbmSUBMISSIONS values(%s,%s,%s,'finished',%s,%s,NOW(),NOW())", (uid_email,doctype,act,access,rn,))
else:
run_sql("UPDATE sbmSUBMISSIONS SET md=NOW(),reference=%s,status='finished' WHERE doctype=%s and action=%s and id=%s and email=%s", (rn,doctype,act,access,uid_email,))
t = websubmit_templates.tmpl_page_endaction(
ln = ln,
weburl = weburl,
# these fields are necessary for the navigation
file = file,
nextPg = nextPg,
startPg = startPg,
access = access,
curpage = curpage,
nbPg = nbPg,
nbpages = nbpages,
doctype = doctype,
act = act,
docname = docname,
actname = actname,
indir = indir,
mainmenu = mainmenu,
finished = finished,
images = images,
function_content = function_content,
next_action = next_action,
)
# start display:
req.content_type = "text/html"
req.send_http_header()
p_navtrail = """<a href="submit.py">""" + _("Submit") +\
"""</a>&nbsp;>&nbsp;<a href="submit.py?doctype=%(doctype)s">%(docname)s</a>""" % {
'doctype' : doctype,
'docname' : docname,
}
return page(title= actname,
body = t,
navtrail = p_navtrail,
description="submit documents in CDSWare",
keywords="submit, CDSWare",
uid = uid,
language = ln,
urlargs = req.args)
def simpleendaction(doctype="", act="", startPg=1, indir="", access="",step=1,mode="U"):
global rn,sysno,dismode,curdir,uid,uid_email,lats_step,action_score
dismode = mode
# check we have minimum fields
if doctype=="" or act=="" or access=="":
return "invalid parameter"
# retrieve the action and doctype data
if indir == "":
res = run_sql("select dir from sbmACTION where sactname=%s", (act,))
if len(res) == 0:
return "cannot find submission directory"
else:
row = res[0]
indir = row[0]
# This defines the path to the directory containing the action data
curdir = "%s/%s/%s/%s" % (storage,indir,doctype,access)
# If the submission directory still does not exist, we create it
if not os.path.exists(curdir):
return "submission directory %s does not exist" % curdir
# retrieve the name of the file in which the reference of
# the submitted document will be stored
res = run_sql("SELECT value FROM sbmPARAMETERS WHERE doctype=%s and name='edsrn'",(doctype,))
if len(res) == 0:
edsrn = ""
else:
edsrn = res[0][0]
# Get document name
res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
if len(res) > 0:
docname = res[0][0]
else:
return "unknown type of document %s" % doctype
# Get action name
res = run_sql("SELECT lactname FROM sbmACTION WHERE sactname=%s", (act,))
if len(res) > 0:
actname = res[0][0]
else:
return "unknown action %s" % act
# Prints the action details, returning the mandatory score
action_score = action_details(doctype,act)
current_level = get_level(doctype, act)
# Calls all the function's actions
print_function_calls(doctype, act, step, "")
return "ok"
def home(req,c=cdsname,ln=cdslang):
"""
Generates and displays the default "home page" for Web-submit - contains a list of links to the various document submissions.
"""
ln = wash_language(ln)
# get user ID:
try:
uid = getUid(req)
except MySQLdb.Error, e:
return errorMsg(e.value)
# start display:
req.content_type = "text/html"
req.send_http_header()
# load the right message language
_ = gettext_set_language(ln)
finaltext = websubmit_templates.tmpl_submit_home_page(
ln = ln,
catalogues = makeCataloguesTable(ln)
)
return page(title=_("Submit"),
body=finaltext,
navtrail=[],
description="submit documents in CDSWare",
keywords="submit, CDSWare",
uid=uid,
language=ln,
urlargs=req.args
)
def makeCataloguesTable(ln):
text = ""
catalogues = []
queryResult = run_sql("SELECT id_son FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father=0 ORDER BY catalogue_order");
if len(queryResult) != 0:
# Query has executed successfully, so we can proceed to display all
# catalogues in the EDS system...
for row in queryResult:
catalogues.append(getCatalogueBranch(row[0], 1))
text = websubmit_templates.tmpl_submit_home_catalogs(
ln = ln,
catalogs = catalogues
)
else:
text = websubmit_templates.tmpl_submit_home_catalog_no_content(ln = ln)
return text
def getCatalogueBranch(id_father,level):
elem = {}
queryResult = run_sql("SELECT name, id FROM sbmCOLLECTION WHERE id=%s", (id_father,))
if len(queryResult) != 0:
row = queryResult[0]
elem['name'] = row[0]
elem['id'] = row[1]
elem['level'] = level
# display the son document types
elem['docs'] = []
res1 = run_sql("SELECT id_son FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_father=%s ORDER BY catalogue_order", (id_father,))
if len(res1) != 0:
for row in res1:
elem['docs'].append(getDoctypeBranch(row[0]))
elem['sons'] = []
res2 = run_sql("SELECT id_son FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father=%s ORDER BY catalogue_order", (id_father,))
if len(res2) != 0:
for row in res2:
elem['sons'].append(getCatalogueBranch(row[0], level + 1))
return elem
def getDoctypeBranch(doctype):
res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
return {'id' : doctype,
'name' : res[0][0],
}
def displayCatalogueBranch(id_father,level,catalogues):
text = ""
queryResult = run_sql("SELECT name, id FROM sbmCOLLECTION WHERE id=%s", (id_father,))
if len(queryResult) != 0:
row = queryResult[0]
if level == 1:
text = "<LI><font size=\"+1\"><strong>%s</strong></font>\n" % row[0]
else:
if level == 2:
text = "<LI>%s\n" % row[0]
else:
if level > 2:
text = "<LI>%s\n" % row[0]
# display the son document types
res1 = run_sql("SELECT id_son FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_father=%s ORDER BY catalogue_order", (id_father,))
res2 = run_sql("SELECT id_son FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father=%s ORDER BY catalogue_order", (id_father,))
if len(res1) != 0 or len(res2) != 0:
text = text + "<UL>\n"
if len(res1) != 0:
for row in res1:
text = text + displayDoctypeBranch(row[0],catalogues)
# display the son catalogues
for row in res2:
catalogues.append(row[0])
text = text + displayCatalogueBranch(row[0],level+1,catalogues)
if len(res1) != 0 or len(res2) != 0:
text = text + "</UL>\n"
return text
def displayDoctypeBranch(doctype,catalogues):
text = ""
res = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
row = res[0]
text = "<LI><a href=\"\" onmouseover=\"javascript:popUpTextWindow('%s',true,event);\" onmouseout=\"javascript:popUpTextWindow('%s',false,event);\" onClick=\"document.forms[0].doctype.value='%s';document.forms[0].submit();return false;\">%s</a>\n" % (doctype,doctype,doctype,row[0])
return text
def action(req,c=cdsname,ln=cdslang,doctype=""):
# load the right message language
_ = gettext_set_language(ln)
nbCateg = 0
snameCateg = []
lnameCateg = []
actionShortDesc = []
indir = []
actionbutton = []
statustext = []
t = ""
ln = wash_language(ln)
# get user ID:
try:
uid = getUid(req)
uid_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value, req, ln)
#parses database to get all data
#first the list of categories
res = run_sql("SELECT * FROM sbmCATEGORIES WHERE doctype=%s ORDER BY lname", (doctype,))
if len(res) > 0:
for arr in res:
nbCateg = nbCateg+1
snameCateg.append(arr[1])
lnameCateg.append(arr[2])
#then data about the document type
res = run_sql("SELECT * FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
if len(res) > 0:
arr = res[0]
docFullDesc = arr[0]
docShortDesc = arr[1]
description = arr[4]
else:
return errorMsg (_("Cannot find document %s") % doctype, req)
#then data about associated actions
res2 = run_sql("SELECT * FROM sbmIMPLEMENT LEFT JOIN sbmACTION on sbmACTION.sactname=sbmIMPLEMENT.actname WHERE docname=%s and displayed='Y' ORDER BY sbmIMPLEMENT.buttonorder", (docShortDesc,))
for arr2 in res2:
res = run_sql("SELECT * FROM sbmACTION WHERE sactname=%s", (arr2[1],))
for arr in res:
actionShortDesc.append(arr[1])
indir.append(arr[2])
actionbutton.append(arr[5])
statustext.append(arr[6])
t = websubmit_templates.tmpl_action_page(
ln = ln,
guest = (uid_email == "" or uid_email == "guest"),
pid = os.getpid(),
now = time.time(),
doctype = doctype,
description = description,
docfulldesc = docFullDesc,
snameCateg = snameCateg,
lnameCateg = lnameCateg,
actionShortDesc = actionShortDesc,
indir = indir,
# actionbutton = actionbutton,
statustext = statustext,
)
p_navtrail = """<a href="submit.py">%(submit)s</a>""" % {'submit' : _("Submit")}
return page(title = docFullDesc,
body=t,
navtrail=p_navtrail,
description="submit documents in CDSWare",
keywords="submit, CDSWare",
uid=uid,
language=ln,
urlargs=req.args
)
def set_report_number (newrn):
global uid_email,doctype,access,rn
# First we save the value in the global object
rn = newrn
# then we save this value in the "journal of submissions"
if uid_email != "" and uid_email != "guest":
run_sql("UPDATE sbmSUBMISSIONS SET reference=%s WHERE doctype=%s and id=%s and email=%s", (newrn,doctype,access,uid_email,))
def get_report_number():
global rn
return rn
def set_sysno (newsn) :
global sysno
sysno = newsn
def get_sysno() :
global sysno
return sysno
def Request_Print(m, txt):
# The argumemts to this function are the display mode (m) and the text to be displayed (txt)
# If the argument mode is 'ALL' then the text is unconditionally echoed
# m can also take values S (Supervisor Mode) and U (User Mode). In these
# circumstances txt is only echoed if the argument mode is the same as
# the current mode
global dismode
if m == "A" or m == dismode:
return txt
else:
return ""
def Evaluate_Parameter (field, doctype):
# Returns the literal value of the parameter. Assumes that the value is
# uniquely determined by the doctype, i.e. doctype is the primary key in
# the table
# If the table name is not null, evaluate the parameter
res = run_sql("SELECT value FROM sbmPARAMETERS WHERE doctype=%s and name=%s", (doctype,field,))
# If no data is found then the data concerning the DEF(ault) doctype is used
if len(res) == 0:
res = run_sql("SELECT value FROM sbmPARAMETERS WHERE doctype='DEF' and name=%s", (field,))
if len(res) == 0:
return ""
else:
if res[0][0] != None:
return res[0][0]
else:
return ""
def Get_Parameters (function, doctype):
# Returns the function parameters, in an array, for the function
# Gets a description of the parameter
parray = {}
res = run_sql("SELECT * FROM sbmFUNDESC WHERE function=%s", (function,))
for i in range(0,len(res)):
parameter = res[i][1]
parray[parameter] = Evaluate_Parameter (parameter , doctype)
return parray
def get_level (doctype, action):
res = run_sql("SELECT * FROM sbmIMPLEMENT WHERE docname=%s and actname=%s", (doctype,action,))
if len(res) > 0:
return res[0][9]
else:
return 0
def action_details (doctype, action):
# Prints whether the action is mandatory or optional. The score of the
# action is returned (-1 if the action was optional)
res = run_sql("SELECT * FROM sbmIMPLEMENT WHERE docname=%s and actname=%s", (doctype,action,))
if len(res)>0:
if res[0][9] != "0":
return res[0][10]
else:
return -1
else:
return -1
def print_function_calls (doctype, action, step, form):
# Calls the functions required by an "action" action on a "doctype" document
# In supervisor mode, a table of the function calls is produced
global htdocsdir,storage,access,pylibdir,dismode
t=""
# Get the list of functions to be called
res = run_sql("SELECT * FROM sbmFUNCTIONS WHERE action=%s and doctype=%s and step=%s ORDER BY score", (action,doctype,step,))
# If no data is found then the data concerning the DEF(ault) doctype is used
if len(res) == 0:
res = run_sql("SELECT * FROM sbmFUNCTIONS WHERE action=%s and doctype='DEF' and step=%s ORDER BY score", (action,step,))
if len(res) > 0:
# while there are functions left...
functions = []
for function in res:
function_name = function[2]
function_score = function[3]
currfunction = {
'name' : function_name,
'score' : function_score,
'error' : 0,
'text' : '',
}
if os.path.exists("%s/cdsware/websubmit_functions/%s.py" % (pylibdir,function_name)):
# import the function itself
#function = getattr(cdsware.websubmit_functions, function_name)
execfile("%s/cdsware/websubmit_functions/%s.py" % (pylibdir,function_name),globals())
if not globals().has_key(function_name):
currfunction['error'] = 1
else:
function = globals()[function_name]
# Evaluate the parameters, and place them in an array
parameters = Get_Parameters(function_name,doctype)
# Call function
currfunction['text'] = function(parameters,curdir,form)
else:
currfunction['error'] = 1
functions.append(currfunction)
t = websubmit_templates.tmpl_function_output(
ln = ln,
display_on = (dismode == 'S'),
action = action,
doctype = doctype,
step = step,
functions = functions,
)
else :
if dismode == 'S':
t = "<br><br><b>" + _("Your chosen action is not supported by the document") + "<b>"
return t
def Propose_Next_Action (doctype,action_score,access,currentlevel,indir):
global machine,storage,act,rn
t=""
res = run_sql("SELECT * FROM sbmIMPLEMENT WHERE docname=%s and level!='0' and level=%s and score>%s ORDER BY score", (doctype,currentlevel,action_score,))
if len(res) > 0:
actions = []
first_score = res[0][10]
for i in range(0,len(res)):
action = res[i]
if action[10] == first_score:
res2 = run_sql("SELECT dir FROM sbmACTION WHERE sactname=%s", (action[1],))
nextdir = res2[0][0]
curraction = {
'page' : action[11],
'action' : action[1],
'doctype' : doctype,
'nextdir' : nextdir,
'access' : access,
'indir' : indir,
'name' : action[12],
}
actions.append(curraction)
t = websubmit_templates.tmpl_next_action(
ln = ln,
actions = actions,
)
return t
def Test_Reload(uid_email,doctype,act,access):
res = run_sql("SELECT * FROM sbmSUBMISSIONS WHERE doctype=%s and action=%s and id=%s and email=%s and status='finished'", (doctype,act,access,uid_email,))
if len(res) > 0:
return 1
else:
return 0
class functionError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class functionStop(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
def errorMsg(title,req,c=cdsname,ln=cdslang):
# load the right message language
_ = gettext_set_language(ln)
return page(title = _("error"),
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
def warningMsg(title,req,c=cdsname,ln=cdslang):
# load the right message language
_ = gettext_set_language(ln)
return page(title = _("warning"),
body = title,
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
def getCookie(name,uid):
# these are not real http cookies but are stored in the DB
res = run_sql("select value from sbmCOOKIES where uid=%s and name=%s", (uid,name,))
if len(res) > 0:
return res[0][0]
else:
return None
def setCookie(name,value,uid):
# these are not real http cookies but are stored in the DB
res = run_sql("select id from sbmCOOKIES where uid=%s and name=%s", (uid,name,))
if len(res) > 0:
run_sql("update sbmCOOKIES set value=%s where uid=%s and name=%s", (value,uid,name,))
else:
run_sql("insert into sbmCOOKIES(name,value,uid) values(%s,%s,%s)", (name,value,uid,))
return 1
def specialchars(text):
text = string.replace(text,"&#147;","\042");
text = string.replace(text,"&#148;","\042");
text = string.replace(text,"&#146;","\047");
text = string.replace(text,"&#151;","\055");
text = string.replace(text,"&#133;","\056\056\056");
return text
diff --git a/modules/websubmit/lib/websubmit_templates.py b/modules/websubmit/lib/websubmit_templates.py
index 7072c8f75..32fe4741f 100644
--- a/modules/websubmit/lib/websubmit_templates.py
+++ b/modules/websubmit/lib/websubmit_templates.py
@@ -1,1930 +1,1930 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
import urllib
import time
import cgi
import gettext
import string
import locale
import re
import operator
import os
from cdsware.config import *
from cdsware.messages import gettext_set_language
class Template:
def tmpl_submit_home_page(self, ln, catalogues):
"""
The content of the home page of the submit engine
Parameters:
- 'ln' *string* - The language to display the interface in
- 'catalogues' *string* - The HTML code for the catalogues list
"""
# load the right message language
_ = gettext_set_language(ln)
return """
<SCRIPT TYPE="text/javascript" LANGUAGE="Javascript1.2">
var allLoaded = 1;
</SCRIPT>
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(document_types)s:</th>
</tr>
<tr>
<td class="portalboxbody">
<BR>
%(please_select)s:
<BR><BR>
<TABLE width="100%%">
<TR>
<TD width="50%%" class="narrowsearchboxbody">
<FORM method=get action="submit.py">
<INPUT type="hidden" name="doctype">
%(catalogues)s
</TD>
</TR>
</TABLE>
</FORM>
</td>
</tr>
</table>""" % {
'document_types' : _("Document types available for submission"),
'please_select' : _("Please select the type of document you want to submit"),
'catalogues' : catalogues,
}
def tmpl_submit_home_catalog_no_content(self, ln):
"""
The content of the home page of submit in case no doctypes are available
Parameters:
- 'ln' *string* - The language to display the interface in
"""
# load the right message language
_ = gettext_set_language(ln)
out = "<h3>" + _("No document types yet...") + "</h3>\n"
return out
def tmpl_submit_home_catalogs(self, ln, catalogs):
"""
Produces the catalogs' list HTML code
Parameters:
- 'ln' *string* - The language to display the interface in
- 'catalogs' *array* - The catalogs of documents, each one a hash with the properties:
- 'id' - the internal id
- 'name' - the name
- 'sons' - sub-catalogs
- 'docs' - the contained document types, in the form:
- 'id' - the internal id
- 'name' - the name
There is at least one catalog
"""
# load the right message language
_ = gettext_set_language(ln)
# import pprint
# out = "<pre>" + pprint.pformat(catalogs)
out = ""
for catalog in catalogs:
out += "<UL>"
out += self.tmpl_submit_home_catalogs_sub(ln, catalog)
return out
def tmpl_submit_home_catalogs_sub(self, ln, catalog):
"""
Recursive function that produces a catalog's HTML display
Parameters:
- 'ln' *string* - The language to display the interface in
- 'catalog' *array* - A catalog of documents, with the properties:
- 'id' - the internal id
- 'name' - the name
- 'sons' - sub-catalogs
- 'docs' - the contained document types, in the form:
- 'id' - the internal id
- 'name' - the name
"""
# load the right message language
_ = gettext_set_language(ln)
if catalog['level'] == 1:
out = "<LI><font size=\"+1\"><strong>%s</strong></font>\n" % catalog['name']
else:
if catalog['level'] == 2:
out = "<LI>%s\n" % catalog['name']
else:
if catalog['level'] > 2:
out = "<LI>%s\n" % catalog['name']
if len(catalog['docs']) or len(catalog['sons']):
out += "<UL>"
if len(catalog['docs']) != 0:
for row in catalog['docs']:
out += self.tmpl_submit_home_catalogs_doctype(ln, row)
if len(catalog['sons']) != 0:
for row in catalog['sons']:
out += self.tmpl_submit_home_catalogs_sub(ln, row)
if len(catalog['docs']) or len(catalog['sons']):
out += "</UL>"
return out
def tmpl_submit_home_catalogs_doctype(self, ln, doc):
"""
Recursive function that produces a catalog's HTML display
Parameters:
- 'ln' *string* - The language to display the interface in
- 'doc' *array* - A catalog of documents, with the properties:
- 'id' - the internal id
- 'name' - the name
"""
# load the right message language
_ = gettext_set_language(ln)
return """<LI><a href="" onClick="document.forms[0].doctype.value='%(id)s';document.forms[0].submit();return false;">%(name)s</a>""" % doc
def tmpl_action_page(self, ln, guest, pid, now, doctype, description, docfulldesc, snameCateg, lnameCateg, actionShortDesc, indir, statustext):
"""
Recursive function that produces a catalog's HTML display
Parameters:
- 'ln' *string* - The language to display the interface in
- 'guest' *boolean* - If the user is logged in or not
- 'pid' *string* - The current process id
- 'now' *string* - The current time (security control features)
- 'doctype' *string* - The selected doctype
- 'description' *string* - The description of the doctype
- 'docfulldesc' *string* - The title text of the page
- 'snameCateg' *array* - The short names of all the categories of documents
- 'lnameCateg' *array* - The long names of all the categories of documents
- 'actionShortDesc' *array* - The short names (codes) for the different actions
- 'indir' *array* - The directories for each of the actions
- 'statustext' *array* - The names of the different action buttons
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
out += """
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
var checked = 0;
function tester() {
"""
if (guest):
out += "alert(\"%(please_login_js)s\");return false;\n" % {
'please_login_js' : _("please log in first.\\nUse the top right menu to log in.")
}
out += """
if (checked == 0) {
alert ("%(select_cat)s");
return false;
} else {
return true;
}
}
function clicked() {
checked=1;
}
function selectdoctype(nb) {
document.forms[0].act.value = docname[nb];
}
</SCRIPT>
<FORM method="get" action="submit.py">
<INPUT type="hidden" name="doctype" value="%(doctype)s">
<INPUT type="hidden" name="indir">
<input type="hidden" name="access" value="%(now)i_%(pid)s">
<INPUT type="hidden" name="act">
<INPUT type="hidden" name="startPg" value="1">
<INPUT type="hidden" name="mainmenu" value="submit.py?doctype=%(doctype)s">
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(docfulldesc)s</th>
</tr>
<tr>
<td class="portalboxbody">%(description)s
<BR>
<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
var nbimg = document.images.length + 1;
</SCRIPT>
<BR>
<TABLE align="center" cellpadding="0" cellspacing="0" border="0">
<TR valign="top">
""" % {
'select_cat' : _("please select a category"),
'doctype' : doctype,
'now' : now,
'pid' : pid,
'docfulldesc' : docfulldesc,
'description' : description,
}
if len(snameCateg) :
out += """<TD align="right">"""
for i in range(0, len(snameCateg)):
out += """%(longname)s<INPUT type="radio" name="combo%(doctype)s" value="%(shortname)s" onClick="clicked();">&nbsp;<BR />""" % {
'longname' : lnameCateg[i],
'doctype' : doctype,
'shortname' : snameCateg[i],
}
out += "</TD>"
else:
out += "<SCRIPT>checked=1;</SCRIPT>"
out += """<TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
<td>
<table>
"""
#display list of actions
for i in range(0,len(actionShortDesc)):
out += """<input type="submit" class="adminbutton" value="%(status)s" onClick="if (tester()) { document.forms[0].indir.value='%(indir)s';document.forms[0].act.value='%(act)s';document.forms[0].submit();}; return false;"><br>""" % {
'status' : statustext[i],
'indir' : indir[i],
'act' : actionShortDesc[i]
}
out += """ </TABLE>
</TD>
</TR>
</TABLE>
<BR>"""
if len(snameCateg) :
out += """<STRONG class="headline">%(notice)s:</STRONG><BR>
%(select_cat)s""" % {
'notice' : _("Notice"),
'select_cat' : _("Select a category and then click the button to perform the action you chose."),
}
out += """
<BR><BR>
<BR>
</FORM>
<FORM action="submit.py"><HR>
<font color="black"><small>%(continue_explain)s</small></FONT>
<TABLE border=0 bgcolor="#CCCCCC" width="100%%"><TR>
<TD width="100%%">
<small>Access Number: <INPUT size=15 name=AN>
<INPUT type="hidden" name="doctype" value="%(doctype)s">
<INPUT class="adminbutton" type="submit" value=" %(go)s ">
</small>
</TD></TR>
</TABLE>
<HR>
</FORM>
</td>
</tr>
</table>""" % {
'continue_explain' : _("To continue an interrupted submission, enter your access number directly in the input box."),
'doctype' : doctype,
'go' : _("go"),
}
return out
def tmpl_warning_message(self, ln, msg):
"""
Produces a warning message for the specified text
Parameters:
- 'ln' *string* - The language to display the interface in
- 'msg' *string* - The message to display
"""
# load the right message language
_ = gettext_set_language(ln)
return """<center><font color="red">%s</font></center>""" % msg
def tmpl_page_interface(self, ln, docname, actname, curpage, nbpages, file, nextPg, access, nbPg, doctype, act, indir, fields, javascript, images, mainmenu):
"""
Produces a page with the specified fields (in the submit chain)
Parameters:
- 'ln' *string* - The language to display the interface in
- 'doctype' *string* - The document type
- 'docname' *string* - The document type name
- 'actname' *string* - The action name
- 'act' *string* - The action
- 'curpage' *int* - The current page of submitting engine
- 'nbpages' *int* - The total number of pages
- 'nextPg' *int* - The next page
- 'access' *string* - The submission number
- 'nbPg' *string* - ??
- 'indir' *string* - the directory of submitting
- 'fields' *array* - the fields to display in the page, with each record having the structure:
- 'fullDesc' *string* - the description of the field
- 'text' *string* - the HTML code of the field
- 'javascript' *string* - if the field has some associated javascript code
- 'type' *string* - the type of field (T, F, I, H, D, S, R)
- 'name' *string* - the name of the field
- 'rows' *string* - the number of rows for textareas
- 'cols' *string* - the number of columns for textareas
- 'val' *string* - the default value of the field
- 'size' *string* - the size for text fields
- 'maxlength' *string* - the maximum length for text fields
- 'htmlcode' *string* - the complete HTML code for user-defined fields
- 'typename' *string* - the long name of the type
- 'javascript' *string* - the javascript code to insert in the page
- 'images' *string* - the path to the images
- 'mainmenu' *string* - the url of the main menu
"""
# load the right message language
_ = gettext_set_language(ln)
# top menu
out = """
<FORM method="POST" action="submit.py" onSubmit="return tester();">
<center><TABLE cellspacing="0" cellpadding="0" border="0">
<TR>
<TD class="submitHeader"><B>%(docname)s&nbsp;</B></TD>
<TD class="submitHeader"><small>&nbsp;%(actname)s&nbsp;</small></TD>
<TD valign="bottom">
<TABLE cellspacing="0" cellpadding="0" border="0" width="100%%">
<TR><TD class="submitEmptyPage">&nbsp;&nbsp;</TD>
""" % {
'docname' : docname,
'actname' : actname,
}
for i in range(1, nbpages+1):
if i == int(curpage):
out += """<TD class="submitCurrentPage"><small>&nbsp;page: %s&nbsp;</small></TD>""" % curpage
else:
out += """<TD class="submitPage"><small>&nbsp;<A HREF='' onClick="if (tester2() == 1){document.forms[0].curpage.value=%s;document.forms[0].submit();return false;} else { return false; }">%s</A>&nbsp;</small></TD>""" % (i,i)
out += """ <TD class="submitEmptyPage">&nbsp;&nbsp;
</TD></TR></TABLE>
</TD>
<TD class="submitHeader" align="right">&nbsp;<A HREF='' onClick="window.open('summary.py?doctype=%(doctype)s&act=%(act)s&access=%(access)s&indir=%(indir)s','summary','scrollbars=yes,menubar=no,width=500,height=250');return false;"><font color="white"><small>%(summary)s(2)</small></font></A>&nbsp;</TD>
</TR>
<TR><TD colspan="5" class="submitHeader">
<TABLE border="0" cellspacing="0" cellpadding="15" width="100%%" class="submitBody"><TR><TD>
<BR>
<INPUT type="hidden" name="file" value="%(file)s">
<INPUT type="hidden" name="nextPg" value="%(nextPg)s">
<INPUT type="hidden" name="access" value="%(access)s">
<INPUT type="hidden" name="curpage" value="%(curpage)s">
<INPUT type="hidden" name="nbPg" value="%(nbPg)s">
<INPUT type="hidden" name="doctype" value="%(doctype)s">
<INPUT type="hidden" name="act" value="%(act)s">
<INPUT type="hidden" name="indir" value="%(indir)s">
<INPUT type="hidden" name="mode" value="U">
<INPUT type="hidden" name="step" value="0">
""" % {
'summary' : _("SUMMARY"),
'doctype' : doctype,
'act' : act,
'access' : access,
'indir' : indir,
'file' : file,
'nextPg' : nextPg,
'curpage' : curpage,
'nbPg' : nbPg,
}
for field in fields:
if field['javascript']:
out += """<SCRIPT LANGUAGE="JavaScript1.1" TYPE="text/javascript">
%s
</SCRIPT>
""" % field['javascript'];
# now displays the html form field(s)
out += "%s\n%s\n" % (field['fullDesc'], field['text'])
out += javascript
out += "<BR>&nbsp;<BR>&nbsp;</TD></TR></TABLE></TD></TR>\n"
# Display the navigation cell
# Display "previous page" navigation arrows
out += """<TR><TD colspan="5"><TABLE border="0" cellpadding="0" cellspacing="0" width="100%%"><TR>"""
if int(curpage) != 1:
out += """ <TD class="submitHeader" align="left">&nbsp;
<A HREF='' onClick="if (tester2() == 1) {document.forms[0].curpage.value=%(prpage)s;document.forms[0].submit();return false;} else { return false; }">
<IMG SRC="%(images)s/left-trans.gif" alt="%(prevpage)s" border="0">
<strong><font color="white">%(prevpage)s</font></strong>
</A>
</TD>
""" % {
'prpage' : int(curpage) - 1,
'images' : images,
'prevpage' : _("previous page"),
}
else:
out += """ <TD class="submitHeader">&nbsp;</TD>"""
# Display the submission number
out += """ <TD class="submitHeader" align="center"><small>%(submission)s: %(access)s</small></TD>\n""" % {
'submission' : _("Submission no(1)"),
'access' : access,
}
# Display the "next page" navigation arrow
if int(curpage) != int(nbpages):
out += """ <TD class="submitHeader" align="right">
<A HREF='' onClick="if (tester2()){document.forms[0].curpage.value=%(nxpage)s;document.forms[0].submit();return false;} else {return false;}; return false;">
<strong><font color="white">%(nextpage)s</font></strong>
<IMG SRC="%(images)s/right-trans.gif" alt="%(nextpage)s" border="0">
</A>
</TD>
""" % {
'nxpage' : int(curpage) + 1,
'images' : images,
'nextpage' : _("next page"),
}
else:
out += """ <TD class="submitHeader">&nbsp;</TD>"""
out += """</TR></TABLE></TD></TR></TABLE></center></FORM>
<BR>
<BR>
<A HREF="%(mainmenu)s" onClick="return confirm('%(surequit)s')">
<IMG SRC="%(images)s/mainmenu.gif" border="0" ALT="%(back)s" align="right"></A>
<BR><BR>
<HR>
<small>%(take_note)s</small><BR>
<small>%(explain_summary)s</small><BR>
""" % {
'surequit' : _("Are you sure you want to quit this submission?"),
'back' : _("back to main menu"),
'mainmenu' : mainmenu,
'images' : images,
'take_note' : _("(1) you should take note of this number at the beginning of the submission, it will allow you to get your information back in case your browser crashes before the end of the submission."),
'explain_summary' : _("(2) mandatory fields appear in red in the 'Summary' window."),
}
return out
def tmpl_submit_field(self, ln, field):
"""
Produces the HTML code for the specified field
Parameters:
- 'ln' *string* - The language to display the interface in
- 'field' *array* - the field to display in the page, with the following structure:
- 'javascript' *string* - if the field has some associated javascript code
- 'type' *string* - the type of field (T, F, I, H, D, S, R)
- 'name' *string* - the name of the field
- 'rows' *string* - the number of rows for textareas
- 'cols' *string* - the number of columns for textareas
- 'val' *string* - the default value of the field
- 'size' *string* - the size for text fields
- 'maxlength' *string* - the maximum length for text fields
- 'htmlcode' *string* - the complete HTML code for user-defined fields
- 'typename' *string* - the long name of the type
"""
# load the right message language
_ = gettext_set_language(ln)
# If the field is a textarea
if field['type'] == 'T':
text="<TEXTAREA name=\"%s\" rows=\"%s\" cols=\"%s\">%s</TEXTAREA>" % (field['name'],field['rows'],field['cols'],field['val'])
# If the field is a file upload
elif field['type'] == 'F':
text="<INPUT TYPE=file name=\"%s\" size=\"%s\" maxlength=\"%s\">" % (field['name'],field['size'], field['maxlength']);
# If the field is a text input
elif field['type'] == 'I':
text="<INPUT name=\"%s\" size=\"%s\" value=\"%s\">" % (field['name'],field['size'],field['val'])
# If the field is a hidden input
elif field['type'] == 'H':
text="<INPUT type=\"hidden\" name=\"%s\" value=\"%s\">" % (field['name'],field['val'])
# If the field is user-defined
elif field['type'] == 'D':
text=field['htmlcode']
# If the field is a select box
elif field['type'] == 'S':
text=field['htmlcode']
# If the field type is not recognized
else:
text="%s: unknown field type" % field['typename']
return text
def tmpl_page_interface_js(self, ln, upload, field, fieldhtml, txt, check, level, curdir, values, select, radio, curpage, nbpages, images, returnto):
"""
Produces the javascript for validation and value filling for a submit interface page
Parameters:
- 'ln' *string* - The language to display the interface in
- 'upload' *array* - booleans if the field is a <input type="file"> field
- 'field' *array* - the fields' names
- 'fieldhtml' *array* - the fields' HTML representation
- 'txt' *array* - the fields' long name
- 'check' *array* - if the fields should be checked (in javascript)
- 'level' *array* - strings, if the fields should be filled (M) or not (O)
- 'curdir' *array* - the current directory of the submission
- 'values' *array* - the current values of the fields
- 'select' *array* - booleans, if the controls are "select" controls
- 'radio' *array* - booleans, if the controls are "radio" controls
- 'curpage' *int* - the current page
- 'nbpages' *int* - the total number of pages
- 'images' *int* - the path to the images
- 'returnto' *array* - a structure with 'field' and 'page', if a mandatory field on antoher page was not completed
"""
# load the right message language
_ = gettext_set_language(ln)
nbFields = len(upload)
# if there is a file upload field, we change the encoding type
out = """<SCRIPT LANGUAGE="JavaScript1.1" TYPE="text/javascript">
"""
for i in range(0,nbFields):
if upload[i] == 1:
out += "document.forms[0].encoding = \"multipart/form-data\";\n"
break
# we don't want the form to be submitted if the user enters 'Return'
# tests if mandatory fields are well filled
out += """function tester(){
return false;
}
function tester2() {
"""
for i in range(0,nbFields):
if re.search("%s\[\]" % field[i],fieldhtml[i]):
fieldname = "%s[]" % field[i]
else:
fieldname = field[i]
out += " el = document.forms[0].elements['%s'];\n" % fieldname
# If the field must be checked we call the checking function
if check[i] != "":
out += """if (%(check)s(el.value) == 0) {
el.focus();
return 0;
} """ % {
'check' : check[i]
}
# If the field is mandatory, we check a value has been selected
if level[i] == 'M':
if select[i] != 0:
# If the field is a select box
out += """if ((el.selectedIndex == -1)||(el.selectedIndex == 0)){
alert("%(field_mandatory)s");
return 0;
} """ % {
'field_mandatory' : _("The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box") % txt[i]
}
elif radio[i] != 0:
# If the field is a radio buttonset
out += """var check=0;
for (var j = 0; j < el.length; j++) {
if (el.options[j].checked){
check++;
}
}
if (check == 0) {
alert("%(press_button)s");
return 0;
}""" % {
'press_button':_("Please press a button.")
}
else:
# If the field is a text input
out += """if (el.value == '') {
alert("%(field_mandatory)s");
return 0;
}""" % {
'field_mandatory' : _("The field `%s` is Mandatory. Please fill it in.") % txt[i]
}
out += """ return 1;
}
<!-- Fill the fields in with the previous saved values-->
"""
# # # # # # # # # # # # # # # # # # # # # # # # #
# Fill the fields with the previously saved values
# # # # # # # # # # # # # # # # # # # # # # # # #
for i in range(0,nbFields):
if re.search("%s\[\]"%field[i],fieldhtml[i]):
fieldname = "%s[]" % field[i]
else:
fieldname = field[i]
text = values[i]
if text != '':
if select[i] != 0:
# If the field is a SELECT element
vals = text.split("\n")
tmp=""
for val in vals:
if tmp != "":
tmp = tmp + " || "
tmp = tmp + "el.options[j].value == \"%s\" || el.options[j].text == \"%s\"" % (val,val)
if tmp != "":
out += """
<!--SELECT field found-->
el = document.forms[0].elements['%(fieldname)s'];
for (var j = 0; j < el.length; j++){
if (%(tmp)s){
el.options[j].selected = true;
}
}""" % {
'fieldname' : fieldname,
'tmp' : tmp,
}
elif radio[i] != 0:
# If the field is a RADIO element
out += """<!--RADIO field found-->
el = document.forms[0].elements['%(fieldname)s'];
if (el.value == "%(text)s"){
el.checked=true;
}""" % {
'fieldname' : fieldname,
'text' : text,
}
elif upload[i] == 0:
text = text.replace('"','\"')
text = text.replace("\n","\\n")
# If the field is not an upload element
out += """<!--INPUT field found-->
el = document.forms[0].elements['%(fieldname)s'];
el.value="%(text)s";
""" % {
'fieldname' : fieldname,
'text' : text,
}
out += """<!--End Fill in section-->
"""
# JS function finish
# This function tests each mandatory field in the whole submission and checks whether
# the field has been correctly filled in or not
# This function is called when the user presses the "End
# Submission" button
if int(curpage) == int(nbpages):
out += """function finish() {
"""
if returnto:
out += """alert ("%(msg)s");
document.forms[0].curpage.value="%(page)s";
document.forms[0].submit();
}
""" % {
'msg' : _("The field '%(field)s' is mandatory.\\nGoing back to page %(page)s") % returnto,
'page' : returnto['page']
}
else:
out += """ if (tester2()) {
document.forms[0].action="submit.py";
document.forms[0].step.value=1;
document.forms[0].submit();
} else {
return false;
}
}"""
out += """</SCRIPT>"""
return out
def tmpl_page_endaction(self, ln, weburl, file, nextPg, startPg, access, curpage, nbPg, nbpages, doctype, act, docname, actname, indir, mainmenu, finished, function_content, next_action, images):
"""
Produces the pages after all the fields have been submitted.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The url of cdsware
- 'doctype' *string* - The document type
- 'act' *string* - The action
- 'docname' *string* - The document type name
- 'actname' *string* - The action name
- 'curpage' *int* - The current page of submitting engine
- 'startPg' *int* - The start page
- 'nextPg' *int* - The next page
- 'access' *string* - The submission number
- 'nbPg' *string* - total number of pages
- 'nbpages' *string* - number of pages (?)
- 'indir' *string* - the directory of submitting
- 'file' *string* - ??
- 'mainmenu' *string* - the url of the main menu
- 'finished' *bool* - if the submission is finished
- 'images' *string* - the path to the images
- 'function_content' *string* - HTML code produced by some function executed
- 'next_action' *string* - if there is another action to be completed, the HTML code for linking to it
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<FORM ENCTYPE="multipart/form-data" action="submit.py" method="POST">
<INPUT type="hidden" name="file" value="%(file)s">
<INPUT type="hidden" name="nextPg" value="%(nextPg)s">
<INPUT type="hidden" name="startPg" value="%(startPg)s">
<INPUT type="hidden" name="access" value="%(access)s">
<INPUT type="hidden" name="curpage" value="%(curpage)s">
<INPUT type="hidden" name="nbPg" value="%(nbPg)s">
<INPUT type="hidden" name="doctype" value="%(doctype)s">
<INPUT type="hidden" name="act" value="%(act)s">
<INPUT type="hidden" name="indir" value="%(indir)s">
<INPUT type="hidden" name="fromdir" value="">
<INPUT type="hidden" name="mainmenu" value="%(mainmenu)s">
<INPUT type="hidden" name="mode" value="U">
<INPUT type="hidden" name="step" value="1">
<INPUT type="hidden" name="deleted" value="no">
<INPUT type="hidden" name="file_path" value="">
<INPUT type="hidden" name="userfile_name" value="">
<center><TABLE cellspacing="0" cellpadding="0" border="0"><TR>
<TD class="submitHeader"><B>%(docname)s&nbsp;</B></TD>
<TD class="submitHeader"><small>&nbsp;%(actname)s&nbsp;</small></TD>
<TD valign="bottom">
<TABLE cellspacing="0" cellpadding="0" border="0" width="100%%">
<TR><TD class="submitEmptyPage">&nbsp;&nbsp;</TD>
""" % {
'file' : file,
'nextPg' : nextPg,
'startPg' : startPg,
'access' : access,
'curpage' : curpage,
'nbPg' : nbPg,
'doctype' : doctype,
'act' : act,
'docname' : docname,
'actname' : actname,
'indir' : indir,
'mainmenu' : mainmenu,
}
if finished == 1:
out += """<TD class="submitCurrentPage">%(finished)s</TD>
<TD class="submitEmptyPage">&nbsp;&nbsp;</TD>
</TR></TABLE>
</TD>
<TD class="submitEmptyPage" align="right">&nbsp;</TD>
""" % {
'finished' : _("finished!"),
}
else:
for i in range(1, nbpages + 1):
out += """<TD class="submitPage"><small>&nbsp;
<A HREF='' onClick="document.forms[0].curpage.value=%s;document.forms[0].action='submit.py';document.forms[0].step.value=0;document.forms[0].submit();return false;">%s</A>&nbsp;</small></TD>""" % (i,i)
out += """<TD class="submitCurrentPage">%(end_action)s</TD><TD class="submitEmptyPage">&nbsp;&nbsp;</TD></TR></TABLE></TD>
<TD class="submitHeader" align="right">&nbsp;<A HREF='' onClick="window.open('summary.py?doctype=%(doctype)s&act=%(act)s&access=%(access)s&indir=%(indir)s','summary','scrollbars=yes,menubar=no,width=500,height=250');return false;"><font color="white"><small>%(summary)s(2)</small></font></A>&nbsp;</TD>""" % {
'end_action' : _("end of action"),
'summary' : _("SUMMARY"),
'doctype' : doctype,
'act' : act,
'access' : access,
'indir' : indir,
}
out += """</TR>
<TR>
<TD colspan="5" class="submitBody">
<small><BR><BR>
%(function_content)s
%(next_action)s
<BR><BR>
</TD>
</TR>
<TR class="submitHeader">
<TD class="submitHeader" colspan="5" align="center">""" % {
'function_content' : function_content,
'next_action' : next_action,
}
if finished == 0:
out += """<small>%(submission)s</small>&sup2;:
<small>%(access)s</small>""" % {
'submission' : _("Submission no"),
'access' : access,
}
else:
out += "&nbsp;\n"
out += """
</TD>
</TR>
</TABLE>
</center>
</form>
<br>
<br>"""
# Add the "back to main menu" button
if finished == 0:
out += """ <A HREF="%(mainmenu)s" onClick="return confirm('%(surequit)s')">""" % {
'surequit' : _("Are you sure you want to quit this submission?"),
'mainmenu' : mainmenu,
}
else:
out += """ <A HREF="%(mainmenu)s">
<IMG SRC="%(images)s/mainmenu.gif" border="0" ALT="%(back)s" align="right"></A>
<BR><BR>""" % {
'back' : _("back to main menu"),
'images' : images,
'mainmenu' : mainmenu,
}
return out
def tmpl_function_output(self, ln, display_on, action, doctype, step, functions):
"""
Produces the output of the functions.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'display_on' *bool* - If debug information should be displayed
- 'doctype' *string* - The document type
- 'action' *string* - The action
- 'step' *int* - The current step in submission
- 'functions' *aray* - HTML code produced by functions executed and informations about the functions
- 'name' *string* - the name of the function
- 'score' *string* - the score of the function
- 'error' *bool* - if the function execution produced errors
- 'text' *string* - the HTML code produced by the function
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
if display_on:
out += """<br><br>%(function_list)s<P>
<table border="1" cellpadding="15">
<tr><th>%(function)s</th><th>%(score)s</th><th>%(running)s</th></tr>
""" % {
'function_list' : _("Here is the %(action)s function list for %(doctype)s documents at level %(step)s") % {
'action' : action,
'doctype' : doctype,
'step' : step,
},
'function' : _("Function"),
'score' : _("Score"),
'running' : _("Running Function"),
}
for function in functions:
out += """<tr><td>%(name)s</td><td>%(score)s</td><td>%(result)s</td></tr>""" % {
'name' : function['name'],
'score' : function['score'],
'result' : function['error'] and (_("function %s does not exist...") % function['name'] + "<br>") or function['text']
}
out += "</table>"
else:
for function in functions:
if not function['error']:
out += function['text']
return out
def tmpl_next_action(self, ln, actions):
"""
Produces the output of the functions.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'actions' *array* - The actions to display, in the structure
- 'page' *string* - the starting page
- 'action' *string* - the action (in terms of submission)
- 'doctype' *string* - the doctype
- 'nextdir' *string* - the path to the submission data
- 'access' *string* - the submission number
- 'indir' *string* - ??
- 'name' *string* - the name of the action
"""
# load the right message language
_ = gettext_set_language(ln)
out = "<BR><BR>%(haveto)s<ul>" % {
'haveto' : _("You now have to"),
}
i = 0
for action in actions:
if i > 0:
out += " <b>" + _("or") + "</b> "
i += 1
out += """<LI><A HREF="" onClick="document.forms[0].action='submit.py';document.forms[0].curpage.value='%(page)s';document.forms[0].startPg.value='%(page)s';document.forms[0].act.value='%(action)s';document.forms[0].doctype.value='%(doctype)s';document.forms[0].indir.value='%(nextdir)s';document.forms[0].access.value='%(access)s';document.forms[0].fromdir.value='%(indir)s';document.forms[0].submit();return false;"> %(name)s </a>""" % action
out += "</ul>"
return out
def tmpl_filelist(self, ln, filelist, recid, docid, version):
"""
Displays the file list for a record.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'recid' *string* - The record id
- 'docid' *string* - The document id
- 'version' *string* - The version of the document
- 'filelist' *string* - The HTML string of the filelist (produced by the BibDoc classes)
"""
# load the right message language
_ = gettext_set_language(ln)
title = _("record #%s") % ("<a href=\"search.py?recid=%s\">%s</a>" % (recid,recid))
if docid != "":
title += _(" document #%s") % docid
if version != "":
title += _(" version #%s") % version
out = """<center><table class="searchbox" summary="" width="500"><tr><th class="portalboxheader">Access&nbsp;to&nbsp;Fulltext&nbsp;&nbsp;&nbsp;&nbsp;<font size=-2>[%s]</font></th></tr><tr><td class="portalboxbody"><!--start file list-->
%s
<!--end file list--></td></tr></table></center>
""" % (title, filelist)
return out
def tmpl_bibrecdoc_filelist(self, ln, types):
"""
Displays the file list for a record.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'types' *array* - The different types to display, each record in the format:
- 'name' *string* - The name of the format
- 'content' *array of string* - The HTML code produced by tmpl_bibdoc_filelist, for the right files
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
for mytype in types:
out += "<small><b>%s</b> %s:</small>" % (mytype['name'], _("file(s)"))
out += "<ul>"
for content in mytype['content']:
out += content
out += "</ul>"
return out
def tmpl_bibdoc_filelist(self, ln, weburl, versions, imagepath, docname, id):
"""
Displays the file list for a record.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The url of cdsware
- 'versions' *array* - The different versions to display, each record in the format:
- 'version' *string* - The version
- 'content' *string* - The HTML code produced by tmpl_bibdocfile_filelist, for the right file
- 'previous' *bool* - If the file has previous versions
- 'imagepath' *string* - The path to the image of the file
- 'docname' *string* - The name of the document
- 'id' *int* - The id of the document
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<table border="0" cellspacing="1" class="searchbox">
<tr>
<td align="left" colspan="2" class="portalboxheader">
<img src='%(imagepath)s' border=0>&nbsp;&nbsp;%(docname)s
</td>
</tr>""" % {
'imagepath' : imagepath,
'docname' : docname
}
for version in versions:
if version['previous']:
versiontext = """<br>(%(see)s <a href="%(weburl)s/getfile.py?docid=%(id)s&version=all">%(previous)s</a>)""" % {
'see' : _("see"),
'weburl' : weburl,
'id' : id,
'previous': _("previous"),
}
else:
versiontext = ""
out += """<tr>
<td class="portalboxheader">
<font size="-2">%(version)s %(ver)s%(text)s</font>
</td>
<td>
<table>
""" % {
'version' : _("version"),
'ver' : version['version'],
'text' : versiontext,
}
for content in version['content']:
out += content
out += "</table></td></tr>"
out += "</table>"
return out
def tmpl_bibdocfile_filelist(self, ln, weburl, id, name, selfformat, version, format, size):
"""
Displays a file in the file list.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'weburl' *string* - The url of cdsware
- 'id' *int* - The id of the document
- 'name' *string* - The name of the file
- 'selfformat' *string* - The format to pass in parameter
- 'version' *string* - The version
- 'format' *string* - The display format
- 'size' *string* - The size of the file
"""
# load the right message language
_ = gettext_set_language(ln)
return """<tr>
<td valign="top">
<small><a href="%(weburl)s/getfile.py?docid=%(docid)s&name=%(quotedname)s&format=%(selfformat)s&version=%(version)s">
%(name)s%(format)s
</a></small>
</td>
<td valign="top">
<font size="-2" color="green">[%(size)s&nbsp;B]</font>
</td></tr>""" % {
'weburl' : weburl,
'docid' : id,
'quotedname' : urllib.quote(name),
'selfformat' : urllib.quote(selfformat),
'version' : version,
'name' : name,
'format' : format,
'size' : size
}
def tmpl_submit_summary (self, ln, values, images):
"""
Displays the summary for the submit procedure.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'values' *array* - The values of submit. Each of the records contain the following fields:
- 'name' *string* - The name of the field
- 'mandatory' *bool* - If the field is mandatory or not
- 'value' *string* - The inserted value
- 'page' *int* - The submit page on which the field is entered
- 'images' *string* - the path to the images
"""
# load the right message language
_ = gettext_set_language(ln)
out = """<body style="background-image: url(%(images)s/header_background.gif);"><table border="0">""" % \
{ 'images' : images }
for value in values:
if value['mandatory']:
color = "red"
else:
color = ""
out += """<tr>
<td align="right">
<small>
<A HREF='' onClick="window.opener.document.forms[0].curpage.value='%(page)s';window.opener.document.forms[0].action='submit.py';window.opener.document.forms[0].submit();return false;">
<FONT color="%(color)s">%(name)s</FONT>
</A>
</small>
</td>
<td>
<I><small><font color="black">%(value)s</font></small></I>
</td>
</tr>""" % {
'color' : color,
'name' : value['name'],
'value' : value['value'],
'page' : value['page']
}
out += "</table>"
return out
def tmpl_yoursubmissions(self, ln, images, weburl, order, doctypes, submissions):
"""
Displays the list of the user's submissions.
Parameters:
- 'ln' *string* - The language to display the interface in
- 'images' *string* - the path to the images
- 'weburl' *string* - The url of cdsware
- 'order' *string* - The ordering parameter
- 'doctypes' *array* - All the available doctypes, in structures:
- 'id' *string* - The doctype id
- 'name' *string* - The display name of the doctype
- 'selected' *bool* - If the doctype should be selected
- 'submissions' *array* - The available submissions, in structures:
- 'docname' *string* - The document name
- 'actname' *string* - The action name
- 'status' *string* - The status of the document
- 'cdate' *string* - Creation date
- 'mdate' *string* - Modification date
- 'id' *string* - The id of the submission
- 'reference' *string* - The display name of the doctype
- 'pending' *bool* - If the submission is pending
- 'act' *string* - The action code
- 'doctype' *string* - The doctype code
"""
# load the right message language
_ = gettext_set_language(ln)
out = ""
out += """
<BR>
<SMALL>
<form>
<input type="hidden" value='%(order)s' name="order">
<input type="hidden" name="deletedId">
<input type="hidden" name="deletedDoctype">
<input type="hidden" name="deletedAction">
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(for)s&nbsp;
<select name="doctype" onchange="document.forms[0].submit();">
<option value="">%(alltype)s</option>
""" % {
'order' : order,
'for' : _("For"),
'alltype' : _("all types of document"),
}
for doctype in doctypes:
out += """<option value="%(id)s" %(sel)s>%(name)s</option>""" % {
'id' : doctype['id'],
'name' : doctype['name'],
'sel' : doctype['selected'] and "SELECTED=\"SELECTED\"" or ""
}
out += """ </select>
</th>
</tr>
<tr>
<td class="portalboxbody">
<table>
<tr>
<td></td>
</tr>
"""
num = 0
docname = ""
for submission in submissions:
if submission['docname'] != docname:
docname = submission['docname']
out += """</table>
%(docname)s<br>
<table border="0" class="searchbox" align="left" width="100%%">
<tr>
<th class="headerselected">%(action)s&nbsp;&nbsp;
<a href='' onClick='document.forms[0].order.value="actiondown";document.forms[0].submit();return false;'><img src="%(images)s/smalldown.gif" border="0"></a>&nbsp;
<a href='' onClick='document.forms[0].order.value="actionup";document.forms[0].submit();return false;'><img src="%(images)s/smallup.gif" border="0"></a>
</th>
<th class="headerselected">%(status)s&nbsp;&nbsp;
<a href='' onClick='document.forms[0].order.value="statusdown";document.forms[0].submit();return false;'><img src="%(images)s/smalldown.gif" border="0"></a>&nbsp;
<a href='' onClick='document.forms[0].order.value="statusup";document.forms[0].submit();return false;'><img src="%(images)s/smallup.gif" border="0"></a>
</th>
<th class="headerselected">%(id)s</th>
<th class="headerselected">%(reference)s&nbsp;&nbsp;
<a href='' onClick='document.forms[0].order.value="refdown";document.forms[0].submit();return false;'><img src="%(images)s/smalldown.gif" border="0"></a>&nbsp;
<a href='' onClick='document.forms[0].order.value="refup";document.forms[0].submit();return false;'><img src="%(images)s/smallup.gif" border="0"></a>
</th>
<th class="headerselected">%(first)s&nbsp;&nbsp;
<a href='' onClick='document.forms[0].order.value="cddown";document.forms[0].submit();return false;'><img src="%(images)s/smalldown.gif" border="0"></a>&nbsp;
<a href='' onClick='document.forms[0].order.value="cdup";document.forms[0].submit();return false;'><img src="%(images)s/smallup.gif" border="0"></a>
</th>
<th class="headerselected">%(last)s&nbsp;&nbsp;
<a href='' onClick='document.forms[0].order.value="mddown";document.forms[0].submit();return false;'><img src="%(images)s/smalldown.gif" border="0"></a>&nbsp;
<a href='' onClick='document.forms[0].order.value="mdup";document.forms[0].submit();return false;'><img src="%(images)s/smallup.gif" border="0"></a>
</th>
</tr>
""" % {
'docname' : submission['docname'],
'action' : _("Action"),
'status' : _("Status"),
'id' : _("id"),
'reference' : _("reference"),
'images' : images,
'first' : _("first access"),
'last' : _("last access"),
}
if submission['pending']:
idtext = """<a href="sub.py?access=%(id)s@%(action)s%(doctype)s">%(id)s</a>
&nbsp;<a onClick='if (confirm("%(sure)s")){document.forms[0].deletedId.value="%(id)s";document.forms[0].deletedDoctype.value="%(doctype)s";document.forms[0].deletedAction.value="%(action)s";document.forms[0].submit();return true;}else{return false;}' href=''><img src="%(images)s/smallbin.gif" border="0" alt='%(delete)s'></a>
""" % {
'images' : images,
'id' : submission['id'],
'action' : submission['act'],
'doctype' : submission['doctype'],
'sure' : _("Are you sure you want to delete this submission?"),
'delete' : _("delete submission %(id)s in %(docname)s") % {
'id' : submission['id'],
'docname' : submission['docname']
}
}
else:
idtext = submission['id']
if operator.mod(num,2) == 0:
color = "#e0e0e0"
else:
color = "#eeeeee"
if submission['reference']:
reference = submission['reference']
else:
reference = """<font color="red">%s</font>""" % _("reference not yet given")
cdate = str(submission['cdate']).replace(" ","&nbsp;")
mdate= str(submission['mdate']).replace(" ","&nbsp;")
out += """
<tr bgcolor="%(color)s">
<td align="center" class="mycdscell">
<small>%(actname)s</small>
</td>
<td align="center" class="mycdscell">
<small>%(status)s</small>
</td>
<td class="mycdscell">
<small>%(idtext)s</small>
</td>
<td class="mycdscell">
<small>&nbsp;%(reference)s</small>
</td>
<td class="mycdscell">
<small>%(cdate)s</small>
</td>
<td class="mycdscell">
<small>%(mdate)s</small>
</td>
</tr>
""" % {
'color' : color,
'actname' : submission['actname'],
'status' : submission['status'],
'idtext' : idtext,
'reference' : reference,
'cdate' : cdate,
'mdate' : mdate,
}
num += 1
out += "</table></td></tr></table></form>"
return out
def tmpl_yourapprovals(self, ln, referees):
"""
Displays the doctypes and categories for which the user is referee
Parameters:
- 'ln' *string* - The language to display the interface in
- 'referees' *array* - All the doctypes for which the user is referee:
- 'doctype' *string* - The doctype
- 'docname' *string* - The display name of the doctype
- 'categories' *array* - The specific categories for which the user is referee:
- 'id' *string* - The category id
- 'name' *string* - The display name of the category
"""
# load the right message language
_ = gettext_set_language(ln)
out = """ <table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(refdocs)s</th>
</tr>
<tr>
<td class="portalboxbody">""" % {
'refdocs' : _("Refereed Documents"),
}
for doctype in referees:
out += """<UL><LI><b>%(docname)s</b><UL><small>""" % doctype
if doctype ['categories'] is None:
out += '''<LI><A HREF="publiline.py?doctype=%(doctype)s">%(generalref)s</a><br>''' % {
'docname' : doctype['docname'],
'doctype' : doctype['doctype'],
'generalref' : _("You are general referee")}
else:
for category in doctype['categories']:
out += """<LI><A HREF="publiline.py?doctype=%(doctype)s&categ=%(categ)s">%(referee)s</a><br>""" % {
'referee' : (_("You are referee for category: %(name)s (%(id)s)") % {
'name' : category['name'],
'id' : category['id']}),
'doctype' : doctype['doctype'],
'categ' : category['id']}
out += "</small></UL></UL>"
out += "</td></tr></table>"
return out
def tmpl_publiline_selectdoctype(self, ln, docs):
"""
Displays the doctypes that the user can select
Parameters:
- 'ln' *string* - The language to display the interface in
- 'docs' *array* - All the doctypes that the user can select:
- 'doctype' *string* - The doctype
- 'docname' *string* - The display name of the doctype
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(list)s</th>
</tr>
<tr>
<td class="portalboxbody">
%(select)s
</small>
<blockquote>""" % {
'list' : _("List of refereed types of documents"),
'select' : _("Select one of the following types of documents to check the documents status:"),
}
for doc in docs:
out += "<li><A HREF='publiline.py?doctype=%(doctype)s'>%(docname)s</A><BR>" % doc
out += """</blockquote>
</td>
</tr>
</table>"""
return out
def tmpl_publiline_selectcateg(self, ln, doctype, title, categories, images):
"""
Displays the categories from a doctype that the user can select
Parameters:
- 'ln' *string* - The language to display the interface in
- 'doctype' *string* - The doctype
- 'title' *string* - The doctype name
- 'images' *string* - the path to the images
- 'categories' *array* - All the categories that the user can select:
- 'id' *string* - The id of the category
- 'waiting' *int* - The number of documents waiting
- 'approved' *int* - The number of approved documents
- 'rejected' *int* - The number of rejected documents
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(title)s: %(list_categ)s</th>
</tr>
<tr>
<td class="portalboxbody">
%(choose_categ)s
<blockquote>
<FORM action="publiline.py" method="get">
<INPUT type="hidden" name="doctype" value='%(doctype)s'>
<INPUT type="hidden" name="categ" value=''>
</FORM>
<TABLE>
<TR>
<TD align=left>""" % {
'title' : title,
'doctype' : doctype,
'list_categ' : _("List of refereed categories"),
'choose_categ' : _("Please choose a category"),
}
for categ in categories:
num = categ['waiting'] + categ['approved'] + categ['rejected']
if categ['waiting'] != 0:
classtext = "class=\"blocknote\""
else:
classtext = ""
out += """<A href="" onClick="document.forms[0].categ.value='%(id)s';document.forms[0].submit();return false;"><SMALL %(classtext)s>%(id)s</SMALL></A><SMALL> (%(num)s document(s)</SMALL>""" % {
'id' : categ['id'],
'classtext' : classtext,
'num' : num,
}
if categ['waiting'] != 0:
out += """| %(waiting)s <IMG ALT="%(pending)s" SRC="%(images)s/waiting_or.gif" border="0">""" % {
'waiting' : categ['waiting'],
'pending' : _("pending"),
'images' : images,
}
if categ['approved'] != 0:
out += """| %(approved)s<IMG ALT="%(approved_text)s" SRC="%(images)s/smchk_gr.gif" border="0">""" % {
'approved' : categ['approved'],
'approved_text' : _("approved"),
'images' : images,
}
if categ['rejected'] != 0:
out += """| %(rejected)s<IMG ALT="%(rejected_text)s" SRC="%(images)s/cross_red.gif" border="0">""" % {
'rejected' : categ['rejected'],
'rejected_text' : _("rejected"),
'images' : images,
}
out += ")</SMALL><BR>"
out += """
</TD>
<TD>
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(key)s:</th>
<tr>
<tr>
<td>
<IMG ALT="%(pending)s" SRC="%(images)s/waiting_or.gif" border="0"> %(waiting)s<BR>
<IMG ALT="%(approved)s" SRC="%(images)s/smchk_gr.gif" border="0"> %(already_approved)s<BR>
<IMG ALT="%(rejected)s" SRC="%(images)s/cross_red.gif" border="0"> %(rejected_text)s<BR><BR>
<SMALL class="blocknote">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SMALL> %(somepending)s<BR></SMALL>
</td>
</tr>
</table>
</TD>
</TR>
</TABLE>
</blockquote>
</td>
</tr>
</table>""" % {
'key' : _("Key"),
'pending' : _("pending"),
'images' : images,
'waiting' : _("waiting for approval"),
'approved' : _("approved"),
'already_approved' : _("already approved"),
'rejected' : _("rejected"),
'rejected_text' : _("rejected"),
'already_approved' : _("already approved"),
'somepending' : _("some documents are pending"),
}
return out
def tmpl_publiline_selectdocument(self, ln, doctype, title, categ, images, docs):
"""
Displays the documents that the user can select in the specified category
Parameters:
- 'ln' *string* - The language to display the interface in
- 'doctype' *string* - The doctype
- 'title' *string* - The doctype name
- 'images' *string* - the path to the images
- 'categ' *string* - the category
- 'docs' *array* - All the categories that the user can select:
- 'RN' *string* - The id of the document
- 'status' *string* - The status of the document
"""
# load the right message language
_ = gettext_set_language(ln)
out = """
<table class="searchbox" width="100%%" summary="">
<tr>
<th class="portalboxheader">%(title)s - %(categ)s: %(list)s</th>
</tr>
<tr>
<td class="portalboxbody">
%(choose_report)s
<blockquote>
<FORM action="publiline.py" method="get">
<INPUT type="hidden" name="doctype" value='%(doctype)s'>
<INPUT type="hidden" name="categ" value='%(categ)s'>
<INPUT type="hidden" name="RN" value=''>
</FORM>
<TABLE class="searchbox">
<TR>
<TH class="portalboxheader">%(report_no)s</TH>
<TH class="portalboxheader">%(pending)s</TH>
<TH class="portalboxheader">%(approved)s</TH>
<TH class="portalboxheader">%(rejected)s</TH>
</TR>
""" % {
'doctype' : doctype,
'title' : title,
'categ' : categ,
'list' : _("List of refereed documents"),
'choose_report' : _("Click on a report number to have more information"),
'report_no' : _("Report Number"),
'pending' : _("Pending"),
'approved' : _("Approved"),
'rejected' : _("Rejected"),
}
for doc in docs:
status = doc ['status']
if status == "waiting":
out += """<TR>
<TD align="center">
<A HREF="" onClick="document.forms[0].RN.value='%(rn)s';document.forms[0].submit();return false;">%(rn)s</A>
</TD>
<TD align="center">
<IMG ALT="check" SRC="%(images)s/waiting_or.gif">
</TD>
<TD align="center">&nbsp;</TD>
<TD align="center">&nbsp;</TD>
</TR>
""" % {
'rn' : doc['RN'],
'images' : images,
}
elif status == "rejected":
out += """<TR>
<TD align="center">
<A HREF="" onClick="document.forms[0].RN.value='%(rn)s';document.forms[0].submit();return false;">%(rn)s</A>
</TD>
<TD align="center">&nbsp;</TD>
<TD align="center">&nbsp;</TD>
<TD align="center"><IMG ALT="check" SRC="%(images)s/cross_red.gif"></TD>
</TR>
""" % {
'rn' : doc['RN'],
'images' : images,
}
elif status == "approved":
out += """<TR>
<TD align="center">
<A HREF="" onClick="document.forms[0].RN.value='%(rn)s';document.forms[0].submit();return false;">%(rn)s</A>
</TD>
<TD align="center">&nbsp;</TD>
<TD align="center"><IMG ALT="check" SRC="%(images)s/smchk_gr.gif"></TD>
<TD align="center">&nbsp;</TD>
</TR>
""" % {
'rn' : doc['RN'],
'images' : images,
}
out += """ </TABLE>
</blockquote>
</td>
</tr>
</table>"""
return out
def tmpl_publiline_displaydoc(self, ln, doctype, docname, categ, rn, status, dFirstReq, dLastReq, dAction, access, images, accessurl, confirm_send, auth_code, auth_message, authors, title, sysno, newrn):
"""
Displays the categories from a doctype that the user can select
Parameters:
- 'ln' *string* - The language to display the interface in
- 'doctype' *string* - The doctype
- 'docname' *string* - The doctype name
- 'categ' *string* - the category
- 'rn' *string* - The document RN (id number)
- 'status' *string* - The status of the document
- 'dFirstReq' *string* - The date of the first approval request
- 'dLastReq' *string* - The date of the last approval request
- 'dAction' *string* - The date of the last action (approval or rejection)
- 'images' *string* - the path to the images
- 'accessurl' *string* - the URL of the publications
- 'confirm_send' *bool* - must display a confirmation message about sending approval email
- 'auth_code' *bool* - authorised to referee this document
- 'auth_message' *string* - ???
- 'authors' *string* - the authors of the submission
- 'title' *string* - the title of the submission
- 'sysno' *string* - the unique database id for the record
- 'newrn' *string* - the record number assigned to the submission
"""
# load the right message language
_ = gettext_set_language(ln)
if status == "waiting":
image = """<IMG SRC="%s/waiting_or.gif" ALT="" align="right">""" % images
elif status == "approved":
image = """<IMG SRC="%s/smchk_gr.gif" ALT="" align="right">""" % images
elif status == "rejected":
image = """<IMG SRC="%s/iconcross.gif" ALT="" align="right">""" % images
else:
image = ""
out = """
<table class="searchbox" summary="">
<tr>
<th class="portalboxheader">%(image)s %(rn)s</th>
</tr>
<tr>
<td class="portalboxbody">""" % {
'image' : image,
'rn' : rn,
}
if confirm_send:
out += """<I><strong class="headline">%(requestsent)s</strong></I><BR><BR>""" % {
'requestsent' : _("Your request has been sent to the referee!"),
}
out += """<FORM action="publiline.py">
<INPUT type="hidden" name="RN" value="%(rn)s">
<INPUT type="hidden" name="categ" value="%(categ)s">
<INPUT type="hidden" name="doctype" value="%(doctype)s">
<SMALL>""" % {
'rn' : rn,
'categ' : categ,
'doctype' : doctype,
}
if title != "unknown":
out += """<strong class="headline">%(title_text)s:</strong>%(title)s<BR><BR>""" % {
'title_text' : _("Title"),
'title' : title,
}
if authors != "":
out += """<strong class="headline">%(author_text)s:</strong>%(authors)s<BR><BR>""" % {
'author_text' : _("Author"),
'authors' : authors,
}
if sysno != "":
out += """<strong class="headline">%(more)s:</strong>
<A HREF="%(url)s?id=%(sysno)s">%(click)s</A>
<BR><BR>
""" % {
'more' : _("More information"),
'click' : _("click here"),
'url' : accessurl,
'sysno' : sysno,
}
if status == "waiting":
out += _("This Document is still <strong class=\"headline\">waiting for approval</strong>.") + "<BR><BR>" +\
_("It has first been sent to approval on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dFirstReq} + "<BR>"
if dLastReq == "0000-00-00 00:00:00":
out += _("Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dFirstReq} + "<BR>"
else:
out += _("Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dLastReq} + "<BR>"
out += "<BR>" + _("You can send an approval request e-mail again by clicking the following button:") + "<BR>" +\
"""<INPUT class="adminbutton" type="submit" name="send" value="%(send)s" onClick="return confirm('%(warning)s')">""" % {
'send' : _("Send Again"),
'warning' : _("WARNING! An e-mail will be send to your referee if you confirm.")
}
if auth_code == 0:
out += "<BR>" + _("As a referee for this document, you may click this button to approve or reject it:") + "<BR>" +\
"""<INPUT class="adminbutton" type="submit" name="approval" value="%(approve)s" onClick="window.location='approve.py?%(access)s';return false;">""" % {
'approve' : _("Approve/Reject"),
'access' : access
}
if status == "approved":
out += _("This Document has been <strong class=\"headline\">approved</strong>.") + "<BR>" +\
_("Its approved reference is: <strong class=\"headline\">%(rn)s</strong>") % {'rn' : newrn} + "<BR><BR>" +\
_("It has first been sent to approval on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dFirstReq} + "<BR>"
if dLastReq == "0000-00-00 00:00:00":
out += _("Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dFirstReq} + "<BR>"
else:
out += _("Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dLastReq} + "<BR>" +\
_("It has been approved on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dAction} + "<BR>"
if status == "rejected":
out += _("This Document has been <strong class=\"headline\">rejected</strong>.") + "<BR><BR>" +\
_("It has first been sent to approval on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dFirstReq} + "<BR>"
if dLastReq == "0000-00-00 00:00:00":
out += _("Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dFirstReq} + "<BR>"
else:
out += _("Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dLastReq} + "<BR>"
out += _("It has been rejected on: <strong class=\"headline\">%(date)s</strong>") % {'date' : dAction} + "<BR>"
out += """ </SMALL></FORM>
<BR></TD></TR></TABLE>
</blockquote>
</td>
</tr>
</table>"""
return out
diff --git a/modules/websubmit/web/Makefile.am b/modules/websubmit/web/Makefile.am
index 539020928..633609198 100644
--- a/modules/websubmit/web/Makefile.am
+++ b/modules/websubmit/web/Makefile.am
@@ -1,36 +1,36 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
SUBDIRS = admin
docdir = $(WEBDIR)
doc_DATA = approve.py \
direct.py \
getfile.py \
publiline.py \
sub.py \
submit.py \
summary.py \
yourapprovals.py \
yoursubmissions.py
EXTRA_DIST = $(doc_DATA)
CLEANFILES = *~ *.tmp *.php *.html
diff --git a/modules/websubmit/web/admin/Makefile.am b/modules/websubmit/web/admin/Makefile.am
index bc6f3d75c..8dc3be73e 100644
--- a/modules/websubmit/web/admin/Makefile.am
+++ b/modules/websubmit/web/admin/Makefile.am
@@ -1,38 +1,38 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
webappdir = $(WEBDIR)/admin/websubmit
FILESWML = $(wildcard $(srcdir)/*.wml)
webapp_DATA = $(FILESWML:$(srcdir)/%.wml=%) referees.py websubmitadmin.py
EXTRA_DIST = $(FILESWML:$(srcdir)/%=%) referees.py websubmitadmin.py
CLEANFILES = $(FILESWML:$(srcdir)/%.wml=%) *~ *.tmp
LINGUAS = $(shell grep -v '^\#' $(top_srcdir)/po/LINGUAS)
MO = $(LINGUAS:%=$(top_builddir)/po/%.gmo)
%.php: %.php.wml $(top_srcdir)/config/config.wml $(top_builddir)/config/configbis.wml \
$(MO)
$(WML) -o\(ALL-LANG_*\)+LANG_EN:$@ $<
for lang in en; do \
$(PYTHON) $(top_srcdir)/po/i18n_update_wml_target.py $${lang} "$*.php" ; \
done
diff --git a/modules/websubmit/web/admin/actionFunctions.php.wml b/modules/websubmit/web/admin/actionFunctions.php.wml
index f9ecc13be..3270d4e8e 100644
--- a/modules/websubmit/web/admin/actionFunctions.php.wml
+++ b/modules/websubmit/web/admin/actionFunctions.php.wml
@@ -1,625 +1,625 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="List of Functions for <i><protect><?print "$action </i>on<i> $doctype";?></protect></I>" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/***********************Function Declarations************************/
function displayFunctions($doctype, $action)
{
global $IMAGES;
$lockStr = "LOCK TABLES sbmFUNCTIONS READ";
# Apply a read lock to the given functions table...
if($lockRes = mysql_query($lockStr))
{
# Execute a query selecting a listing of the functions that make
# up an action for the given document type
$queryResult = mysql_query("SELECT * FROM sbmFUNCTIONS WHERE
doctype='$doctype' and action='$action' ORDER BY step, score");
# We must unlock our table...
$unlockRes = mysql_query("UNLOCK TABLES");
# If there were rows returned by this query (i.e. there are
# functions composing the given action on the given doctype, we
# can display them.
if(mysql_num_rows($queryResult) > 0)
{
# We can now create a table to display the query dynaset in...
print("<TABLE ALIGN='center' BORDER=1 CELLSPACING=0 "
. "CELLPADDING=0>");
# Open the first table row for the column headings...
print("<TR BGCOLOR='#CCDDFF'>");
# Get information about the fields in the table...
$columns = mysql_list_fields(DOCS_DATABASE, "sbmFUNCTIONS");
# Display all of the column headings
for($headerIndex = 2; $headerIndex < mysql_num_fields($columns);
$headerIndex++)
{
print("<TH>&nbsp; ");
print(mysql_field_name($columns, $headerIndex));
print("</TH>");
if(mysql_field_name($columns, $headerIndex) == "function")
{ # Add another column...
print("<TH>&nbsp;</TH>");
}
} // END for
# Now that we have added all of the header columns, we can add
# one more column header offering the user the ability to
# delete a function from the current action on the current
# doctype...
print("<TH STYLE=\"color: red\">Delete</TH>\n");
print("</TR>");
# Make a counter for the rows...
$rowCount = 0;
# Put the contents of the query dynaset into a temporary
# array...
while($dataRow = mysql_fetch_array($queryResult))
{
$allRows[$rowCount] = $dataRow;
$rowCount++;
} // End while
# Reset $rowCount to 0 for use in further processing...
$rowCount = 0;
# Now, we can display the body of the table...
for($i = 0; $i < mysql_num_rows($queryResult); $i++)
{
print("<TR BGCOLOR='#FFFFCC'>");
# For each column...
for($colIndex = 2; $colIndex < mysql_num_fields($columns);
$colIndex++)
{
if(mysql_field_name($columns, $colIndex) == "function")
# If the column is the function name,
# create a link to the description of
# that function in the fundesc table.
{
print("<TD ALIGN='center'>");
print("<A ");
print("HREF='func.php?functionName=");
print(urlencode($allRows[$i][$colIndex]));
print("&doctype=$doctype&action=$action&returnTo="
. "actionFunctions.php' ");
print("onMouseOver=\"");
print("window.defaultstatus = ''; window.status = ");
print("'View parameters taken by ");
print($allRows[$i][$colIndex] . " function for the "
. "$action action, ");
print("on $doctype doctype'\">&nbsp;");
print(htmlspecialchars($allRows[$i][$colIndex]));
print("</A></TD>");
# Now we can add the up and down buttons to the
# table.
# Add the small "up" button...
print("<TD><TABLE BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0"
. "><TR>"
. "<FORM ACTION='actionFunctions.php' "
. "METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='calledBefore' "
. "VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>"
. "<INPUT TYPE='hidden' NAME='action' "
. "VALUE='$action'>"
. "<INPUT TYPE='hidden' NAME='up' VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='function' VALUE='"
. $allRows[$i]['function'] . "'>"
. "<INPUT TYPE='hidden' NAME='currentScore' "
. "VALUE='" . $allRows[$i]['score'] . "'>"
. "<INPUT TYPE='hidden' NAME='currentStep' "
. "VALUE='" . $allRows[$i]['step'] . "'>");
if($rowCount == 0)
{
print("<TD>"
. "<IMG SRC='".$IMAGES."/up.gif' BORDER=0 HEIGHT=11"
. " WIDTH=11"
. " ALT='Function Already At Top Of Order. "
. " Unable To Move Up!'>");
} // END if
else
{
print("<INPUT TYPE='hidden' NAME='previousFunct"
. "ion'"
. " VALUE='" . $allRows[$i - 1]['function'] . "'>"
. "<INPUT TYPE='hidden' NAME='previousScore'"
. " VALUE='" . $allRows[$i - 1]['score'] . "'>"
. "<INPUT TYPE='hidden' NAME='previousStep' "
. "VALUE='"
. $allRows[$i - 1]['step'] . "'><TD>"
. "<INPUT TYPE=image SRC='".$IMAGES."/up.gif'"
. " BORDER=0 "
. "HEIGHT=11 WIDTH=11 onClick=\"submit()\">");
} // END else
# Add the small "down" button...
print("</TD></FORM></TR>"
. "<FORM ACTION='actionFunctions.php' "
. "METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='calledBefore' "
. "VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>"
. "<INPUT TYPE='hidden' NAME='action' "
. "VALUE='$action'>"
. "<INPUT TYPE='hidden' NAME='down' VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='function' VALUE='"
. $allRows[$i]['function'] . "'>"
. "<INPUT TYPE='hidden' NAME='currentScore' VALUE='"
. $allRows[$i]['score'] . "'>"
. "<INPUT TYPE='hidden' NAME='currentStep' VALUE='"
. $allRows[$i]['step'] . "'>");
if($rowCount == mysql_num_rows($queryResult) - 1)
{
print("<TD>"
. "<IMG SRC='".$IMAGES."/down.gif' BORDER=0"
. " HEIGHT=11 WIDTH=11"
. " ALT='Function Already At Bottom Of Order. "
. " Unable To Move Down!'>");
} // END if
else
{
print("<INPUT TYPE='hidden' NAME='nextFunction' "
. "VALUE='"
. $allRows[$i + 1]['function'] . "'>"
. "<INPUT TYPE='hidden' NAME='nextScore' VALUE='"
. $allRows[$i + 1]['score'] . "'>"
. "<INPUT TYPE='hidden' NAME='nextStep' VALUE='"
. $allRows[$i + 1]['step'] . "'><TD>"
. "<INPUT TYPE='image' SRC='".$IMAGES."/down.gif'"
. " BORDER=0 HEIGHT=11"
. " WIDTH=11 onClick=\"submit()\">");
} // END else
print("</TD></FORM></TR></TABLE></TD>");
}
else # Just display the value, as per normal.
{
print("<TD ALIGN='center'>&nbsp;");
print(htmlspecialchars($allRows[$i][$colIndex]));
print("</TD>\n");
} // End else
} // End for
# Now, we can fill the contents of the last column with the
# "delete button" for removing a function...
print("<FORM ACTION='actionFunctions.php' METHOD='post' "
. "onSubmit=\"if(confirm('Really delete this function from"
. " the $action action of the $doctype document type?')) {"
. " return true; } else { return false; }\">\n"
. "<INPUT TYPE='hidden' NAME='deleteFunc' "
. "VALUE='true'>\n<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n<INPUT TYPE='hidden' NAME='action' "
. "VALUE='$action'>\n<INPUT TYPE='hidden' NAME='"
. " calledBefore"
. "' VALUE='true'>\n<INPUT TYPE='hidden' NAME='function' "
. "VALUE='" . $allRows[$i]['function'] . "'>\n<INPUT TYPE='hidden' "
. "NAME='currentScore' VALUE='" . $allRows[$i]['score']
. "'>\n<INPUT TYPE='hidden' NAME='currentStep' VALUE='"
. $allRows[$i]['step'] . "'>\n<TD ALIGN='center'>\n<INPUT "
. "TYPE='image' SRC='".$IMAGES."/answer_bad.gif' BORDER=0 "
. "NAME='remove' HEIGHT=14 WIDTH=14 ALIGN='center'>\n"
. "</TD>\n</FORM>\n");
# We have now completed the current row, and can close it
print("</TR>");
# Increment the value of $rowCount...
$rowCount++;
} // End for
# Close the table, as it is now finished...
print("</TABLE>\n");
# Now, we can display a button to offer the user the chance to
# go back to the listing of actions for the given document
# type.
# This is done using a button.
print("<P><BR>\n<TABLE ALIGN='center' BORDER=0 "
. "CELLSPACING=0>\n"
. "<TR><FORM ACTION='addFunctions.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='action' VALUE='$action'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<TD ALIGN='center'><INPUT TYPE='button' VALUE='ADD "
. "FUNCTION' onClick=\"submit();\">\n</TD>\n</FORM>\n"
. "<FORM ACTION='documentEDS.php?doctype=$doctype' METHOD="
. "'post'>\n<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n<TD ALIGN='center'>\n"
. "<INPUT TYPE=button VALUE='FINISHED'"
. " onClick=\"submit()\">\n"
. "</TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // End if
else
{
print("<BR><DIV STYLE='color: red; text-align: center; "
. "font-size"
. ": medium; font-weight: bold'>There Are No Functions "
. "Associated With The $action Action For The $doctype "
. "Document Type</DIV>\n");
# Now, we can offer the user the chance to add functions to
# the given action on the given doctype...
# This requires a table with a form in it, with a button to
# press in order to add the functions.
print("<BR>\n<BR>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0><TR>"
. "<TD ALIGN='center'>");
print("\n<FORM ACTION='addFunctions.php' METHOD='post'>\n");
print("<INPUT TYPE='hidden' NAME='action' VALUE='$action'>\n");
print("<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n");
print("<INPUT TYPE='button' VALUE='ADD FUNCTIONS' onClick=\"");
print("submit()\">\n");
print("</FORM></TD>\n");
print("<TD>&nbsp;</TD>\n");
print("<TD ALIGN='center'><FORM ACTION='' "
. "METHOD='post'>");
print("<INPUT TYPE='button' VALUE='MAIN PAGE' "
. "onClick=\"submit()\">");
print("</FORM></TD>\n");
print("<TD>&nbsp;</TD>\n");
print("<TD ALIGN='center'><FORM>\n");
print("<INPUT TYPE='button' VALUE='BACK' ");
print("onClick=\"parent.history.back();\">\n");
print("</FORM></TD>\n");
print("</TR></TABLE>\n");
} // End else
} # END if
else
{
# Display error message (couldnt lock tables).
print("<DIV STYLE='text-align: center; font-weight: bold; "
. "font-size: large; color: navy'>\n<SPAN STYLE='color: red'>"
. "Error:</SPAN> Unable to retrieve information.</DIV>\n<BR>".mysql_error()."\n");
print("<TABLE ALIGN='center' CELLSPACING=0 CELLPADDING=0 BORDER="
. "0>\n<TR><FORM ACTION='documentEDS.php' METHOD='post'>\n<INPUT "
. "TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n<TD "
. "ALIGN='center'>\n<INPUT TYPE=button VALUE='OK'"
. " onClick=\"submit()\">\n</TD>\n</FORM>\n</TR>\n</TABLE>\n");
} # END else
} // END function displayFunctions()
function displayPage()
{
global $calledBefore,$doctype,$action,$up,$x,$y,$previousScore,$currentStep,$previousStep,$function,$currentScore,$down,$nextStep,$nextScore,$deleteFunc,$previousFunction,$nextFunction;
if(!($calledBefore))
{
displayFunctions($doctype, $action);
} // END if
else
{
if(isset($up))
{
# Destroy memory space associated with x and y coordinates
# which were passed from the input image...
unset($x);
unset($y);
# Destroy $up...
unset($up);
# Make a query string to update the row to move, to its new
# score and step values...
$queryStringA = "UPDATE sbmFUNCTIONS SET score = "
. "'$previousScore'";
if($previousStep < $currentStep)
{ # If the function aboves step is lower, then we must also
# change this...
$queryStringA = $queryStringA . ", step = "
. "'$previousStep'";
} // END if
$queryStringA = $queryStringA . " WHERE doctype = '$doctype'"
. " AND function = '$function' AND score = "
. "'$currentScore' AND step = '$currentStep' and action='$action'";
# Now, make another query string to update the function that
# was above the function that we have just updated in the
# order. This function should be updated to have the values
# that the function that we just updated had!
$queryStringB = "UPDATE sbmFUNCTIONS SET score = "
. "'$currentScore'";
if($previousStep < $currentStep)
{ # If the function we are alterring to the one above has a
# lower step than the one that came after it in the list,
# we must change the steps around...
$queryStringB = $queryStringB . ", step = '$currentStep'";
} // END if
$queryStringB = $queryStringB . " WHERE doctype = '$doctype'"
. " AND function = '$previousFunction' AND "
. "score = '$previousScore' AND step = "
. "'$previousStep' and action='$action'";
# Lock our tables...
$lockStr = "LOCK TABLES sbmFUNCTIONS WRITE";
if($lockRes = mysql_query($lockStr))
{
# Execute the update on the first function...
$queryResultA = mysql_query($queryStringA) or
die("Could Not Update Table. Error: (A) $queryStringA");
# Execute the update on the second function...
$queryresultB = mysql_query($queryStringB) or
die("Could Not Update Table. Error: (B)");
# Unlock our tables...
$unlockRes = mysql_query("UNLOCK TABLES");
} # END if
else
{
# Couldn't lock tables, therefore couldn't allow write
print("<DIV STYLE='text-align: center; font-weight: bold; "
. "font-size: large; color: navy'>\n<SPAN STYLE='color: "
. "red'>Error:</SPAN> Unable to commit movement."
. "</DIV>\n<BR>\n");
} # END else
unset($lockStr);
# Display the table of functions once again...
displayFunctions($doctype, $action);
} // END if
elseif(isset($down))
{
# Destroy memory space associated with $x and $y coordinates
# which were passed from the input image...
unset($x);
unset($y);
# Destroy $down
unset($down);
# Make a query string to update the row to move, to it's new
# score and step values...
$queryStringA = "UPDATE sbmFUNCTIONS SET score = "
. "'$nextScore'";
if($currentStep < $nextStep)
{ # If the step requires changing also, change it...
$queryStringA = $queryStringA . ", step = '$nextStep'";
}
$queryStringA = $queryStringA . " WHERE doctype = '$doctype'"
. " AND function = '$function' AND score = "
. "'$currentScore' AND step = '$currentStep' and action='$action'";
# Now make another query string to update the function whose
# position in the order the other function is moving to...
$queryStringB = "UPDATE sbmFUNCTIONS SET score = "
. "'$currentScore'";
if($currentStep < $nextStep)
{ # If the step requires changing also, change it...
$queryStringB = $queryStringB . ", step = '$currentStep'";
}
$queryStringB = $queryStringB . " WHERE doctype = '$doctype'"
. "AND function = '$nextFunction' AND score = "
. "'$nextScore' AND step = '$nextStep' and action='$action'";
# Lock our tables...
$lockStr = "LOCK TABLES sbmFUNCTIONS WRITE";
if($lockRes = mysql_query($lockStr))
{
# Execute the query on the first data item...
$queryResultA = mysql_query($queryStringA) or
die("no query A!");
# Execute the query on the second data item...
$queryresultB = mysql_query($queryStringB) or
die("no query B!");
# Unlock our tables...
$unlockRes = mysql_query("UNLOCK TABLES");
} # END if
else
{
# Couldn't lock tables, therefore couldn't allow write
print("<DIV STYLE='text-align: center; font-weight: bold; "
. "font-size: large; color: navy'>\n<SPAN STYLE='color: "
. "red'>Error:</SPAN> Unable to commit movement."
. "</DIV>\n<BR>\n");
} # END else
unset($lockStr);
# Display the table of functions once more...
displayFunctions($doctype, $action);
} // END elseif
elseif(isset($deleteFunc))
{
# This is a call to delete a function from the current action
# of the current doctype.
# Free some wasted space.
unset($deleteFunc);
$delStr = "DELETE FROM sbmFUNCTIONS WHERE doctype = '$doctype"
. "' AND function = '$function' AND score = '$currentScore' "
. "AND step = '$currentStep' and action='$action'";
# Make our LOCK query...
$lockStr = "LOCK TABLES sbmFUNCTIONS WRITE";
if($lockRes = mysql_query($lockStr))
{
$delRes = mysql_query($delStr);
if($delRes)
{
# The deletion query was successful, but did it actually
# delete anything?
if(mysql_affected_rows() == 1)
{
# 1 row deleted as expected.
# unlock table
$unlockRes = mysql_query("UNLOCK TABLES");
# Mail the admin.
# Get the current date and time...
$dateDets = getdate();
$msgTxt = "The $function function with a score of "
. "$currentScore and step of $currentStep was "
. " deleted from the $action action of the $doctype"
. " document "
. "type on " . $dateDets['weekday'] . " "
. $dateDets['mday'] . " "
. $dateDets['month'] . " " . $dateDets['year']
. ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . ".\n\nWebSubmit Administrator.";
mail(ADMIN_EMAIL, "${action}.${doctype}.$function "
. "function Deletion", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
elseif(mysql_affected_rows() > 1)
{
# deleted more than 1 row.
# Maybe we had a function in twice with exactly the
# same details?
# unlock table...
$unlockRes = mysql_query("UNLOCK TABLES");
# Free the lock & unlock query results...
mysql_free_result($lockRes);
mysql_free_result($unlockRes);
print("<SCRIPT TYPE='text/javascript'>\nalert('The "
. "deletion of the requested function caused "
. mysql_affected_rows() . " rows to be "
. "deleted.\\nIt is possible that the function had "
. "this many entries with exactly\\nthe same score "
. "and step.');\n</SCRIPT>\n");
} // END elseif
else
{
# deleted no function!
$unlockRes = mysql_query("UNLOCK TABLES");
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR:"
. " Unable to delete the requested function. Try "
. "again or inform system "
. "administrator.');\n</SCRIPT>\n");
} // END else
} // END if
else
{
# Deletion query failed.
$unlockRes = mysql_query("UNLOCK TABLES");
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: "
. "Unable to delete the requested function. Try again "
. "or inform system administrator.');\n</SCRIPT>\n");
} // END else
} # END if
else
{
# Could not lock the table. No display allowed.
print("<DIV STYLE='text-align: center; font-weight: bold; "
. "font-size: large; color: navy'>\n<SPAN STYLE='color: "
. "red'>Error:</SPAN> Unable to delete function."
. "</DIV>\n<BR>\n");
} # END else
# Display the table of functions once more...
displayFunctions($doctype, $action);
} // END elseif
else
{
print("<BR><H3 STYLE='text-align: center; font-color: red'>"
. "\nERROR IN UPDATE</H3>\n");
} // END else
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage($doctype);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/addActionEDS.php.wml b/modules/websubmit/web/admin/addActionEDS.php.wml
index de3212ab1..cbe4698ac 100644
--- a/modules/websubmit/web/admin/addActionEDS.php.wml
+++ b/modules/websubmit/web/admin/addActionEDS.php.wml
@@ -1,438 +1,438 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Create a new action" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT TYPE='text/javascript'>
<!-- hide
function validateIsInt(param)
// This function validates its parameter to ensure that it is an integer
// value.
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// ca8nro@yahoo.co.uk
// Created: 16/11/2000
// Last Modified: 16/11/2000
{
// Create a flag to indicate that we have found a non-digit value
var nonDigit = false;
for(index = 0; index < param.length; index++)
{
if(!(param[index] >= 0 && param[index] <= 9))
{
// In this case, we've found a non-digit value, and can stop
// searching, as the parameter is clearly not an integer
nonDigit = true;
break;
} // END if
} // END for
return true;
} // END function validateIsInt(param)
function checkRequired(sactname, lactname)
// This is a function to ensure that the user enters the required
// parameters for the action.
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// ca8nro@yahoo.co.uk
// Created: Long ago!
// Last Modified: 19/12/2000
{
// If the field is left blank by the user...
if((sactname == "") || (lactname == ""))
{ // Alert them, and return false.
alert("Values must be entered into the Action Code,"
+ "Long Action Name fields.");
return false;
} // End if
else // If level has been filled by the user...
{
return true;
} // End else
} // End function checkRequired(param)
// -->
</SCRIPT>
<?
/*********************Function Descriptions***************************/
function enterEDSaction($lactname = "", $dir = "",
$actionbutton = "", $statustext = "", $sactname = "")
{
/*******************************************************************
This function has the task of creating a form in which a user can
enter a new EDS action.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 19/12/2000
Last Modified: 17/01/2001
*******************************************************************/
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below, is "
. "a form in which you can enter the details of a new action."
. "<BR><BR>When you enter a new action, it will not be "
. "accepted by the system unless you have given it a unique "
. "\"Action Code\".<BR>"
. "<BR>You can commit this new action to the database by "
. "clicking on \"SAVE DETAILS\".</P>\n</TD>\n</TR>\n</TABLE>"
. "\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
print("<FORM ACTION='addActionEDS.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='commitAct' VALUE='true'>\n"
. "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN='center' "
. "WIDTH='100%'>\n");
# Get the columns list
$columns = mysql_list_fields(DOCS_DATABASE, "sbmACTION");
# Get the number of fields
$numTblFlds = mysql_num_fields($columns);
# Get the data, so that it can be committed for the modification
# date field (md)...
$dateDets = makeEDSmdDate();
# Now display the upper part of the table - fields that are system
# generated...
print("<TABLE WIDTH='100%' ALIGN='center' CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0>\n<TR>\n<TH BGCOLOR='#D3DCE3' "
. "ALIGN='right' WIDTH='20%'>\nCreation "
. "Date:&nbsp;</TH>\n<TD WIDTH='80%' ALIGN='left' BGCOLOR="
. "'#FFFFCC'><INPUT TYPE='readonly' NAME='cd' VALUE='"
. "$dateDets'>\n</TD>\n</TR>\n<TR>\n<TH WIDTH='20%'"
. " BGCOLOR='#D3DCE3' ALIGN='right'>\nModification "
. "Date:&nbsp;</TH>\n<TD WIDTH='80%' ALIGN='left' "
. "BGCOLOR='#FFFFCC'><INPUT TYPE='readonly' NAME='md' "
. "VALUE='$dateDets'>\n</TD>\n</TR>\n");
# Now create the fields that the user can edit...
# Make the sactname field...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Action Code:&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<INPUT TYPE='text' NAME='sactname' SIZE="
. mysql_field_len($columns, 1) . " VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars(${mysql_field_name($columns, 1)}))
. "'>\n</TD>\n</TR>\n");
print("<input type=\"hidden\" name=\"actionbutton\" value=\"\">");
for($indx = 0; $indx < $numTblFlds; $indx++)
{
# Get the name of the current field...
$currentField = mysql_field_name($columns, $indx);
# Ensure we dont once again print certain fields
if(($currentField != "cd") && ($currentField != "md")
&& ($currentField != "sactname")&& ($currentField != "actionbutton"))
{
# First display the form field label...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' "
. "WIDTH='20%'>\n");
if($currentField == "lactname")
{
print("Action Description:&nbsp;");
} // END if
else
{
print("$currentField" . ":&nbsp;");
} // END else
print("&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<INPUT TYPE='text' NAME="
. "'$currentField' SIZE=");
if(mysql_field_type($columns, $indx) == "blob")
{
print("60");
} // END if
else
{
print(mysql_field_len($columns, $indx));
} // END else
print(" VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars(${mysql_field_name($columns, $indx)}))
. "'>\n</TD>\n</TR>\n");
} // END if
} // END for
# Now that the table has been created, it can be closed...
print("</TABLE>\n");
# Now make the commit buttons that must be used for the form...
print("<TABLE ALIGN='center' CELLSPACING=2 CELLPADDING=2 BORDER=0>"
. "<TR>\n<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='SAVE DETAIL"
. "S' onClick=\"if(checkRequired(sactname.value, lactname.value"
. ")) { if(confirm('Really Commit This New Action"
. "?')) { submit(); } else { return false; } }\">\n</TD><TD ALIGN='"
. "center'>\n<INPUT TYPE='button' VALUE='RESET' onClick=\"reset();"
. "\">\n</TD>\n</FORM>\n<FORM ACTION='allActionsEDS.php' METHOD='po"
. "st'>\n<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='CANCEL' onC"
. "lick=\"submit();\">\n</TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // END function enterEDSaction()
function displayPage()
{
global $commitAct,$sactname,$lactname,$dir,$actionbutton,$statustext;
if($commitAct)
{
# In this case, the user has entered the details of the new
# action, and these details should be committed to the DB.
# Make sure the sactname field is uppercase...
$sactname = strtoupper($sactname);
# First we can ensure that there is not already an action in the
# DB with the same name as that given to the new action...
# Lock table
mysql_query("LOCK TABLES sbmACTION READ");
$checkRes = mysql_query("SELECT sactname FROM sbmACTION WHERE "
. "sactname = '$sactname'");
if($checkRes)
{
# In this case, the query has worked , so carry on...
if(mysql_num_rows($checkRes) != 0)
{
# Ah-Hah! They have tried to add an action whose ID Code
# is already in use!
mysql_query("UNLOCK TABLES");
# Let the check result go...
mysql_free_result($checkRes);
# Give them an explanatory error message...
print("<P STYLE=\"color: red; text-align: center; font-"
. "size: small; font-weight: bold\">Unable To Commit These"
. " Details. The Action Code Used Already Exists. Try "
. "Again With A New Code.</P>\n");
# Now a JavaScript alert...
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: It "
. "was not possible to commit these details for the new "
. "action because the action code chosen already exists in"
. DOCS_DATABASE . ".\\n\\nTry submitting he details again "
. "with a new action code.</SCRIPT>\n");
# Now redisplay the page...
enterEDSaction($lactname, $dir, $actionbutton,
$statustext);
} // END if
else
{
# The details should now be fine to commit...
# Unlock tables.
mysql_query("UNLOCK TABLES");
# Let the previous result set go...
mysql_free_result($checkRes);
# Make the insert string...
$updStr = "INSERT INTO sbmACTION (lactname, sactname, dir, "
. "cd, md, actionbutton, statustext) VALUES"
. "('$lactname', '$sactname', '$dir', '$cd', '$md', "
. "'$actionbutton', '$statustext')";
# LOCK sbmACTION table as write.
mysql_query("LOCK TABLES sbmACTION WRITE");
# Commit the details...
$updRes = mysql_query($updStr);
if($updRes)
{
# Query worked...
if(mysql_affected_rows() == 1)
{
# Insertion successful...alert user, email admin, and
# redirect browser...
# UNLOCK TABLES.
mysql_query("UNLOCK TABLES");
print("<SCRIPT TYPE='text/javascript'>\nalert('New "
. "Action Added.');\n</SCRIPT>\n");
print("<P STYLE=\"color: green; text-align: center; "
. "font-size: large\">The New Action Has Been Added."
. "</P>\n");
$msgTxt = "A new action has been added to the "
. DOCS_DATABASE;
$msgTxt .= " database.";
$msgTxt .= " This action is the $sactname "
. "action.\n\n";
$msgTxt .= "WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sactname Action Added to "
. "EDS/WebSubmit", $msgTxt,
"From: WebSubmit_Administrator");
# Redirect the browser...
print("<FORM ACTION='allActionsEDS.php' METHOD='post"
. "' NAME='referForm'>\n<INPUT TYPE='hidden'>"
. "</FORM>\n");
print("<SCRIPT TYPE='text/javascript'>\n"
. "setTimeout(\"document.referForm.submit();\", "
. "1000);\n</SCRIPT>\n");
} // END if
else
{
# Unable to add the thing...
# Now unlock the ACTION table.
mysql_query("UNLOCK TABLES");
# Alert the user...
print("<P STYLE=\"color: red; text-align: center; "
. "font-size: small; font-weight: bold\">Unable To "
. "Commit These Details. Try Again Later.</P>\n");
print("<SCRIPT TYPE='text/javascript'>\nalert('"
. "ERROR: It was not possible to commit the details"
. " for the new action.\\n\\nTry again, or contact "
. "the system administrator.');\n</SCRIPT>\n");
# Redisplay the form - with the details...
enterEDSaction($lactname, $dir, $actionbutton,
$statustext, $sactname);
} // END else
} // END if
else
{
# Couldn't execute insert query
# Now unlock the sbmACTION table.
mysql_query("UNLOCK TABLES");
# Alert the user...
print("<P STYLE=\"color: red; text-align: center; "
. "font-size: small; font-weight: bold\">Unable To "
. "Execute The Query To Commit These Details. Try "
. "Again Later.</P>\n");
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR:"
. " It was not possible to execute the query to commit"
. " the details for the new action.\\n\\nTry again, or"
. " contact the system administrator.');\n</SCRIPT>\n");
# Redisplay the form - with the details...
enterEDSaction($lactname, $dir, $actionbutton,
$statustext, $sactname);
} // END else
} // END else
} // END if
else
{
# In this case, we were unable to read from the sbmACTION table
# to see if there was already a record withthe same action
# code as the action that we have just attempted to add. We
# should therefore not try to add the new action, incase we
# cause key inconsistencies in the sbmACTION table. Instead,
# simply redisplay the form, with the new action data in it.
# Unlock tables.
mysql_query("UNLOCK TABLES");
# Alert the user of the problem...
print("<P STYLE=\"color: red; text-align: center; font-size: "
. "small; font-weight: bold\">Unable To Commit These Details."
. " Try Again Later.</P>\n");
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: It was "
. "not possible to perform a query upon the sbmACTION table.\\n"
. "This meant that it was not possible to commit the new acti"
. "on\\n\\nTry again later, or inform the system administrato"
. "r.');\n</SCRIPT>\n");
# Now redisplay the form...
enterEDSaction($lactname, $dir, $actionbutton,
$statustext, $sactname);
} // END else
} // END if
else
{
# In this case, this is the first call to the page, so we should
# just display the form in which the new action will be entered.
enterEDSaction();
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/addCheckEDS.php.wml b/modules/websubmit/web/admin/addCheckEDS.php.wml
index eda125abd..5089fe348 100644
--- a/modules/websubmit/web/admin/addCheckEDS.php.wml
+++ b/modules/websubmit/web/admin/addCheckEDS.php.wml
@@ -1,250 +1,250 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Add a javascript checking function" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listchecks"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/********************Function Declarations****************************/
function makeChecksInputFormEDS($chdesc = "", $chname = "")
{
/*******************************************************************
This function has the task of displaying a form for the inputting
of a new check. The function is passed 3 variables. These are
the $link variable, the $chdesc variable (which is the
description of the check i.e. the actual JavaScript code itself),
and the chname variable (which is the unique name of the check.
The chdesc and chname variables can be defaulted to nothing when
they are left out. This is because depending upon certain error
conditions when we attempt to add a check, we may want to refuse
committment of the check, and redisplay the form with its details
for certain parts to be changed.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 18/12/2000
Last Modified: 18/12/2000
*******************************************************************/
# Provide a quick description of the pages function...
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below, is a"
. " form that allows you to add a new check to EDS.<BR><BR>"
. "An EDS check is a checking function written in JavaScript"
. " that can be applied to a given EDS submission page or "
. "element(s),<BR>to perform some sort of validation task."
. "<BR><BR>It is important that when you create new EDS "
. "checks, you do not give them a name that is already in "
. "use, as the check name must<BR>be unique due to the fact "
. "that it is used to identify a given check when the EDS "
. "system attempts to use it.<BR><BR>When the check has been "
. "written in the text area provided (Check Description), "
. "click on the \"SAVE DETAILS\" button<BR>to commit this new"
. " check to EDS.</P>\n</TD>\n</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Get the current date...
$modifiedDate = makeEDSmdDate();
# Get a list of the fields in the sbmCHECKS table
$columns = mysql_list_fields(DOCS_DATABASE, "sbmCHECKS");
# Now begin making the form...
print("<TABLE WIDTH='100%' ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<FORM ACTION='addCheckEDS.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='addIt' VALUE='true'>\n"
. "<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>Creation "
. "Date:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'"
. "><INPUT TYPE='readonly' NAME='cd' VALUE='$modifiedDate'></TD>\n"
. "<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>Modificat"
. "ion Date:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH="
. "'80%'><INPUT TYPE='readonly' NAME='md' VALUE='$modifiedDate'>"
. "</TD>\n</TR>\n<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH="
. "'20%'>Check Name:&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'><INPUT TYPE='text' NAME='chname' SIZE="
. mysql_field_len($columns, 0) . " VALUE='$chname'>\n</TD>\n</TR>"
. "\n<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>Check Description:"
. "&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><"
. "TEXTAREA COLS=50 ROWS=20 NAME='chdesc'>$chdesc"
. "</TEXTAREA></TD>\n</TR>\n</TABLE>\n");
# Now make a table to contain a set of buttons for the submission of
# the form, resetting of the form, and cancelling of a check
# addition (this will send the browser back to "allChecksEDS.php").
print("<TABLE BORDER=0 CELLPADDING=2 CELLSPACING=2 ALIGN='center'>"
. "\n<TR>\n<TD ALIGN='right'><INPUT TYPE='button' VALUE='SAVE DETAI"
. "LS' onClick=\"if(chname.value != '') { submit(); } else { alert("
. "'The \'Check Name\' Field Is Mandatory'); }\"></TD>\n<TD ALIGN='"
. "center'><INPUT TYPE='button' VALUE='RESET' onClick=\"reset();\">"
. "</TD>\n</FORM>\n<FORM ACTION='allChecksEDS.php' METHOD='post'>\n"
. "<TD ALIGN='left'><INPUT TYPE='button' VALUE='CANCEL' onClick=\""
. "submit();\"></TD>\n</TR>\n</TABLE>\n");
} // END function makeChecksInputFormEDS()
function displayPage()
{
global $addIt,$chname,$chdesc;
if($addIt)
{
# In this case, the user has filled in the form to add a new
# check, and has submitted it...
# The first thing to do is to run a quick query to ensure that
# there is not already a check with the same name as that that we
# have just entered...
$quickRes = mysql_query("SELECT chname FROM sbmCHECKS WHERE chname "
. "= '$chname'");
if($quickRes)
{
# Query successful
if(mysql_num_rows($quickRes) != 0)
{
# Check name already used...redisplay form, with the check
# in it
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Checkname Entered Already Exists. Try "
. "Another.</P>\n");
makeChecksInputFormEDS($chdesc);
} // END if
else
{
# Checkname not used, so commit these new details to the
# database
# free the above result for speeds sakes.
mysql_free_result($quickRes);
# Build an insert query string...
$insStr = "INSERT INTO sbmCHECKS (chname, chdesc, cd, md, "
. "chefi1, chefi2) VALUES('$chname', '$chdesc', '$cd', "
. "'$md', '', '')";
# Execute this query...
$insRes = mysql_query($insStr);
if($insRes)
{
# The new check has been entered into the database!
# Inform the user & the administrator, and redirect the
# browser to "allChecksEDS.php".
print("<SCRIPT TYPE='text/javascript'>\nalert('The "
. "$chname check has been successfully added to "
. "EDS.');\n</SCRIPT>\n");
$msgTxt = "The $chname check has been added to the EDS "
. "Database.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "EDS: $chname Check Added",
$msgTxt, "From: WebSubmit_Administrator");
# Make a background...
print("<P STYLE=\"color: green; font-size: large; text-"
. "align: center\">The $chname Check Has Been Added To "
. DOCS_DATABASE . "</P>\n");
# Redirect the browser
print("<FORM ACTION='allChecksEDS.php' METHOD='post' "
. "NAME='referForm'>\n<INPUT TYPE='hidden'></FORM>\n");
print("<SCRIPT LANGUAGE=\"JavaScript\">\n"
. "setTimeout(\"document.referForm.submit();\", "
. "1000);\n</SCRIPT>\n");
} // END if
else
{
# The insert query has failed for some reason.
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: "
. "Unable to commit the details of this check.\\nPlease"
. " try again or inform the system administrator');\n"
. "</SCRIPT>\n");
makeChecksInputFormEDS($chdesc);
} // END else
} // END else
} // END if
else
{
# In this case, we were unable to read from the sbmCHECKS table
# to see if there was already a check with the name of the
# current check. This means that we should not try to commit
# the new check, simply redisplay the form with the check
# details in it, and display an error message to the user...
print("<SCRIPT TYPE='text/javascript'>\nalert('Error: Unable "
. "to verify check name details.\\nContact system administrat"
. "or or retry later.');\n</SCRIPT>\n");
# Redisplay the form wih all of the details in it...
makeChecksInputFormEDS($chdesc, $chname);
} // END else
} // END if
else
{
# In this case, this is the first call to this script, so it can
# simply display the form in which the details of the new
# JavaScript check can be entered...
makeChecksInputFormEDS();
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/addElement2PageEDS.php.wml b/modules/websubmit/web/admin/addElement2PageEDS.php.wml
index 9512844ee..74873dd4e 100644
--- a/modules/websubmit/web/admin/addElement2PageEDS.php.wml
+++ b/modules/websubmit/web/admin/addElement2PageEDS.php.wml
@@ -1,781 +1,781 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Add Element to Page <protect><?print "$pageNumber of $subname"?></protect>" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT LANGUAGE="JavaScript">
<!-- hide
function checkRequired(param)
// This is a function to ensure that the user enters the required
// value for the level parameter of an EDS submission page element
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// ca8nro@yahoo.co.uk
// Created: Long ago!
// Last Modified: 14/12/2000
{
// If the field is left blank by the user...
if((param == "") || ((param.toUpperCase() != "M") &&
(param.toUpperCase() != "O")))
{ // Alert them, and return false.
alert("A value of M or O must be entered in the level field.");
return false;
} // End if
else // If level has been filled by the user...
{
return true;
} // End else
} // End function checkRequired(param)
// -->
</SCRIPT>
<?
/*********************Function Declarations***************************/
function TestFormField( $fidesc, $level )
{
$res = mysql_query("select type,fidesc from sbmFIELDDESC where name='$fidesc'");
$row = mysql_fetch_row($res);
$type = $row[0];
$body = $row[1];
if ($level == "M" && $type == "S" && !ereg(".*<option>[^<]*Select:.*",$body)) {
print "<SCRIPT TYPE='text/javascript'>alert('The mandatory $fidesc select box must begin with \"<option>Select:</option>\"');</SCRIPT>";
return 0;
}
return 1;
}
function procInsrtn($subname, $pageNumber, $fieldnb, $fidesc, $fitext,
$level, $sdesc, $checkn, $doctype, $nPgs)
{
/******************************************************************
This function has the task of actually processing the insertion
of an element into a submission page for a given doctype. It is
passed all of the various values that should be inserted into the
sbmFIELD table. It then constructs an insert query, and inserts
these values into the table. After the insertion has been
completed, it either informs the user that the new values have
successfully been inserted or not, depending upon whether the
query was successful or not.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 14/12/2000
Last Modified: 25/01/2001
******************************************************************/
if (!TestFormField($fidesc,$level)){
return 0;
}
# Now we can begin building the query string...
$insStr = "INSERT INTO sbmFIELD (subname, pagenb, fieldnb, fidesc, "
. "fitext, level, sdesc, checkn, cd, md, fiefi1, fiefi2) VALUES("
. "'$subname', '$pageNumber', '$fieldnb', '$fidesc', '$fitext', "
. "'$level', '$sdesc', '$checkn', NOW(), NOW(), NULL, NULL)";
# Now execute the above query string...
$insRes = mysql_query($insStr);
# Conduct a test to see if the instertion of these details was
# successful...
if($insRes)
{
# In this case, the details have been inserted correctly. This
# means we must update the modification date of the current
# submission, and the modification date of the current document
# type. We must also redirect the browser back to the
# "pageDetsEDS.php" page to show details of the current
# submission page.
# Update the md field for our submission.
$mdResult = mysql_query("UPDATE sbmIMPLEMENT SET md = "
. "'$md' WHERE subname = '$subname'");
if($mdResult)
{
# In this case, the update result for updating the
# modification date of a submission worked, so we can free
# it's result pointer
mysql_free_result($mdResult);
} // END if
else
{
# Update the submission md query error...output a quick alert
print("<SCRIPT TYPE='text/javascript'>alert('ERROR: Unable"
. " to update the Modification Date field for this "
. "submission<BR>in the sbmIMPLEMENT table.');</SCRIPT>\n");
} // END else
# Update the md field for our doctype
updateEDSDOCTYPEmd($doctype, $md);
# Now output a message on screen informing the user that the
# update has been completed
print("<P STYLE=\"color: green; font-weight: bold; font-size: "
. "large; text-align: center\">The New Element Has Been Added"
. "</P>\n");
# Now make a message and send it to the system administrator to
# inform them that this element addition has taken place.
$msgTxt = "A new element has been added to page $pageNumber of "
. "the $subname submission of the $doctype document type. "
. "This new element is an instance of the $fidesc element "
. "description, and was inserted into position $fieldnb."
. "\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$fidesc Element added to $subname page "
. "$pageNumber", $msgTxt, "From: WebSubmit_Administrator");
# Now redirect the browser to "pageDetsEDS.php"
sendToPageDets($subname, $pageNumber, $nPgs, $doctype);
} // END if
else
{
# In this case, the query to insert the new details has failed.
# This means that we must warn the user of this problem, warn the
# administrator by email, and then redirect the page back to the
# "pageDetsEDS.php" page.
# Now output a message on screen informing the user that the
# update has been completed
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable To Add This Element To The <EM>$subname</EM>"
. " Submission</P>\n");
# Now make a message and send it to the system administrator to
# inform them that this element addition has taken place.
$msgTxt = "An error ocurred when attempting to add the "
. "$fidesc element to page $pageNumber of "
. "the $subname submission of the $doctype document type. "
. "This error meant that it was not possible to commit the "
. "details for this new element to the sbmFIELD table, and "
. "therefore the element has not been added.\n\nThere may be"
. " a problem with the sbmFIELD table, and this situation should"
. " be looked into as soon as possible.\n\nWebSubmit Administrator "
. "(";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: Unable To Add $fidesc Element To "
. "$subname Page $pageNumber",
$msgTxt, "From: WebSubmit_Administrator");
# Now redirect the browser to "pageDetsEDS.php"
sendToPageDets($subname, $pageNumber, $nPgs, $doctype);
} // END else
} // END function procInsrtn()
//************
function charSmaller($chr, $datum)
{
/**************************************************************
This function simply compares 2 values to see if a character
($chr) is smaller than a given other character ($datum). It was
written because I wanted to split a <SELECT> box which was
massive up into several select boxes alphabetically. The
original select query on the DB returned the results sorted
alphabetically ascending, and it returned any numeric values as
coming before alphabetic values, so I made this function claim
that anything that is not a letter is smaller than the datum if
it is alphabetic. If the datum is not alphabetic, I just let the
computer decide whether or not the $chr is less than the datum,
as I don't really care, as I never intend to call the function
with non-alphabetic datums.
Not brilliant practice I know! :o
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 17/01/2001
Last Modified: 17/01/2001
**************************************************************/
if(($datum >= "A" && $datum <= "Z") ||
($datum >= "a" && $datum <= "z"))
{
# $datum is an alphabetic char, and all is easy...
if(($chr >= "A" && $chr <= "Z") ||
($chr >= "a" && $chr <= "z"))
{
# Here, the character to compare is an alphabetic char.
if(strtolower($chr) < strtolower($datum))
{
# In this case, our letter is less than the allowed limit
return true;
} // END if
else
{
# In this case, the letter has exceeded it's boundary
return false;
} // END else
} // END if
else
{
# Char to compare is not alphabetic. Therefore, we just let
# Mr computer decide!
return ($chr < strtoupper($datum)) ? true : false;
} // END else
} // END if
else
{
# Datum is non-alphabetic...Grrr!
if(($chr >= "A" && $chr <= "Z") ||
($chr >= "a" && $chr <= "z"))
{
# The character is alphabetic
return (strtoupper($chr) < $datum) ? true : false;
} // END if
else
{
# Character is ! alphabetic, so just let Mr Computer decide
return ($chr < $datum) ? true : false;
} // END else
} // END else
} // END function charSmaller()
//*************
function makeEleForm($subname, $pageNumber, $nPgs, $doctype,
$noElements, $fitext = "", $level = "", $sdesc = "",
$checkn = "", $whichBox = "", $fidesc = "")
{
/*******************************************************************
This function has the job of creating the form that is used to
enter the details of a new element for a page. The function
executes a select query to retrieve the codes for each of the
element descriptions from the sbmFIELDDESC table. If this query was
successful, it then proceeds to create the input form.
Otherwise, it creates the relevant error messages.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 15/12/2000
Last Modified: 30/01/2001
*******************************************************************/
# The first thing we need to do is get a list of all element
# descriptions from the sbmFIELDDESC table...
$qRes = mysql_query("SELECT distinct(name) FROM sbmFIELDDESC ORDER BY "
. "name");
if($qRes)
{
# In this case, the query to get a list of all of the elements
# has been successful, so we can continue making the form
if(mysql_num_rows($qRes) <= 0)
{
# In this case, there are no element descriptions stored in
# the sbmFIELDDESC table. This means we can't add an element to
# a page, so we'd better let the user know this!
print("<P CLASS='errorMsg'>There are currently no element "
. "descriptions stored in EDS.<BR>Unable to add a new "
. "element</P>\n");
print("<SCRIPT TYPE=\"text/javascript\">alert('Because there "
. " are no element configuration descriptions stored in the"
. "\\nsbmFIELDDESC table of EDS, it is not possible to add a new"
. " element instance to a submission.\\n\\nIf you wish to add"
. " elements to a submission page, you must first add meta "
. "data about\\nthese elements to the sbmFIELDDESC table.');"
. "</SCRIPT>\n");
# Now redirect the browser
sendToPageDets($subname, $pageNumber, $nPgs, $doctype);
} // END if
else
{
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD ALIGN='"
. "center'>\n<P STYLE=\"color: blue; text-align: center; "
. "font-size: small; font-weight: bold\">The following form "
. "can be used to add a new element to <EM>page $pageNumber"
. "</EM> of the <EM>$subname</EM> submission.<BR>The first "
. "step is to select an element from a list box. The "
. "element selected will determine the configuration "
. "information template<BR>used to create the element for the"
. " submission page.<BR><BR>When the element description has "
. "been selected, enter all of the other details using the "
. "form and submit it by clicking on \"SAVE CHANGES\".<BR><BR"
. "><SPAN STYLE=\"color: green\">There are many EDS element "
. "descriptions. For ease of selection, they have been split"
. " alphabetically into 3 list boxes.<BR>When selecting an "
. "element, please only select from 1 list box. &nbsp;If se"
. "veral are selected, the value will be taken from the<BR>"
. "left-most listbox.</SPAN>\n</P>\n"
. "</TD>\n</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now, begin making the form for the new elements details.
print("<FORM ACTION='addElement2PageEDS.php' METHOD='post'>"
. "\n<INPUT TYPE='hidden' NAME='insertElement' VALUE='true'>"
. "\n<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='nPgs' VALUE='$nPgs'>\n"
. "<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 ALIGN='center'"
. " BGCOLOR='#CECEFF' WIDTH='100%'>\n<TR>\n<TH ALIGN='right' "
. "WIDTH='25%'>\n<SPAN STYLE=\"color: green;\""
. ">Element Description Code:&nbsp;</SPAN></TH>\n<TD "
. "ALIGN='left' WIDTH='75%'>\n");
# We are going to have 3 select boxes (1 for a-h, 1 for i-p
# and 1 for p-z), because there are so many elements.
# Get the number of elements returned by query
$numEles = mysql_num_rows($qRes);
# Put all elements as returned by the query into a 2d array
$eles = resToArray($qRes);
# ****************Make the 1st select list*****************
print("<SELECT NAME='fidesc_A'>\n<OPTION"
. " VALUE='--X--'>-----A..H-----"
. "</OPTION>\n");
for($idx = 0; (($idx < $numEles) &&
(charSmaller($eles[$idx][0][0], "H"))); $idx++)
{
if($eles[$idx][0])
{
print("<OPTION");
if($whichBox == "fidesc_A" && $fidesc == $eles[$idx][0])
{
# The current element descr should be selected
print(" SELECTED");
} // END if
print(" VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($eles[$idx][0]))
. "'>" . ereg_replace("'", "&#39;",
htmlspecialchars($eles[$idx][0]))
. "</OPTION>\n");
} // END if
} // END for
# Close the current select list
print("</SELECT>");
print("&nbsp;");
# ****************Make the 2nd select list*****************
print("<SELECT NAME='fidesc_B'>\n<OPTION"
. " VALUE='--X--'>-----I..P-----"
. "</OPTION>\n");
for($idx2 = $idx; (($idx2 < $numEles) &&
(charSmaller($eles[$idx2][0][0], "Q"))); $idx2++)
{
if($eles[$idx2][0])
{
print("<OPTION VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($eles[$idx2][0]))
. "'");
if($whichBox == "fidesc_B" &&
$fidesc == $eles[$idx2][0])
{
# The current element descr should be selected
print(" SELECTED");
} // END if
print(">" . ereg_replace("'", "&#39;",
htmlspecialchars($eles[$idx2][0]))
. "</OPTION>\n");
} // END if
} // END for
# Close the current select list
print("</SELECT>");
print("&nbsp;");
# ****************Make the 3rd select list*****************
print("<SELECT NAME='fidesc_C'>\n<OPTION"
. " VALUE='--X--'>-----Q..Z-----"
. "</OPTION>\n");
for($idx3 = $idx2; $idx3 < $numEles; $idx3++)
{
if($eles[$idx3][0])
{
print("<OPTION VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($eles[$idx3][0]))
. "'");
if($whichBox == "fidesc_C" &&
$fidesc == $eles[$idx3][0])
{
# The current element descr should be selected
print(" SELECTED");
} // END if
print(">" . ereg_replace("'", "&#39;",
htmlspecialchars($eles[$idx3][0]))
. "</OPTION>\n");
} // END if
} // END for
# Close the current select list
print("</SELECT>");
# Now close up the newly created listbox
print("\n</TD>\n</TR>\n</TABLE>\n");
# Now, we can present the user with the form in which they can
# fill in the details that will be committed to the sbmFIELD
# table...
# Get the date for the created date & modification date
$theDate = makeEDSmdDate();
# Get information about all of the fields in the fitext table
$cols = mysql_list_fields(DOCS_DATABASE, "sbmFIELD");
print("<BR><TABLE CELLSPACING=0 CELLPADDING=0 ALIGN='center' "
. "WIDTH='100%' BORDER=0>\n<TR><TH ALIGN='right' WIDTH='25%'"
. " BGCOLOR='"
. "#D3DCE3'>Submission Code:&nbsp;</TH>\n<TD WIDTH='75%' ALIG"
. "N='left' BGCOLOR='#FFFFCC'><INPUT TYPE='readonly' NAME='"
. "subname' VALUE='$subname'></TD>\n</TR>\n<TR>\n<TH ALIGN='"
. "right' WIDTH='25%' BGCOLOR='#D3DCE3'>Page Number:&nbsp;</"
. "TH>\n<TD WIDTH='75%' ALIGN='left' BGCOLOR='#FFFFCC'><INPUT"
. " TYPE='readonly' NAME='pageNumber' VALUE='$pageNumber'></T"
. "D>\n</TR>\n<TR>\n<TH ALIGN='right' WIDTH='25%' BGCOLOR='"
. "#D3DCE3'>Field Number:&nbsp;</TH>\n<TD WIDTH='75%' ALIGN='"
. "left' BGCOLOR='#FFFFCC'><INPUT TYPE='readonly' NAME='field"
. "nb' VALUE='" . ($noElements + 1) . "'></TD>\n</TR>\n<TR><"
. "TH ALIGN='right' WIDTH='25%' BGCOLOR='#D3DCE3'>Creation D"
. "ate:&nbsp;</TH><TD WIDTH='75%' ALIGN='left' BGCOLOR='#FFF"
. "FCC'><INPUT TYPE='readonly' NAME='cd' VALUE='$theDate'>"
. "</TD>\n</TR>\n<TR><TH ALIGN='right' WIDTH='25%' BGCOLOR='"
. "#D3DCE3'>Modification Date:&nbsp;</TH>\n<TD WIDTH='75%' "
. "ALIGN='left' BGCOLOR='#FFFFCC'><INPUT TYPE='readonly' "
. "NAME='md' VALUE='$theDate'></TD>\n</TR>\n<TR><TH ALIGN='"
. "right' WIDTH='25%' BGCOLOR='#87CEFA'>Element Label:&nbsp;"
. "</TH><TD WIDTH='75%' ALIGN='left' BGCOLOR='#FFFFCC'><"
. "INPUT TYPE='text' NAME='fitext' SIZE=40 VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($fitext))
. "'></TD>\n</TR>\n<TR><TH ALIGN="
. "'right' WIDTH='25%' BGCOLOR='#87CEFA'>Level:&nbsp;</TH><T"
. "D WIDTH='75%' ALIGN='left' BGCOLOR='#FFFFCC'><SELECT NAME="
. "'level'>\n<OPTION VALUE='M'>Mandatory</OPTION>\n<OPTION ");
if($level == "O" || $level == "o")
{
print("SELECTED ");
} // END if
print("VALUE='O'>Optional</OPTION>\n</SELECT>\n"
. "</TD>\n</TR>\n<TR><TH ALIGN='right' WIDTH='25%' BGCOLOR="
. "'#87CEFA'>Short Desc:&nbsp;</TH><TD WIDTH='75%' ALIGN='"
. "left' BGCOLOR='#FFFFCC'><INPUT TYPE='text' NAME='sdesc' "
. "SIZE=40 VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars($sdesc))
. "'></TD>\n</TR>\n<TR><TH ALIGN='right' WIDTH='25%' BGCOLOR="
. "'#87CEFA'>Check:&nbsp;</TH><TD WIDTH='75%' ALIGN='left' "
. "BGCOLOR='#FFFFCC'>");
# Now, we wish to use a select list of checks to ensure that
# the user can only select checks that are already stored in
# the EDS DB. Therefore, we need to query sbmCHECKS.
if($chksRes = mysql_query("SELECT chname FROM sbmCHECKS ORDER "
. "BY chname"))
{
# Query fine.
if(mysql_num_rows($chksRes) > 0)
{
# Checks to be put into a select box...good!
print("<SELECT NAME='checkn'>\n<OPTION VALUE=''>"
. "NO CHECK</OPTION>\n");
while($stuff = mysql_fetch_row($chksRes))
{
print("<OPTION VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars($stuff[0]))
. "'");
if($checkn == $stuff[0])
{
# This check was already selected, so note that
print(" SELECTED");
} // END if
print(">" . ereg_replace("'", "&#39;",
htmlspecialchars($stuff[0]))
. "</OPTION>\n");
} // END while
# Close up the select list
print("</SELECT>\n");
} // END if
else
{
# No checks stored in DB! Offer link to add a check page
print("<SPAN STYLE=\"font-size: small; font-weight: "
. "bold; text-align: left; color: red\">There are "
. "currently no " . DOCS_DATABASE . " checks. &nbsp;"
. "<A HREF='addCheckEDS.php'>Add.</A></SPAN><INPUT "
. "TYPE='hidden' NAME='checkn' VALUE=''>\n");
} // END else
} // END if
else
{
# Can't query for checks, therefore can't add any!
print("<SPAN STYLE=\"font-size: small; font-weight: bold;"
. " text-align: left; color: red\">Unable to retrieve "
. "details of checks from " . DOCS_DATABASE . ". &nbsp;"
. "Try adding check later.</SPAN><INPUT TYPE='hidden' "
. "NAME='checkn' VALUE=''>\n");
} // END else
# Close the current table cell
print("</TD>\n</TR>\n</TABLE>");
# Now that we have finished displaying the input fields of the
# form, we can produce some buttons....1 for submitting the
# form, 1 for resetting the form, and 1 for cancelling the
# action (i.e. not adding a new element at all) - this button
# will return you to the "pageDetsEDS.php" page.
print("<TABLE CELLSPACING=1 CELLPADDING=1 ALIGN="
. "'center' BORDER=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE="
. "'button' VALUE='SAVE DETAILS' onClick=\"submit();\">\n"
. "</TD>\n<TD ALIGN='center'>\n<INPUT TYPE='button'"
. " VALUE='RESET' onClick=\"reset();\">\n</TD>\n</FORM>\n<FO"
. "RM ACTION='pageDetsEDS.php' METHOD='post'>\n<INPUT TYPE='h"
. "idden' NAME='subname' VALUE='$subname'>\n<INPUT TYPE='hidd"
. "en' NAME='pageNumber' VALUE='$pageNumber'>\n<INPUT TYPE='"
. "hidden' NAME='nPgs' VALUE='$nPgs'>\n<INPUT TYPE='hidden' "
. "NAME='doctype' VALUE='$doctype'>\n<TD ALIGN='left'>"
. "<INPUT TYPE='button' VALUE='CANCEL' onClick=\"submit();\">"
. "\n</TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // END else
} // END if
else
{
# In this case, the query to retrieve the descriptions of all
# elements has failed, so we can display an error message
# indicating this and redirect the browser to the
# "pageDetsEDS.php" page
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> It was not possible to retrieve the details of "
. "the element descriptions from the <EM>sbmFIELDDESC</EM> "
. "table.<BR>Unable to add element.</P>\n");
# Now redirect the browser
sendToPageDets($subname, $pageNumber, $nPgs, $doctype);
} // END else
} // END function makeEleForm()
function displayPage()
{
global $insertElement,$fidesc_A,$fidesc_B,$fidesc_C,$subname,$pageNumber,$nPgs,$doctype,$fieldnb,$fitext,$level,$sdesc,$checkn,$noElements;
# The first thing to do is to work out what sort of call to the script
# this is. It can either be a first call whereby the form to fill in
# must be displayed, or a self-referential call, whereby the new
# element must actually be inserted into the sbmFIELD table.
if(isset($insertElement))
{
# In this case, this call to the page is a call to insert the new
# element details. We must however perform certain tests to ensure
# values have been filled/selected, just incase our JavaScript
# failed (Likely!).
# Free the $insertElement value...
unset($insertElement);
# Now ensure that the value of "level" is in upper case...
$level = strtoupper($level);
if($fidesc_A == "--X--" && $fidesc_B == "--X--" &&
$fidesc_C == "--X--")
{
# No element descr code selected
print("<P STYLE=\"color: red; text-align: center; font-size:"
. " medium; font-weight: bold\">\nNo Element Description "
. "Code Was Selected\n</P>\n");
# Redisplay the form for re-entry.
makeEleForm($subname, $pageNumber, $nPgs, $doctype,
$fieldnb - 1, $fitext, $level, $sdesc, $checkn);
} // END if
elseif($fidesc_A != "--X--")
{
# take the left-most, which in this case is
# $fidesc_A, so it does not matter if $fidesc_B or $fidesc_C
# are selected or not - we don't care.
if($level == "M" || $level == "O")
{
# $level checks out.
if (!procInsrtn($subname, $pageNumber, $fieldnb, $fidesc_A, $fitext, $level, $sdesc, $checkn, $doctype, $nPgs)) {
# Redisplay input form
makeEleForm($subname, $pageNumber, $nPgs, $doctype,$fieldnb - 1, $fitext, "", $sdesc, $checkn, "fidesc_A", $fidesc_A);
}
} // END if
else
{
# Level doesn't check out
print("<P STYLE=\"color: red; text-align: center; font-size:"
. " medium; font-weight: bold\">\nThe Value of the Level "
. "Field Must be \"M\" or \"O\"\n</P>\n");
# Redisplay input form
makeEleForm($subname, $pageNumber, $nPgs, $doctype,
$fieldnb - 1, $fitext, "", $sdesc, $checkn,
"fidesc_A", $fidesc_A);
} // END else
} // END elseif
elseif($fidesc_A == "--X--" && $fidesc_B != "--X--")
{
# Here, $fidesc_A has not been selected, but $fidesc_B has
# been, meaning that $fidesc_B is the leftmost, and we don't
# care whether or not $fidesc_C has been selected - we take B
if($level == "M" || $level == "O")
{
# $level checks out.
if (!procInsrtn($subname, $pageNumber, $fieldnb, $fidesc_B,$fitext, $level, $sdesc, $checkn, $doctype,$nPgs)) {
# Redisplay input form
makeEleForm($subname, $pageNumber, $nPgs, $doctype,$fieldnb - 1, $fitext, "", $sdesc, $checkn, "fidesc_B", $fidesc_B);
}
} // END if
else
{
# $level doesn't check out
print("<P STYLE=\"color: red; text-align: center; font-size:"
. " medium; font-weight: bold\">\nThe Value of the Level "
. "Field Must be \"M\" or \"O\"\n</P>\n");
# Redisplay input form
makeEleForm($subname, $pageNumber, $nPgs, $doctype,
$fieldnb - 1, $fitext, "", $sdesc, $checkn,
"fidesc_B", $fidesc_B);
} // END else
} // END elseif
else
{
# $fidesc_C must be the only one selected
if($level == "M" || $level == "O")
{
# $level checks out.
if (!procInsrtn($subname, $pageNumber, $fieldnb, $fidesc_C,$fitext, $level, $sdesc, $checkn, $doctype,$nPgs)) {
# Redisplay input form
makeEleForm($subname, $pageNumber, $nPgs, $doctype,$fieldnb - 1, $fitext, "", $sdesc, $checkn, "fidesc_C", $fidesc_C);
}
} // END if
else
{
# Level doesn't check out
print("<P STYLE=\"color: red; text-align: center; font-size:"
. " medium; font-weight: bold\">\nThe Value of the Level "
. "Field Must be \"M\" or \"O\"\n</P>\n");
# Redisplay input form
makeEleForm($subname, $pageNumber, $nPgs, $doctype,
$fieldnb - 1, $fitext, "", $sdesc, $checkn,
"fidesc_C", $fidesc_C);
} // END else
} // END else
} // END if
else
{
# In this case, this is the first call to the page, and it is
# necessary to display the form in which the user can enter the
# details of the new element for the given page of the given
# submission of the given doctype.
makeEleForm($subname, $pageNumber, $nPgs, $doctype,
$noElements);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/addElementDescrEDS.php.wml b/modules/websubmit/web/admin/addElementDescrEDS.php.wml
index 98ca8c9c9..f465c1866 100644
--- a/modules/websubmit/web/admin/addElementDescrEDS.php.wml
+++ b/modules/websubmit/web/admin/addElementDescrEDS.php.wml
@@ -1,930 +1,930 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Add an element description" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listelements"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*********************Function Descriptions***************************/
function enterEDSelementDescr($elename = "", $alephcode = "",
$size = "", $rows = "", $cols = "", $maxlength = "", $val = "",
$fidesc = "", $cookie = 0, $type = "", $modifytext = "")
{
/*******************************************************************
This function has the task of creating the form that allows a
user to enter the details of a new element description.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 10/01/2001
Last Modified: 08/02/2001
*******************************************************************/
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below, is "
. "a form in which you can enter the details of a new "
. "element description."
. "<BR><BR>When you enter a new element description, it will "
. "not be accepted by the system unless you have given it a "
. "unique<BR>\"Element Name\".<BR>"
. "<BR>You can commit this new element description to the "
. "database by clicking on \"SAVE DETAILS\".</P>\n</TD>\n"
. "</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
print("<FORM ACTION='addElementDescrEDS.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='commitElement' VALUE='true'>\n"
. "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN='center' "
. "WIDTH='100%'>\n");
# Get the columns list
$columns = mysql_list_fields(DOCS_DATABASE, "sbmFIELDDESC");
# Get the number of fields
$numTblFlds = mysql_num_fields($columns);
# Get the data, so that it can be committed for the modification
# date field (md)...
$dateDets = makeEDSmdDate();
# Now display the upper part of the table - fields that are system
# generated...
print("<TABLE WIDTH='100%' ALIGN='center' CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0><INPUT TYPE='hidden' NAME='cd' VALUE='"
. "$dateDets'><INPUT TYPE='hidden' NAME='md' "
. "VALUE='$dateDets'>");
# Now create the fields that the user can edit...
# Make the name field...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Element Name <EM STYLE=\"font-size: small\">"
. "(Req'd)</EM>:&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<INPUT TYPE='text' NAME='elename' SIZE="
. mysql_field_len($columns, 0) . " VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($elename))
. "'>\n</TD>\n</TR>\n");
# Make the modify text field...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Modification Text:&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<INPUT TYPE='text' NAME='modifytext' SIZE="
. mysql_field_len($columns, 0) . " VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($modifytext))
. "'>\n</TD>\n</TR>\n");
# Make the type field...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Element Type <EM STYLE=\"font-size: small\">(Req'd)</EM>:&nbsp;"
. "</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n"
. "<SELECT NAME='type'>\n<OPTION VALUE='NONE_SELECTED'>"
. "Select Element Type...</OPTION>\n");
# Now test to see if this is a recall (due to erroneous form
# filling), whereby a given type must be 'selected'.
# Make User defined type option
print("<OPTION ");
if($type == "D")
{
# D was already selected...
print("SELECTED ");
} // END if
print("VALUE='D'>User Defined Input</OPTION>\n");
# Make Select box type option
print("<OPTION ");
if($type == "S")
{
# S was already selected...
print("SELECTED ");
} // END if
print("VALUE='S'>Select Box</OPTION>\n");
# Make File input type option
print("<OPTION ");
if($type == "F")
{
# F was already selected...
print("SELECTED ");
} // END if
print("VALUE='F'>File Input</OPTION>\n");
# Make Hidden input type option...
print("<OPTION ");
if($type == "H")
{
# H was already selected...
print("SELECTED ");
} // END if
print("VALUE='H'>Hidden Input</OPTION>\n");
# Make Text input type option...
print("<OPTION ");
if($type == "I")
{
# I was already selected...
print("SELECTED ");
} // END if
print("VALUE='I'>Text Input</OPTION>\n");
# Make Response type option...
print("<OPTION ");
if($type == "R")
{
# I was already selected...
print("SELECTED ");
} // END if
print("VALUE='R'>Response</OPTION>\n");
# Make TextArea input type option...
print("<OPTION ");
if($type == "T")
{
# T was already selected...
print("SELECTED ");
} // END if
print("VALUE='T'>Text Area Element</OPTION>\n</SELECT>\n</TD>\n"
. "</TR>\n");
for($indx = 0; $indx < $numTblFlds; $indx++)
{
# Get the name of the current field...
$currentField = mysql_field_name($columns, $indx);
# Ensure we dont once again print certain fields
if(($currentField != "cd") && ($currentField != "md")
&& ($currentField != "name") && ($currentField != "type")
&& ($currentField != "cookie") && ($currentField != "modifytext")
&& ($currentField != "fddfi2"))
{
# First display the form field label...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' "
. "WIDTH='20%'>\n");
if($currentField == "alephcode")
{
print("Aleph Code <EM STYLE=\"font-size: small\">"
. "</EM>:");
} // END if
elseif($currentField == "marccode")
{
print("Marc Code:");
} // END elseif
elseif($currentField == "size")
{
print("Size <EM STYLE=\"font-size: small\">(Text"
. ")</EM>:");
} // END elseif
elseif($currentField == "rows")
{
print("No. Rows <EM STYLE=\"font-size: small\">(TextArea)"
. "</EM>:");
} // END elseif
elseif($currentField == "cols")
{
print("No. Cols <EM STYLE=\"font-size: small\">(TextArea)"
. "</EM>:");
} // END elseif
elseif($currentField == "maxlength")
{
print("Max Length <EM STYLE=\"font-size: small\">(Text)"
. "</EM>:");
} // END elseif
elseif($currentField == "val")
{
print("Value <EM STYLE=\"font-size: small\">(Text"
. "/Hidden)</EM>:");
} // END elseif
elseif($currentField == "fidesc")
{
print("Item Description <EM STYLE=\"font-size: small\">"
. "(User Defined)</EM>:");
} // END elseif
else
{
print("$currentField:");
} // END else
print("&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='"
. "#FFFFCC'>\n");
if($currentField == "fidesc")
{
# Here, we ought to make a textarea for fidesc...
print("<TEXTAREA NAME='$currentField' ROWS=25 COLS=50>"
. ereg_replace("'", "&#39;",
htmlspecialchars(${mysql_field_name($columns, $indx)}))
. "</TEXTAREA>\n");
} // END if
else
{
# Just a normal text input will do...
print("<INPUT TYPE='text' NAME='$currentField' "
. "SIZE=");
if(mysql_field_type($columns, $indx) == "blob")
{
print("60");
} // END if
else
{
print(mysql_field_len($columns, $indx));
} // END else
print(" VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars(${mysql_field_name($columns, $indx)}))
. "'>\n");
} // END else
print("</TD>\n</TR>\n");
} // END if
} // END for
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Sets Cookie?:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC'"
. "WIDTH='80%'>");
printCookie($cookie);
# Close up the cookie row, and the table!
print("</TH>\n</TR>\n</TABLE>\n");
# Now make the commit, reset, and cancel buttons for the form...
print("<TABLE ALIGN='center' CELLSPACING=2 CELLPADDING=2 BORDER=0>"
. "<TR>\n<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='SAVE DETAIL"
. "S' onClick=\"submit();\">\n</TD><TD "
. "ALIGN='center'>\n<INPUT TYPE='button' VALUE='RESET' onClick=\""
. "reset();\">\n</TD>\n</FORM>\n<FORM ACTION='allElementsEDS.php' "
. "METHOD='post'>\n<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='"
. "CANCEL' onClick=\"submit();\">\n</TD>\n</FORM>\n</TR>\n</TABLE>"
. "\n");
} // END enterEDSelementDescr()
//************
function charIsInt($thing)
{
/*******************************************************************
This function tests to see if a string only contains integer
characters.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 11/01/2001
Last Modified: 11/01/2001
*******************************************************************/
# Reset an error flag
$errorFlag = 0;
# get the length of the string..
$len = strlen($thing);
for($i = 0; $i < $len; $i++)
{
if($thing[$i] < "0" || $thing[$i] > "9")
{
$errorFlag = 1;
break;
} // END if
} // END for
# Return true/false depending upon string status
return ($errorFlag == 1) ? false : true;
} // END function charIsInt($thing)
//********
function insertBon($elename)
{
/*******************************************************************
This function has the task of displaying a message on the screen
to say that the insertion of the new element was successful. It
also displays a button to click to send the browser to the page
displaying the details of the new element description.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 11/01/2001
Last Modified: 11/01/2001
*******************************************************************/
print("<P STYLE=\"font-size: large; font-weight: bold; text-align: "
. "center; color: green\">Element Added.<BR>Click To View details."
. "</P>\n<FORM ACTION='elementConfigDetsEDS.php' METHOD='post' NAME"
. "='referForm'>\n<INPUT TYPE='hidden' NAME='name' VALUE='$elename'"
. ">\n<INPUT TYPE='hidden' NAME='caller' VALUE='allElementsEDS.php"
. "'>\n<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 CELLPADDING="
. "0>\n<TR>\n<TD ALIGN='center'>\n<INPUT TYPE='button' VALUE='VIEW "
. "DETAILS' onClick=\"submit();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>"
. "\n<SCRIPT TYPE='text/javascript'>\nsetTimeout(\"document.refer"
. "Form.submit();\",1000);\n</SCRIPT>\n");
} // END function insertBon()
//***********
function insertMal()
{
/*******************************************************************
This function handles the situation whereby the insert of the new
element description has failed, and we wish to inform the user,
and provide a button to click to goto the list all element
descriptions page.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 12/01/2001
Last Modified: 12/01/2001
*******************************************************************/
print("<P CLASS=\"errorMsg\">\n<SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable to insert new element description.</P>\n"
. "<TABLE ALIGN='center' BORDER=0>\n<TR>\n<TD ALIGN='center'>\n"
. "<FORM ACTION='allElementsEDS.php' METHOD='post'>\n<INPUT TYPE="
. "'button' VALUE='OK' onClick=\"submit();\">\n</FORM>\n</TD>\n"
. "</TR>\n</TABLE>\n");
print mysql_error();
} // END function insertMal()
//************
function emailRecord($elename)
{
/*******************************************************************
Since it is necessary to email the admin informing them about the
success of the addition of a new element description, this
function has been written, which does just that.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 11/01/2001
Last Modified: 25/01/2001
*******************************************************************/
$msgTxt = "A new element description was successfully added to the "
. DOCS_DATABASE . " database. This was the $elename element "
. "description.\n\nWebSubmit Administrator. (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$elename Element Description Added",
$msgTxt, "From: WebSubmit_Administrator");
} // END function emailRecord($elename)
function displayPage()
{
global $commitElement,$elename,$alephcode,$marccode,$size,$rows,$cols,$maxlength,$val,$fidesc,$cookie,$type,$modifytext;
if($commitElement)
{
# In this case, this is a self-referential call to the form, and
# it is time to process the addition of the new element.
# Carry out some form validation and take the relevant action
# based upon the resuts
if($type == "NONE_SELECTED")
{
# In this case, the user has not selected a type for the new
# element. Therefore redisplay the form with the values in
# that they have already entered.
print("<P STYLE=\"font-size: medium; text-align: center; "
. "font-weight: bold; color: red\">Selection Of Element "
. "Type is Mandatory.</P>\n");
enterEDSelementDescr($elename, $alephcode, $size,
$rows, $cols, $maxlength, stripslashes($val),
stripslashes($fidesc), $cookie, "",$modifytext);
} // END if
else
{
# The element type was selected, but we must now ensure that
# the other various field combos were correct
if(!$elename)
{
# User has not input the element name, or aleph code.
print("<P STYLE=\"font-size: medium; text-align: center; "
. "font-weight: bold; color: red\">The Element Name "
. "Field Is Mandatory.</P>\n");
enterEDSelementDescr($elename, $alephcode, $size,
$rows, $cols, $maxlength, stripslashes($val),
stripslashes($fidesc), $cookie, $type, $modifytext);
} // END if
else
{
if(!test_key_legal($elename))
{
# invalid characters in either the alephcode or the element name
print("<P STYLE=\"font-size: medium; text-align: center"
. "; font-weight: bold; color: red\">The Element Name "
. "May Only Contain Alphabetical"
. " Characters, Integer Digits or Underscores.</P>\n");
enterEDSelementDescr("", $alephcode, $size,
$rows, $cols, $maxlength, stripslashes($val),
stripslashes($fidesc), $cookie, $type,$modifytext);
} // END if
else
{
# General Mandatory fields all filled correctly. Now
# make specialised tests
if($type == "T")
{
# Element is TextArea - can have rows and cols.
if($rows)
{
if(!charIsInt($rows))
{
# non-int value given for $rows
print("<P STYLE=\"font-size: medium; text-ali"
. "gn: center; font-weight: bold; color: "
. "red\">The <EM>No. Rows</EM> Field Must Have"
. " an Integer Value.</P>");
# Make an error flag to mark this fact
$rowsInvalid = true;
enterEDSelementDescr($elename,
$alephcode,
$size, "", $cols, $maxlength,
stripslashes($val), stripslashes($fidesc),
$cookie, $type,$modifytext);
} // END if
} // END if
if($cols && !$rowsInvalid)
{
if(!charIsInt($cols))
{
# non-int value given for $rows
print("<P STYLE=\"font-size: medium; text-ali"
. "gn: center; font-weight: bold; color: "
. "red\">The <EM>No. Cols</EM> Field Must Have"
. " an Integer Value.</P>");
# Set an error flag to mark this failure
$colsInvalid = true;
enterEDSelementDescr($elename,
$alephcode, $size, $rows, "", $maxlength,
stripslashes($val),
stripslashes($fidesc), $cookie, $type,$modifytext);
} // END if
} // END if
if(!$rowsInvalid && !$colsInvalid)
{
# Well now. If we have reached this far, then the
# TEXTAREA present and valid: make new element description and commit to DB
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode"
. ", marccode, type, size, rows, cols, maxlength, val, "
. "fidesc, cd, md, modifytext, fddfi2, cookie) VALUES"
. "('$elename', '$alephcode', '$marccode', '$type', NULL, ";
# Deal with rows
if(isset($rows) && $rows != "")
{
# A value was provided for rows
$insStr .= "'$rows', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
# Deal with cols
if(isset($cols) && $cols != "")
{
# A value was provided for rows
$insStr .= "'$cols', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
$insStr .= "NULL, NULL, NULL, NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ") . " NULL, '$cookie')";
$insRes = mysql_query($insStr);
if($insRes)
{
# insert of element description successful.
emailRecord($elename);
insertBon($elename);
} // END if
else
{
insertMal();
} // END else
} // END if
} // END if
elseif($type == "I")
{
# Element is HTML text input - needs size, maxlength, val
if($size)
{
if(!charIsInt($size))
{
# non-int value given for $size
print("<P STYLE=\"font-size: medium; text-ali"
. "gn: center; font-weight: bold; color: "
. "red\">The <EM>Size</EM> Field Must Have an"
. " Integer Value.</P>");
# Make a flag to mark this failure
$sizeFailed = true;
enterEDSelementDescr($elename,
$alephcode, "", $rows, $cols, $maxlength,
stripslashes($val), stripslashes($fidesc),
$cookie, $type,$modifytext);
} // END if
} // END if
if($maxlength && !$sizeFailed)
{
if(!charIsInt($maxlength))
{
# non-int value given for $maxlength
print("<P STYLE=\"font-size: medium; text-alig"
. "n: center; font-weight: bold; color: red\">"
. "The <EM>Max Length</EM> Field Must Have an "
. "Integer Value.</P>");
# Make a flag to mark this failure
$maxlengthFailed = true;
enterEDSelementDescr($elename,
$alephcode, $size, $rows, $cols, "",
stripslashes($val), stripslashes($fidesc),
$cookie, $type,$modifytext);
} // END if
} // END if
if(!$sizeFailed && !$maxlengthFailed)
{
# commit new element description to DB
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode, marccode"
. ", type, size, rows, cols, maxlength, val, "
. "fidesc, cd, md, modifytext, fddfi2, cookie) "
. "VALUES('$elename', '$alephcode', '$marccode', '$type', ";
# Deal with size
if(isset($size) && $size != "")
{
# A value was provided for rows
$insStr .= "'$size', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
$insStr .= "NULL, NULL, ";
# Deal with maxlength
if(isset($maxlength) && $maxlength != "")
{
# A value was provided for rows
$insStr .= "'$maxlength', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
# Deal with val
if(isset($val) && $val != "")
{
# A value was provided for rows
$insStr .= "'$val', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
$insStr .= "NULL, NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ")."NULL, "
. "'$cookie')";
$insRes = mysql_query($insStr);
if($insRes)
{
# insert of element description successful
emailRecord($elename);
insertBon($elename);
} // END if
else
{
insertMal();
} // END else
} // END if
} // END elseif
elseif($type == "H")
{
# Element is hidden - can have val
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode, marccode, "
. "type, size, rows, cols, maxlength, val, fidesc, "
. "cd, md, modifytext, fddfi2, cookie) VALUES('"
. "$elename', '$alephcode', '$marccode', '$type', NULL, NULL, "
. "NULL, NULL, ";
# Deal with val
if(isset($val) && $val != "")
{
# A value was provided for rows
$insStr .= "'$val', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
$insStr .= "NULL, NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ")."NULL, "
. "'$cookie')";
$insRes = mysql_query($insStr);
if($insRes)
{
# Insert successful
emailRecord($elename);
insertBon($elename);
} // END if
else
{
# Insert failed
insertMal();
} // END else
} // END elseif
elseif($type == "F")
{
# Element is file - needs size, maxlength
if($size)
{
if(!charIsInt($size))
{
# non-int value given for $size
print("<P STYLE=\"font-size: medium; text-"
. "align: center; font-weight: bold; color:"
. " red\">The <EM>Size</EM> Field Must Have "
. "an Integer Value.</P>");
# Make a flag to mark this failure
$sizeFailed = true;
enterEDSelementDescr($elename,
$alephcode, "", $rows, $cols, $maxlength,
stripslashes($val), stripslashes($fidesc),
$cookie, $type,$modifytext);
} // END if
} // END if
if($maxlength && !$sizeFailed)
{
if(!charIsInt($maxlength))
{
# non-int value given for $maxlength
print("<P STYLE=\"font-size: medium; text-alig"
. "n: center; font-weight: bold; color: red\">"
. "The <EM>Max Length</EM> Field Must Have an "
. "Integer Value.</P>");
# Make a flag to mark this failure
$maxlengthFailed = true;
enterEDSelementDescr($elename,
$alephcode, $size, $rows, $cols, "",
stripslashes($val), stripslashes($fidesc),
$cookie, $type,$modifytext);
} // END if
} // END if
if(!$sizeFailed && !$maxlengthFailed)
{
# commit new element to DB
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode"
. ", marccode, type, size, rows, cols, maxlength, val, "
. "fidesc, cd, md, modifytext, fddfi2, cookie) "
. "VALUES('$elename', '$alephcode', '$marccode', '$type', ";
# Deal with size
if(isset($size) && $size != "")
{
# A value was provided for rows
$insStr .= "'$size', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
$insStr .= "NULL, NULL, ";
# Deal with maxlength
if(isset($maxlength) && $maxlength != "")
{
# A value was provided for rows
$insStr .= "'$maxlength', ";
} // END if
else
{
# No value was provided for rows
$insStr .= "NULL, ";
} // END else
$insStr .= "NULL, NULL, NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ")."NULL,"
. " '$cookie')";
# Execute the insertion
$insRes = mysql_query($insStr);
if($insRes)
{
emailRecord($elename);
insertBon($elename);
} // END if
else
{
insertMal();
} // END else
} // END if
} // END elseif
elseif($type == "D")
{
# Element is user defined - needs fidesc
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode, marccode, "
. "type, size, rows, cols, maxlength, val, fidesc, "
. "cd, md, modifytext, fddfi2, cookie) VALUES('"
. "$elename', '$alephcode', '$marccode', '$type', NULL, NULL, "
. "NULL, NULL, NULL, ";
$insStr .= "'$fidesc', NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ")."NULL, "
. "'$cookie')";
# Execute the insertion
$insRes = mysql_query($insStr);
if($insRes)
{
# Insert succesful
emailRecord($elename);
insertBon($elename);
} // END if
else
{
# Insert failed
insertMal();
} // END else
} // END elseif
elseif($type == "R")
{
# Element is of response type - needs fidesc
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode, marccode, "
. "type, size, rows, cols, maxlength, val, fidesc, "
. "cd, md, modifytext, fddfi2, cookie) VALUES('"
. "$elename', '$alephcode', '$marccode', '$type', NULL, NULL, "
. "NULL, NULL, NULL, ";
$insStr .= "'$fidesc', NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ")."NULL, "
. "'$cookie')";
$insRes = mysql_query($insStr);
if($insRes)
{
emailRecord($elename);
insertBon($elename);
} // END if
else
{
insertMal();
} // END else
} // END elseif
elseif($type == "S")
{
# Element is user defined - needs fidesc
$insStr = "INSERT INTO sbmFIELDDESC (name, alephcode, marccode, "
. "type, size, rows, cols, maxlength, val, fidesc, "
. "cd, md, modifytext, fddfi2, cookie) VALUES('"
. "$elename', '$alephcode', '$marccode', '$type', NULL, NULL, "
. "NULL, NULL, NULL, ";
$insStr .= "'$fidesc', NOW(), NOW(), ".(isset($modifytext)?"'$modifytext', ":"NULL, ")."NULL, "
. "'$cookie')";
$insRes = mysql_query($insStr);
if($insRes)
{
emailRecord($elename);
insertBon($elename);
} // END if
else
{
insertMal();
} // END else
} // END elseif
else
{
# Element type invalid! deny commit, redisplay form
print("<P STYLE=\"font-size: medium; text-align: "
. "center; font-weight: bold; color: red\">Invalid "
. "Element Type is Mandatory.</P>\n");
enterEDSelementDescr($elename, $alephcode,
$size, $rows, $cols, $maxlength,
stripslashes($val), stripslashes($fidesc),
$cookie,"",$modifytext);
} // END else
} // END else
} // END else
} // END else
} // END if
else
{
# In this case, this is not a self-referential call to this page,
# and it is therefore time to display a form in which the user
# can enter the details of the element description...
enterEDSelementDescr();
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/addFunctions.php.wml b/modules/websubmit/web/admin/addFunctions.php.wml
index edeb66271..9c6dc882b 100644
--- a/modules/websubmit/web/admin/addFunctions.php.wml
+++ b/modules/websubmit/web/admin/addFunctions.php.wml
@@ -1,570 +1,570 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Add a functions for <i><protect><?print "$action </i>on<i> $doctype";?></protect></I>" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT TYPE='text/javascript'>
<!-- hide
function checkScoreStep(score, step)
// This function checks that the user has entered numeric
// values for the score and step fields
{
// create a variable, foundNonNumeric, which will be a boolean
// variable, to determine whether or not the user has input a
// non-numeric value for score or step.
var foundNonNumericScore = false;
var foundNonNumericStep = false;
if(score != "" && step != "")
{
for(index = 0; index < score.length; index++)
{
if(!(score.charAt(index) >= "0" && score.charAt(index) <= "9"))
{
foundNonNumericScore = true;
break;
} // End if
} // End for
if(!foundNonNumericScore)
{
for(index = 0; index < step.length; index++)
{
if(!(step.charAt(index) >= "0" && step.charAt(index) <= "9"))
{
foundNonNumericStep = true;
break;
} // End if
} // End for
if(!foundNonNumericStep)
{
return true;
} // end if
else
{
alert('Only Numeric Values Are Legal For score and step'
+ ' fields!');
return false;
} // End else
} // End if
else
{
alert('Only Numeric Values Are Legal For score');
return false;
} // End else
} // End if
else
{
alert('It is necessary to enter values into both\n the score'
+ ' and step fields!');
return false;
} // End else
} // End function checkScoreStep(score, step)
// -->
</SCRIPT>
<?
/**********************Function Declarations**************************/
function createActFunsList($selQRes, $action, $doctype)
{
/*****************************************************************
This function has the task of displaying either a table of
functions belonging to a given action on a given doctype, or
displaying a message informing the user that the action for the
doctype has no functions if this is the case.
The function is used in this script to display the functions &
their details (step etc) in a table alongside the new function
input form, so that the user can see the current functions etc
for an action on a doctype as they decide uppon values for their
new function.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 10/10/2000
Lsat Modified: 05/02/2001
*****************************************************************/
# Display an explanation for the top of the column...
print("<H4 STYLE=\"background-color: transparent; text-align: "
. "center\">Functions of the $action action<BR>on the $doctype"
. " document type</H4>\n");
if(mysql_num_rows($selQRes) > 0)
{
# If this clause has been reached, there are functions
# belonging to the current action on the given doctype, and
# therefore we can create a table to display them in for
# reference when adding the new function.
# Get the fields names of the fields in the relevant functions
# table...
$tableFields = mysql_list_fields(DOCS_DATABASE, "sbmFUNCTIONS");
print("<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 "
. "ALIGN='center'>\n<TR BGCOLOR='#CCDDFF'>");
# Display the column titles in the table
makeTableHeaderRow($tableFields, 2);
print("</TR>");
# Now that the table headers have been displayed, it is
# possible to display the table body.
makeTbleBdy($selQRes,2);
# Now close the table, as it is finished.
print("</TABLE>\n");
# Destroy all query result sets etc that are no longer needed
mysql_free_result($tableFields);
} // END if
else
{
# If this clause has been reached, it means that there are no
# functions belonging to the current action on the current
# doctype, and so we should just display a message stating
# this, as opposed to a table of functions.
print("<H4 STYLE=\"text-align: center\">The $action action on"
. " the $doctype<BR>document type has no functions</H4>");
} // END else
} // END function createActFunsList($selQRes)
//*****************
function makeTbleBdy($result, $forIndxStrt = 0)
{
/*******************************************************************
This function is a very simple function that creates the body of
a table, with no bells or whistles, by taking a result set, and
displaying each row of the result set in a row of the table. It
closes each row after it has been displayed. The function is
passed the $result variable, which contains the result set, and
the $forIndxStrt variable, which simply contains an integer,
allowing the function to commence each row at a given cell index.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 10/10/2000
Last Modified: 10/10/2000
*******************************************************************/
# Get the number of fields in the result set
$numTblFlds = mysql_num_fields($result);
while($dataRow = mysql_fetch_array($result))
{
print("<TR BGCOLOR='#FFFFCC'>\n");
# Display each field in a given row...
for($indx = $forIndxStrt; $indx < $numTblFlds; $indx++)
{
print("<TD ALIGN='center'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "</TD>\n");
} // END for
# Now close up the table row...
print("</TR>\n");
} // END while
} // END function
//**********************
function pageFocusHome()
{
/******************************************************************
This function is just a simple page to redirect the browser to
the prototype.php page (the administrators home page).
is the page that displays details of a document type and all of
its actions. The function makes a quick form with no inputs, but
an action of prototype.php.
It then pauses for 2 seconds, before submitting this form, and
hence calling the prototype.php script.
This function uses client-side JavaScript to automatically submit
the form after a time delay.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 04/09/2000
Last Modified: 06/02/2001
******************************************************************/
# Make the invisible html form...
print("<FORM ACTION='index.php' METHOD='post' NAME='referForm'>\n"
. "<INPUT TYPE='hidden'>\n"
. "</FORM>\n");
# Now, pause for 2 seconds, and then submit the form...
print("<SCRIPT TYPE='text/javascript'>\n"
. "setTimeout(\"document.referForm.submit();\", 2000);\n"
. "</SCRIPT>\n");
} // END function pageFocusHome()
//***************
function makeSelectList($queryResult, $listName, $defaultCode,
$defaultText, $valueIndex, $textIndex)
{
/****************************************************************
This function has the task of making a drop down list (type
SELECT in HTML). The list made is of course part of a form, but
this form is not made by this function. It is intended that this
function will be called after the form has been opened, and when
it is desired that a SELECT list be added to a form.
This function is passed 6 variables upon calling. They are as
follows:
1. $queryResult. This is the result of mysql_query - a select
query.
2. $listName. This is the name that the SELECT list will be
given.
3. $defaultCode. This is the default value of the first selected
item of the list.
4. $defaultText. This is the text of the first default selected
item.
5. $valueIndex. The values for each <OPTION> of the SELECT list
will be taken from the array dataRow, which will contain all
fields of a single row of queryResult. $valueIndex will be
the array index for the cell of dataRow that contains the
value desired for the VALUE attribute of the OPTION.
6. $textIndex. This is another index of the dataRow array. It
will contain the text that is to go between OPTION tags, and
hence what the user sees.
I hope this makes sense!
The function will basically build the SELECT list, and will fill
it with the desired values from each row of queryResult. The
SELECT list will then be closed, but note that the form WILL NOT
BE CLOSED.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 29/08/2000
Last Modified: 06/02/2001
****************************************************************/
print("<SELECT NAME='$listName'>\n"
. "<OPTION SELECTED VALUE='$defaultCode'>$defaultText"
. "</OPTION>\n");
# If the query executed successfully, utilise the data
# provided by it. This basically means that if the query was
# unable to trawl any data from the table for cloning it will simply
# ignore the next section of code, and the list will only have the
# default value in it, and hence PHP won't throw out any errors,
# etc...
if($queryResult)
{
while($dataRow = mysql_fetch_array($queryResult))
{
print("<OPTION VALUE='"
. htmlspecialchars($dataRow[$valueIndex])
. "'>");
print(ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$textIndex])));
print("</OPTION>\n");
} // END while
} // END if
print("</SELECT>\n");
} // END function makeSelectList()
function displayPage($doctype)
{
global $addNow,$funToAdd,$score,$step,$action;
# Now conduct a test to determine the type of call to the page this
# actually is (it can either be the first call to the page, whereby
# the ability to input the new functions details is given to the
# user, or the second call to the page, whereby the actual addition
# processing is done.
if($addNow)
{
# If this condition has been reached, this call to the page is a
# call to actually commit the new function for the given action
# on the given doctype to the relevant functions table.
# It is now possible to commit the new function for the given
# action on the given doctype into the database...
$comStr = "INSERT INTO sbmFUNCTIONS (doctype, function, score, step, action) VALUES('$doctype', '$funToAdd', '$score', '$step','$action')";
$comRes = mysql_query($comStr);
if($comRes)
{
# Display an alert message on the screen of the user informing
# them of the sucessful addition of the new function to the
# given action on the given doctype.
print("<SCRIPT TYPE='text/javascript'>alert('The $funToAdd "
. "function was added to the $action action\\non the "
. "$doctype document type.\\n\\nYou should now examine the"
. " values for each\\nof the functions parameters, and "
. " ensure that\\nthere is an entry for them.\\n\\nYour"
. " browser has been diverted to the screen where you can"
. " investigate this.')</SCRIPT>\n");
# Now redirect the browser to the func.php page...
print("<FORM ACTION='func.php' METHOD='post' NAME='sub'>\n"
. "<INPUT TYPE='hidden' NAME='returnTo' "
. "VALUE='actionFunctions.php'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='action' VALUE='$action'>\n"
. "<INPUT TYPE='hidden' NAME='functionName' "
. "VALUE='$funToAdd'>\n"
. "</FORM>\n"
. "<SCRIPT TYPE='text/javascript'>\n"
. "setTimeout(\"document.sub.submit();\", 0);\n"
. "</SCRIPT>\n");
# Get the current date and time...
$dateDets = getdate();
# Make the message...
$msgTxt = "Please be informed that the $funToAdd function was"
. " added to the $action action of the $doctype document "
. "type on "
. $dateDets['weekday'] . " " . $dateDets['mday'] . " "
. $dateDets['month'] . " " . $dateDets['year']
. ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . "."
. "\n\nWebSubmit Administrator.";
# Send the message...
mail(ADMIN_EMAIL, "$funToAdd Function Added to $action"
. ".$doctype Action", $msgTxt, "From: WebSubmit_Administrator");
} // END if
else
{
# If this clause has been reached, it means that the insert of
# the new function to the relevant functions has failed. As a
# result, the user should be informed of this by a javascript
# alert, and the browser should redirect to the WebSubmit
# Asdministrator main page.
print("<SCRIPT TYPE='text/javascript'>alert('The $funToAdd "
. "function could not be commited to the functions table,"
. "\\nand hence could not be added to the $action action for"
. " the $doctype document type.\\n\\nPlease Inform System "
. "Administrator.');</SCRIPT>\n");
# We should also email the administrator to inform them of
# this fault, or it may go unnoticed...
# Get the current date and time...
$dateDets = getdate();
# Make the message...
$msgTxt = "I have encountered an error!\n\nI was unable to "
. " add the $funToAdd function to the $action action of the"
. " $doctype document type. This is because I could not "
. "commit the details to the functions table.\n\nThis "
. "fault ocurred on "
. $dateDets['weekday'] . " " . $dateDets['mday'] . " "
. $dateDets['month'] . " " . $dateDets['year']
. ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . "."
. "\n\nYou should investigate this problem as soon as "
. "possible.\n\nWebSubmit Administrator.";
# Send the message...
mail(ADMIN_EMAIL, "ERROR: $funToAdd Function Not Added To "
. "${action}.$doctype", $msgTxt, "From: WebSubmit_Administrator");
# Now redirect the browser to the Administrator main page...
pageFocusHome();
} // END else
} // END if
else
{
# If this clause has been reached, it means that this is the
# first call to the page, whereby the details for inputting a new
# function should be presented to the user.
$selStr = "SELECT * FROM sbmFUNCTIONS WHERE doctype='$doctype' and action='$action'"
. " ORDER BY step, score";
# Execute this query...
$selQRes = mysql_query($selStr) or die("<H4>Unable to obtain a "
. "list of function for the $doctype doctype from the "
. "functions table. Processing Terminated.</H4>\n</TD>\n"
. "</TR>\n</TABLE>\n</BODY>\n</HTML>\n");
# Open a table with two columns, in which to display the page
print("<TABLE BORDER=0 ALIGN='center' WIDTH='100%' CELLSPACING=0"
. " CELLPADDING=0>\n<TR>\n<TD WIDTH='29%'"
. " ALIGN='center' VALIGN='top'>\n");
createActFunsList($selQRes, $action, $doctype);
# free space associated with unused variables/result sets
mysql_free_result($selQRes);
unset($selStr);
# Close the current page dividing table cell, then reopen another
# for the input new function form...
print("</TD>\n<TD WIDTH='1%'>\n&nbsp;</TD>\n<TD WIDTH='60%' "
. "VALIGN='top' ALIGN='center'>\n");
# Now that we have displayed the current usage of functions for
# the given action on the given doctype, it is possible to
# produce the 'addition of another function' facility...
print("<SPAN STYLE='text-align: center; color: navy; font-size:"
. " medium; font-weight: bold'>Add a function to the $action "
. "action of the $doctype document type</SPAN>\n");
# The first task is to obtain a list of all functions in WebSubmit
$funcQuery = mysql_query("SELECT function FROM sbmALLFUNCDESCR ORDER
BY function");
if($funcQuery)
{
# If the query has worked, we can create a select drop-down
# list to contain the functions. The user can then choose one
# of them to add to their action.
# Make a table to contain an input form...
print("<FORM ACTION='addFunctions.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='addNow' VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='action' VALUE='$action'>\n"
. "<TABLE WIDTH='100%' BORDER=0 ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0>\n<TR>\n<TD ALIGN='right'"
. ">\n<H4 STYLE=\"text-align: right\">Function to "
. "add:</H4></TD>\n<TD>&nbsp;</TD>\n<TD ALIGN='left'>\n");
# Create the list of functions...
makeSelectList($funcQuery, "funToAdd", "NO_FUNC",
"Select...", 0, 0);
print("</TD>\n</TR>\n<TR>\n<TD ALIGN='right'>\n<H4 STYLE=\""
. "text-align: right\">\nScore:</H4>\n</TD>\n"
. "<TD>&nbsp;</TD>\n<TD ALIGN="
. "'left'>\n<INPUT TYPE='text' SIZE=3 NAME='score'>\n"
. "</TD>\n</TR>\n<TR>\n<TD ALIGN='right'>\n<H4 STYLE=\""
. "text-align: right\">\nStep:</H4>\n</TD>\n<TD>&nbsp;"
. "</TD>\n<TD ALIGN='"
. "left'>\n<INPUT TYPE='text' SIZE=3 NAME='step'>\n"
. "</TD>\n</TR>\n<TD>&nbsp;</TD>\n</TR>\n<TR>\n<TD "
. "ALIGN='right'>\n<INPUT "
. "TYPE='button' VALUE='SAVE DETAILS' "
. "onClick=\"if(funToAdd.options[funToAdd.selectedIndex]"
. ".value != 'NO_FUNC') { if(checkScoreStep(score.value, "
. "step.value)) { if(confirm('You are about to add a "
. "function to the\\n$action action for the $doctype "
. "doctype.\\n\\nThis action will require you to manually"
. " provide values for \\nthe function parameters under "
. "this doctype.\\n\\nAre You Sure You Wish To Do "
. "This?')) { submit(); } } } else { alert('Select a "
. " function to add!'); }\">"
. "\n</TD>\n</FORM><FORM ACTION='actionFunctions.php?action=$action&doctype=$doctype' "
. "METHOD='post'>\n<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n<TD>&nbsp;</TD>\n<TD ALIGN='left'>"
. "\n<INPUT "
. "TYPE='button' VALUE='CANCEL' onClick=\"submit();\">\n"
. "</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END if
else
{
# If this clause has been reached, the script has been able to
# query the sbmALLFUNCDESCR table in order to obtain a list of
# all of the WebSubmit functions. In this case, it is simply
# appropriate to display a suitable error message, and send
# the browser focus to the WebSubmit Administrator home page, as it
# is obviously not possible to add a function in this case...
print("<H3>ERROR: Unable To Retrieve WebSubmit Functions List"
. "</H3>\n");
# Now redirect the browser...
pageFocusHome();
} // END else
# Now that the main page has been displayed, it possible to
# close up the page organisation table.
print("</TD>\n</TR>\n</TABLE>\n");
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage($doctype);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/allActionsEDS.php.wml b/modules/websubmit/web/admin/allActionsEDS.php.wml
index d588c8576..92335749c 100644
--- a/modules/websubmit/web/admin/allActionsEDS.php.wml
+++ b/modules/websubmit/web/admin/allActionsEDS.php.wml
@@ -1,121 +1,121 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Available Actions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listactions"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function displayListActionsPage()
{
# Query the "sbmACTION" table, obtaining a list of all EDS actions...
$queryResult = mysql_query("SELECT lactname, sactname FROM sbmACTION "
. "ORDER BY lactname");
if($queryResult)
{
# In this case, the query executed successfully. We can now
# display the results returned by it.
if(mysql_num_rows($queryResult) > 0)
{
# In this case, EDS has actions in it that we can display..
# Display the table header..
print("<TABLE BORDER=0 ALIGN='center'>\n");
# Now display each action item in the table..
while($dataItems = mysql_fetch_row($queryResult))
{
print("<TR>\n<TD ALIGN='left'>\n<A HREF='viewActionEDS."
. "php?actname=" . ereg_replace("'", "&#39;",
htmlspecialchars($dataItems[1]))
. "&caller=allActionsEDS.php'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataItems[1]))
. ": "
. ereg_replace("'", "&#39;",
htmlspecialchars($dataItems[0]))
. "</A></TD>\n</TR>\n");
} // END while
# Now that the table has been made, it is possible to close
# it..
print("</TABLE>\n");
} // END if
else
{
# In this case, EDS has no actions in it (very unlikely)..
print("<P STYLE=\"text-align: center; font-size: medium; "
. "color: green\">There are currently no actions stored in "
. "the <EM>" . DOCS_DATABASE . "</EM>.</P>\n");
} // END else
# Now that the actions have been displayed (or not), we can
# display a button to allow the addition of a new action to
# EDS...
print("<FORM ACTION='addActionEDS.php' METHOD='post'><TABLE "
. "BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN='center' WIDTH="
. "'100%'>\n<TR><TD ALIGN='center'>\n<INPUT TYPE='button' VALUE"
. "='ADD NEW ACTION' onClick=\"submit();\">\n</TD>\n</TR>\n"
. "</TABLE>\n</FORM>\n");
} // END if
else
{
# In this case, the query has failed, so we can display an error
# message to the user..
print("<P STYLE=\"font-size: large; color: navy; text-align: "
. "center\"><SPAN STYLE=\"color: red\">ERROR:</SPAN> Unable to"
. " query the <EM>sbmACTION</EM> table of the " . DOCS_DATABASE
. " database.<BR>"
. "Please contact system administrator.</P>\n");
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayListActionsPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/allChecksEDS.php.wml b/modules/websubmit/web/admin/allChecksEDS.php.wml
index 85441b349..f350b8477 100644
--- a/modules/websubmit/web/admin/allChecksEDS.php.wml
+++ b/modules/websubmit/web/admin/allChecksEDS.php.wml
@@ -1,116 +1,116 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Available javascript checking functions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listchecks"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function displayPage()
{
# Query the sbmCHECKS table to obtain a list of all EDS checks.
$qRes = mysql_query("SELECT * FROM sbmCHECKS ORDER BY chname");
if($qRes)
{
# In this case, the query worked, and we can now obtain a list of
# all of the checks.
if(mysql_num_rows($qRes) < 1)
{
# In this case, there are no checks in the DB, so we can just
# display a message stating this fact...
print("<TABLE WIDTH='100%' BORDER=0 CELLPADDING=0 ALIGN='"
. "center' CELLSPACING=0>\n<TR>\n<TD ALIGN='center'><SPAN "
. "STYLE=\"color: green; text-align: center; font-size: "
. "large\">There are currently no checks in the database</SPA"
. "N></TD>\n</TR>\n</TABLE>\n");
} // END if
else
{
# In this case, there are checks to display, so we can get on
# with it!
# Display the table header..
print("<TABLE BORDER=0 ALIGN='center'>\n");
# Now display each action item in the table..
while($dataItems = mysql_fetch_array($qRes))
{
print("<TR>\n<TD ALIGN='left'>\n<A HREF='viewChecksEDS."
. "php?chname=" . ereg_replace("'", "&#39;",
htmlspecialchars($dataItems["chname"])) . "'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataItems["chname"]))
. "</A></TD>\n</TR>\n");
} // END while
# Now that the table has been made, it is possible to close it
print("</TABLE>\n");
} // END else
# Now that the actions have been displayed (or not), we can
# display a button to allow the addition of a new action to EDS
print("<FORM ACTION='addCheckEDS.php' METHOD='post'><TABLE "
. "BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN='center' WIDTH="
. "'100%'>\n<TR><TD ALIGN='center'>\n<INPUT TYPE='button' VALUE"
. "='ADD NEW CHECK' onClick=\"submit();\">\n</TD>\n</TR>\n</TAB"
. "LE>\n</FORM>\n");
} // END if
else
{
# In this case, the query failed, so we can display an error
# message
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> It was not possible to obtain a list of checks from "
. "the sbmCHECKS table of the " . DOCS_DATABASE . " database.<BR>"
. "Please contact the system administrator.</P>\n");
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/allElementsEDS.php.wml b/modules/websubmit/web/admin/allElementsEDS.php.wml
index 2e1dd28c3..cb1ea32dc 100644
--- a/modules/websubmit/web/admin/allElementsEDS.php.wml
+++ b/modules/websubmit/web/admin/allElementsEDS.php.wml
@@ -1,143 +1,143 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Available Element Descriptions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listelements"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function displayPage()
{
// get all element descriptions.
$queryResult = mysql_query("SELECT name FROM sbmFIELDDESC ORDER BY "
. "name");
if($queryResult)
{
if(mysql_num_rows($queryResult) < 1)
{
// No elements
print("<P CLASS=\"errorMsg\">There Are Currently No Element "
. "Descriptions In " . DOCS_DATABASE . "</P>\n");
}
else
{
print("<TABLE BORDER=1 CELLSPACING=3 ALIGN=\"center\">\n"
. "<TR>\n");
// only display 25 items in a table column
$itemCount = 0;
$numEls = mysql_num_rows($queryResult);
// Put all of the elements in an array
$allOfThem = resToArray($queryResult);
for($i = 0; $i < $numEls; $i++)
{
if($itemCount == 0)
{
// First item of a table
print("<TD ALIGN=\"center\" VALIGN=\"top\">\n"
. "<TABLE ALIGN=\"center\" BORDER=0"
. " CELLSPACING=0 CELLPADDING=0>\n<TR><TD ALIGN=\""
. "left\">\n<A HREF=\"elementConfigDetsEDS.php?name="
. ereg_replace("\"", "&#34;",
htmlspecialchars($allOfThem[$i][0]))
. "&caller=allElementsEDS.php\">"
. ereg_replace("\"", "&#34;",
htmlspecialchars($allOfThem[$i][0]))
. "</A>&nbsp;</TD></TR>\n");
$itemCount++;
}
elseif($itemCount == 24)
{
// Last item for the current table column
print("<TR><TD ALIGN=\"left\">\n<A HREF=\"elementConfig"
. "DetsEDS.php?name=" . ereg_replace("\"", "&#34;",
htmlspecialchars($allOfThem[$i][0]))
. "&caller=allElementsEDS.php\">"
. ereg_replace("\"", "&#34;",
htmlspecialchars($allOfThem[$i][0]))
. "</A>&nbsp;</TD></TR>\n</TABLE>\n</TD>\n");
$itemCount = 0;
}
else
{
// Just a normal column element
print("<TR><TD ALIGN=\"left\"><A HREF=\"elementConfigD"
. "etsEDS.php?name=" . ereg_replace("\"", "&#34;",
htmlspecialchars($allOfThem[$i][0]))
. "&caller=allElementsEDS.php\">"
. ereg_replace("\"", "&#34;",
htmlspecialchars($allOfThem[$i][0]))
. "</A>&nbsp;</TD></TR>\n");
$itemCount++;
}
}
if($itemCount != 0)
{
print("</TABLE>\n</TD>");
}
print("</TR>\n</TABLE>\n");
}
print("<FORM ACTION=\"addElementDescrEDS.php\" METHOD=\"post\"><TA"
. "BLE BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN=\"left\" "
. "WIDTH=\"100%\">\n<TR><TD ALIGN=\"center\">\n<INPUT TYPE=\"submit\""
. " VALUE=\"CREATE NEW ELEMENT DESCRIPTION\">\n"
. "</TD>\n</TR>\n</TABLE>\n</FORM>\n");
}
else
{
print("<P STYLE=\"font-size: large; color: navy; text-align: "
. "center\"><SPAN STYLE=\"color: red\">ERROR:</SPAN> Unable to "
. "query the <EM>sbmFIELDDESC</EM> table of the " . DOCS_DATABASE
. " database.<BR>Please contact system administrator.</P>\n");
}
}
/**********************Start of main script***************************/
// Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
// Select the Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/commonPhpFunctions.php.wml b/modules/websubmit/web/admin/commonPhpFunctions.php.wml
index d8d93a9cb..1b9d5c83e 100644
--- a/modules/websubmit/web/admin/commonPhpFunctions.php.wml
+++ b/modules/websubmit/web/admin/commonPhpFunctions.php.wml
@@ -1,893 +1,893 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
## load config variables:
define("DOCS_DATABASE", "<DBNAME>");
define("MYSQLDOCMACHINE","<DBHOST>");
define("MYSQLDOCUSERID","<DBUSER>");
define("MYSQLDOCPASSWORD","<DBPASS>");
define("ADMIN_EMAIL","<ADMINEMAIL>");
$IMAGES="<WEBURL>/img";
## okay, config variables loaded, the script can continue:
/*********************************************************************
This script is not executable in a browser. It contains the
definitions of all PHP functions that are common to all of the
scripts in the WebSubmit Administrator system. This script has been
adapted from its WebSubmit counterpart, and contains some of the
functions of that script.
*********************************************************************/
/********************Common Global Constants*************************/
# Make a global constant to store the color for the background of cells
# in the page header for linking to other pages/administrative tools...
define("MENU_NAME_COLOUR", "cornflowerblue");
# Make another golbal constant to store the colour for the background
# of cells for the options in the menus...
define("MENU_OPTION_COLOUR", "#9AE2C0");
/********************Includes*************************/
include("<WEBDIR>/sessinit.inc.php");
require_once("<LIBDIR>/php/cdsware/errors/errorHandling.php");
/*********************Authentication*******************************/
function canUseWebSubmitAdmin($uid,$doctype='%')
{
$uid_email = getEmail($uid);
$auth = acc_authorize_action($uid, "cfgwebsubmit");
if($auth[0] == 0)
return array(true, $auth[1]);
else
return array(false, $auth[1]);
}
function makeEDSmdDate()
{
/****************************************************************
This function creates a date in the numeric format YYYY-MM-DD.
This date is made into a text string, and returned by this
function.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 14/12/2000
Last Modified: 14/12/2000
***************************************************************/
# Get the date, so that it can be committed for the
# modification date field (md) and the creation date field
# (cd)...
$dateDets = getdate();
# Now put the date into a variable in a nice MySQL friendly
# format
$theDate = $dateDets['year'] . "-" . $dateDets['mon'] . "-"
. $dateDets['mday'];
# Now return our newly created date...
return $theDate;
} // END function makeEDSmdDate()
function makeDate()
{
/***************************************************************
This function has the simple task of getting the date from the
system, and printing it to a variable in the form "Thursday 16
Nov 2000, at 11:54". The contents of this string are then
returned to the calling function, to be concatenated to another
string.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 16/11/2000
Last Modified: 16/11/2000
***************************************************************/
# Get the current date and time...
$dateDets = getdate();
# Make a string containing the date...
$dateString = $dateDets['weekday'] . " "
. $dateDets['mday'] . " " . $dateDets['month'] . " "
. $dateDets['year'] . ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'];
# Now return this strings contents...
return $dateString;
} // END function makeDate()
function getCallingPage($theRefererPage)
{
/******************************************************************
We don't want to allow the user to call a page by simply
typing something in the uri bar of his/her browser. We only want
a given page to be called from certain other scripts belonging to
the WebSubmit2 administrator. This is a security feature, as we don't
want the user to be able to corrupt the database either
accidentally, or maliciously by typing URIs of scripts with CGI
variables being passed to them. We can ensure this doesn't
happen by testing the special HTTP variable HTTP_REFERER to
ensure that it contains the name of a legal WebSubmit2 administrator
script.
This function gets the name of the calling page from the
variable theRefererPage, which is actually a copy of the
HTTP_REFERER variable that has been passed from the calling
script. The name of the calling page is then returned to the
calling script for evaluation.
Author: Nicholas Robinson.
Email: Nicholas.Robinson@cern.ch
Created: 09/08/2000
Last Modified: 02/02/2001
*******************************************************************/
# Test to see if the string is empty... if it is, it means that the
# page has not been called by another page...i.e. somebody has typed
# a URL into the location bar. This means we can return a string
# containing a character that would never feature in a URL, so that
# it is known that the page calling was invalid...
# This has actually come about due to the fact that the page can be
# a legitimate call when there is no page name when the page is
# called index.
if($theRefererPage == "")
{
# Return a garbage string so that no confusion is made about the
# referer variable being empty...
return "";
} // END if
else
{
$callingPage = $theRefererPage;
if(strstr($callingPage, '?'))
{
# If it did have variables encoded in the URL...
# Find the position of the question mark that separates the
# page URL from the variables...
$posQuestMark = strpos($callingPage, "?");
# Remove the portion of the string from the ? onwards, as we
# are only required to test the name of the calling page, not
# any arguments passed to it. Set the value of $callingPage...
$callingPage = substr($callingPage, 0, $posQuestMark);
} // End if
$posLastSlash = strrpos($callingPage, "/");
# Increment $posLastSlash, as it is the data after the slash that
# is of interest to us here, as that is the page name...
$posLastSlash++;
# Now, use PHPs substr function to find the remainder of the
# theRefererPage string, which should actually be the name of the
# calling page...
$callingPage = substr($callingPage, $posLastSlash);
# Return the name of the calling page for further processing in
# the system...
return $callingPage;
} // END else
} // End function getCallingPage(theRefererPage)
// ******************************
function displayInvalidEntry()
{
/******************************************************************
This function merely displays a simple warning message on the
screen, informing the user that permission has been denied to
load the page, and provides a link to the home page. This
function will be called when the user has attempted to load one
of the administrator pages in an inappropriate way, such as
typing the URI into the location bar, and pressing enter, instead
of following the WebSubmit2 Administrator pages through the hierarchy
to get to a specific page.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 09/08/2000
Last Modified: 24/10/2000
*****************************************************************/
# Display the error message...
print('<H3 STYLE="color: red">Permission Denied: Please ');
print('Start At The <A HREF="index.php">Main ');
print('Page</A>.</H3>');
} // End function displayInvalidEntry()
// ******************************
function serverConnect($host, $username, $password)
{
/******************************************************************
This function is a very simple function that allows a user to
connect to a mySQL server of their choice. The function uses the
mysql_connect function provided by php to attempt to connect to
the server. If connection fails, an appropriate error message is
displayed, otherwise the connection link is returned.
Function modified on 28/09/2000 to add </td>, </tr>, and </table>
tags, as the message wasn't being printed due to the fact that
when the die() function was executed, it stopped processing,
hence the table that contains the pages data was never being
closed, resulting in it being impossible to display anything in
this table.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 21/08/2000
Last Modified: 28/09/2000
*****************************************************************/
# Make a connection to the database server...
$link = mysql_connect($host, $username, $password) or
die('<BR><P><H3 ALIGN="center">Unable To '
. 'Connect To SQL Server. Try Reload Of Page.'
. '</H3></P></TD></TR></TABLE></BODY>'
. '</HTML>');
# Return the link to the connection...
return $link;
} // END function serverConnect($host, $username, $password)
// ******************************
function dbSelect($dbName)
{
/******************************************************************
This function is a very simple function that allows a user to
select a mySQL database of their choice. The function uses the
mysql_select_db function provided by php to attempt to select the
DB. If selection fails, an appropriate error message is
displayed, and processing terminates. Otherwise the function
ends normally, returning control to the calling function.
Function modified on 28/09/2000 to add </td>, </tr>, and </table>
tags, as the message wasn't being printed due to the fact that
when the die() function was executed, it stopped processing,
hence the table that contains the pages data was never being
closed, resulting in it being impossible to display anything in
this table.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 21/08/2000
Last Modified: 28/09/2000
******************************************************************/
# Select the database...
mysql_select_db($dbName) or
die('<BR><P><H3 ALIGN="center">Unable To Select'
. ' $dbName Database. Try Reload Of Page.'
. '</H3></P></TD></TR></TABLE></BODY>'
. '</HTML>');
} // END function dbSelect($dbName)
// ******************************
function makeTableHeaderRow($columns, $indexValue)
{
/****************************************************************
This function serves the single purpose of producing a header row
for a table. The function is passed a variable $columns, which
is a list of all columns in the table whose header is to be
produced. The function is also passed a variable $indexValue,
which should hold an integer that the for loop index is to be
initialised to. This has the purpose of allowing the table to
start from any column. This function loops through each column in
the table, FROM the column specified by $indexValue, and prints
this columns title inside a table cell using HTMLs <TH> notation.
It should be noted that it does not open or close the table with
the <TABLE> or </TABLE> tags, as it is assumed that it will only
be called to add the header information to a table, as this is a
commonly done thing for all tables.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 23/08/2000
Last Modified: 23/08/2000
****************************************************************/
for($index = $indexValue; $index < mysql_num_fields($columns);
$index++)
{
print('<TH>&nbsp;');
print(mysql_field_name($columns, $index));
print('&nbsp;</TH>');
} // END for
} // END function makeTableHeaderRow($columns, $indexValue)
//**********************
function resToArray($queryResult)
{
/******************************************************************
This function has the purpose of making a 2D array from the
result of a select query. The query result pointer is passed to
the function, and each row of the result is read into an array
cell. When the query result set has been exhausted, it is
returned to the calling function.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 28/08/2000
Last Modified: 28/08/2000
******************************************************************/
# Make a counter for the rows...
$rowCount = 0;
# Put the contents of the query dynaset into
# a temporary array...
while($dataRow = mysql_fetch_row($queryResult))
{
$allRows[$rowCount] = $dataRow;
$rowCount++;
} // End while
return $allRows;
} // END function resToArray($queryResult)
//******************
function drawSeparator()
{
/***************************************************************
This is a very simple function to draw a horizontal separator
line across the page. This line is encapsulated in <P>aragraph
tags.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 02/10/2000
Last Modified: 02/10/2000
***************************************************************/
# Draw the horizontal separator line...
print('<P><HR WIDTH="100%" ALIGN="center"></P>');
} // END function drawSeparator()
//***************
function displayParams($paramResult, $function)
{
/**************************************************************
This function has the task of displaying the parameters of a
function in a table. The function is passed a query result,
which should point to a dynaset of parameters. If the result set
contains rows (i.e. there are parameters to display), the query
displays these parameters in the table. If however the result
set is empty (there are no parameters to display), the functions
outputs a suitable message to say this.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 02/10/2000
Last Modified: 31/01/2001
**************************************************************/
global $IMAGES;
if(mysql_num_rows($paramResult) > 0)
{
# Output the parameter details in a table...
print('<BR><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 '
. 'ALIGN="center"><TR BGCOLOR="#CCDDFF">');
# Output the table headers...
print('<TH>Field</TH>');
print('<TH STYLE="color: red">Delete</TH></TR>');
# Now output the body of the table...
while($dataRow = mysql_fetch_array($paramResult))
{
print('<TR BGCOLOR="#FFFFCC">'
. '<TD>&nbsp;' . $dataRow['param'] . '&nbsp;</TD>');
# Now, we can display a button icon on which to click to
# delete a parameter from the current function...
print('<FORM ACTION="veditFunDets.php" METHOD="post" '
. 'onSubmit="if(confirm(\'Really Remove This Parameter '
. 'From This Function?\')) { return true; } else { '
. 'return false; }">'
. '<INPUT TYPE="hidden" NAME="deleteParam" VALUE="true">'
. '<INPUT TYPE="hidden" NAME="function" VALUE="'.$function.'">'
. '<INPUT TYPE="hidden" NAME="param" VALUE="'
. $dataRow['param'] . '">'
. '<TD ALIGN="center"><INPUT TYPE="image" SRC="'
. $IMAGES.'/answer_bad.gif" WIDTH=14 HEIGHT=14 BORDER=0 '
. 'ALT="Delete Parameter" onClick="submit();"></TD>'
. '</FORM></TR>');
} // END while
# Now that the table has been filled, we can close it up...
print('</TABLE>');
} // END if
else
{
# If this clause has been reached, then it means that the
# query on the sbmFUNDESC table has returned no rows, hence
# meaning that the function in question takes no
# parameters...
print('<H4 STYLE="text-align: center; color: red;'
. ' background-color: transparent">This function'
. ' takes'
. ' no parameters</H4>');
} // END else
} // END function displayParams($paramResult, $function)
//***********************
function offerAddParam($function, $formsAction)
{
/****************************************************************
This function has the task of offering the user the option to
add parameters to the function. It effectively displays a table
with cells containing various input boxes where the parameter can
be chosen, and then submitted by means of a submit button.
The function displays one select list for the table part of the
parameter, and one select list for the fields part of the
parameter, if the table that the parameter is to be found in has
been selected.
It had been my intention to implement this feature by means of a
nested dropdown list, made using JavaScript, (as at this stage,
browsers do not support HTML 4s optgroup tag), but for reasons
of compatibility, I have decided against this idea. Maybe at
some point in the future, that is what I shall do. For now
however, I think I shall just use html selection boxes.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 02/10/2000
Last Modified: 03/10/2000
****************************************************************/
dbSelect(DOCS_DATABASE);
# Open a table in which to contain this section...
print('<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 '
. 'ALIGN=center BGCOLOR=#E0E0E0 WIDTH=95%>'
. '<TR><TD ALIGN=left>');
# Output the title of the section, along with a short description
# of how to add a parameter...
print('<H4>Add A Parameter:</H4>'
. '<SMALL><EM>Please select the parameter you want to add to this function:<BR></EM></SMALL>');
# Run a SELECT query to obtain a list of all tables in the WebSubmit
# database. This will be used as the table that the parameter is
# to be found in when a user adds a parameter to the function.
print('<TABLE BORDER=1 ALIGN=center CELLSPACING=0 '
. 'CELLPADDING=0 BGCOLOR=ivory WIDTH=80%>'
. '<TR><TD ALIGN=center WIDTH=50%'
. ' BGCOLOR=ivory>');
print('<FORM ACTION='.$formsAction.' METHOD=get>'
. '<INPUT TYPE=hidden NAME=insertParam'
. ' VALUE=true>'
. '<INPUT TYPE=hidden NAME=function'
. ' VALUE='.$function.'>'
. '<SELECT NAME=theParam>'
. '<OPTION SELECTED VALUE=NO_VALUE>Select a'
. ' field...</OPTION>');
$res = mysql_query("select DISTINCT name from sbmPARAMETERS order by name");
while ($row = mysql_fetch_row($res))
{
print '<option value="'.$row[0].'">'.$row[0].'</OPTION>';
}
print('</SELECT>');
print ' <small>or enter a new one: <INPUT size=25 name=newParam></small>';
# We can now shut the cell down, and insert a button to
# allow the user to add the parameter to the function...
print('</TD></TR></TABLE>');
print('<BR><CENTER><INPUT TYPE=button VALUE=\'UPDATE'
. ' PARAMETER\' onClick="if(theParam.options[theParam.'
. 'selectedIndex].value == \'NO_VALUE\' && newParam.value == \'\')'
. ' { alert(\'A table field must be selected in order'
. ' to add a parameter!\'); } else { if(confirm(\'Warning:'
. '\\nAdding a parameter to a function will mean that'
. ' further manual updating of the WebSubmit database is '
. 'necessary.\\nAre you sure you wish to undertake'
. ' this action?\')) { submit(); } }"'
. '></CENTER></FORM>');
# Now that the section is finished, we can close the table up...
print('</TD></TR></TABLE>');
} // END function offerAddParam()
//*****************
function displayFuncDets($queryResult, $formsAction)
{
/**************************************************************
This function has the task of making an input form that contains
the details of the function (its name, and its description). The
form is contained within 2 tables. The first table contains the
actual input fields for the form, and the second table contains
the submit button for the form, which allows the user to submit
an update to the description field.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 02/10/2000
Last Modified: 02/10/2000
**************************************************************/
# Get a list of the fields in the sbmALLFUNCDESCR table
$fields = mysql_list_fields(DOCS_DATABASE, "sbmALLFUNCDESCR");
# Now get the length of the description field...
$descLen = mysql_field_len($fields, 1);
# Read the only row of the query dynaset into an array...
$dataRow = mysql_fetch_array($queryResult);
# Open an HTML form to allow the user to view the details of
# the function name, and description fields, and to edit the
# function description field if they so wish...
print('<FORM METHOD=post ACTION="'.$formsAction.'">'
. '<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>'
. '<INPUT TYPE='
. 'hidden NAME=function VALUE="' . $dataRow['function']
. '"><TR><TD ALIGN=right><STRONG>'
. '<H4>description:</H4></STRONG></TD>'
. '<TD>&nbsp;&nbsp;</TD><TD ALIGN=left>'
. '<INPUT TYPE=text NAME=description VALUE="'
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow['description']))
. '" SIZE=60'
. '></TD></TR></TABLE>');
/***************************************************************
Add a submit button to the form to allow the user to update
the function description details if they so wish:
For this, we also need to add 2 new hidden input fields. One
of these is to contain a flag to indicate that the page has
been called before, and the other is to contain a flag to
indicate that the next instance of the page will be for
updating the function description (updateDescr).
***************************************************************/
print('<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0'
. ' ALIGN=center><TR><TD>'
. '<INPUT TYPE=hidden NAME=updateFunDets VALUE=true>'
. '</TD><TD ALIGN=center><INPUT TYPE=button '
. 'VALUE="UPDATE'
. ' DETAILS" onClick="submit()"></TD><TD>&nbsp;</TD>'
. '</TR></TABLE></FORM>');
} // END function displayFuncDets($queryResult)
//****************
function makePageBody($function, $formsAction)
{
/*****************************************************************
This is the function that creates the page. It does so by
executing a number of queries, and then calling other functions
to display their results.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 02/10/2000
Last Modified: 22/03/2001
*****************************************************************/
# Execute a query to get all of the information about a given
# function from the sbmFUNDESC table...
# Apply table locks
if($lockRes = mysql_query("LOCK TABLES sbmALLFUNCDESCR READ, sbmFUNDESC READ"))
{
$queryResult = mysql_query("SELECT * FROM sbmALLFUNCDESCR WHERE "
. "function = '$function'");
# If the function has an entry in the mandatory function
# description table (sbmALLFUNCDESCR)...
if($queryResult)
{
# Display the details of the function in a form, offering the
# user the chance to update the description...
displayFuncDets($queryResult, $formsAction);
# Add a separator...
drawSeparator();
# Now display the parameters for the function (if any)...
print('<P><H4>Parameters:</H4></P>');
/*************************************************************
We must test to see if the function takes parameters. If it
does take parameters, these parameters will be found in the
sbmFUNDESC table, as this table contains details of parameters
for functions. This means that we can simply query the sbmFUNDESC
table for functions matching the functions whose details we
are displaying...
*************************************************************/
$paramResult = mysql_query("SELECT param FROM
sbmFUNDESC
WHERE function = '$function'");
# Unlock the tables...
$unlockRes = mysql_query("UNLOCK TABLES");
# Now take the appropriate action (whether to display
# parameters or not), depending upon whether this query
# returned rows...
if($paramResult)
{
# If the query for retrieving parameters has been
# successful, display these parameters...
displayParams($paramResult, $function);
} // END if
else
{
# If this clause has been reached, then the system has been
# unable to query the sbmFUNDESC table for some reason, and
# hence an error message should be displayed...
print('<SCRIPT TYPE="text/javascript">alert("Error:'
. 'Unable to query sbmFUNDESC table. Inform system '
. 'administrator.")</SCRIPT>');
} // END else
# Now, we can once again separate sections with a horizontal
# rule...
drawSeparator();
# Now offer the user the option to add parameters to the
# function
offerAddParam($function, $formsAction);
# Add a separator to close the section...
drawSeparator();
} // END if
else
{
# Unlock the tables...
$unlockRes = mysql_query("UNLOCK TABLES");
# Display error message...
print('<SCRIPT TYPE="text/javascript">alert("Error:'
. 'Unable to retrieve information concerning the function '
. 'from the sbmALLFUNCDESCR table");</SCRIPT>');
} // END else
} # END if
else
{
# Oh dear - unable to get table lock - simply display error
# message.
print('<DIV STYLE="color: navy; text-align: center; font-size:'
. ' large; font-weight: bold"><SPAN STYLE="color: red">Error:'
. '</SPAN> Unable to retrieve function information.</DIV>'
. mysql_error().'<BR>');
} # END else
} // END function makePageBody()
//*****************
function test_key_legal($theKey)
{
/*******************************************************************
It has been decided that it is safe if a unique "key" for a table
is made up only of alphabetical characters, integer digits, and
underscores. This stops any other characters from causing errors
due to "wild card" features. This function loops through a
string and ensures that it meets these requirements. It returns
true if the string is legal, and false if not.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 11/01/2001
Last Modified: 11/01/2001
*******************************************************************/
# Set an error flag to false...
$errorFlag = 0;
# Get the length of the string to be tested...
$len = strlen($theKey);
for($i = 0; $i < $len; $i++)
{
if(($theKey[$i] < "a" || $theKey[$i] > "z")
&& ($theKey[$i] < "A" || $theKey[$i] > "Z")
&& ($theKey[$i] < "0" || $theKey[$i] > "9")
&& ($theKey[$i] != "_"))
{
# If the current character in the string is not an
# alphabetical character, a number, or an underscore, then it
# is illegal!
# Set the error flag...
$errorFlag = 1;
break;
} // END if
} // END for
# Return true/false, depending upon string legality...
return ($errorFlag == 1) ? false : true;
} // END function test_key_legal($theKey)
//*****************
function printCookie($coookeee)
{
/****************************************************************
Because when we are offering the opportunity to change the
details of an element description, we want to offer the user the
chance to change the set cookie flag by using a radio button, we
need to write the same piece of code several times. To counter
this, a nice function has been made.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 30/11/2000
Last Modified: 10/01/2001
****************************************************************/
if($coookeee)
{
print('<INPUT TYPE=radio NAME=cookie '
. 'VALUE=0>No<BR><INPUT TYPE=radio NAME=cookie '
. 'VALUE=1 checked>Yes');
} // END if
else
{
print('<INPUT TYPE=radio NAME=cookie VALUE=0 '
. 'checked>No<BR><INPUT TYPE=radio NAME=cookie '
. 'VALUE=1>Yes');
} // END else
} // END function printCookie($cookeee)
//***************
//************
//**************
function updateEDSDOCTYPEmd($doctype, $md)
{
/******************************************************************
This function has been created, because it is often necessary to
update the modification date field of the sbmDOCTYPE table for a
given EDS doctype. This is because whenever we make alterations
to a submission or its elements etc, we are also making
alterations to the actual doctype that this submission belongs
to. This means that we must update the modification date field
of this doctype to reflect that it has been changed in some way.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 14/12/2000
Last Modified: 14/12/2000
******************************************************************/
$mdResult = mysql_query("UPDATE sbmDOCTYPE SET md = '$md' WHERE "
. "sdocname = '$doctype'");
if($mdResult)
{
# In this case, the update result for updating the
# modification date of a doctype worked, so we can free
# it's result pointer
mysql_free_result($mdResult);
} // END if
else
{
# Update the submission md query error...output a quick alert
print('<SCRIPT TYPE="text/javascript">alert("ERROR: Unable'
. ' to update the Modification Date field for the '
. 'current document type<BR>in the sbmDOCTYPE table.");'
. '</SCRIPT>');
} // END else
} // END function updateEDSDOCTYPEmd($doctype)
//************
function sendToPageDets($subname, $pageNumber, $nPgs, $doctype)
{
/*******************************************************************
This function simply redirects the browser focus to the
"pageDetsEDS.php" page.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 12/12/2000
Last Modified: 06/02/2001
*******************************************************************/
# We can now redirect the browser to the the page showing the
# details of this document type & its submissions
print('<FORM ACTION="pageDetsEDS.php" METHOD="post" '
. 'NAME="referForm">'
. '<INPUT TYPE=hidden NAME=doctype VALUE="'.$doctype.'">'
. '<INPUT TYPE=hidden NAME=subname VALUE="'.$subname.'">'
. '<INPUT TYPE=hidden NAME=pageNumber VALUE="'.$pageNumber
. '"><INPUT TYPE=hidden NAME=nPgs VALUE="'.$nPgs.'">'
. '</FORM>');
print('<SCRIPT TYPE="text/javascript">'
. 'setTimeout("document.referForm.submit();", 1000);'
. '</SCRIPT>');
} // END function sendToPageDets()
/*************End of header file commonPhpFunctions.php*************/
?>
diff --git a/modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml b/modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml
index 5745408d6..d6efa9636 100644
--- a/modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml
+++ b/modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml
@@ -1,539 +1,539 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Edit categories of the <i><protect><?print $doctype;?></protect></i> document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*********************Function Descriptions***************************/
function showCatsEDS($doctype)
{
/*******************************************************************
This function has the task of effectively making the page that
displays all of the categories of the current doctype in a table.
It also makes a button allowing the user to add a new category if
they wish.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 15/01/2001
Last Modified: 15/01/2001
*******************************************************************/
global $IMAGES;
$dataRes = mysql_query("SELECT * FROM sbmCATEGORIES WHERE doctype = "
. "'$doctype' ORDER BY sname");
if($dataRes)
{
# In this case, the query executed successfully.
if(mysql_num_rows($dataRes) > 0)
{
print("<TABLE WIDTH='50%' ALIGN='center' BORDER=1 "
. "CELLSPACING=0 CELLPADDING=0><TR BGCOLOR='#CCDDFF'>"
. "<TH>Category ID</TH><TH>Category"
. " Description</TH><TH>&nbsp;</TH><TH>&nbsp;</TH>"
. "</TR>");
while($row = mysql_fetch_array($dataRes))
{
print("<TR BGCOLOR='#FFFFCC'><TD ALIGN='center'>"
. $row["sname"] . "&nbsp;</TD><TD ALIGN='center'>"
. $row["lname"] . "&nbsp;</TD>");
# Now add a form for editing this cat.
print("<FORM ACTION='doctypeCategoriesEDS.php' METHOD='"
. "post'><INPUT TYPE='hidden' NAME='editCatForm' VALUE="
. "'true'><INPUT TYPE='hidden' NAME='doctype' VALUE='"
. "$doctype'><INPUT TYPE='hidden' NAME='sname' VALUE='"
. $row["sname"] . "'><TD ALIGN='center'><INPUT TYPE='"
. "image' SRC='".$IMAGES."/edit1.gif' BORDER=0 onClick=\""
. "submit();\" ALIGN='center' WIDTH=18 HEIGHT=18></TD>"
. "</FORM>");
# Now add a form for deleting this cat
print("<FORM ACTION='doctypeCategoriesEDS.php' METHOD='"
. "post'><INPUT TYPE='hidden' NAME='delCat' VALUE='"
. "true'><INPUT TYPE='hidden' NAME='doctype' VALUE='"
. "$doctype'><INPUT TYPE='hidden' NAME='sname' VALUE='"
. $row["sname"] . "'><TD ALIGN='center'><INPUT TYPE='"
. "image' SRC='".$IMAGES."/answer_bad.gif' BORDER=0 ALIGN='"
. "center' WIDTH=14 HEIGHT=14></TD></FORM>");
print("</TR>");
} // END while
print("</TABLE>");
} // END if
else
{
# No rows returned - output a message saying that the
# current doctype does not yet have any categories
print("<P STYLE=\"color: green; font-size: large; text-align:"
. " center; font-weight: bold\"><EM>$doctype</EM> "
. "Document Type Has No Categories</P>");
} // END else
# Now make a button that the user can press in order to add a new
# category
print("<FORM ACTION='doctypeCategoriesEDS.php' METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='addCatForm' VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>"
. "<TABLE ALIGN='center' BORDER=0><TR><TD ALIGN='center'>"
. "<INPUT TYPE='button' VALUE='ADD A CATEGORY' onClick=\""
. "submit();\"></TD></TR></TABLE></FORM>");
mysql_free_result($dataRes);
} // END if
else
{
# In this case, the query failed, so we just output the warning
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR"
. ":</SPAN> Unable To Retrieve Details of Categories for "
. "<EM>$doctype</EM> Document Type.<BR>Inform System Adminis"
. "trator.</P>");
} // END else
print("<FORM ACTION='documentEDS.php' METHOD='post'><INPUT "
. "TYPE='hidden' NAME='doctype' VALUE='$doctype'><TABLE "
. "ALIGN='center' BORDER=0><TR><TD ALIGN='center'>"
. "<INPUT TYPE='button' VALUE='FINISHED' onClick=\"submit();"
. "\"></TD></TR></TABLE></FORM>");
} // END function showCatsEDS($doctype)
//************
function addEditCatForm($doctype, $formType, $sname = "")
{
/*******************************************************************
This function has the task of creating an html form. This form
will contain the details of a given category for the given
doctype. It is called for both the adding of a new category, and
the editing of an existing category description. The difference
is that a value is passed to the function. This value is a
string containing a word that will be used to determine whether
or not to present the form in a manner in which all details can
be entered into it (for a cat addition), or in a manner in
which there are already cat dets in the form, and only the cat
descr can be edited. When the form is submitted, the relevant
update/insert is carried out.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 15/01/2001
Last Modified: 15/01/2001
*******************************************************************/
# Reset error flag
$editQError = 0;
if($formType != "ADD")
{
$res = mysql_query("SELECT * FROM sbmCATEGORIES WHERE doctype = '"
. "$doctype' AND sname = '$sname'");
if(!$res)
{
$editQError = 1;
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable To Retrieve Details Of <EM>$sname</EM"
. "> Category.</P>");
showCatsEDS($doctype);
} // END if
else
{
if(mysql_num_rows($res) < 1)
{
$editQError = 1;
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable To Retrieve Details Of <EM>$sname"
. "</EM> Category.</P>");
showCatsEDS($doctype);
} // END if
elseif(mysql_num_rows($res) > 1)
{
# Too many rows. Data inconsistency problem.
$editQError = 1;
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> More Than 1 Category Was Found With The "
. "ID <EM>$sname</EM For The <EM>$doctype</EM> Document "
. "Type.<BR>Inform System Administrator.</P>");
showCatsEDS($doctype);
} // END elseif
else
{
$dataRow = mysql_fetch_array($res);
} // END else
} // END else
} // END if
# if the $editQError flag has not been set, continue building form
if(!$editQError)
{
# Get a list of the fields in the sbmCATEGORIES table
$columns = mysql_list_fields(DOCS_DATABASE, "sbmCATEGORIES");
print("<P CLASS=\"errorMsg\">");
print("</P><TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='"
. "center' BGCOLOR='#D3DCE3' BORDER=1 CELLSPACING=0 CELLPADDING"
. "=0><TR><TD ALIGN='center'><P STYLE=\"color: blue; text"
. "-align: center; font-size: small; font-weight: bold\">Below, "
. "is a form that allows you to ");
if($formType == "ADD")
{
print("enter the details of a new category for the <EM>"
. "$doctype</EM> document type.<BR><BR>It is important that "
. "when you create a new category, you do not give it a name "
. "that is already in use for a category,<BR>as the category "
. "name must be unique due to the fact that it is used to ide"
. "ntify a given EDS document category.<BR><BR>When the "
. "category has been entered, click on the \"SAVE DETAILS\""
. " button to commit this new category to EDS.");
} // END if
else
{
print("edit a category description for the <EM>$doctype</EM> "
. "document type.<BR><BR>When the description has been "
. "edited, click on the \"SAVE DETAILS\" button to commit the"
. " changes.");
} // END else
print("</P></TD></TR></TABLE>");
drawSeparator();
print("<TABLE WIDTH='100%' ALIGN='center' BORDER=0 CELLSPACING=0"
. " CELLPADDING=0><FORM ACTION='doctypeCategoriesEDS.php' "
. "METHOD='post'><INPUT TYPE='hidden' NAME='");
# We must ensure that we tell our script next time whether to
# insert the details in the form, or simply update the
# description details.
if($formType == "ADD")
{
print("addCatCommit");
} // END if
else
{
print("editCatCommit");
} // END else
print("' VALUE='true'><TR><TH BGCOLOR='#D3DCE3' ALIGN='"
. "right'WIDTH='20%'>Document Type ID:&nbsp;</TH><TD ALIGN"
. "='left'BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT TYPE='readonl"
. "y' NAME='doctype' VALUE='$doctype'></TD></TR><TR>"
. "<TH BGCOLOR='");
if($formType == "ADD")
{
print("#87CEFA' ALIGN='right' WIDTH='20%'>Category ID:&nbsp;"
. "</TH><TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>"
. "<INPUT TYPE='text' NAME='sname' SIZE="
. mysql_field_len($columns, 1)
. "></TD></TR>");
} // END if
else
{
print("#D3DCE3' ALIGN='right' WIDTH='20%'>Category ID:&nbsp;"
. "</TH><TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>"
. "<INPUT TYPE='readonly' NAME='sname' VALUE='$sname'></TD>"
. "</TR>");
} // END else
print("<TR><TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>"
. "Category Description:&nbsp;</TH><TD ALIGN='left' WIDTH='"
. "80%' BGCOLOR='#FFFFCC'><INPUT TYPE='text' NAME='lname' ");
if($formType != "ADD")
{
# If we're not adding, then there must be a value to edit!
print("VALUE='" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["lname"]))
. "' ");
} // END if
print("SIZE=" . mysql_field_len($columns, 2)
. "></TD></TR></TABLE>");
# Now we can make another table containing the buttons (save,
# reset & cancel)
print("<TABLE ALIGN='center' CELLSPACING=2 CELLPADDING=2 "
. "BORDER=0><TR><TD ALIGN='right'><INPUT TYPE='button' "
. "VALUE='SAVE DETAILS' onClick=\"submit();\"></TD><TD "
. "ALIGN='center'><INPUT TYPE='button' VALUE='RESET' "
. "onClick=\"reset();\"></TD></FORM><FORM ACTION='"
. "doctypeCategoriesEDS.php' METHOD='post'><INPUT TYPE='"
. "hidden' NAME='doctype' VALUE='$doctype'><TD ALIGN='center"
. "'><INPUT TYPE='button' VALUE='CANCEL' onClick=\"submit();"
. "\"></TD></FORM></TR></TABLE>");
} // END if (!$editQError)
} // END function addEditCatForm()
function displayCategoriesList($doctype,$delCat,$addCatForm,$editCatForm,$editCatCommit,$addCatCommit)
{
global $sname,$lname;
if(isset($delCat))
{
# This is a call to delete a given category from the current doctype
unset($delCat);
$delStr = "DELETE FROM sbmCATEGORIES WHERE doctype = '$doctype' AND"
. " sname = '$sname'";
$delRes = mysql_query($delStr);
if($delRes && mysql_affected_rows() > 0)
{
# Print a message letting the user know of the delete
print("<P STYLE=\"color: red; text-align: center; font-size: "
. "small; font-weight: bold\">Category Deleted</P>");
# Get the date, so that it can be committed for the
# modification date field (md) for the current doctype in
# sbmDOCTYPE
$modifiedDate = makeEDSmdDate();
$mdRes = mysql_query("UPDATE sbmDOCTYPE SET md = '$modifiedDate'"
. " WHERE sdocname = '$doctype'");
if($mdRes)
{
mysql_free_result($mdRes);
} // END if
else
{
print("<SCRIPT TYPE='text/javascript'>alert('Unable To "
. "Update Modification Date For $doctype Doctype.');"
. "</SCRIPT>");
} // END else
$msgTxt ="The $sname category has been deleted from the "
. "$doctype"
. " document type in the " . DOCS_DATABASE . " database."
. "WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "${doctype}.$sname Category Deleted",
$msgTxt, "From: WebSubmit_Administrator");
# redisplay the table containing the categories
showCatsEDS($doctype);
} // END if
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable To Delete Category. Retry or Inform"
. " System Administrator.</P>");
} // END else
} // END if
elseif(isset($addCatForm))
{
unset($addCatForm);
addEditCatForm($doctype, "ADD");
} // END elseif
elseif(isset($addCatCommit))
{
# commit new categ to the database
unset($addCatCommit);
if($sname != "" && test_key_legal($sname))
{
$testRes = mysql_query("SELECT * FROM sbmCATEGORIES WHERE "
. "doctype = '$doctype' AND sname = '$sname'");
if($testRes)
{
if(mysql_num_rows($testRes) > 0)
{
# Category does not have unique name. warn user.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: "
. "red\">Warning.</SPAN> The Category Was Not Given A"
. " Unique Name.<BR>Could Not Commit.</P>");
showCatsEDS($doctype);
} // END if
else
{
$addStr = "INSERT INTO sbmCATEGORIES (doctype, sname, "
. "lname) VALUES('$doctype', '$sname', '$lname')";
$addRes = mysql_query($addStr);
if($addRes && mysql_affected_rows() == 1)
{
print("<P STYLE=\"color: red; font-size: medium; "
. "font-weight: bold; text-align: center\">Categ"
. "ory Added</P>");
# update modify date for doctype
$modifiedDate = makeEDSmdDate();
$mdRes = mysql_query("UPDATE sbmDOCTYPE SET md = '"
. "$modifiedDate' WHERE sdocname = '$doctype'");
if($mdRes)
{
mysql_free_result($mdRes);
} // END if
else
{
print("<SCRIPT TYPE='text/javascript'>alert('Un"
. "able To Update Modification Date For $doctype "
. "Doctype.');</SCRIPT>");
} // END else
$msgTxt = "The $sname Category has been added to the"
. " $doctype doctype in the " . DOCS_DATABASE
. " database.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$sname Category Added To "
. "$doctype",
$msgTxt, "From: WebSubmit_Administrator");
showCatsEDS($doctype);
} // END if
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: "
. "red\">ERROR:</SPAN> Unable to insert category "
. "correctly.</P>");
showCatsEDS($doctype);
} // END else
} // END else
} // END if
else
{
# Unable to retrieve results of test query. Therefore cant
# commit new cat.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to Verify Category Name. Cannot "
. "Insert.</P>");
showCatsEDS($doctype);
} // END else
} // END if
else
{
print("<P STYLE=\"color: red; text-align: center; font-weig"
. "ht: bold; font-size: medium\">Illegal Characters Used In"
. " Category Name. Please Retry.</P>");
showCatsEDS($doctype);
} // END else
} // END elseif
elseif(isset($editCatForm))
{
# In this case, we must display the details of the selected cat
# in a form for editing
unset($editCatForm);
addEditCatForm($doctype, "EDIT", $sname);
} // END elseif
elseif(isset($editCatCommit))
{
# In this case, the user has alterred the details of the selected
# cat, and we must commit the update to the DB.
unset($editCatCommit);
$updRes = mysql_query("UPDATE sbmCATEGORIES SET lname = '$lname' "
. "WHERE doctype = '$doctype' AND sname = '$sname'");
if($updRes)
{
if(mysql_affected_rows() > 0)
{
# Now update modify date for doctype
$modifiedDate = makeEDSmdDate();
$mdRes = mysql_query("UPDATE sbmDOCTYPE SET md = '"
. "$modifiedDate' WHERE sdocname = '$doctype'");
if($mdRes)
{
mysql_free_result($mdRes);
} // END if
else
{
print("<SCRIPT TYPE='text/javascript'>alert('Unabl"
. "e To Update Modification Date For $doctype "
. "Doctype.');</SCRIPT>");
} // END else
$msgTxt = "The description of the $sname Category of the"
. " $doctype doctype has been updated in the "
. DOCS_DATABASE . " database.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "${doctype}.$sname Category Updated",
$msgTxt, "From: WebSubmit_Administrator");
print("<P STYLE=\"color: red; font-weight: bold; font-size"
. ": medium; text-align: center\">Category Updated."
. "</P>");
showCatsEDS($doctype);
} // END if
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No Categories Were Updated.<BR>Please "
. "Retry.</P>");
showCatsEDS($doctype);
} // END else
} // END if
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable To Update Category.<BR>Please Retry"
. ".</P>");
showCatsEDS($doctype);
} // END else
} // END elseif
else
{
showCatsEDS($doctype);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayCategoriesList($doctype,$delCat,$addCatForm,$editCatForm,$editCatCommit,$addCatCommit);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/documentEDS.php.wml b/modules/websubmit/web/admin/documentEDS.php.wml
index ea6ccec20..7d05d58af 100644
--- a/modules/websubmit/web/admin/documentEDS.php.wml
+++ b/modules/websubmit/web/admin/documentEDS.php.wml
@@ -1,640 +1,640 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Details of the <i><protect><?print $doctype;?></protect></i> document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
/*********************Function Descriptions***************************/
function displayDocsAndSubs($doctype)
{
/******************************************************************
This function is used to pruduce the entire page. It effectively
performs the queries that retrieve data about the doctype & its
submissions, and then produces the tables that contain this
information.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Last Modified: 25/01/2001
******************************************************************/
global $URLPATH,$IMAGES;
$queryResult = mysql_query("SELECT * FROM sbmDOCTYPE WHERE sdocname ="
. " '$doctype'");
if($queryResult)
{
# test for multiple or no rows returned
if(mysql_num_rows($queryResult) > 1)
{
# If this clause is reached, too many rows have been returned
# by the query. There should only be 1 row returned. -> We
# must inform the user of this error, and email the
# administrator about it.
print('<H3>ERROR: Too many rows have been returned for the '
. $doctype . ' document type from the DOCTYPE table</H3>');
} // END if
elseif(mysql_num_rows($queryResult) < 1)
{
# In this case, no rows have been returned, which means we
# must have a data consistency error going on.
print('<H3>ERROR: No data has been returned from the DOCTYPE'
. ' table for the '.$doctype.' document type</H3>');
} // END elseif
else
{
# In this case, 1 row has been returned, which is perfect!
# Get a list of all fields in the DOCTYPE table...
$doctypeColumns = mysql_list_fields(DOCS_DATABASE, "sbmDOCTYPE");
# Open a table to hold the data...
print('<TABLE ALIGN=center BORDER=1 CELLSPACING=0 '
. 'CELLPADDING=0 WIDTH=85%>');
# Now make the table/form that will be used to contain all
# data about the document type...
$numTblFlds = mysql_num_fields($doctypeColumns);
$dataRow = mysql_fetch_array($queryResult);
for($indx = 0; $indx < $numTblFlds; $indx++)
{
# First, display the field name (but give each field a
# meaningful name)...
print('<TR><TH BGCOLOR=#CCDDFF ALIGN=right '
. 'WIDTH=30%>');
# Get the name of the current field...
$fName = mysql_field_name($doctypeColumns, $indx);
if($fName == "ldocname")
{
print("Document Type Description");
} // END if
elseif($fName == "sdocname")
{
print("Document Type ID");
} // END elseif
elseif($fName == "cd")
{
print("Creation Date");
} // END elseif
elseif($fName == "md")
{
print("Modification Date");
} // END elseif
else
{
print("$fName");
} // END else
print(":&nbsp;</TH>");
# Now display the data in a table field...
print('<TD BGCOLOR=#FFFFCC ALIGN=left>');
# If it is the description field, display it as html - otherwise just
# display the field normally..
if(mysql_field_name($doctypeColumns, $indx) == "description")
{
print("$dataRow[$indx]");
} // END if
else
{
print(ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx])));
} // END else
print("&nbsp;</TD></TR>");
} // END for
# Now close the doctype table...
print("</TABLE>");
# Now offer a button to edit the document types details..
print('<FORM ACTION="editDoctypeEDS.php" METHOD=post>'
. '<TABLE BORDER=0 ALIGN=center CELLSPACING=4 CELLPADDING=0 '
. '><TR>'
. '<INPUT TYPE=hidden NAME=doctype VALUE='.$doctype.'>'
. '<TD>'
. '<INPUT TYPE=button VALUE="EDIT DOCUMENT TYPE DETAILS"'
. ' onClick="submit();"></TD></FORM>');
# Now we can display a button on which the user can click
# in order to display the CATEGORIES relating to this
# doctype
print('<FORM ACTION="doctypeCategoriesEDS.php" METHOD="'
. 'post"'
. '><INPUT TYPE=hidden NAME=doctype VALUE='.$doctype
. '><TD ALIGN=center'
. '><INPUT TYPE=button VALUE="VIEW CATEGORIES" onClick'
. '="submit();"></TD></FORM>');
print('<FORM ACTION="referees.py" METHOD="'
. 'post"'
. '><INPUT TYPE=hidden NAME=doctype VALUE='.$doctype
. '><TD ALIGN=center'
. '><INPUT TYPE=button VALUE="SIMPLE APPROVAL REFEREES" onClick'
. '="submit();"></TD></TR></TABLE></FORM>');
# Make a horizontal rule to divide the page sections...
drawSeparator();
####################
# Now, we can display each of the actions (submissions) for
# the current doctype...
$actionsQuery = mysql_query("SELECT * FROM sbmIMPLEMENT WHERE "
. "docname = '$doctype' ORDER BY actname");
if($actionsQuery)
{
# In this case, the query executed without error.
# Display a title for this new page section...
print('<P STYLE="font-size: large; color: navy; '
. 'text-align: left">Implemented actions for the '
. '<EM>'.$doctype.'</EM> document type:</P>');
# Now that the section heading has been displayed, the
# table of actions can be displayed on-screen..
if(mysql_num_rows($actionsQuery) != 0)
{
# List columns in the IMPLEMENT TABLE
$implCols = mysql_list_fields(DOCS_DATABASE, "sbmIMPLEMENT");
# Get the number of fields in the IMPLEMENT table...
$imlNoFields = mysql_num_fields($implCols);
# Display the actions for the current doctype in a
# table..
print('<TABLE ALIGN=center WIDTH=90% BORDER=1 '
. 'CELLPADDING=0 CELLSPACING=0><TR '
. 'BGCOLOR=#CCDDFF>');
for($cnt = 1; $cnt < $imlNoFields; $cnt++)
{
# Don't display the subname column..
if(mysql_field_name($implCols, $cnt) != "subname")
{
# Get the current field name...
$curfName = mysql_field_name($implCols, $cnt);
print("<TH>");
# Rename the columns..
if($curfName == "displayed")
{
print("On Submission<BR>Page");
} // END if
elseif($curfName == "actname")
{
print("Action<BR>Name");
} // END elseif
elseif($curfName == "nbpg")
{
print("No.<BR>Pages");
} // END elseif
elseif($curfName == "cd")
{
print("Creation<BR>Date");
} // END elseif
elseif($curfName == "md")
{
print("Modification<BR>Date");
} // END elseif
elseif($curfName == "buttonorder")
{
print("Button<BR>Order");
} // END elseif
elseif($curfName == "statustext")
{
print("Status<BR>Text");
} // END elseif
else
{
print("$curfName");
} // END else
print("</TH>");
} // END if
} // END for
# Make 1 more column the subname column (it is 3rd in the
# IMPLEMENT table)
print("<TH>Edit<br>Submission<br>Pages</TH>");
# Make 1 more column for editing functions
print("<TH>Edit<br>Functions</TH>");
# Make 1 more column for editing the submission item
print("<TH>Edit<br>Submission</TH>");
# Now make 1 more column (in which the delete button
# will be placed)...
print("<TH>Delete<br>Submission</TH>");
# Now the header row can be closed..
print("</TR>");
# Display the table to hold the action data - links 'n'
# all
while($actDataRow = mysql_fetch_array($actionsQuery))
{
print('<TR BGCOLOR=#FFFFCC>');
for($count = 1; $count < $imlNoFields; $count++)
{
# Don't display the subname column..
if(mysql_field_name($implCols, $count) !=
"subname")
{
print('<TD ALIGN=center>');
if(mysql_field_name($implCols, $count) ==
"actname")
{
# Make a link to the page to view details of
# an action
print('<A HREF="viewActionEDS.php?actname='
. ereg_replace("'", "&#39;",
htmlspecialchars($actDataRow[$count]))
. '&caller=documentEDS.php&doctype='
. $doctype.'">'
. ereg_replace("'", "&#39;",
htmlspecialchars($actDataRow[$count]))
. '</A>');
} // END if
else
{
print(ereg_replace("'", "&#39;",
htmlspecialchars($actDataRow[$count])));
} // END else
print("&nbsp;</TD>");
} // END if
} // END for
# column to edit pages...
print('<TD ALIGN=center><A HREF=viewEditSub'
. 'missionEDS.php?subname='
. $actDataRow["subname"] . '&doctype='.$doctype.'>'
. '<IMG SRC="'.$IMAGES.'/edit1.gif" border=0>'
. '</A></TD>');
# column to edit functions...
print('<TD ALIGN=center><A HREF=action'
. 'Functions.php?action='
. $actDataRow["actname"] . '&doctype='.$doctype.'>'
. '<IMG SRC="'.$IMAGES.'/edit1.gif" border=0>'
. '</A></TD>');
# column to edit the submission...
print('<TD ALIGN=center><A HREF=edit'
. 'ActionDets.php?actname='
. $actDataRow["actname"] . '&doctype='.$doctype.'>'
. '<IMG SRC="'.$IMAGES.'/edit1.gif" border=0>'
. '</A></TD>');
# Now, insert the button for deleting a submission
print('<FORM ACTION=documentEDS.php METHOD=post '
. 'onSubmit="if(confirm(\'Really delete this '
. 'submission, its pages and all of their '
. 'elements?\')) { return true; } else { return '
. 'false; }"><INPUT TYPE=hidden NAME=subname'
. ' VALUE="' . $actDataRow["subname"]
. '"><INPUT TYPE=hidden NAME=doctype VALUE="'
. $doctype.'"><INPUT TYPE=hidden NAME=deleteSub'
. ' VALUE=true><TD ALIGN=center VALIGN="'
. 'middle"><INPUT TYPE=image SRC="'.$IMAGES.'/answer'
. '_bad.gif" WIDTH=14 HEIGHT=14 BORDER=0 ALT="Delet'
. 'e Submission" onClick="submit();"></TD>'
. '</FORM>');
print("</TR>");
} // END while
# Close up the table of submissions...
print("</TABLE>");
} // END if
else
{
# In this case, the current doctype has no actions..
print('<H3 STYLE="color: green">The <EM>$doctype</EM>'
. ' document type currently has no submissions.'
. '</H3>');
} // END else
# Now that the submissions for the current doctype have
# been displayed (or not), we can add a botton to allow the
# addition of new submissions to that doctype..
print('<FORM ACTION="newSubmissionEDS.php" METHOD=post>'
. '<INPUT TYPE=hidden NAME=doctype VALUE='.$doctype.'>'
. '<TABLE ALIGN=center WIDTH=100% CELLSPACING=0 '
. 'CELLPADDING=0 BORDER=0><TR><TD ALIGN=center>'
. '<INPUT TYPE=button VALUE="ADD A NEW ACTION" '
. 'onClick="submit();"></TD></TR></TABLE>'
. '</FORM>');
# Now, we can display a "FINISHED" button..
print('<FORM ACTION="index.php" METHOD=post><TABLE'
. ' BORDER=0 ALIGN=center WIDTH=100% CELLSPACING=0'
. ' CELLPADDING=0><TR><TD ALIGN=center><INPUT '
. 'TYPE=button VALUE=FINISHED onClick="submit();"'
. '></TD></TR></TABLE></FORM>');
} // END if
else
{
# In this case, there was an error while trying to get the
# actions for the given doctype from IMPLEMENT
print('<H2 STYLE="text-align: center; color: navy">'
. '<SPAN STYLE="color: red">ERROR:</SPAN> Unable to '
. 'retrieve data for the <EM>'.$doctype.'</EM> document type'
. ' from the <EM>IMPLEMENT</EM> table.<BR>Please inform '
. 'the system administrator.</H2>');
} // END else
} // END else
} // END if($queryResult)
else
{
# In this case, it was not possible to query the DOCTYPE table.
# This means that there is no point in continuing with the
# displaying of other data, so an error message can be output,
# and we can terminate processing
print('<H2 STYLE="text-align: center; color: navy"><SPAN '
. 'STYLE="color: red">ERROR:</SPAN> Unable to retrieve data '
. 'from the <EM>DOCTYPE</EM> table.<BR>Please inform the system'
. ' administrator.</H2>');
} // END else
} // END function displayDocsAndSubs($doctype)
//************
function killSub($subname)
{
/*******************************************************************
This function simply removes the row for the submission whose
name is passed to it from the actual IMPLEMENT table.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 25/01/2001
Last Modified: 25/01/2001
*******************************************************************/
# Delete the entry for the doctype from the IMPLEMENT table...
$subDelRes = mysql_query("DELETE FROM sbmIMPLEMENT WHERE subname = '"
. "$subname'");
if($subDelRes)
{
# Get the number of rows deleted..
$noRowsDel = mysql_affected_rows();
if($noRowsDel == 1)
{
mysql_free_result($subDelRes);
print('<SCRIPT TYPE="text/javascript">alert("'.$subname
. ' submission deleted.");</SCRIPT>');
$msgTxt = "The $subname submission has been deleted "
. "WebSubmit Administrator(" . makeDate()
. ")";
mail(ADMIN_EMAIL, "$subname Submission Deleted", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
elseif($noRowsDel < 1)
{
# Couldn't delete the submission.
mysql_free_result($subDelRes);
print('<SCRIPT TYPE="text/javascript">alert("Unable to '
. 'delete submission. Please retry.");</SCRIPT>');
} // END elseif
else
{
# Multiple rows deleted
mysql_free_result($subDelRes);
print('<SCRIPT TYPE="text/javascript">alert("'.$subname
. ' submission deleted.HOWEVER, '.$noRowsDel
. ' submission records were deleted from database. It is '
. 'possible that there were many records for the same '
. 'submission, which would break consistency rules.'
. 'They have now however, been removed.");</SCRIPT>');
$msgTxt = "The $subname submission has been deleted "
. ". However, $noRowsDel rows were "
. "deleted from IMPLEMENT for this submission. It is "
. "possible that for some reason, there were several "
. "rows for the same submission in this table."
. "WebSubmit Administrator(" . makeDate() . ")";
mail(ADMIN_EMAIL, "ERROR: Several Records Deleted "
. "For $subname Submission", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END if
else
{
print('<SCRIPT TYPE="text/javascript">alert("Unable to delete'
. ' $subname.Please Retry.");</SCRIPT>');
} // END else
} // END function killSub($subname)
//************
function deleteAsubmission($subname, $doctype)
{
/*******************************************************************
This function has the purpose of deleting a submission and any
elements that it may have, from an EDS document type. If the
deletion is successful, the user & administrator will be informed
of this fact. If there are any serious problems with the
deletion, the user & admin will also be informed.
It is worth noting that this deletion process will not remove the
"SUBMISSION_NAME.php" file from the access/protection directory
that is used for the various security by the Apache webserver.
This is because my supervisor informed me that doing this would
be unnecessessary.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 25/01/2001
Last Modified: 25/01/2001
*******************************************************************/
# retrieve action name
$res = mysql_query("SELECT actname from sbmIMPLEMENT where subname='$subname'");
$row = mysql_fetch_array($res);
$action = $row['actname'];
# delete functions
$res = mysql_query("DELETE FROM sbmFUNCTIONS where doctype='$doctype' and action='$action'");
# First, execute a query to see how many elements there are for the
# current submission
$noElesRes = mysql_query("SELECT * FROM sbmFIELD WHERE subname = '"
. "$subname'");
if($noElesRes)
{
# Good, query success
$noEles = mysql_num_rows($noElesRes);
# Free up the $noElesRes result set to quicken the pace
mysql_free_result($noElesRes);
# Delete all elements for the current doctype submission
$eleDelRes = mysql_query("DELETE FROM sbmFIELD WHERE subname = '"
. "$subname'");
if($eleDelRes)
{
# Get the date for the created date & modification date
$theDate = makeEDSmdDate();
if(mysql_affected_rows() == $noEles)
{
mysql_free_result($eleDelRes);
# Update the md field for our doctype
updateEDSDOCTYPEmd($doctype, $theDate);
# Now carry on with the deletion of the submission
killSub($subname);
} // END if
elseif(mysql_affected_rows() > $noEles)
{
# Too many rows deleted - error
print('<SCRIPT TYPE="text/javascript">alert("ERROR: '
. 'When the page elements of the '.$subname.' submission '
. 'were deleted,' . mysql_affected_rows()
. ' elements were deleted, when there were only '.$noEles
. ' elements to delete.The deletion of the '
. 'submission was however, continued.");</SCRIPT>');
$msgTxt = "An error ocurred when the page elements of the"
. "$subname submission were deleted. A total of "
. mysql_affected_rows() . " page elements were "
. "deleted when there were only $noEles page elements to "
. "delete. Despite this fact, the deletion process was "
. "continued, as there is no way to counteract this fact,"
. " or determine which extra elements were deleted."
. "WebSubmit Administrator(" . makeDate() . ")";
mail(ADMIN_EMAIL, "ERROR: Too Many Elements Deleted "
. "During $subname Submission Deletion", $msgTxt,
"From: WebSubmit_Administrator");
mysql_free_result($eleDelRes);
# Update the md field for our doctype
updateEDSDOCTYPEmd($doctype, $theDate);
# Now carry on with the deletion of the submission
killSub($subname);
} // END elseif
else
{
# Too few elements deleted - error
mysql_free_result($eleDelRes);
# Update the md field for our doctype
updateEDSDOCTYPEmd($doctype, $theDate);
print('<SCRIPT TYPE="text/javascript">alert("ERROR: '
. 'When deleting the elements for the '.$subname
. ' submission, not all elements were deleted. The '
. 'submission itself has therefore been left un-dele'
. 'ted, and should be deleted again.");</SCRIPT>');
} // END else
} // END if
else
{
# could not delete
print('<SCRIPT TYPE="text/javascript">alert("Unable To '
. 'Perform Delete. Please Retry.");</SCRIPT>');
} // END else
} // END if
else
{
print('<SCRIPT TYPE="text/javascript">alert("Unable To Perfor'
. 'm Deletion - Could Not Retrieve Details Of Submissions '
. 'Page Elements.Please Retry.");</SCRIPT>');
} // END else
} // END function deleteAsubmission($subname, $doctype)
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
{
if(isset($deleteSub))
{
unset($deleteSub);
# Delete submission
deleteAsubmission($subname, $doctype);
# Redisplay the page
displayDocsAndSubs($doctype);
} // END if
else
{
# display page
displayDocsAndSubs($doctype);
} // END else
}
/************************End of main script***************************/
?>
diff --git a/modules/websubmit/web/admin/editActionDets.php.wml b/modules/websubmit/web/admin/editActionDets.php.wml
index f6ec73f21..4c5ca74f9 100644
--- a/modules/websubmit/web/admin/editActionDets.php.wml
+++ b/modules/websubmit/web/admin/editActionDets.php.wml
@@ -1,539 +1,539 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Edit <i><protect><?print $actname;?></protect></i> action implementation details" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT TYPE='text/javascript'>
<!-- hide
function validateMandOpt(theParameter)
// This is a very simple function, to ensure that the user enters
// either M or O in the level field. (The level can be either Mandatory
// or Optional.
// The function caters for upper and lower case values.
{
if(theParameter == "M" || theParameter == "O" || theParameter == "m"
|| theParameter == "o")
{
return true; // ...return true, as everything is fine.
} // end if
else
{
alert("You Must Enter M or O For The level Parameter.");
return false;
} // end else
} // End function validateMandOpt(theParameter)
function checkScoreStpage(score, stpage)
// This function checks that the user has entered either a numeric
// value for level, or a
{
// create a variable, foundNonNumeric, which will be a boolean
// variable, to determine whether or not the user has input a
// non-numeric value for score or stpage.
var foundNonNumericScore = false;
var foundNonNumericStpage = false;
if(score != "" || stpage != "")
{
for(index = 0; index < score.length; index++)
{
if(!(score.charAt(index) >= 0 && score.charAt(index) <= 9))
{
foundNonNumericScore = true;
break;
} // End if
} // End for
if (!foundNonNumericScore)
{
for (index = 0; index < stpage.length; index++)
{
if (!(stpage.charAt(index) >= 0 && stpage.charAt(index) <= 9))
{
foundNonNumericStpage = true;
break;
} // End if
}
if (!foundNonNumericStpage)
{
return true;
}
else
{
alert('Only Numeric Values Are Legal For stpage');
return false;
} // End else
} // End if
else
{
alert('Only Numeric Values Are Legal For score');
return false;
} // End else
} // End if
else
return true;
} // End function checkScoreStpage(score, stpage)
// -->
</SCRIPT>
<?
/***********Function Declarations**********************************/
// This function simply displays an ok button, which when pressed,
// returns to the page that displays the doctype and its actions
// (document.php)...
function displayOKButton($doctype)
{
print("<BR><FORM ACTION=\"documentEDS.php\" METHOD=\"post\">");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLSPACING=0><TR><TD>"
. "<INPUT TYPE=\"hidden\" NAME=\"doctype\" value=\"$doctype\">"
. "<INPUT TYPE=\"button\" VALUE=\"OK\" onClick=\"submit()\">"
. "</TD></TR></TABLE></FORM>");
} // End function displayOKButton($doctype)
// This function produces an HTML form containing the values of the
// details of the relevant action on a given doctype. It is passed the
// values of $doctype, and $actname, and from these produces the table.
function allowEditOfActionDets($doctype, $actname)
{
global $URLPATH;
if($lockRes = mysql_query("LOCK TABLES sbmIMPLEMENT READ"))
{
// Execute a query on the sbmIMPLEMENT table in the WebSubmit2 DB to
// find the values of the given action ($actname) for the relevant
// doctype ($doctype)
$queryResult = mysql_query("SELECT * FROM sbmIMPLEMENT WHERE
docname = '$doctype' AND actname = '$actname'");
// Unlock the sbmIMPLEMENT table - we are finished with it for now
$unlockRes = mysql_query("UNLOCK TABLES");
if($queryResult)
{
if(mysql_num_rows($queryResult) < 1)
{
// If there were no rows returned by the query...
print("<BR><H3 STYLE=\"text-align: center; color: "
. "navy\">Error:"
. " No matching actions were found for this document "
. "type.</H3>\n<BR>\n");
} // End if
elseif(mysql_num_rows($queryResult) > 1)
{
// If too many rows ( > 1) were returned by the query, then
// there is obviously some DB consistency error...
print("<BR><H3 STYLE=\"color: red; text-align: center\">"
. "Error: Too many matching rows found.</H3><BR>");
} // End elseif
else
{
// If 1 row is found, then this is the expected and correct
// result
// Get information about the columns in sbmIMPLEMENT
$columns = mysql_list_fields(DOCS_DATABASE,
"sbmIMPLEMENT");
// Get the data from $queryResult and store it in an array
$dataRow = mysql_fetch_array($queryResult);
// Now, we can display the details of the action on the
// given
// doctype in a form for editing. This requires the fields
// to be put in a table
print("<FORM ACTION=\"editActionDets.php\" METHOD=\"post\">");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLSPACING=0>\n");
for($index = 1; $index < mysql_num_fields($columns);
$index++)
{
if(mysql_field_name($queryResult, $index) != "actname" &&
mysql_field_name($queryResult, $index) != "subname" &&
mysql_field_name($queryResult, $index) != "nbpg" &&
mysql_field_name($queryResult, $index) != "cd" &&
mysql_field_name($queryResult, $index) != "md")
{
// Print the field name in the first column...
print("<TR><TD ALIGN=\"right\"><STRONG STYLE=\"color: "
. "navy\">" . mysql_field_name($columns, $index)
. "</STRONG></TD>\n");
// Add a blank separator column between the 2 main
// columns...
print("<TD>&nbsp;</TD>\n");
// Print the field data in the second column...
print("<TD ALIGN=\"left\">");
}
if(mysql_field_name($queryResult, $index) == "actname" ||
mysql_field_name($queryResult, $index) == "subname" ||
mysql_field_name($queryResult, $index) == "nbpg" ||
mysql_field_name($queryResult, $index) == "cd" ||
mysql_field_name($queryResult, $index) == "md")
{
// If it is the actname field, we don't want the user
// to update it, so make it read only...
print("<INPUT TYPE=\"hidden\" NAME=\"");
print(mysql_field_name($queryResult, $index));
print("\" VALUE=\"");
print(ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$index])));
print("\">");
}
elseif(mysql_field_name($columns, $index) == "displayed")
{
// The level fiel can either be N or Y. This means
// that we can simply make it a SELECT list.
print("<SELECT NAME=\""
. mysql_field_name($columns, $index)
. "\"><OPTION VALUE=\"Y\"");
if($dataRow[$index] == "Y" ||
$dataRow[$index] == "y")
{
print(" SELECTED");
}
print(">YES</OPTION>\n<OPTION VALUE=\"N\"");
if($dataRow[$index] == "N" ||
$dataRow[$index] == "n")
{
print(" SELECTED");
}
print(">NO</OPTION>\n</SELECT>\n");
}
else
{
// If it is any other field, allow the user to update it
print("<INPUT TYPE=\"text\" NAME=\"");
print(mysql_field_name($columns, $index));
print("\" VALUE=\"");
print(ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$index])));
print("\" SIZE=");
if(mysql_field_name($columns, $index) != "txt")
{
print(mysql_field_len($columns, $index) + 3);
} // END if
else
{
print(mysql_field_len($columns, $index) - 15);
} // END else
print(">");
}
if(mysql_field_name($queryResult, $index) != "actname" &&
mysql_field_name($queryResult, $index) != "subname" &&
mysql_field_name($queryResult, $index) != "nbpg" &&
mysql_field_name($queryResult, $index) != "cd" &&
mysql_field_name($queryResult, $index) != "md")
print("</TD></TR>\n");
} // End for
print("</TR>\n");
/**********************************************************
Before we close up the table, and the form, it is
necessary to add more inputs to the form. One input will
be a hidden input, and will be called calledBefore. It will
be used after the form has been submitted, to determine
whether the call to the page is a recursive call or not
(i.e. the details of the action for the given doctype have
been ammended by the user).
It is also necessary to add a hidden input field to the
form for the doctype field. This will contain the value of
doctype and is necessary because if we didn't include it,
doctype would not be sent.
**********************************************************/
print("<TR><TD><INPUT TYPE=\"hidden\" NAME=\"calledBefore\" "
. "VALUE=\"true\"></TD>\n");
print("<TD><INPUT TYPE=\"hidden\" NAME=\"doctype\" ");
print("VALUE=\"$doctype\">");
print("</TD>\n</TR></TABLE>\n");
# Let's make a nice on-the-fly javascript function to
# handle our form checking.
print("<SCRIPT TYPE=\"text/javascript\">\n<!--\n"
. "function verifyChanges(curA, sugA");
for($theIndex = 4; mysql_field_name($columns, $theIndex) !=
""; $theIndex++)
{
print(", cur" . $theIndex . ", sug" . $theIndex);
} # END for
print(")\n{\n if((curA == sugA)");
for($theIndex = 4; mysql_field_name($columns, $theIndex) !=
""; $theIndex++)
{
print(" && (cur" . $theIndex . " == sug" . $theIndex
. ")");
}
print(")\n {\n return false;\n }\n else"
. "\n {\n return true;\n }\n}\n\n// -->\n"
. "</SCRIPT>\n");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLSPACING=0><TR>\n"
. "<TD><INPUT TYPE=\"button\" VALUE=\"SAVE\"");
print(" onClick=\"for(i=0; i < "
. "level.length; i++) { if(level[i].selected) { break; } }"
. " if((verifyChanges(escape('");
print(ereg_replace("'","\\'",
htmlspecialchars($dataRow[3])));
print("'), escape(score.value)");
for($theIndex = 4; mysql_field_name($columns, $theIndex) !=
""; $theIndex++)
{
print(", escape('");
print(ereg_replace("'", "\\'",
htmlspecialchars($dataRow[$theIndex])));
print("'), escape(");
print(mysql_field_name($columns, $theIndex));
print(".value)");
} // End for
print(")) || (level[i].value != '"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["level"]))
. "')) { ");
print("if(checkScoreStpage(score.value, stpage.value)) { ");
print("if(confirm('Really Alter These Details?')) { ");
print("submit() } } } else { alert('No Changes Made To "
. "Data! Cannot Submit.'); }\">");
print("</TD>\n<TD>&nbsp;</TD>\n");
print("<TD><INPUT TYPE=\"reset\" "
. "VALUE=\"RESET\"></TD>\n</FORM>");
print("<TD>&nbsp;</TD>\n");
print("<FORM ACTION=\"documentEDS.php\" METHOD=\"post\"><TD>"
. "<INPUT TYPE=\"hidden\" NAME=\"doctype\" VALUE=\"$doctype\">"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit()\"></TD></FORM>\n");
print("</TR></TABLE>\n");
} // End else
} // End if
else
{
// If the query caused an error to be returned...
print("<BR><H3 STYLE=\"color: red; text-align: center\">"
. "Database Query Error!</H3><BR>\n");
} // End else
}
else
{
// couldn't lock table. We should therefore not
// allow the query to be processed as it is unsafe.
print("<DIV STYLE=\"color: navy; font-weight: bold; font-size: "
. "large; text-align: center\"><SPAN STYLE=\"color: red\">Error:"
. "</SPAN> Unable to lock sbmIMPLEMENT table.<br>"
. mysql_error() . "</DIV>\n<BR>\n"
. "<A STYLE=\"font-size: medium; text-align: center\" HREF=\""
. "editActionDets.php?doctype=$doctype&actname=$actname\">Please"
. " retry.</A>\n<BR>\n");
}
}
function displayPage($doctype)
{
global $calledBefore,$x,$y,$actname,$level,$score,$stpage,$endtxt,$displayed,$buttonorder,$statustext;
if(!isset($calledBefore))
{
unset($x);
unset($y);
allowEditOfActionDets($doctype, $actname);
}
else
{
unset($calledBefore);
$doctype = strtoupper($doctype);
$actname = strtoupper($actname);
$level = strtoupper($level);
// Now, we can run an update query on the database, updating the
// relevant fields in the sbmIMPLEMENT table for the relevant
// action on the relevant doctype
/*
Before we run this update query however, we must test the
values of score and stpage. It has been noted that if these
fields are empty, the query will set their values in the DB to
0, not NULL as it should do. This can be corrected by testing
if score and stpage are empty, or have simply been filled with
a value of '0' (zero). If they have a zero value, this can
be inserted, but if they have a NULL value, the keyword 'NULL'
can be explicitly inserted into the query string.
*/
$theDate = makeEDSmdDate();
$queryString = "UPDATE sbmIMPLEMENT SET level = '$level', "
. "score = ";
// Test value of $score...
if(!$score)
{
if($score == '0')
$queryString = $queryString . " '$score', stpage = ";
else
$queryString = $queryString . " NULL, stpage = ";
} // END if
else
{
$queryString = $queryString . " '$score', stpage = ";
} // End testing value of $score
// Test value of $stpage...
if(!$stpage)
{
if($stpage == '0')
$queryString = $queryString . "'$stpage', ";
else
$queryString = $queryString . "NULL, ";
} // END if
else
{
$queryString = $queryString . "'$stpage', ";
} // End testing value of stpage
$queryString .= "endtxt = '$endtxt', displayed='$displayed',buttonorder='$buttonorder',statustext='$statustext',md='$theDate' "
. "WHERE ";
$queryString .= "docname = '$doctype' AND "
. "actname ";
$queryString .= "= '$actname'";
if($lockRes = mysql_query("LOCK TABLES sbmIMPLEMENT WRITE"))
{
$queryResult = mysql_query("$queryString");
if($queryResult)
{
if(mysql_affected_rows() == 1)
{
$unlockRes = mysql_query("UNLOCK TABLES");
# Call the allowEditOFActionDets function to give the
# user the option of further editing the details
allowEditOfActionDets($doctype, $actname);
} // End if
elseif(mysql_affected_rows() > 1)
{
$unlockRes = mysql_query("UNLOCK TABLES");
print("<H3 STYLE=\"text-align: center; color: "
. "red\">ERROR: Too Many Rows Updated. There Are "
. "Database Consistency Problems!</H3>\n");
displayOKButton($doctype);
} // End elseif
else
{
$unlockRes = mysql_query("UNLOCK TABLES");
print("<H3 STYLE=\"text-align: center; color: red\">ERROR"
. ": Unable To Update Action Details.</H3>\n");
displayOKButton($doctype);
} // End else
} // End if
else
{
// Else, if the query didn't execute properly...
$unlockRes = mysql_query("UNLOCK TABLES");
print("<H3 STYLE=\"text-align: center; color: red\">ERROR: "
. "Unable To Execute Database Update!</H3>");
displayOKButton($doctype);
} // End else
} # END if
else
{
// couldn't lock table. We should therefore not
// allow the query to be processed as it is unsafe.
print("<DIV STYLE=\"color: navy; font-weight: bold; font-size:"
. " large; text-align: center\"><SPAN STYLE='color: "
. "red'>Error:</SPAN> Unable to lock sbmIMPLEMENT table.</DIV>\n");
// Call the allowEditOFActionDets function to give the
// user the option of further editing the details
allowEditOfActionDets($doctype, $actname);
}
}
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1]. "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage($doctype);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/editCatalogues.php.wml b/modules/websubmit/web/admin/editCatalogues.php.wml
index c46f02e9a..1b3548f48 100644
--- a/modules/websubmit/web/admin/editCatalogues.php.wml
+++ b/modules/websubmit/web/admin/editCatalogues.php.wml
@@ -1,409 +1,409 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Organise webSubmit main page" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_organise"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function makeCataloguesTable()
{
global $catalogues;
$queryResult = mysql_query("SELECT id_son FROM sbmCOLLECTION_sbmCOLLECTION "
. "where id_father=0 ORDER BY catalogue_order");
if($queryResult)
{
# Query has executed successfully, so we can proceed to display all
# catalogues in the EDS system...
if (mysql_num_rows($queryResult) == 0)
print "<h3>No catalogues yet...</h3>\n";
else
print "<UL>\n";
while ($row = mysql_fetch_array($queryResult))
{
array_push($catalogues,$row[id_son]);
displayCatalogueBranch($row[id_son],1);
}
if (mysql_num_rows($queryResult) != 0)
print "</UL>\n";
} // END if
else
{
# In this case, the query failed, so we can terminate the scripts
# running, and terminate the WebSubmit Administrator session, as no
# further actions can be carried out...
print("<H3>Error: Unable to retrieve data from the catalogues table."
. "</H3>\n");
} // END else
}
function displayCatalogueBranch($id_father,$level)
{
global $catalogues,$IMAGES;
$res = mysql_query("SELECT name,id FROM sbmCOLLECTION WHERE id=$id_father");
$row = mysql_fetch_row($res);
if ($level == 1)
print "<LI><font size=\"+1\"><strong>"
. $row[0]."</strong></font>\n";
elseif ($level == 2)
print "<LI>". $row[0]."\n";
elseif ($level > 2)
print "<LI>". $row[0]."\n";
print "<A HREF=\"editCatalogues.php?upCatalogue=yes&id=" .$row[1]. "\">"
. "<IMG SRC=\"".$IMAGES."/up.gif\" width=14 height=14 border=0 HSPACE=0 VSPACE=0 alt=up></A>\n";
print "<A HREF=\"editCatalogues.php?downCatalogue=yes&id=" .$row[1]. "\">"
. "<IMG SRC=\"".$IMAGES."/down.gif\" width=14 height=14 border=0 HSPACE=0 VSPACE=0 alt=down></A>\n";
print "<A HREF=\"editCatalogues.php?deleteCatalogue=yes&id=" .$row[1]
. "\" onClick=\"if (!confirm('Are you sure you want to delete this catalogue? "
. "All sub-catalogues will be deleted as well!')) {return false} \">"
. "<IMG SRC=\"".$IMAGES."/iconcross.gif\" border=0 HSPACE=0 VSPACE=0></A>\n";
// display the son document types
$res1 = mysql_query("SELECT id_son from sbmCOLLECTION_sbmDOCTYPE WHERE id_father=$id_father ORDER BY catalogue_order");
$res2 = mysql_query("SELECT id_son FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father=$id_father ORDER BY catalogue_order");
if (mysql_num_rows($res1) != 0 || mysql_num_rows($res2) != 0)
print "<UL>\n";
if (mysql_num_rows($res1) != 0)
while ($row = mysql_fetch_array($res1))
displayDoctypeBranch($row[id_son],$id_father);
// display the son catalogues
while ($row = mysql_fetch_array($res2))
{
array_push($catalogues,$row[id_son]);
displayCatalogueBranch($row[id_son],$level+1);
}
if (mysql_num_rows($res1) != 0 || mysql_num_rows($res2) != 0)
print "</UL>\n";
}
function displayDoctypeBranch($doctype,$id_father)
{
global $catalogues,$IMAGES;
$res = mysql_query("SELECT ldocname,sdocname FROM sbmDOCTYPE WHERE sdocname='$doctype'");
$row = mysql_fetch_row($res);
print "<LI><small>"
. "<a href=\"documentEDS.php?doctype=$doctype\">"
. $row[0]."</a></small>\n";
print "<A HREF=\"editCatalogues.php?upDoctype=yes&id=".$row[1]."&id_father=$id_father\">"
. "<IMG SRC=\"".$IMAGES."/up.gif\" width=14 height=14 border=0 HSPACE=0 VSPACE=0 alt=up></A>\n";
print "<A HREF=\"editCatalogues.php?downDoctype=yes&id=" .$row[1]. "&id_father=$id_father\">"
. "<IMG SRC=\"".$IMAGES."/down.gif\" width=14 height=14 border=0 HSPACE=0 VSPACE=0 alt=down></A>\n";
print "<A HREF=\"editCatalogues.php?deleteDoctype=yes&id=" .$doctype. "&id_father=$id_father"
. "\" onClick=\"if (!confirm('Are you sure you want to delete this document type? "
. "')) {return false} \">"
. "<IMG SRC=\"".$IMAGES."/iconcross.gif\" border=0 HSPACE=0 VSPACE=0></A>\n";
}
function deleteBranch($id)
{
// First delete the attached doctypes
$res = mysql_query("DELETE FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_father=$id");
// Then the sub-catalogues
$res = mysql_query("SELECT id_son FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father=$id");
while ($row = mysql_fetch_row($res))
deleteBranch($row[0]);
// Then the catalogue itself
$res = mysql_query("DELETE FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_son=$id");
$res2 = mysql_query("DELETE FROM sbmCOLLECTION WHERE id=$id");
if (!res || !$res2)
print "<h3><font color=red>WARNING:</font> Could not delete catalogue(<EM>".mysql_error()."</EM>)</h3>";
}
function deleteDoctype($id,$id_father)
{
$res = mysql_query("DELETE FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_son='$id' and id_father='$id_father'");
if (!$res)
print "<h3><font color=red>WARNING:</font> Could not delete doctype(<EM>".mysql_error()."</EM>)</h3>";
}
function makeAddCatalogueInterface()
{
global $catalogues;
print "<SMALL>\n";
print("<H2>Add a Catalogue</H2>\n");
print("<br>");
print "<FORM>";
print "<INPUT type=hidden name=addCatalogue value=yes>\n";
print "Catalogue name:<br><INPUT size=50 name=catalogue_name>\n<br>";
print "Attached to: <SELECT name=attached>\n";
print "<OPTION value=\"0\"> top level\n";
reset($catalogues);
while (list($number,$value) = each($catalogues))
{
$res = mysql_query("SELECT name FROM sbmCOLLECTION WHERE id=$value");
$row = mysql_fetch_row($res);
print "<OPTION value=\"$value\">".$row[0]."\n";
}
print "</SELECT><br><br>\n";
print "<CENTER><INPUT type=button value=\"ADD\" onclick=\"submit();\">\n";
print "&nbsp;\n";
print "</CENTER></FORM>\n";
print "</SMALL>\n";
}
function makeAddDoctypeInterface()
{
global $catalogues;
print "<SMALL>\n";
print("<H2>Add a Document Type</H2>\n");
print("<br>");
print "<FORM>";
print "<INPUT type=hidden name=addDoctype value=yes>\n";
print "Document type name: <SELECT multiple name=doctype[] size=5>\n";
$res = mysql_query("SELECT sdocname,ldocname from sbmDOCTYPE order by ldocname");
while ($row = mysql_fetch_array($res))
print "<OPTION value=\"".$row[sdocname]."\">".$row[ldocname];
print "</SELECT>\n<br>";
print "Attached to: <SELECT name=attached>\n";
reset($catalogues);
while (list($number,$value) = each($catalogues))
{
$res = mysql_query("SELECT name FROM sbmCOLLECTION WHERE id=$value");
$row = mysql_fetch_row($res);
print "<OPTION value=\"$value\">".$row[0]."\n";
}
print "</SELECT><br><br>\n";
print "<CENTER><INPUT type=button value=\"ADD\" onclick=\"submit();\">\n";
print "&nbsp;\n";
print "</CENTER></FORM>\n";
print "</SMALL>\n";
}
function upCatalogue($id)
{
// Get father id
$res = mysql_query("SELECT id_father,catalogue_order FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_son='$id'");
$row = mysql_fetch_row($res);
$id_father = $row[0];
$order = $row[1];
// Get smallest number before this one
$res = mysql_query("SELECT MAX(catalogue_order) FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father='$id_father' and catalogue_order < $order");
if (mysql_num_rows($res) != 0)
{
$row = mysql_fetch_row($res);
$neworder = $row[0];
mysql_query("UPDATE sbmCOLLECTION_sbmCOLLECTION SET catalogue_order='$order' WHERE id_father='$id_father' and catalogue_order='$neworder'");
mysql_query("UPDATE sbmCOLLECTION_sbmCOLLECTION SET catalogue_order='$neworder' where id_son='$id'");
}
}
function downCatalogue($id)
{
// Get father id
$res = mysql_query("SELECT id_father,catalogue_order FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_son='$id'");
$row = mysql_fetch_row($res);
$id_father = $row[0];
$order = $row[1];
// Get smallest number after this one
$res = mysql_query("SELECT MIN(catalogue_order) FROM sbmCOLLECTION_sbmCOLLECTION WHERE id_father='$id_father' and catalogue_order > $order");
if (mysql_num_rows($res) != 0)
{
$row = mysql_fetch_row($res);
$neworder = $row[0];
mysql_query("UPDATE sbmCOLLECTION_sbmCOLLECTION SET catalogue_order='$order' WHERE id_father='$id_father' and catalogue_order='$neworder'");
mysql_query("UPDATE sbmCOLLECTION_sbmCOLLECTION SET catalogue_order='$neworder' where id_son='$id'");
}
}
function upDoctype($id,$id_father)
{
// Get current order
$res = mysql_query("SELECT catalogue_order FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_son='$id' and id_father='$id_father'");
$row = mysql_fetch_row($res);
$order = $row[0];
// Get smallest number before this one
$res = mysql_query("SELECT MAX(catalogue_order) FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_father='$id_father' and catalogue_order < $order");
if (mysql_num_rows($res) != 0)
{
$row = mysql_fetch_row($res);
$neworder = $row[0];
mysql_query("UPDATE sbmCOLLECTION_sbmDOCTYPE SET catalogue_order='$order' WHERE id_father='$id_father' and catalogue_order='$neworder'");
mysql_query("UPDATE sbmCOLLECTION_sbmDOCTYPE SET catalogue_order='$neworder' where id_son='$id'");
}
}
function downDoctype($id,$id_father)
{
// Get current order
$res = mysql_query("SELECT catalogue_order FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_son='$id' and id_father='$id_father'");
$row = mysql_fetch_row($res);
$order = $row[0];
// Get smallest number after this one
$res = mysql_query("SELECT MIN(catalogue_order) FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_father='$id_father' and catalogue_order > $order");
if (mysql_num_rows($res) != 0)
{
$row = mysql_fetch_row($res);
$neworder = $row[0];
mysql_query("UPDATE sbmCOLLECTION_sbmDOCTYPE SET catalogue_order='$order' WHERE id_father='$id_father' and catalogue_order='$neworder'");
mysql_query("UPDATE sbmCOLLECTION_sbmDOCTYPE SET catalogue_order='$neworder' where id_son='$id'");
}
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
{
if ($addCatalogue == "yes")
{
$res = mysql_query("INSERT INTO sbmCOLLECTION (name) VALUES ('$catalogue_name')");
if ($res)
{
$newid = mysql_insert_id();
$res = mysql_query("SELECT MAX(catalogue_order) FROM sbmCOLLECTION_sbmCOLLECTION where id_father='$attached'");
if (mysql_num_rows($res) != 0)
{
$row = mysql_fetch_row($res);
$order = $row[0] + 1;
}
else
$order = 1;
$res = mysql_query("INSERT INTO sbmCOLLECTION_sbmCOLLECTION (id_father,id_son,catalogue_order) VALUES ($attached,$newid,$order)");
}
else
print "<h3><font color=red>WARNING:</font> Could not insert new catalogue(<EM>".mysql_error()."</EM>)</h3>";
}
if ($addDoctype == "yes")
{
while ($currentdoc = current($doctype))
{
$res = mysql_query("SELECT MAX(catalogue_order) FROM sbmCOLLECTION_sbmDOCTYPE where id_father='$attached'");
if (mysql_num_rows($res) != 0)
{
$row = mysql_fetch_row($res);
$order = $row[0] + 1;
}
else
$order = 1;
$res = mysql_query("INSERT INTO sbmCOLLECTION_sbmDOCTYPE (id_father,id_son,catalogue_order) VALUES ('$attached','$currentdoc','$order')");
if (!$res)
print "<h3><font color=red>WARNING:</font> Could not insert new doctype(<EM>".mysql_error()."</EM>)</h3>";
next($doctype);
}
}
if ($deleteCatalogue == "yes")
deleteBranch($id);
if ($deleteDoctype == "yes")
deleteDoctype($id,$id_father);
if ($upCatalogue == "yes")
upCatalogue($id);
if ($downCatalogue == "yes")
downCatalogue($id);
if ($upDoctype == "yes")
upDoctype($id,$id_father);
if ($downDoctype == "yes")
downDoctype($id,$id_father);
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">This page is "
. "used for defining the catalogues which will appear on"
. " the CDS Submit main page.<br>These catalogues are not necessarily "
. "the same as those defined in the search interface (CDS Search)."
. "</P>\n</TD>\n</TR>\n</TABLE>\n");
print("<br><br>");
# Initialise catalogues array
$catalogues = array();
print "<table width=\"100%\" border=0>\n";
print "<tr><td valign=top>\n";
makeCataloguesTable();
print "</td><td valign=top>\n";
print "<table width=\"100%\" border=0 bgcolor=lightblue cellspacing=20>\n";
print "<tr><td valign=top>\n";
makeAddCatalogueInterface();
print "</td></tr><tr><td valign=top>\n";
makeAddDoctypeInterface();
print "</td></tr></table>\n";
print "</td></tr></table>\n";
print "<hr>\n";
print "<FORM action=index.php>";
print "<CENTER><INPUT type=button value=\"FINISHED\" onClick=\"document.location='index.php';\">\n";
print "</CENTER></FORM>\n";
}
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/editDoctypeEDS.php.wml b/modules/websubmit/web/admin/editDoctypeEDS.php.wml
index 3fe7b29ee..f3bef227a 100644
--- a/modules/websubmit/web/admin/editDoctypeEDS.php.wml
+++ b/modules/websubmit/web/admin/editDoctypeEDS.php.wml
@@ -1,547 +1,547 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Edit details of the <i><protect><?print $doctype;?></protect></i> type of document" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
?>
<SCRIPT TYPE='text/javascript'>
<!-- hide
function checkRequired(param)
// This is a function to ensure that the user enters the required
// parameter for the action.
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// ca8nro@yahoo.co.uk
// Created: Long ago!
// Last Modified: 16/11/2000
{
// If the field is left blank by the user...
if(param == "")
{ // Alert them, and return false.
alert("You must enter a value in the Long Document Name field.");
return false;
} // End if
else // If level has been filled by the user...
{
return true;
} // End else
} // End function checkRequired(param)
function verifyChanges(curLdocname, sugLdocname, curDocfi1, sugDocfi1)
// Function to test whether the values for the parameters to be changed
// have actually been changed by the user when they submit them to the
// database for update. If not, the function returns false. If so, the
// function returns true.
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// Created: 27/07/2000
// Last Modified: 16/11/2000
{
if( (curLdocname == sugLdocname) &&
(curDocfi1 == sugDocfi1))
{
alert("No Change In The Data Has Been Made! Cannot Submit.");
return false;
} // End if
else
{
return true;
} // End else
} // End function verifyChanges()
// -->
</SCRIPT>
<?php
/*********************Function Descriptions***************************/
<protect>
function makeEDSdoctypeButtons($dataRow)
{
/**************************************************************
This function has the simple task of creating and displaying the
"SAVE CHANGES" button, the "RESET" button and the "FINISHED"
button for the edit doctype form. It is bundled into a function,
as it is quite a messy piece of code due to the large parameters
to the JavaScript function "verifyChanges".
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 16/11/2000
Last Modified: 10/01/2001
**************************************************************/
print("<P>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>"
. "\n<INPUT TYPE='button' VALUE='SAVE CHANGES' onClick=\""
. "if(verifyChanges(escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["ldocname"]))
. "'), escape(ldocname.value), escape('"
. ereg_replace("[\n\r]+","\\n",ereg_replace("'","\\'",
htmlspecialchars($dataRow["description"])))
. "'), escape(description.value))) { if(checkRequired("
. "ldocname.value)) { if(confirm('Are You Sure You Wish To Alter "
. "These Details?')) { submit(); } } }\">\n</TD>\n<TD ALIGN='"
. "center'><INPUT TYPE='button' VALUE='RESET' onClick=\"reset();"
. "\">\n</TD>\n</FORM>\n<FORM ACTION='documentEDS.php' METHOD='"
. "post'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE='"
. $dataRow["sdocname"] . "'>\n<TD ALIGN='left'>\n<INPUT TYPE='"
. "button' VALUE='FINISHED' onClick=\"submit();\">\n</TD>\n</FORM>"
. "\n</TR>\n</TABLE>\n</P>\n");
} // END function makeEDSdoctypeButtons($dataRow)
//*************
function displayEDSdoctypeForm($doctype)
{
/*******************************************************************
This function has the task of creating the main form in which the
details of the given document type are displayed. each data item
of the doctype appears in an input box, so that the user can
modify its value, and then save the changes that they have made.
The fields that should not ever be modified by the user (such as
the modification date, etc) are displayed in readonly text fields
so that the user can not tamper with them.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 16/11/2000
Last Modified: 10/01/2001
*******************************************************************/
# Execute a query on the sbmsbmDOCTYPE table for the given action...
$queryResult = mysql_query("SELECT * from sbmDOCTYPE WHERE sdocname = "
. "'$doctype'");
if($queryResult)
{
# The query has executed successfully, so we can continue with
# the production of the page...
# Produce the appropriate output, depending upon the number of
# rows returned by the query...
if(mysql_num_rows($queryResult) == 1)
{
# In this case, as expected, there is one entry for the given
# doctype in the sbmDOCTYPE table..
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1><TR><TD "
. "ALIGN='center'><P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below are "
. "the details of the <EM>$doctype</EM> document type.<BR>You"
. "can edit them by alterring values in boxes, and clicking "
. "on \"SAVE CHANGES\".</P></TD></TR></TABLE>");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now, we are ready to display the details of the given
# doctype in a table. Each data item will be contained within
# a form input box so that it can be edited if this is
# desirable.
print("<FORM ACTION='editDoctypeEDS.php' METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='update' VALUE='true'>"
. "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN='center"
. "' WIDTH='100%'>");
# Now make the table: names & fields...
# Get the columns list
$columns = mysql_list_fields(DOCS_DATABASE, "sbmDOCTYPE");
# Get the number of fields
$numTblFlds = mysql_num_fields($columns);
# Get the row of data
$dataRow = mysql_fetch_array($queryResult);
# Before we display most of the table, we can first display
# the upper part of the table, which will be the sactname, cd,
# and md fields, that can't be modified...
print("<TABLE WIDTH='100%' ALIGN='center' CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0><TR><TH BGCOLOR='#D3DCE3' ALIGN"
. "='right' WIDTH='20%'>Document Type ID:&nbsp;</TH><TD "
. "ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT "
. "TYPE='readonly' NAME='sdocname' VALUE='"
. $dataRow["sdocname"] . "'></TD></TR><TR><TH "
. "BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>Creation "
. "Date:&nbsp;</TH><TD WIDTH='80%' ALIGN='left' BGCOLOR="
. "'#FFFFCC'><INPUT TYPE='readonly' NAME='cd' VALUE='"
. $dataRow["cd"] . "'></TD></TR><TR><TH WIDTH='20%'"
. " BGCOLOR='#D3DCE3' ALIGN='right'>Modification "
. "Date:&nbsp;</TH><TD WIDTH='80%' ALIGN='left' "
. "BGCOLOR='#FFFFCC'><INPUT TYPE='readonly' NAME='md' "
. "VALUE='" . $dataRow["md"] . "'></TD></TR>");
# Now fill this new table with all of the details...
for($indx = 0; $indx < $numTblFlds; $indx++)
{
# Get the name of the current field...
$currentField = mysql_field_name($columns, $indx);
# Ensure that we don't once again print our non-editable
# fields out...
if(($currentField != "sdocname") && ($currentField != "cd")
&& ($currentField != "md"))
{
# First, display the field name...
print("<TR><TH BGCOLOR='#87CEFA' ALIGN='right' "
. "WIDTH='20%'>");
if($currentField == "ldocname")
{
print("Document Type Description:&nbsp;");
} // END if
else
{
print("$currentField" . ":&nbsp;");
} // END else
if ($currentField == "description")
{
print ("&nbsp;</TH><TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'><TEXTAREA COLS=60 ROWS=5 WRAP NAME='description'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "</TEXTAREA></TD></TR>");
} //END if
else
{
print("&nbsp;</TH><TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'><INPUT TYPE='text' NAME="
. "'$currentField' SIZE=");
if(mysql_field_type($columns, $indx) == "blob")
{
# This is a text field (lots of characters allowed -
# too many for HTML form in browser to display), so
# just give it a visible length of 60 characters.
print("60");
} // END if
else
{
print(mysql_field_len($columns, $indx));
} // END else
print(" VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "'></TD></TR>");
} // END else
} // END if
} // END for
# Now that the table has been filled with all of the actions
# details, it can be closed..
print("</TABLE>");
# Now that the form has been drawn, it is possible to produce
# a new table underneath, containing buttons. There will be a
# "SAVE" button, and a "FINISHED button.
makeEDSdoctypeButtons($dataRow);
} // END if
elseif(mysql_num_rows($queryResult) > 1)
{
# In this case, there are many rows for the given doctype in
# the sbmDOCTYPE table, which means that the sbmDOCTYPE table has
# primary key violations..
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> More "
. "than one row of data concerning the <EM>$doctype</EM> "
. "document type was returned from the <EM>sbmDOCTYPE</EM> table"
. "of the" . DOCS_DATABASE . " database.<BR>This indicates "
. "primary key duplication in this table.<BR>Please inform "
. "system administrator.</P>");
# Send a mail to the system admin people to warn them about
# this serious error..
# Get the current date and time...
$dateDets = getdate();
$msgTxt = "When the editDoctypeEDS.php attempted to retrieve"
. "the details of the $doctype document type, several "
. "rows were returned for this document type from the sbmDOCTYPE"
. " table. The query was made using the \"sdocname\" field "
. "as the search key. As the \"sdocname\" field is the "
. "primary key for the sbmDOCTYPE table, this means that there "
. "must be key violations in this table.This problem "
. "should be corrected immediately.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "sbmDOCTYPE Table Key Violation!", $msgTxt,
"From: WebSubmit_Administrator");
} // END elseif
elseif(mysql_num_rows($queryResult) == 0)
{
# This means that the given doctype has no row in the sbmDOCTYPE
# table..Signifies a database inconsistency error.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No data"
. " concerning the <EM>$doctype</EM> doctype was found in the"
. " <EM>sbmDOCTYPE</EM> table.<BR>This suggests a data "
. "consistency error in the " . DOCS_DATABASE . " database."
. "<BR>Please inform the system administrator.</P>");
# Now send an email to the administrator(s) to inform them of
# this serious error...
$msgTxt = "When the editDoctypeEDS.php script attempted to "
. "retrieve the details of the $doctype document type, no "
. "rows were returned from the sbmDOCTYPE table for this "
. "document type.Because the user had to click a link to"
. " get to this page fpr the given doctype, the details of "
. "this doctype, must be referred to in other tables of EDS."
. " This suggests that there are either data inconsistencies"
. " or concurrency problems within EDS.This should be "
. "investigated and corrected ASAP.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$doctype Possible Data Inconsistency "
. "Error!", $msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# Some other sort of error has ocurred, so present the error
# message on the screen.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable"
. " to correctly retrieve data from the <EM>sbmDOCTYPE</EM> "
. "table of " . DOCS_DATABASE . ".<BR>Please inform system "
. "administrator.</P>");
} // END else
} // END if
else
{
# Unfortunately, the query has failed, so we can display an error
# message.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to conduct a query on the "
. "<EM>sbmDOCTYPE</EM> table of " . DOCS_DATABASE . ".<BR>Please"
. " inform system administrator.</P>");
} // END else
} // END function displayEDSdoctypeForm($doctype)
function displayEditPage($update,$doctype)
{
global $ldocname,$description,$sdocname;
# Conduct a test to see if this is the first call to this script, or
# if it is a self-referential call, whereby the user has chosen to
# update values of the given action...
if($update)
{
# In this case, this is a call to update the doctypes details...
# Free memory space associated with $update...
unset($update);
# Get the date, so that it can be committed for the modification
# date field (md)...
$modifiedDate = makeEDSmdDate();
# Begin constructing the UPDATE query string...
$queryString = "UPDATE sbmDOCTYPE SET ldocname = '$ldocname', description = "
. "'$description', md = '$modifiedDate' WHERE "
. "sdocname = '$sdocname'";
# Now actually execute the update query
$updateResult = mysql_query($queryString);
if($updateResult)
{
# If the query could actually be executed without error
if(mysql_affected_rows() == 1)
{
# In this case, only 1 rows was updated, which is as
# expected
# Display a nice message informing the user that the update
# has been carried out...
print("<P STYLE=\"color: green; text-align: center; font-"
. "style: bold; font-size: large\">Document Type "
. "Modification Complete</P>");
# Send the administrator a message to inform them of the
# update that has taken place...
$msgTxt = "An update has been carried out on the $sdocname"
. " document type in the " . DOCS_DATABASE
. " database.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "EDS Doctype Updated", $msgTxt,
"From: WebSubmit_Administrator");
# We can now redirect the browser to the the page showing
# the details of this document type...
print("<FORM ACTION='documentEDS.php' METHOD='post' "
. "NAME='referForm'>"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$sdocname'"
. "></FORM>");
print("<SCRIPT LANGUAGE=\"JavaScript\">"
. "setTimeout(\"document.referForm.submit();\", 0);"
. "</SCRIPT>");
} // END if
elseif(mysql_affected_rows() > 1)
{
# More than 1 row was updated -> bad news: key duplication
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Multiple rows have been updated in the "
. "<EM>sbmDOCTYPE</EM> table.<BR>This has resulted from an "
. "attempt to update the <EM>$sdocname</EM> document type."
. "<BR>Please inform the system administrator.</P>");
# Now, email the administrator to let them know this, as it
# is a potentially dangerous error.
$msgTxt = "When a user updated the details of "
. "the $sdocname document type using the EDS Administrat"
. "or, several rows were affected in the sbmDOCTYPE table. "
. " The update was conducted using the \"sdocname\" field "
. "as the key. As the \"sdocname\" field is the primary "
. "key for the sbmDOCTYPE table, this means that there must "
. "be key violations in this table. There should only "
. "have been 1 row affected by this update.This "
. "problem should be investigated and corrected immediate"
. "ly.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: sbmDOCTYPE Table Multiple Row"
. " Update!", $msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# No rows were updated -> Something strange here!
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>"
. "sbmDOCTYPE</EM> table.<BR>This suggests that there could "
. "be data inconsistencies or concurrency problems.<BR>"
. "Please inform the system administrator.</P>");
# Better email the administrator & let them know...
$msgTxt = "When a user attempted to update the details of "
. "the $sdocname document type using the WebSubmit Administrator"
. ", no rows were affected in the sbmDOCTYPE table by this "
. "update.Because the user must have altered a documen"
. "t types details to submit an update on it, it must have"
. " been present at around the time that the user submitte"
. "d their update.This suggests the possibility of "
. "concurrency or data inconsistency problems in this "
. "table.This should be investigated and corrected "
. "ASAP.WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "Error: Possible Concurrency Problems",
$msgTxt, "From: WebSubmit_Administrator");
} // END else
} // END if
else
{
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>sbmDOCTYPE"
. "</EM> table.<BR>This suggests that there could be data "
. "inconsistencies or concurrency problems.<BR>Please inform"
. " the system administrator.</P>");
} // END else
} // END if
else
{
# In this case, this is the first call to the page, so we can
# basically just display the details of the given doctype in a
# form...
displayEDSdoctypeForm($doctype);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayEditPage($update,$doctype);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/editPageElementEDS.php.wml b/modules/websubmit/web/admin/editPageElementEDS.php.wml
index e8eb6e671..38d771542 100644
--- a/modules/websubmit/web/admin/editPageElementEDS.php.wml
+++ b/modules/websubmit/web/admin/editPageElementEDS.php.wml
@@ -1,702 +1,702 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Edit the <I><protect><?print $fidesc;?></protect></I> Element on page <protect><?print $pageNumber;?></protect> of <protect><?print $subname;?></protect>" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT LANGUAGE="JavaScript">
<!-- hide
function verifyChanges(curFitext, sugFitext, curLevel, sugLevel,
curSdesc, sugSdesc, curCheckn, sugCheckn)
// Function to test whether the values for the parameters to be changed
// have actually been changed by the user when they submit them to the
// database for update. If not, the function returns false. If so, the
// function returns true.
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// Created: 27/07/2000
// Last Modified: 31/01/2001
{
if((curFitext == sugFitext) &&
(curLevel == sugLevel) &&
(curSdesc == sugSdesc) &&
(curCheckn == sugCheckn))
{
alert("No Change In The Data Has Been Made! Cannot Submit.");
return false;
} // End if
else
{
return true;
} // End else
} // End function verifyChanges()
// -->
</SCRIPT>
<?
/*********************Function Descriptions***************************/
function makeElementEditInterface($subname, $pageNumber, $fidesc,
$fieldnb, $doctype, $nPgs)
{
/******************************************************************
The purpose of this function is to effectively create the page
that allows the user to edit the details of a given element as it
appears on a given page of a given submission. The function
creates a form that will hold the details of a given element as
it appears on a given page of a given submission in the EDS
system. By altering the details of the element using this form
and then submitting it, the user will be able to alter the
details storred for the element in the database.
The function also creates another form that consists of a
"FINISHED" button. When the user presses this button, the
administrator returns to the page that displays the details of a
submission page and all of its elements, without making any
changes.
The function is passed several parameters. These are the
$subname value, which is the id of the given submission in which
this instance of the element is being used; the $pageNumber
value, which is the page number of the submission on which this
instance of the element is located; the $fidesc value, which is
the description of the element that is being used; the $fieldnb
value, which is the position number of the instance of the
element on the given page of the given submission; the $link
value, which is actually a pointer to a connection to the
database server; the $doctype value, which holds the unique
identifier of the doctype to which the submission belongs. This
is actually passed to the function simply so that the value can
be passed with the form when it is submitted, as it is needed to
correctly display the details of a page when the user moves
backward through the administrator system to the page which
displays the details of a given doctype; the $nPgs value, which
holds a value for the number of pages that make up the given
submission.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 28/11/2000
Last Modified: 09/05/2001
******************************************************************/
# The first step is to execute a query, selecting the detials of the
# given element as it appears on the given page...
$res = mysql_query("SELECT * FROM sbmFIELD WHERE subname = '$subname'"
. " AND pagenb = '$pageNumber' AND fidesc = '$fidesc' AND fieldnb ="
. " '$fieldnb'");
if($res)
{
# The query to retrieve the information about an element of the
# page has worked.
# Produce the appropriate output, depending upon the number of
# rows returned by the query...
if(mysql_num_rows($res) == 1)
{
# In this case, as expected, there is one entry for the given
# doctype in the sbmDOCTYPE table..
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below are "
. "the details of the <EM>$fidesc</EM> element as it "
. "appears on page <EM>$pageNumber</EM> of the <EM>$subname"
. "</EM> submission.<BR>You can edit them by alterring values"
. " in boxes, and clicking on \"SAVE CHANGES\".</P>\n</TD>\n"
. "</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now make the table: names & fields...
# Get the columns list
$columns = mysql_list_fields(DOCS_DATABASE, "sbmFIELD");
# Get the number of fields
$numTblFlds = mysql_num_fields($columns);
# Get the row of data
$dataRow = mysql_fetch_array($res);
# Now, we are ready to display the details of the given
# element of the given page of the given submission in a
# table. Each data item will be contained within a form input
# box so that it can be edited if this is desirable.
print("<FORM ACTION='editPageElementEDS.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='update' VALUE='true'>\n");
# Before we display most of the table, we can first display
# the upper part of the table, which will be the subname,
# pagenb, fieldnb, fidesc, cd, md: fields, that can't be
# modified...
print("<INPUT TYPE='hidden' NAME='subname' VALUE='" . $dataRow["subname"] . "'><INPUT TYPE='hidden' NAME='pageNumber' VALUE='" . $dataRow["pagenb"] . "'><INPUT TYPE='hidden' NAME='fieldnb' VALUE='" . $dataRow["fieldnb"] . "'><INPUT TYPE='hidden' NAME='fidesc' VALUE='" . $dataRow["fidesc"] . "'><INPUT TYPE='hidden' NAME='cd' VALUE='" . $dataRow["cd"] . "'><INPUT TYPE='hidden' NAME='md' VALUE='" . $dataRow["md"] . "'>");
print ("<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN='center"
. "' WIDTH='100%'>\n");
# Now fill this new table with all of the details...
for($indx = 0; $indx < $numTblFlds; $indx++)
{
# Get the name of the current field...
$currentField = mysql_field_name($columns, $indx);
# Ensure that we don't once again print our non-editable
# fields out...
if(($currentField != "subname") && ($currentField !=
"pagenb") && ($currentField != "fieldnb") &&
($currentField != "fidesc") && ($currentField != "cd")
&& ($currentField != "md") && ($currentField !=
"fiefi1")
&& ($currentField != "fiefi2"))
{
# First, display the field name...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' "
. "WIDTH='20%'>\n");
if($currentField == "fitext")
{
print("Element Label:&nbsp;");
} // END if
elseif($currentField == "level")
{
print("Level:&nbsp;");
} // END elseif
elseif($currentField == "sdesc")
{
print("Short Desc:&nbsp;");
} // END elseif
elseif($currentField == "checkn")
{
print("Check:&nbsp;");
} // END elseif
else
{
print("$currentField" . ":&nbsp;");
} // END else
print("&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n");
if($currentField == "checkn")
{
# This is the check field, and we must simply present
# a drop-down list full of checks.
if($chksRes = mysql_query("SELECT chname FROM sbmCHECKS"
. " ORDER BY chname"))
{
# Query fine.
if(mysql_num_rows($chksRes) > 0)
{
# Checks to be put into a select box...good!
print("<SELECT NAME='checkn'>\n");
if($dataRow["checkn"] != "")
{
# It has a value, so we can show it.
print("<OPTION VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "'>" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "</OPTION>\n");
} // END if
# Add option for having no JavaScript Check for
# the element.
print("<OPTION VALUE=''>--NO JAVASCRIPT "
. "CHECK--</OPTION>\n");
while($stuff = mysql_fetch_row($chksRes))
{
if($stuff[0] != $dataRow["checkn"])
{
# Add the check to the list if it is not
# the currently added check
print("<OPTION VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($stuff[0]))
. "'>" . ereg_replace("'", "&#39;",
htmlspecialchars($stuff[0]))
. "</OPTION>\n");
} // END if
} // END while
# Close up the select list
print("</SELECT>\n");
} // END if
else
{
# No checks stored in DB! We therefore can't
# allow the user to alter the current check
# incase they start putting in weird illegal
# checknames that would break referential
# integrity rules.
print("<INPUT TYPE='readonly' NAME='checkn' "
. "VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "'>&nbsp;&nbsp;<SPAN STYLE=\"font-size: "
. "small; font-weight: bold; color: red; "
. "text-align: center\">No Checks Stored In "
. DOCS_DATABASE . ". Cannot Allow Ammending. "
. "<A HREF='addCheckEDS.php'>Add Check</A>"
. ".</SPAN>\n");
} // END else
# Free the memory wasting $chksRes result pointer
mysql_free_result($chksRes);
} // END if
else
{
# Can't query for checks, therefore can't edit it!
print("<INPUT TYPE='readonly' NAME='checkn' "
. "VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "'>&nbsp;&nbsp;<SPAN STYLE=\"font-size: "
. "small; font-weight: bold; color: red; "
. "text-align: center\">Cannot Retrieve Check"
. " Details from " . DOCS_DATABASE . ". Cannot"
. " Allow Ammending of Current Value."
. "</SPAN>\n");
} // END else
} // END if
elseif($currentField == "level")
{
# 'Tis a select list with M or O values that we want
print("<SELECT NAME='$currentField'>\n<OPTION VALUE="
. "'M'>Mandatory</OPTION>\n<OPTION ");
if($dataRow[$indx] == "O" || $dataRow[$indx] == "o")
{
# Make this one selected...
print("SELECTED ");
} // END if
print("VALUE='O'>Optional</OPTION>\n</SELECT>\n");
} // END elseif
else
{
# No need for a listbox...just make it a normal text
# input field...
print("<INPUT TYPE='text' NAME="
. "'$currentField' SIZE=");
if($currentField != "level" &&
mysql_field_type($columns, $indx) == "blob")
{
print("60");
} // END if
else
{
print(mysql_field_len($columns, $indx) + 1);
} // END else
### I'm going to replace all "\n" chars with nothing!
print(" VALUE='" . ereg_replace("\n", " ",
ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx])))
. "'>\n");
} // END else
print("</TD>\n</TR>\n");
} // END if
} // END for
# Now that the table has been filled with all of the actions
# details, it can be closed..
print("</TABLE>\n");
# Now that the form has been drawn, it is possible to produce
# a new table underneath, containing buttons. There will be a
# "SAVE" button, a "RESET" button and a "FINISHED button.
print("<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>"
. "\n<INPUT TYPE='hidden' NAME='nPgs' VALUE='$nPgs'>\n<P>\n"
. "<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "level.length; i++) { if(level[i].selected) { break; } } "
. "if(verifyChanges("
. "escape('" . ereg_replace("\n", " ",
ereg_replace("'","\\'",
htmlspecialchars($dataRow["fitext"])))
. "'), escape(fitext.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["level"]))
. "'), escape(level[i].value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["sdesc"]))
. "'), escape(sdesc.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["checkn"]))
. "'), escape(checkn.options[checkn.selectedIndex].value))) {"
. " if(confirm('Are You Sure You"
. " Want To "
. "Modify These Details?')) { submit(); } }\">\n</TD>\n"
. "<TD ALIGN='center'>\n<INPUT TYPE='button' VALUE='RESET "
. "CHANGES' onClick=\"reset();\">\n</TD>\n</FORM>\n<FORM "
. "ACTION='pageDetsEDS.php' METHOD='post'>\n<INPUT TYPE='"
. "hidden' NAME='subname' VALUE='" . $dataRow["subname"]
. "'>\n<INPUT TYPE='hidden' NAME='pageNumber' VALUE='"
. "$pageNumber'>\n<INPUT TYPE='hidden' NAME='nPgs' VALUE='"
. "$nPgs'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE='"
. "$doctype'>\n<TD ALIGN='center'>\n<INPUT TYPE='button' "
. "VALUE='FINISHED' onClick=\"submit();\">\n</TD>\n</FORM>\n"
. "</TR>\n</TABLE>\n</P>\n");
} // END if
elseif(mysql_num_rows($queryResult) > 1)
{
# In this case, there are more than 1 row for the given
# element instance on a page stored in the sbmFIELD table, which
# means that the sbmFIELD table must have some kind of primary
# key violations..
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> More than one row of data concerning element <EM>"
. "$fieldnb ($fidesc)</EM> on page <EM>$pageNumber</EM> of "
. "the <EM>$subname</EM> submission has been returned from "
. "the <EM>sbmFIELD</EM> table.<BR>This indicates primary key "
. "duplication in this table.<BR>Please inform system "
. "administrator.</P>\n");
# Send a mail to the system admin people to warn them about
# this serious error..
# Get the current date and time...
$dateDets = getdate();
$msgTxt = "When the editDoctypeEDS.php page attempted to "
. "retrieve the details of the <EM>$fieldnb ($fidesc)</EM> on"
. " page <EM>$pageNumber</EM> of the <EM>$subname</EM> "
. "submission, several rows were returned for this element "
. "instance from the sbmFIELD table. The query was made using "
. "the subname, pagenb, fidesc and fieldnb fields as the "
. "search key. As these fields together should uniquely "
. "identify an instance of an element on a page, there "
. "must be key violations in this table.\n\nThis problem "
. "should be corrected immediately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "sbmFIELD Table Possible Key Violation!",
$msgTxt, "From: WebSubmit_Administrator");
} // END elseif
elseif(mysql_num_rows($queryResult) == 0)
{
# This means that the given element instance has no entry in
# the sbmFIELD table...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No data concerning element <EM>$fieldnb "
. "($fidesc)</EM> on page <EM>$pageNumber</EM> of the "
. "<EM>$subname</EM> submission was found in the <EM>sbmFIELD"
. "</EM> table.<BR>This suggests a data consistency error in"
. " the " . DOCS_DATABASE . " database.<BR>Please inform the "
. "system administrator.</P>\n");
# Now send an email to the administrator(s) to inform them of
# this serious error...
$msgTxt = "When the editDoctypeEDS.php script attempted to "
. "retrieve the details of element $fieldnb ($fidesc) on page"
. " $pageNumber of the $subname submission, no rows were "
. "returned from the sbmFIELD table.\n\nBecause the user had to "
. "click a link to get to this page for the given element "
. "instance, its details must be referred to in other tables "
. " of EDS. This suggests that there are either data "
. "inconsistencies or concurrency problems within EDS.\n\n"
. "This should be investigated and corrected ASAP.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "Possible Data Inconsistency Error!",
$msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# Some other sort of error has ocurred, so present the error
# message on the screen.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to correctly retrieve data from the"
. " <EM>sbmFIELD</EM> table of " . DOCS_DATABASE . ".<BR>Please"
. " inform system administrator.</P>\n");
} // END else
# Now, free the query result...
mysql_free_result($res);
} // END if
else
{
# The query to retrieve the details of the element on the page
# has failed.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to conduct a query on the "
. "<EM>sbmFIELD</EM> table of " . DOCS_DATABASE . ".<BR>Please"
. " inform system administrator.</P>\n");
} // END else
} // END function makeElementEditInterface()
function displayPage()
{
global $doctype,$update,$fitext,$level,$sdesc,$checkn,$subname,$pageNumber,$fidesc,$fieldnb,$nPgs;
# Conduct a test to see if this call to the page is the first call
# to it, whereby it should simply display the information about the
# element in a form, or if it is a self-referential call to the
# page, whereby it should carry out some sort of updating of
# details, then redisplay the information
if($update)
{
# In this case, this is a call to update the elements details...
# Free memory space associated with $update...
unset($update);
# Get the data, so that it can be committed for the modification
# date field (md)...
$dateDets = getdate();
# Now put the date into a variable in a nice MySQL friendly
# format
$modifiedDate = $dateDets['year'] . "-" . $dateDets['mon'] . "-"
. $dateDets['mday'];
# Begin constructing the UPDATE query string...
$queryString = "UPDATE sbmFIELD SET fitext = '$fitext', level = '"
. "$level', sdesc = '$sdesc', checkn = '$checkn', md = '"
. "$modifiedDate' WHERE subname = '$subname' AND pagenb = "
. "'$pageNumber' AND fidesc = '$fidesc' AND fieldnb = "
. "'$fieldnb'";
# Now actually execute the update query
$updateResult = mysql_query($queryString);
if($updateResult)
{
# If the query could actually be executed without error
if(mysql_affected_rows() == 1)
{
# In this case, only 1 rows was updated, which is as
# expected
# Display a nice message informing the user that the update
# has been carried out...
print("<P STYLE=\"color: green; text-align: center; font-"
. "style: bold; font-size: large\">Modification of Element"
. " Complete</P>\n");
# Send the administrator a message to inform them of the
# update that has taken place...
$msgTxt = "An update has been carried out on an element of"
. " the $subname submission. The update was carried out "
. "on element $fieldnb ($fidesc), which appears on page "
. "$pageNumber of the $subname submission in the "
. DOCS_DATABASE . " database.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "${subname}.$fidesc Element Updated "
. " (Page $pageNumber)",
$msgTxt, "From: WebSubmit_Administrator");
# Now, we need to update the modified date field for this
# submission in the sbmIMPLEMENT table, so that the actual
# submission itself shows as having been modified.
$mdResult = mysql_query("UPDATE sbmIMPLEMENT SET md = "
. "'$modifiedDate' WHERE subname = '$subname'");
if($mdResult)
{
# The modification query worked, so free its result
mysql_free_result($mdResult);
} // END if
else
{
# The update query failed, so output a quick alert...
print("<SCRIPT TYPE='text/javascript'>alert('ERROR: "
. "Unable to update the md field for this submission"
. "<BR>in the sbmIMPLEMENT table.');</SCRIPT>\n");
} // END else
# We can now redirect the browser to the the page showing
# the details of this document type...
print("<FORM ACTION='pageDetsEDS.php' METHOD='post' "
. "NAME='referForm'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>\n"
. "<INPUT TYPE='hidden' NAME='pageNumber' VALUE='"
. "$pageNumber'>\n<INPUT TYPE='hidden' NAME='nPgs' VALUE='"
. "$nPgs'>\n</FORM>\n");
print("<SCRIPT LANGUAGE=\"JavaScript\">\n"
. "setTimeout(\"document.referForm.submit();\", 0);\n"
. "</SCRIPT>\n");
} // END if
elseif(mysql_affected_rows() > 1)
{
# More than 1 row was updated -> bad news: key duplication
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Multiple rows have been updated in the "
. "<EM>sbmFIELD</EM> table.<BR>This has resulted from an "
. "attempt to update element <EM>$fieldnb ($fidesc)</EM> "
. "on page <EM>$pageNumber</EM> of the <EM>$subname</EM> "
. "submission.<BR>Please inform the system administrator."
. "</P>\n");
# Now, email the administrator to let them know this, as it
# is a potentially dangerous error.
$msgTxt = "When a user updated the details of element "
. "$fieldnb ($fidesc) on page $pageNumber of the $subname "
. "submission, using the WebSubmit Administrator, several rows "
. "were affected in the sbmFIELD table. The update was "
. "conducted using the subname, pagenb, fidesc and fieldnb"
. " fields as keys. As an element should only appear once"
. " on a submission page in a certain position, this means"
. " that there must be key violations in the sbmFIELD table. "
. " There should only have been 1 row affected by this "
. " update.\n\nThis problem should be investigated and cor"
. "rected immediately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: sbmFIELD Table Multiple Row "
. "Update!", $msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# No rows were updated -> Something strange here!
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>"
. "sbmFIELD</EM> table.<BR>This suggests that there could be"
. " data inconsistencies or concurrency problems.<BR>Plea"
. "se inform the system administrator.</P>\n");
# Better email the administrator & let them know...
$msgTxt = "When a user updated the details of element "
. "$fieldnb ($fidesc) on page $pageNumber of the $subname "
. "submission, using the WebSubmit Administrator, no rows were "
. "affected in the sbmFIELD table by this update.\n\nBecause "
. "the user must have altered this elements details to "
. "submit an update on it, it must have been present at "
. "around the time that the user submitted their update.\n"
. "\nThis suggests the possibility of concurrency or data "
. "inconsistency problems in this table.\n\nThis should"
. " be investigated and corrected ASAP.\n\nEDS Administrat"
. "or (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "Error: Possible Concurrency Problems",
$msgTxt, "From: WebSubmit_Administrator");
} // END else
} // END if
else
{
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>sbmFIELD"
. "</EM> table.<BR>This suggests that there could be data "
. "inconsistencies or concurrency problems.<BR>Please inform"
. " the system administrator.</P>\n");
} // END else
} // END if
else
{
# In this case, this is the first call to the page, so we can
# simply display the details of the given element, as it appears
# on the given page of the given submission...
makeElementEditInterface($subname, $pageNumber, $fidesc,
$fieldnb, $doctype, $nPgs);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1]. "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/editRecordFile.php.wml b/modules/websubmit/web/admin/editRecordFile.php.wml
index 174145b5b..08bcde73d 100644
--- a/modules/websubmit/web/admin/editRecordFile.php.wml
+++ b/modules/websubmit/web/admin/editRecordFile.php.wml
@@ -1,250 +1,250 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Edit <i>bibconvert</i> configuration for the <I><protect><?print $doctype;?></protect></i> document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>$uploadTplPath = "</protect><ETCDIR><protect>/bibconvert/config";</protect>
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*********************Function Declarations***************************/
function criticalFileFailRedirect($functionName, $doctype, $action,
$returnTo)
{
/*******************************************************************
This function simply redirects
the browser to the func.php page. It is called when the file
cannot be opened for reading/writing.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 01/02/2001
Last Modified: 06/02/2001
*******************************************************************/
# Make the functionality to send the page back home...
print("<FORM ACTION='func.php' METHOD='post' NAME='referForm'"
. ">\n<INPUT TYPE='hidden' NAME='functionName' VALUE='"
. "$functionName'>\n<INPUT TYPE='hidden' NAME='doctype' VALU"
. "E='$doctype'>\n<INPUT TYPE='hidden' NAME='action' VALUE='"
. "$action'>\n<INPUT TYPE='hidden' NAME='returnTo' VALUE='"
. "$returnTo'>\n<TABLE BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0 ALIGN='center'>\n<TR>\n<TD ALIGN='center'>"
. "\n<INPUT TYPE='button' VALUE='OK' onClick=\"submit();\""
. ">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n<SCRIPT TYPE='text/"
. "javascript'>\nsetTimeout(\"document.referForm.submit();"
. "\", 1000);\n</SCRIPT>\n");
} // END function criticalFileFailRedirect()
//**************
function doBusiness($uploadTplPath, $file, $functionName, $doctype, $action, $returnTo)
{
/*******************************************************************
This function has the task of reading from the file, and with
this data, producing the page.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 01/02/2001
Last Modified: 01/02/2001
*******************************************************************/
# Test to see if the file already exists.
if(!is_file("$uploadTplPath/$file"))
{
# The file does not exist. Create it.
if(!$filePtr = fopen("$uploadTplPath/$file", "w"))
{
# Unable to make the file
# Set an error flag to indicate the failure of this file creation.
$file_there = false;
} // END if
else
{
fclose($filePtr);
$file_there = true;
} // END else
} // END if
else
{
# File already exists, so we can set the flag to say so...
$file_there = true;
} // END else
# Now we can see if the file exists or not. If so, we can output
# our form, with its details. If not, we can simply present the
# user with an error message, and redirect the page back to
# "func.php".
if($file_there)
{
# read file contents
if(!$fPtr = fopen("$uploadTplPath/$file", "r"))
{
print("<DIV STYLE=\"color: red; font-size: large; text-align:"
. " center; font-weight: bold\">Unable To Open File."
. "</DIV>\n");
criticalFileFailRedirect($functionName, $doctype, $action,
$returnTo);
} // END if
else
{
print("<SPAN STYLE=\"color: navy; font-size: medium; font-"
. "weight: bold; text-align: center\">Contents of <EM>"
. "$file</EM></SPAN>\n");
#Separate our page out....
drawSeparator();
# Make our text area with all of the files data in it...
print("<FORM ACTION='editRecordFile.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='saveDets' VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='file' VALUE='$file'>\n"
. "<INPUT TYPE='hidden' NAME='functionName' VALUE='"
. "$functionName'>\n<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n<INPUT TYPE='hidden' NAME='action'"
. " VALUE='$action'>\n<INPUT TYPE='hidden' NAME='returnTo"
. "' VALUE='$returnTo'>\n<TABLE ALIGN='center' BORDER=0 "
. "CELLSPACING=0 CELLPADDING=0>\n<TR>\n<TD ALIGN='center"
. "'>\n<TEXTAREA NAME='content' COLS=100 ROWS=25>");
fpassthru($fPtr);
# fpassthru() will have closed our file pointer for us.
print("</TEXTAREA>\n</TD>\n</TR>\n</TABLE><TABLE BORDER=0"
. " CELLSPACING=2 CELLPADDING=2 ALIGN='center'>\n<TR>\n"
. "<TD ALIGN='center'>\n<INPUT TYPE='button' VALUE='"
. "SAVE CHANGES' onClick=\"submit();\">\n</TD>\n<TD ALIGN"
. "='center'>\n<INPUT TYPE='reset' VALUE='RESET CHANGES'"
. ">\n</TD>\n</FORM>\n<FORM ACTION='func.php' METHOD='pos"
. "t'>\n<INPUT TYPE='hidden' NAME='functionName' VALUE='"
. "$functionName'>\n<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n<INPUT TYPE='hidden' NAME='action"
. "' VALUE='$action'>\n<INPUT TYPE='hidden' NAME='returnT"
. "o' VALUE='$returnTo'>\n<TD ALIGN='center'>\n<INPUT TYP"
. "E='button' VALUE='CANCEL' onClick=\"submit();\">\n<"
. "/TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // END else
} // END if
else
{
# File can't be raised. Better just output error messages,
# and redirect page to "func.php".
print("<DIV STYLE=\"color: red; font-size: large; text-align:"
. " center; font-weight: bold\">Unable To Open File."
. "</DIV>\n");
criticalFileFailRedirect($functionName, $doctype, $action,
$returnTo);
} // END else
} // END function doBusiness()
function displayPage($uploadTplPath)
{
global $doctype,$saveDets,$functionName,$action,$returnTo,$content,$file;
$file=basename($file);
# Now perform tests to determine what to do
if(isset($saveDets))
{
# In this case, this is a self referential call to the form in
# order to update the file.
# Free some wasted space...
unset($saveDets);
if(!$fh = fopen("$uploadTplPath/$file", "w"))
{
# Could not open this file for writing.
print("<DIV STYLE=\"color: red; font-size: large; text-align:"
. " center; font-weight: bold\">Unable To Open File."
. "</DIV>\n");
criticalFileFailRedirect($functionName, $doctype, $action, $returnTo);
} // END if
else
{
# ereg_replace to replace any \015 (CR)
# (\r) chars with nothing.
$content = stripslashes(ereg_replace("\015","",$content));
# Open file for writing
if(!fwrite($fh, $content, strlen($content)))
{
# Couldn't write to the file.
print("<DIV STYLE=\"color: red; font-size: large; text-"
. "align: center; font-weight: bold\">Unable To Open File."
. "</DIV>\n");
fclose($fh);
criticalFileFailRedirect($functionName, $doctype, $action,
$returnTo);
} // END if
else
{
fclose($fh);
print("<DIV STYLE=\"color: green; font-size:"
. " medium; text-align: center; font-weight: bold\">File "
. "Updated</DIV>\n");
# Now redisplay the main page.
doBusiness($uploadTplPath, $file, $functionName, $doctype, $action, $returnTo);
} // END else
} // END else
} // END if
else
{
# This is the first call to this script, and it is simply our
# task to display the files dets in a textarea box, offering
# links to update it, or simply leave this form.
doBusiness($uploadTplPath, $file, $functionName, $doctype, $action, $returnTo);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
$uploadTplPath = "</protect><ETCDIR><protect>/bibconvert/config";
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage($uploadTplPath);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/elementConfigDetsEDS.php.wml b/modules/websubmit/web/admin/elementConfigDetsEDS.php.wml
index a2a6543fd..99649aeb4 100644
--- a/modules/websubmit/web/admin/elementConfigDetsEDS.php.wml
+++ b/modules/websubmit/web/admin/elementConfigDetsEDS.php.wml
@@ -1,1507 +1,1507 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Details of the <I><protect><?print $name;?></protect></I> Form Element" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*********************Function Descriptions***************************/
function Jscript_submit($elementType, $dataRow)
{
/***************************************************************
When the page to display/edit the details of a given EDS element
description is loaded, the fields that are displayed depends upon
the type of element. This means that the JavaScript functions to
check these fields must be generated dynamically, as we dont know
which fields we will need to check until run-time.
Depending upon the type of element, this function makes the
function, passing the relevant params to it, and makes the submit
button to pass the relevant params to the function.
Created: 06/12/2000
Last Modified: 28/01/2001
***************************************************************/
# Test the element type, and make the relevant function & submit
# button.
if($elementType == "T")
{
# Output the Javascript functions...
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curRows, sugRows, curCols,"
. " sugCols, curCode, sugCode, curMarc, sugMarc, curCoo, sugCoo, curMod, sugMod)"
. "\n{\n if((curRows == sugRows) && (curCols == "
. "sugCols) && (curCoo == sugCoo) && (curCode == sugCode) && (curMarc == sugMarc) && (curMod == sugMod))\n "
. "{\n alert('No Change In The Data Has Been Made! Can"
. "not Submit.');\n return false;\n }\n else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "cookie.length; i++) { if(cookie[i].checked) { break; } } "
. "if(verifyChanges(escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["rows"]))
. "'), escape(rows.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["cols"]))
. "'), escape(cols.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value),escape('");
if($dataRow["cookie"])
{
print("1");
} // END else
else
{
print("0");
} // END else
print("'), escape(cookie[i].value), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END if
elseif($elementType == "I")
{
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curSize, sugSize, curMaxlength,"
. " sugMaxlength, curVal, sugVal, curCode, sugCode, curMarc, sugMarc, curCoo, sugCoo, curMod, sugMod)"
. "\n{\n if((curSize == sugSize) && (curMaxlength == "
. "sugMaxlength) && (curVal == sugVal) && (curCode == sugCode) && (curCoo == "
. "sugCoo) && (curMarc == sugMarc) && (curMod == sugMod))\n "
. "{\n alert('No Change In The Data Has Been Made! Can"
. "not Submit.');\n return false;\n }\n else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "cookie.length; i++) { if(cookie[i].checked) { break; } } "
. "if(verifyChanges(escape"
. "('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["size"]))
. "'), escape(size.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["maxlength"]))
. "'), escape(maxlength.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["val"]))
. "'), escape(val.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value), escape('");
if($dataRow["cookie"])
{
print("1");
} // END else
else
{
print("0");
} // END else
print("'), escape(cookie[i].value), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END elseif
elseif($elementType == "H")
{
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curVal, sugVal, curCode, sugCode, curMarc, sugMarc, curCoo, sugCoo, curMod, sugMod)"
. "\n{\n if((curVal == sugVal) && (curCoo == sugCoo) && (curCode == sugCode) && (curMarc == sugMarc) && (curMod == sugMod))\n "
. " {\n alert('No Change In The Data Has Been Made! "
. "Can not Submit.');\n return false;\n }\n "
. "else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "cookie.length; i++) { if(cookie[i].checked) { break; } } "
. "if(verifyChanges(escape"
. "('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["val"]))
. "'), escape(val.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value), escape('");
if($dataRow["cookie"])
{
print("1");
} // END else
else
{
print("0");
} // END else
print("'), escape(cookie[i].value), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END elseif
elseif($elementType == "F")
{
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curSize, sugSize, curMaxlength,"
. " sugMaxlength, curCode, sugCode, curMarc, sugMarc, curCoo, sugCoo, curMod, sugMod)"
. "\n{\n if((curSize == sugSize) && (curMaxlength == "
. "sugMaxlength) && (curCoo == sugCoo) && (curCode == sugCode) && (curMarc == sugMarc) && (curMod == sugMod))\n "
. "{\n alert('No Change In The Data Has Been Made! Can"
. "not Submit.');\n return false;\n }\n else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "cookie.length; i++) { if(cookie[i].checked) { break; } } "
. "if(verifyChanges(escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["size"]))
. "'), escape(size.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["maxlength"]))
. "'), escape(maxlength.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value), escape('");
if($dataRow["cookie"])
{
print("1");
} // END else
else
{
print("0");
} // END else
print("'), escape(cookie[i].value), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END elseif
elseif($elementType == "D")
{
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curFidesc, sugFidesc, curCode, sugCode, curMarc, sugMarc, curCoo, sugCoo, curMod, sugMod)"
. "\n{\n if(curFidesc == sugFidesc && curCoo == "
. "sugCoo && sugCode == curCode && sugMarc == curMarc && sugMod == curMod)\n "
. "{\n alert('No Change In The Data Has Been Made! Can"
. "not Submit.');\n return false;\n }\n else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "cookie.length; i++) { if(cookie[i].checked) { break; } } "
. "if(verifyChanges(escape('" . ereg_replace("\r", "",
ereg_replace("\n", "\\n",
ereg_replace("'","\\'",
htmlspecialchars($dataRow["fidesc"]))))
. "'), escape(fidesc.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value), escape('");
if($dataRow["cookie"])
{
print("1");
} // END else
else
{
print("0");
} // END else
print("'), escape(cookie[i].value), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END elseif
elseif($elementType == "R")
{
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curFidesc, sugFidesc, curCode, sugCode, curMarc, sugMarc, curMod, sugMod)"
. "\n{\n if(curFidesc == sugFidesc"
. " && sugCode == curCode && sugMarc == curMarc && sugMod == curMod)\n "
. "{\n alert('No Change In The Data Has Been Made! Can"
. "not Submit.');\n return false;\n }\n else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\" "
. "if(verifyChanges(escape('" . ereg_replace("\r", "",
ereg_replace("\n", "\\n",
ereg_replace("'","\\'",
htmlspecialchars($dataRow["fidesc"]))))
. "'), escape(fidesc.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value), escape('");
print("'), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END elseif
elseif($elementType == "S")
{
print("<SCRIPT TYPE='text/javascript'>\n\n<!-" . "- hide\n\n"
. "function verifyChanges(curFidesc, sugFidesc, curCode, sugCode, curMarc, sugMarc, curCoo, sugCoo, curMod, sugMod)"
. "\n{\n if(curFidesc == sugFidesc && curCoo == "
. "sugCoo && sugCode == curCode && sugMarc == curMarc && sugMod == curMod)\n "
. "{\n alert('No Change In The Data Has Been Made! Can"
. "not Submit.');\n return false;\n }\n else\n"
. " {\n return true;\n }\n}\n\n// -->"
. "</SCRIPT>\n");
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"for(i=0; i < "
. "cookie.length; i++) { if(cookie[i].checked) { break; } } "
. "if(verifyChanges(escape('" . ereg_replace("\r", "",
ereg_replace("\n", "\\n",
ereg_replace("'","\\'",
htmlspecialchars($dataRow["fidesc"]))))
. "'), escape(fidesc.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["alephcode"]))
. "'), escape(alephcode.value), escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["marccode"]))
. "'), escape(marccode.value), escape('");
if($dataRow["cookie"])
{
print("1");
} // END else
else
{
print("0");
} // END else
print("'), escape(cookie[i].value), escape('" . ereg_replace("'","\\'",htmlspecialchars($dataRow["modifytext"])) . "'), escape(modifytext.value))) { submit(); }\">\n</TD>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='RESET CHANGES'"
. " onClick=\"reset();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END elseif
else
{
# Unknown file type, so just output a button not allowing the
# form to be submitted.
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='"
. "button' VALUE='SAVE CHANGES' onClick=\"alert('Unknown "
. "Element Type! Cannot Submit');"
. "\">\n</TD>\n<TD ALIGN='left'>\n<INPUT TYPE='button'"
. "VALUE='RESET CHANGES' onClick=\"reset();\">\n</TD>\n"
. "</TR>\n</TABLE>\n</FORM>\n");
} // END else
} // END function Jscript_submit()
//***************
function fabricateElementDetsFormEDS($name, $caller,
$subname = "", $pageNumber = "", $nPgs = "", $doctype = "")
{
/*****************************************************************
This function has the task of creating the html form that
contains the data of the element description. This form varies
depending upon what kind of "input" the element whose details are
being displayed is. This is because for some inputs, certain
parameters (like size or maxlength) are important, but are not
used for others. This means that we do not need to display
certain fields of the sbmFIELDS table for certain elements, that we
need to dislay for others.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 04/12/2000
Last Modified: 30/01/2001
*****************************************************************/
# Conduct a select query to retrieve the description details of the
# given element from the sbmFIELDDESC table.
$queryResult = mysql_query("SELECT * FROM sbmFIELDDESC WHERE name = "
. "'$name'");
# Take the relevant action depending upon whether it was
# successfully executed or not...
if($queryResult)
{
# In this case, the query executed successfully...
# Produce the appropriate output, depending upon the number of
# rows returned by the query...
if(mysql_num_rows($queryResult) == 1)
{
# In this case, as expected, there is one entry for the given
# element DESCRIPTION in the sbmFIELDDESC table..
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below are "
. "the details of the <EM>$name</EM> element description.<BR>"
. "These details can be edited by alterring the values in the"
. " the various input boxes, and clicking on \"SAVE CHANGES\""
. ".<BR><BR>It is also possible to change the type of the "
. "element description, which will cause the page to<BR>"
. "refresh, displaying the fields relevant to the new element"
. " type.</P>\n</TD>\n</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
print("<DIV STYLE='text-align: center; color: navy; "
. "font-weight: bold; font-size: medium'>Element "
. "Preview</DIV>\n");
# Get the row of data
$dataRow = mysql_fetch_array($queryResult);
# Now, let us make a nice preview of the element...
print("<FORM>\n<TABLE ALIGN='center' BORDER=1 CELLSPACING=0 "
. "CELLPADDING=0 WIDTH='100%' BGCOLOR='#87CEFA'>\n<TR>\n<TD "
. "ALIGN='center' VALIGN='middle'>\n");
$leType = $dataRow["type"];
if($leType == "T")
{
# We can draw a textarea element
print("<TEXTAREA ROWS=" . $dataRow["rows"] . " COLS="
. $dataRow["cols"] . ">\n</TEXTAREA>\n");
} // END if
elseif($leType == "I")
{
# normal HTML input...
print("<INPUT TYPE='text' SIZE=" . $dataRow["size"]
. " VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["val"]))
. "'>\n");
} // END elseif
elseif($leType == "H")
{
# say that it is a hidden input field...
print("<DIV STYLE='color: green; text-align: center; "
. "font-weight: bold; font-size: medium'>Hidden Input."
. " Contains Following:<BR><BR><SPAN STYLE='color: red'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["val"]))
. "</SPAN></DIV>\n");
} // END elseif
elseif($leType == "F")
{
# display a File input...
print("<INPUT TYPE='file' SIZE=" . $dataRow["size"]
. ">\n");
} // END elseif
elseif($leType == "D")
{
# display the user defined item - whatever it is
if($dataRow["fidesc"] != "")
{
# If the element has some data definition.
print("&nbsp;" . $dataRow["fidesc"] . "&nbsp;");
} // END if
else
{
print("<SPAN STYLE=\"color: green; font-size: medium; "
. "text-align: center; font-weight: bold\">Item "
. "Definition Not Yet Provided</SPAN>\n");
} // END else
} // END elseif
elseif($leType == "S")
{
# display the select box
if($dataRow["fidesc"] != "")
{
# If the element has some data definition.
print("&nbsp;" . $dataRow["fidesc"] . "&nbsp;");
} // END if
else
{
print("<SPAN STYLE=\"color: green; font-size: medium; "
. "text-align: center; font-weight: bold\">Item "
. "Definition Not Yet Provided</SPAN>\n");
} // END else
} // END elseif
elseif($leType == "R")
{
# cannot display the response element
print("<SPAN STYLE=\"color: green; font-size: medium; "
. "text-align: center; font-weight: bold\">Response "
. "Item: see description field</SPAN>\n");
} // END elseif
else
{
# Unknown element type. Therefore we can't display it.
print("<DIV STYLE='color: red; text-align: center; "
. "font-weight: bold; font-size: medium'>Unknown "
. "Element Type. Cannot Display.</DIV>\n");
} // END else
# Close up form & table
print("</TD>\n</TR>\n</TABLE>\n</FORM>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# ready to display the details of the
# element description in a form within a table. Each field of
# the element description will be contained within a form
# input box so that it can be edited if this is desirable.
# begin allowing the user to edit certain fields
# Element type (Will be a combo box, that allows you to change
# the type of the element
print("<FORM ACTION='elementConfigDetsEDS.php' METHOD='post'>"
. "\n<INPUT TYPE='hidden' NAME='changeType' VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='caller' VALUE='$caller'>\n"
. "<INPUT TYPE='hidden' NAME='name' VALUE='"
. $dataRow["name"] . "'>\n");
# Add extra fields (if necessary)
if($caller == "pageDetsEDS.php")
{
print("<INPUT TYPE='hidden' NAME='subname' VALUE='"
. "$subname'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE="
. "'$doctype'>\n<INPUT TYPE='hidden' NAME='pageNumber' "
. "VALUE='$pageNumber'>\n\n<INPUT TYPE='hidden' NAME='"
. "nPgs' VALUE='$nPgs'>\n");
} // END if
print("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN='"
. "center' WIDTH='100%'>\n<TR>\n<TH WIDTH='20%' BGCOLOR='"
. "#87CEFA' ALIGN='right'>\nElement Type:&nbsp"
. ";</TH>\n<TD WIDTH='80%' ALIGN='left' BGCOLOR='#FFFFCC'>"
. "<SELECT NAME='type' onChange=\"submit();\">\n<OPTION VALUE"
. "='UNKNOWN_TYPE'>Unknown Element Type</OPTION>\n");
# Make User defined type option
print("<OPTION ");
if($dataRow["type"] == "D")
{
print("SELECTED ");
} // END if
print("VALUE='D'>User Defined Input</OPTION>\n");
# Make Select box type option
print("<OPTION ");
if($dataRow["type"] == "S")
{
print("SELECTED ");
} // END if
print("VALUE='S'>Select Box</OPTION>\n");
# Make File input type option
print("<OPTION ");
if($dataRow["type"] == "F")
{
print("SELECTED ");
} // END if
print("VALUE='F'>File Input</OPTION>\n");
# Make Hidden input type option...
print("<OPTION ");
if($dataRow["type"] == "H")
{
print("SELECTED ");
} // END if
print("VALUE='H'>Hidden Input</OPTION>\n");
# Make Text input type option...
print("<OPTION ");
if($dataRow["type"] == "I")
{
print("SELECTED ");
} // END if
print("VALUE='I'>Text Input</OPTION>\n");
# Make response type option...
print("<OPTION ");
if($dataRow["type"] == "R")
{
print("SELECTED ");
} // END if
print("VALUE='R'>Response</OPTION>\n");
# Make TextArea input type option...
print("<OPTION ");
if($dataRow["type"] == "T")
{
print("SELECTED ");
} // END if
print("VALUE='T'>Text Area Element</OPTION>\n</SELECT>\n</TD>"
. "\n</TR>\n</TABLE>\n</FORM>\n");
# Now make main form
print("<FORM ACTION='elementConfigDetsEDS.php' METHOD='post'>"
. "\n<INPUT TYPE='hidden' NAME='update' VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='caller' VALUE='$caller'>\n"
. "<INPUT TYPE='hidden' NAME='type' VALUE='"
. $dataRow["type"] . "'>\n"
. "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN='center"
. "' WIDTH='100%'>\n");
# Now make the table: names & fields
# Get the columns list
$columns = mysql_list_fields(DOCS_DATABASE, "sbmFIELDDESC");
# Get the number of fields
$numTblFlds = mysql_num_fields($columns);
# Before we display most of the table, we can first display
# the upper part of the table, which will be the fields, that
# shouldn't be modified by the user. These are the name, cd
# and md fields.
$tblHead = "<TABLE WIDTH='100%' ALIGN='center' CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0>\n<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN"
. "='right' WIDTH='20%'>\nElement:&nbsp;</TH>\n<TD "
. "ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT "
. "TYPE='readonly' NAME='name' VALUE='"
. $dataRow["name"] . "'>\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>\nCreation "
. "Date:&nbsp;</TH>\n<TD WIDTH='80%' ALIGN='left' BGCOLOR="
. "'#FFFFCC'><INPUT TYPE='readonly' NAME='cd' VALUE='"
. $dataRow["cd"] . "'>\n</TD>\n</TR>\n<TR>\n<TH WIDTH='20"
. "%' BGCOLOR='#D3DCE3' ALIGN='right'>\nModification Date:"
. "&nbsp;</TH>\n<TD WIDTH='80%' ALIGN='left' BGCOLOR='"
. "#FFFFCC'><INPUT TYPE='readonly' NAME='md' VALUE='"
. $dataRow["md"] . "'>\n</TD>\n</TR>\n";
# Now make the alephcode field
$tblHead .= "<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nAleph Code:"
. "&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%"
. "'><INPUT TYPE='text' NAME='alephcode' VALUE='"
. $dataRow["alephcode"] . "' SIZE="
. mysql_field_len($columns, 1) . ">\n</TD>\n</TR>\n";
# Now make the marccode field
$tblHead .= "<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nMarc Code:"
. "&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%"
. "'><INPUT TYPE='text' NAME='marccode' VALUE='"
. $dataRow["marccode"] . "' SIZE="
. mysql_field_len($columns, 2) . ">\n</TD>\n</TR>\n";
# Now make the modifytext field
$tblHead .= "<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nModification Text:"
. "&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%"
. "'><INPUT TYPE='text' NAME='modifytext' VALUE='"
. $dataRow["modifytext"] . "' SIZE="
. mysql_field_len($columns, 2) . ">\n</TD>\n</TR>\n";
# it is possible to show the rest of the data that will be
# editable.
# elements are a form of html forms input. This means that
# there can be several different types of input (text, file,
# etc). Different types of html input use different
# parameters, so depending upon what type of input the element
# whose details are being displayed is, only certain fields
# from the sbmFIELDDESC table will be displayed, and others will
# remain hidden, as they are not used by this element. This
# means that we must test to see what type of element it is,
# and then display the relevant fields based upon this
$elementType = $dataRow["type"];
if($elementType == "T")
{
# In this case, the element is a <TEXTAREA> element.
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nRows:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#F"
. "FFFCC' WIDTH='80%'><INPUT TYPE='text' name='rows' "
. "VALUE='" . $dataRow["rows"] . "' SIZE="
. mysql_field_len($columns, 5) . ">\n</TD>\n</TR>\n<TR>\n"
. "<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nColu"
. "mns:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' "
. "WIDTH='80%'><INPUT TYPE='text' name='cols' VALUE='"
. $dataRow["cols"] . "' SIZE="
. mysql_field_len($columns, 6) . ">\n</TD>\n"
. "</TR>\n<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' "
. "WIDTH='20%'>\nCookie:&nbsp;</TH>\n<TD ALIGN='left' "
. "BGCOLOR='#FFFFCC' WIDTH='80%'>");
printCookie($dataRow["cookie"]);
# close up the current row (it is actually the last row)
print("</TD>\n</TR>\n");
} // END if
elseif($elementType == "I")
{
# item is a normal html text input
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nSize:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#F"
. "FFFCC' WIDTH='80%'><INPUT TYPE='text' name='size' VAL"
. "UE='" . $dataRow["size"] . "' SIZE=4"
. " MAXLENGTH=4"
. ">\n</TD>\n</TR>\n<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='ri"
. "ght' WIDTH='20%'>\nMaxlength:&nbsp;</TH>\n<TD ALIGN='"
. "left' BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT TYPE='text'"
. " name='maxlength' VALUE='" . $dataRow["maxlength"]
. "' SIZE=" . mysql_field_len($columns, 7)
. ">\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nValue:"
. "&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='"
. "80%'><INPUT TYPE='text' name='val' VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["val"]))
. "' SIZE=60 >\n</TD>\n</TR>\n<TR>\n"
. "<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nCook"
. "ie:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WID"
. "TH='80%'>");
printCookie($dataRow["cookie"]);
# close up the current row (it is actually the last row)
print("</TD>\n</TR>\n");
} // END elseif
elseif($elementType == "H")
{
# item is a hidden input field.
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nValue:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FF"
. "FFCC' WIDTH='80%'><INPUT TYPE='text' name='val' VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["val"]))
. "' SIZE=60 >\n</TD>\n</TR>\n<TR>\n"
. "<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nCook"
. "ie:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WID"
. "TH='80%'>");
printCookie($dataRow["cookie"]);
# close up the current row (it is actually the last row)
print("</TD>\n</TR>\n");
} // END elseif
elseif($elementType == "F")
{
# item is a file input type.
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nSize:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFF"
. "FCC' WIDTH='80%'><INPUT TYPE='text' NAME='size' VALUE='"
. $dataRow["size"] . "' SIZE="
. mysql_field_len($columns, 4)
. ">\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nMaxlength"
. ":&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' "
. "WIDTH='80%'><INPUT TYPE='text' name='maxlength' VALUE='"
. $dataRow["maxlength"] . "' SIZE="
. mysql_field_len($columns, 7) . ">\n</TD>\n</TR>\n<TR>\n"
. "<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Cookie:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC'"
. " WIDTH='80%'>");
printCookie($dataRow["cookie"]);
# close up the current row (it is actually the last row)
print("</TD>\n</TR>\n");
} // END elseif
elseif($elementType == "D")
{
# item is a user defined input type.
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nItem Description:&nbsp;</TH>\n<TD ALIGN='left' "
. "BGCOLOR='#FFFFCC' WIDTH='80%'><TEXTAREA COLS=100 ROWS=50"
. " NAME='fidesc' wrap='nowrap'>" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["fidesc"]))
. "</TEXTAREA>\n</TD>\n</TR>\n<TH BGCOLOR='#87CEFA' "
. "ALIGN='right' WIDTH='20%'>\nCookie:&nbsp;</TH>\n<TD "
. "ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'>");
printCookie($dataRow["cookie"]);
# close up the current row (it is actually the last row)
print("</TD>\n</TR>\n");
} // END elseif
elseif($elementType == "R")
{
# item is a response input type.
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nItem Description:&nbsp;</TH>\n<TD ALIGN='left' "
. "BGCOLOR='#FFFFCC' WIDTH='80%'><TEXTAREA COLS=100 ROWS=50"
. " NAME='fidesc' wrap='nowrap'>" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["fidesc"]))
. "</TEXTAREA>\n</TD>\n</TR>\n");
} // END elseif
elseif($elementType == "S")
{
# item is a select box input type.
print("$tblHead");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nItem Description:&nbsp;</TH>\n<TD ALIGN='left' "
. "BGCOLOR='#FFFFCC' WIDTH='80%'><TEXTAREA COLS=100 ROWS=50"
. " NAME='fidesc' wrap='nowrap'>" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow["fidesc"]))
. "</TEXTAREA>\n</TD>\n</TR>\n<TH BGCOLOR='#87CEFA' "
. "ALIGN='right' WIDTH='20%'>\nCookie:&nbsp;</TH>\n<TD "
. "ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'>");
printCookie($dataRow["cookie"]);
# close up the current row (it is actually the last row)
print("</TD>\n</TR>\n");
} // END elseif
print("</TABLE>\n");
# Now that the form has been constructed, it is possible to
# produce the buttons that allow the form to either be
# submitted, reset or the user to exit this page without
# making any chages, and return to the page from which they
# came.
if($caller == "pageDetsEDS.php")
{
print("<INPUT TYPE='hidden' NAME='subname' VALUE='"
. "$subname'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE="
. "'$doctype'>\n<INPUT TYPE='hidden' NAME='pageNumber' "
. "VALUE='$pageNumber'>\n\n<INPUT TYPE='hidden' NAME='"
. "nPgs' VALUE='$nPgs'>\n<P>\n");
} // END if
Jscript_submit($elementType, $dataRow);
# Now that the details of this element description have been
# displayed, display links to all of the other submission
# pages that use an instance of this element.
# divide page sections
drawSeparator();
$othersRes = mysql_query("SELECT subname, pagenb FROM "
. "sbmFIELD WHERE fidesc='$name'");
if($othersRes)
{
# The query to discover all of the other submission pages
# that use this submission has been executed successfully.
print("<P STYLE=\"color: navy; font-weight: bold\">Element"
. " Used On The Following Submissions</P>");
print("<TABLE BORDER=0 ALIGN='center' CELLSPACING=0 "
. "CELLPADDING=0>\n");
if(mysql_num_rows($othersRes) > 0)
{
while($aRow = mysql_fetch_array($othersRes))
{
$str = "SELECT * FROM sbmIMPLEMENT WHERE subname = '"
. $aRow["subname"] . "' ORDER BY subname";
$sometmpRs = mysql_query("SELECT * FROM sbmIMPLEMENT "
. "WHERE subname = '" . $aRow["subname"]
. "' ORDER BY subname");
if($sometmpRs)
{
# Then the query to get the details of the
# location of each instance of the element has
# worked
if(mysql_num_rows($sometmpRs) == 1)
{
# If there is only one row for the given
# instance of the element as it appears in a
# submission
# Read the record into an array...
$line = mysql_fetch_array($sometmpRs);
# Display a link to a page that contains the
# details of the element instance...
print("<TR>\n");
print("<TD ALIGN='center'><A HREF='pageDets"
. "EDS.php?subname=" . $line["subname"]
. "&pageNumber=" . $aRow["pagenb"] . "&nPgs="
. $line["nbpg"] . "&doctype="
. $line["docname"] . "'>[" . $line["subname"]
. " Page " . $aRow["pagenb"]
. "]</A>\n</TD>\n</TR>\n");
} // END if
} // END if
} // END while
} // END if
else
{
# In this case, there are no submission pages that use
# this element description to make element instances
print("<TR>\n");
print("<TD ALIGN='center'>\n<SPAN STYLE=\"text-align: "
. "center; font-color: red; font-size: small\">Element"
. " Not Used In EDS Submissions</SPAN>\n</TD>\n</TR>");
} // END else
print("</TABLE>\n");
# divide page sections
drawSeparator();
# finished button:
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD ALIGN='center'>\n"
. "<FORM ACTION='");
# Send browser to correct page
if($caller == "pageDetsEDS.php")
{
# pass back all of the extra
# info that is needed for going back to a given page of
# a given submission
print("pageDetsEDS.php' METHOD='post'>\n<INPUT "
. "TYPE='hidden' NAME='subname' VALUE='$subname"
. "'>\n<INPUT TYPE='hidden' NAME='pageNumber' VALUE='"
. "$pageNumber'>\n<INPUT TYPE='hidden' NAME='nPgs' "
. "VALUE='$nPgs'>\n<INPUT TYPE='hidden' NAME='doctype'"
. " VALUE='$doctype'>\n");
} // END if
else
{
# Came from allElementsEDS.php area, so go back
print("allElementsEDS.php' METHOD='post'>\n");
} // END else
print("<TD ALIGN='center'>\n<INPUT TYPE='button' "
. "VALUE='FINISHED' onClick=\"submit();\">\n</TD>\n</FORM>"
. "\n</TR>\n</TABLE>\n</P>\n");
# Free query result
mysql_free_result($othersRes);
} // END if
} // END if
elseif(mysql_num_rows($queryResult) > 1)
{
# more than 1 row for the
# element DESCRIPTION stored in the sbmFIELDDESC table, which
# means that the sbmFIELDDESC table must have some kind of
# primary key violations
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> More than one row of data concerning the element "
. "description <EM>$name</EM> has been returned from "
. "the <EM>sbmFIELDDESC</EM> table.<BR>This indicates primary "
. "key duplication in this table.<BR>Please inform system "
. "administrator.</P>\n");
# Send a mail to the system admin people to warn them about
# this serious error..
$msgTxt = "When the elementConfigdetsEDS.php page attempted "
. "to retrieve the details of the <EM>$name</EM> element "
. "description, several rows were returned from the sbmFIELDDESC"
. " table. The query was made using the name field as the "
. "search key. As this field should uniquely "
. "identify an element description in EDS, there "
. "must be key violations in this table.\n\nThis problem "
. "should be corrected immediately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "sbmFIELDDESC Table Possible Key Violation!",
$msgTxt, "From: WebSubmit_Administrator");
} // END elseif
elseif(mysql_num_rows($queryResult) == 0)
{
# element DESCRIPTION has no entry
# in the sbmFIELDDESC table. This is a problem, as a link was
# clicked to get to this element, so there are references
# (probably element instances of it) somewhere in EDS, when
# the description of it doesn't exist. this is a
# data inconsistency problem.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No data concerning the <EM>$name</EM> "
. "element description was found in the <EM>sbmFIELDDESC</EM> "
. "table.<BR>This suggests a data consistency error in"
. " the " . DOCS_DATABASE . " database.<BR>Please inform the "
. "system administrator.</P>\n");
# Now send an email to the administrator(s) to inform them of
# this error
$msgTxt = "When the elementConfigDetsEDS.php script attempted"
. " to retrieve the details of the $name element description,"
. " no rows were returned from the sbmFIELDDESC table.\n\n"
. "Because the user had to click a link to get to this page "
. "for the given element description, its details must be "
. "referred to in other tables of EDS. This suggests that "
. "there are either data inconsistencies or concurrency "
. "problems within EDS.\n\nThis should be investigated and "
. "corrected ASAP.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Possible Data Inconsistency Error!",
$msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# Some other sort of error has ocurred, so present the error
# message on the screen.
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to correctly retrieve data from the"
. " <EM>sbmFIELDDESC</EM> table of " . DOCS_DATABASE
. ".<BR>Please inform system administrator.</P>\n");
} // END else
# free query result
mysql_free_result($queryResult);
} // END if
else
{
# In this case, the query failed, so we must display the relevant
# error message
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to conduct a query on the "
. "<EM>sbmFIELDDESC</EM> table of " . DOCS_DATABASE . ".<BR>Please"
. " inform system administrator.</P>\n");
} // END else
} // END function fabricateElementDetsFormEDS()
function displayPage()
{
global $doctype,$update,$changeType,$val,$rows,$cols,$cookie,$alephcode,$marccode,$type,$size,$maxlength,$fidesc,$name,$subname,$pageNumber,$nPgs,$caller,$modifytext;
# Conduct a test to see if this is the first call to this page, or a
# recursive call whereby the user is attempting to update the
# element descriptions details
if($update)
{
# In this case, this is a call to update the Element description.
# Therefore, update it, and redirect the "pageDetsEDS.php" page.
$updtStr = "UPDATE sbmFIELDDESC SET ";
# determine what kind of element we are
# actually updating here, as we only need to amend certain fields
# for certain elements
if($type == "T")
{
# <TEXTAREA> element.
$updtStr .="rows = '$rows', cols = '$cols', cookie = "
. "'$cookie', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END if
elseif($type == "I")
{
# normal html text input
$updtStr .= "size = '$size', maxlength = '$maxlength', val = "
. "'$val', cookie = '$cookie', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END elseif
elseif($type == "H")
{
# hidden input field.
$updtStr .= "val = '$val', cookie = '$cookie', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END elseif
elseif($type == "F")
{
# file input type.
$updtStr .= "size = '$size', maxlength = '$maxlength', cookie"
. " = '$cookie', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END elseif
elseif($type == "D")
{
# user defined input type.
$updtStr .= "fidesc = '$fidesc', cookie = '$cookie', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END elseif
elseif($type == "R")
{
# response input type.
$updtStr .= "fidesc = '$fidesc', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END elseif
elseif($type == "S")
{
# select box input type.
$updtStr .= "fidesc = '$fidesc', cookie = '$cookie', alephcode = '$alephcode', marccode = '$marccode', modifytext = '$modifytext'";
} // END elseif
else
{
# Element type is something unknown, so we will perform no
# updates upon it.
# Set an error flag...
$error = 1;
} // END else
if(isset($error))
{
# The error flag is set, so do no further processing. Simply
# display an error message, and redirect the page to
# pageDetsEDS.php.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Invalid Element Type. Cannot Update."
. "</P>\n");
print("<FORM ACTION='");
# Send the browser to the relevant page
if($caller == "pageDetsEDS.php")
{
print("pageDetsEDS.php' METHOD='post' "
. "NAME='referForm'>\n"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>\n"
. "<INPUT TYPE='hidden' NAME='pageNumber' "
. "VALUE='$pageNumber'>\n<INPUT TYPE='hidden' NAME='nPgs'"
. "VALUE='$nPgs'>\n<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n");
} // END if
else
{
print("allElementsEDS.php' METHOD='post' NAME='referForm'"
. ">\n");
} // END else
print("<TABLE ALIGN='center' BORDER=0>\n<TR>\n<TD ALIGN='"
. "center'>\n<INPUT TYPE='button' VALUE='OK' onClick=\""
. "submit();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n<SCRIPT "
. "LANGUAGE=\"JavaScript\">\nsetTimeout(\"document.referForm"
. ".submit();\", 0);\n</SCRIPT>\n");
} // END if
else
{
# Get the data, so that it can be committed for the
# modification date field (md)
$dateDets = getdate();
# Now put the date into a variable in a nice MySQL friendly
# format
$modifiedDate = $dateDets['year'] . "-" . $dateDets['mon']
. "-" . $dateDets['mday'];
$updtStr .= ", md = '$modifiedDate' WHERE name = '$name'";
# Now execute the query, and take the relevant action based
# upon its result
$updtRes = mysql_query($updtStr);
if($updtStr)
{
# update has been executed successfully
if(mysql_affected_rows() == 1)
{
# Display a nice message informing the user that the
# update has been carried out...
print("<P STYLE=\"color: green; text-align: center; "
. "font-style: bold; font-size: large\">Element "
. "Description Modification Complete</P>\n");
# Send the administrator a message to inform them of the
# update that has taken place
$msgTxt = "An update has been carried out on the $name"
. " element description in the " . DOCS_DATABASE
. " database.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$name Element Description Updated",
$msgTxt, "From: WebSubmit_Administrator");
# We can now redirect the browser back to the the page
# showing the details of the element as it appears
# on the given submission type, or simply redisplay the
# form with the elements details in it if this came from
# the allElementsEDS.php area
print("<FORM ACTION='");
if($caller == "pageDetsEDS.php")
{
print("pageDetsEDS.php' METHOD='post' NAME='referFor"
. "m'>\n<INPUT TYPE='hidden' NAME='subname' VALUE='"
. "$subname'>\n<INPUT TYPE='hidden' NAME='pageNumber"
. "' VALUE='$pageNumber'>\n<INPUT TYPE='hidden' "
. "NAME='nPgs' VALUE='$nPgs'>\n<INPUT TYPE='hidden' "
. "NAME='doctype' VALUE='$doctype'>\n");
} // End if
else
{
print("elementConfigDetsEDS.php' METHOD='post' "
. "NAME='referForm'>\n<INPUT TYPE='hidden' "
. "NAME='caller' VALUE='$caller'>\n<INPUT TYPE='"
. "hidden' NAME='name' VALUE='$name'>\n");
} // END else
print("<TABLE ALIGN='center' BORDER=0>\n<TR>\n<TD "
. "ALIGN='center'>\n<INPUT TYPE='button' VALUE='OK' "
. "onClick=\"submit();\">\n</TD>\n</TR>\n</TABLE>\n"
. "</FORM>\n");
print("<SCRIPT TYPE='text/javascript'>\n"
. "setTimeout(\"document.referForm.submit();\", "
. "1000);\n</SCRIPT>\n");
} // END if
elseif(mysql_affected_rows() > 1)
{
# More than 1 row was updated -> bad news: key
# duplication
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Multiple rows have been updated in the"
. " <EM>sbmFIELDDESC</EM> table.<BR>This has resulted from"
. " an attempt to update the <EM>$name</EM> element "
. "description."
. "<BR>Please inform the system administrator.</P>\n");
# Now, email the administrator to let them know this, as
# it is a potentially dangerous error.
$msgTxt = "When a user updated the details of "
. "the $name element description using the EDS "
. "Administrator, several rows were affected in the "
. "sbmFIELDDESC table. The update was conducted using the"
. " \"name\" field as the key. As the \"name\" field "
. "is the primary key for the sbmFIELDDESC table, this "
. "means that there must be key violations in this "
. "table. There should only have been 1 row affected "
. "by this update.\n\nThis problem should be investiga"
. "ted and corrected immediately.\n\nWebSubmit Administrator"
. " (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "ERROR: sbmFIELDDESC Table Multiple Row"
. " Update!", $msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# No rows were updated
# Display an error message about this...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the "
. "<EM>sbmFIELDDESC</EM> table.<BR>This suggests that "
. "there could be data inconsistencies or concurrency "
. "problems.<BR>Please inform the system administrator"
. ".</P>\n");
# email the administrator & let them know...
$msgTxt = "When a user attempted to update the details"
. " of the $name element description using the EDS "
. "Administrator, no rows were affected in the sbmFIELDDE"
. "SC table by this update.\n\nBecause the user must "
. "have altered an element descriptions details to "
. "submit an update on it, it must have been present at"
. " around the time that the user submitted their "
. "update.\n\nThis suggests the possibility of "
. "concurrency or data inconsistency problems in this "
. "table.\n\nThis should be investigated and corrected "
. "ASAP.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Error: Possible Concurrency "
. "Problems", $msgTxt, "From: WebSubmit_Administrator");
} // END else
} // END if
else
{
# In this case, the execution of the query has not been
# successful, so we can display an error message, and
# redirect the page focus to "pageDetsEDS.php".
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>"
. "sbmFIELDDESC</EM> table.<BR>This was because it was not "
. "possible to conduct an UPDATE query.<BR>Please inform"
. " the system administrator.</P>\n");
} // END else
} // END else
} // END if
elseif(isset($changeType))
{
# we are changing the element type of the element,
# so we must update the type to the new type, then redisplay the
# form.
unset($changeType);
# update the type of the element to be whatever was
# selected.
if($type == "UNKNOWN_TYPE")
{
# simply redisplay the form, as the user
# has attempted to set the element type to unknown.
if($caller == "pageDetsEDS.php")
{
# Ensure that the function is called with the info to send
# it back to pageDetsEDS.php in the end.
fabricateElementDetsFormEDS($name, $caller,
$subname, $pageNumber, $nPgs, $doctype);
} // END if
else
{
# Just send the info req'd for eventual resending to the
# allElementsEDS.php page...
fabricateElementDetsFormEDS($name, $caller);
} // END else
} // END if
else
{
# element is ready for updating to the new type
# Get the data, so that it can be committed for the
# modification date field (md)...
$dateDets = getdate();
# Now put the date into a variable in a nice MySQL friendly
# format
$modifiedDate = $dateDets['year'] . "-" . $dateDets['mon']
. "-" . $dateDets['mday'];
$chTypeQ = "UPDATE sbmFIELDDESC SET type = '$type', "
. "md = '$modifiedDate'";
# check if the fields concerned with each row are
# blank, and if so, add some default values to them.
# Therefore, we must query the sbmFIELDDESC table.
$valsRes = mysql_query("SELECT * FROM sbmFIELDDESC WHERE name ="
. " '$name'");
if($valsRes)
{
$valsRow = mysql_fetch_array($valsRes);
if($type == "F" || $type == "I")
{
# The input type is a FILE input or a text input, both
# of whom have a size & maxlength field...
if($valsRow["size"] == "")
{
# No val for size, so give it one!
$chTypeQ .= ", size = '" . DEFAULT_SIZE . "'";
} // END if
if($valsRow["maxlength"] == "")
{
# No val for maxlength, so give it one
$chTypeQ .= ", maxlength = '" . DEFAULT_MAXLENGTH
. "'";
} // END if
} // END if
elseif($type == "T")
{
# changing the element to a <textarea> field..
if($valsRow["rows"] == "")
{
# No val for rows, so give it one...
$chTypeQ .= ", rows = '" . DEFAULT_ROWS . "'";
} // END if
if($valsRow["cols"] == "")
{
# No val for cols, so give it one...
$chTypeQ .= ", cols = '" . DEFAULT_COLS . "'";
} // END if
} // END elseif
mysql_free_result($valsRes);
} // END if
$chTypeQ .= " WHERE name = '$name'";
$chTypeQres = mysql_query($chTypeQ);
if(!$chTypeQres)
{
# Query failed. We will output an error message, and
# simply refresh the screen.
print("<SCRIPT TYPE='text/javascript'>\nalert('Unable to "
. "change element type.');\n</SCRIPT>\n");
} // END if
else
{
if(mysql_affected_rows() < 1)
{
# No update has been made. Better just tell the
# user & redisplay the form
print("<SCRIPT TYPE='text/javascript'>\nalert('Unable "
. "To Update Element Type');\n</SCRIPT>\n");
} // END if
elseif(mysql_affected_rows() > 1)
{
# More than 1 row was affected.
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: "
. "Multiple Element Descriptions Updated');\n"
. "</SCRIPT>\n");
$msgTxt = "When a user attempted to change the type of "
. "the $name element description in the "
. DOCS_DATABASE . " database, "
. mysql_affected_rows() . " rows were updated in "
. "the sbmFIELDDESC table.\n\nWebSubmit Administrator ("
. makeDate() . ")";
mail(ADMIN_EMAIL, "Error: $name Element Desc - Multiple"
. " Updates", $msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
$msgTxt = "The type of the $name element description in"
. " the " . DOCS_DATABASE . " database, has been "
. "changed.\n\nWebSubmit Administrator (" . makeDate() . ")";
mail(ADMIN_EMAIL, "$name Element Desc Type Change",
$msgTxt, "From: WebSubmit_Administrator");
} // END else
} // END else
# Now we can redisplay our form for the new doctype...
if($caller == "pageDetsEDS.php")
{
# Ensure that the function is called with the info to send
# it back to pageDetsEDS.php in the end.
fabricateElementDetsFormEDS($name, $caller,
$subname, $pageNumber, $nPgs, $doctype);
} // END if
else
{
# Just send the info req'd for eventual resending to the
# allElementsEDS.php page...
fabricateElementDetsFormEDS($name, $caller);
} // END else
} // END else
} // END elseif
else
{
# Display the form containing the details of the Element
# description to update...
if($caller == "pageDetsEDS.php")
{
# Ensure that the function is called with the info to send
# it back to pageDetsEDS.php in the end.
fabricateElementDetsFormEDS($name, $caller, $subname,
$pageNumber, $nPgs, $doctype);
} // END if
else
{
# Just send the info req'd for eventual resending to the
# allElementsEDS.php page...
fabricateElementDetsFormEDS($name, $caller);
} // END else
} // END else
}
/**********************Start of main script***************************/
$caller = getCallingPage($HTTP_REFERER);
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1]. "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/func.php.wml b/modules/websubmit/web/admin/func.php.wml
index 76f5feabe..7d0f5439f 100644
--- a/modules/websubmit/web/admin/func.php.wml
+++ b/modules/websubmit/web/admin/func.php.wml
@@ -1,371 +1,371 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="List of parameters of function <I><protect><?print $functionName;?></protect></i> for the <I><protect><?print $doctype;?></protect></i> document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*********************Function Declarations**************************/
function displayReturnButton($buttonText, $returnTo, $doctype,
$functionName, $action)
{
/****************************************************************
This function simply outputs a simple button in a table, which is
centered on the page. When the button is clicked, it calls the
script previous to func.php, which is actionFunctions.php
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 24/08/2000
Last Modified: 05/02/2001
****************************************************************/
# Display the button...
print("<BR><TABLE BORDER=0 CELLSPACING=0 ALIGN='center'><TR>");
print("<FORM ACTION='$returnTo' METHOD='post'><TD>\n");
if($returnTo == "funcUsage.php")
{
print("<INPUT TYPE='hidden' NAME='function' "
. "VALUE='$functionName'>");
} // END if
else
{
print("<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>");
print("<INPUT TYPE='hidden' NAME='action' VALUE='$action'>");
} // END else
print("<INPUT TYPE='button' VALUE='$buttonText' onClick=\"");
print("submit()\"></TD></FORM></TR></TABLE>\n");
} // END function displayReturnButton()
//*********************
function makeFuncParamsTableBody($queryResult, $columns, $functionName,
$returnTo, $doctype, $action)
{
/*****************************************************************
This function serves the purpose of creating the main body of the
table of parameters for a given function as part of a given
action performed upon a given doctype. The function does not
actually open or close the table itself, merely build the body
of the table (the data rows). Yhe function is passed the
$queryResult parameter, which is used to get the data for each
row of the table. It is also passed the $columns parameter,
which is used to determine how many columns there are in the
table. It is also passed the $functionName, $doctype and $action
parameters, which are all used in building the hyperlink that
can be clicked on for viewing the value of a given parameter.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 24/08/2000
Last Modified: 08/02/2001
*****************************************************************/
global $HTDOCSDIR,$IMAGES;
while($rowData = mysql_fetch_array($queryResult))
{ # While there are rows of the query dynaset to read...
print("<TR BGCOLOR='#FFFFCC'>\n");
for($colIndex = 0; $colIndex < mysql_num_fields($columns);
$colIndex++)
{ # For each column, display its value...
print("<TD ALIGN='center'>&nbsp;");
print(htmlspecialchars($rowData[$colIndex]));
print("</TD>\n");
} // End FOR
print("<TD ALIGN='center'>&nbsp;");
# Execute a select query that will select the value of the
# current rows parameter from the relevant table...
$querStr = "SELECT value FROM sbmPARAMETERS WHERE doctype = '$doctype' and name='" . $rowData['param'] . "'";
# Place a READ lock on the given table...
$lockStr = "LOCK TABLES sbmPARAMETERS READ";
$lockRes = mysql_query($lockStr);
# Execute the SELECT query...
$querRes = mysql_query($querStr);
# Remove the table lock...
if($lockRes)
{
$unlockRes = mysql_query("UNLOCK TABLES");
} # END if
unset($lockStr);
if($querRes)
{
if(mysql_num_rows($querRes) == 1)
{
# Display parameter details.
# If function is "Make_Record" or "Make_Modify_Record", link to upload template file so that it can be edited.
# Get the parameters value...
list($value) = mysql_fetch_row($querRes);
if(($functionName == "Make_Record") ||
($functionName == "Make_Modify_Record"))
{
# link to the text file editor script...
print("<A TITLE=\"EDIT THE FILE\" HREF=\"editRecordFile"
. ".php?file=" . ltrim(ereg_replace("'", "&#39;",
htmlspecialchars($value))) . "&amp;doctype="
. ereg_replace("'", "&#39;",
htmlspecialchars($doctype)) . "&amp;function"
. "Name=" . ereg_replace("'", "&#39;",
htmlspecialchars($functionName)) . "&amp;"
. "action=" . ereg_replace("'", "&#39;",
htmlspecialchars($action)) . "&amp;returnTo="
. ereg_replace("'", "&#39;",
htmlspecialchars($returnTo)) . "\">"
. ereg_replace("'", "&#39;",
htmlspecialchars($value)) . "</A>\n");
} // END if
else
{
# so just display the value as a standard text field.
print(htmlspecialchars($value));
} // END else
} // END if
elseif(mysql_num_rows($querRes) > 1)
{
/**************
If this condition has been reached, it means that
more than 1 row has been returned by this query. This
means that there are DB consistency errors, as there
should never be more than 1 row for a parameters value
for a given doctype.
**************/
# Mail the administrator to inform them of the error that
# has ocurred...
$errMailTxt = "An error has occurred when attempting to "
. "obtain a parameter value for the " . $rowData['param']
. "parameter of the $functionName function. The data was"
. "selected from the parameters table"
. " for the $doctype document type.\n\nPlease look "
. "into this problem, as it suggests that there are "
. "multiple values for this parameter, which breaks DB"
. "consistency.\n\n"
. "This error occurred on " . $dateDets['weekday'] . " "
. $dateDets['mday'] . " " . $dateDets['month'] . " "
. $dateDets['year'] . ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . ".";
mail(ADMIN_EMAIL, "Error: Multiple Values For A Parameter",
$errMailTxt, "From: WebSubmit_Administrator");
# Inform the user of this error using a javascript alert..
print("<SCRIPT TYPE='text/javascript'>alert('Error:\\n\\n"
. "Too many rows returned when selecting "
. $rowData['param']
. " parameter\\nfrom the parameters"
. " table for $doctype document type');</SCRIPT>");
} // END elseif
else
{
# In this case, no rows have been returned (i.e. there is
# no value in the DB for the parameter on this doctype, so
# a little warning will be displayed in the value cell!
print("<IMG SRC=\"".$IMAGES."/noway.gif\" ALT=\"No value"
. " stored in the " . $rowData['param'] . " column of"
. " the parameters table for the "
. "$doctype document type.\" BORDER=0 WIDTH=14 "
. "HEIGHT=14>\n");
} // END else
} // END if
else
{
/**************************
If this condition has been reached, it means that the query
has failed to execute for some reason.
**************************/
print("<SCRIPT TYPE='text/javascript'>alert('Error:\\t\\t"
. "Unable to select " . $rowData['param']
. " parameter from parameters "
. " table for $doctype document type');</SCRIPT>");
} // END else
print("</TD>\n");
# Now display an icon to allow the user to edit the value of the
# parameter. This will require a form with invisible inputs in
# order to pass the relevant parameters to the parameterUpdate
# script...
print("<FORM ACTION='parameterUpdate.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='param' VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($rowData['param']))
. "'>\n<INPUT TYPE='hidden' NAME='functionName' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($functionName))
. "'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($doctype))
. "'>\n<INPUT TYPE='hidden' NAME='action' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($action))
. "'>\n"
. "<INPUT TYPE='hidden' NAME='returnTo' VALUE='$returnTo'>\n"
. "<TD><INPUT TYPE='image' SRC='".$IMAGES."/edit1.gif' "
. "WIDTH=20 HEIGHT=20 BORDER=0 ALT='Edit Parameter Value' "
. "onClick=\"submit();\"></TD>\n</FORM>\n");
# Close up the table row...
print("</TR>\n");
} // End while
} // END function makeFuncParamsTableBody()
//*******************
function processQuery($queryResult, $doctype, $action, $functionName,
$returnTo)
{
/*****************************************************************
This function is passed a queryResult from the main function of
func.php. The query was a select query to get all rows from the
sbmFUNDESC table for a given function (i.e. all of that functions
parameters). This function tests to see if rows were returned by
this query, and if there were rows returned, a table containing
the details of the parameters is created and output on the fly.
If no rows were returned by the query however, a relevant
informative message is displayed on the screen instead of the
table.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 24/08/2000
Last Modified: 06/02/2001
*****************************************************************/
$numRows = mysql_num_rows($queryResult);
if($numRows > 0)
{
# Get information about the sbmFUNDESC table. This will be used to
# display the column headers in the table of info about the
# chosen function.
$columns = mysql_list_fields(DOCS_DATABASE, "sbmFUNDESC");
# Now, we can create a table to hold the function info. First,
# we will put the column headings in it...
print("<TABLE BORDER=1 CELLSPACING=0 ALIGN='center'>\n");
print("<TR BGCOLOR='#CCDDFF'>\n");
makeTableHeaderRow($columns, 0);
# Add another column for the value of the parameter...
print("<TH>&nbsp;value&nbsp;</TH>\n");
# Add another column for the edit parameter value icon to be put
# in...
print("<TH>&nbsp;</TH>\n</TR>\n");
# Now that the column headers have been displayed for the
# function information table, we can create the rest of the
# table, with the actual information about the function in it.
makeFuncParamsTableBody($queryResult, $columns, $functionName,
$returnTo, $doctype, $action);
print("</TABLE>\n");
} // End if
else # If there are no parameters to display...
{
print("<P><H4 STYLE=\"color: red; text-align: center\">The "
. "$functionName function has no parameters to display.</H4>"
. "\n</P>\n");
} // End else
} // END function processQuery()
function displayPage()
{
global $functionName,$doctype,$action,$returnTo;
# Decode the $functionName parameter from url encoding...
$functionName = urldecode($functionName);
# Execute a query on the sbmFUNDESC table, retrieving data about the
# function whose name was passed as an argument to the script.
# The function data really just gives details of the parameters
# that the function takes, and the table that these parameters
# can be found in. The output is sorted in ascending order of
# parameters.
# Lock the sbmFUNDESC table as READ
if($lockRes = mysql_query("LOCK TABLES sbmFUNDESC READ"))
{
$queryResult = mysql_query("SELECT * FROM sbmFUNDESC WHERE
function = '$functionName' ORDER BY param");
$unlockRes = mysql_query("UNLOCK TABLES");
# Test the query result, and take the appropriate action...
processQuery($queryResult, $doctype, $action, $functionName,
$returnTo);
# Display a 'finished' button...
displayReturnButton("FINISHED", $returnTo, $doctype,
$functionName, $action);
} # END if
else
{
# Unable to lock sbmFUNDESC table. Unsafe to read from it, so
# don't.
print("<DIV STYLE='text-align: center; color: navy; font-weight:"
. " bold; font-size: large'><SPAN STYLE='color: red'>Error:"
. "</SPAN> Unable to lock sbmFUNDESC table.</DIV>\n<BR>\n");
displayReturnButton("OK", $returnTo, $doctype,
$functionName, $action);
} # END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/funcUsage.php.wml b/modules/websubmit/web/admin/funcUsage.php.wml
index 6fe43740d..e60fe6ab0 100644
--- a/modules/websubmit/web/admin/funcUsage.php.wml
+++ b/modules/websubmit/web/admin/funcUsage.php.wml
@@ -1,358 +1,358 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Where the <i><protect><?print $function;?></protect></i> function is used" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listfunctions"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/******************************************************************
This script has been written so that a user can view the usage of a
particular function throughout the WebSubmit system. The script is
passed the variable $function from the calling page (which is
listFunctions.php). The script runs a series of queries,
retrieving all doctypes in the WebSubmit database, then retrieving all
actions for each of these queries, then retrieving all functions
that match with the function name stored in $function, for each of
these actions. This means that a form of hierarchical list can be
built showing on which actions on which doctypes the function being
examined is used.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 21/09/2000
Last Modified: 22/03/2001
******************************************************************/
/**********************Function Declarations***********************/
function killThisScript()
{
/***************************************************************
This is just a simple function to stop the processing of this
script. It will be called whenever a fatal query error occurs.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 21/09/2000
Last Modified: 05/02/2001
***************************************************************/
# Stop processing this script...
die("</TD></TR></TABLE><STRONG STYLE='text-align: center; color: "
. "red>Report Processing Terminated. <A HREF='index.php'>Main "
. "Page.</A></STRONG></TD>\n</TR>\n</TABLE>\n</BODY>\n"
. "</HTML>\n");
} // END function killThisPage()
//***************
function makeFuncUsageList($doctypesQuery, $function)
{
/*******************************************************************
This function takes 2 parameters. The first is a query result
set that points to all of the doctypes in the sbmDOCTYPE table, and
the second is a function name (the one whose usage is to be
examined). The function loops through every doctype in the
result set, and for each one, it executes a query finding all of
the actions on that doctype. For each of these actions, it then
executes a query to see if the function we are examining is used
by that action on that doctype. If it is, it is displayed in a
bullet pointed list. The action on the doctype that the function
is used in is the text that is actually displayed, and it is
displayed as a link to the func.php page, where the parameters
for that function can be displayed.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 25/09/2000
Last Modified: 22/03/2001
*******************************************************************/
if($doctypesQuery) # If the query to get all doctypes was successful
{
# Open an invisible table that will contain the bullet list of
# doctypes and actions in which the function is utilised.
print("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 "
. "ALIGN='center'>\n<TR><TD>");
# A flag is needed to determine whether or not a doctype has been
# printed on screen (as all actions are indented from this. The
# flag is first set to 0, as no doctype has been displayed at
# first...
$headerDrawn = 0;
# For each document type returned by the query (each doctype in
# the WebSubmit database...
while(list($doctypeItem, $doctypeName) =
mysql_fetch_row($doctypesQuery))
{
# Execute a query to retrieve the actions belonging to this
# particular document type...
# Lock the sbmIMPLEMENT table.
$lockRes = mysql_query("LOCK TABLES sbmIMPLEMENT READ");
$actionsQuery = mysql_query("SELECT actname FROM sbmIMPLEMENT
WHERE docname = '$doctypeItem'");
if($lockRes)
{
# Unlock the table...
$unlockRes = mysql_query("UNLOCK TABLES");
} # END if
# If this actions query was executed successfully...
if($actionsQuery)
{
# For each action of the current document type...
while(list($actItem) = mysql_fetch_row($actionsQuery))
{
# Execute a query to retrieve all of the entries for the
# function being tested for, as part of the current
# action on the current document type...
$string = "SELECT function FROM sbmFUNCTIONS WHERE "
. "doctype = '$doctypeItem' AND function = '$function' and action='${actItem}'";
# Lock the current table as READ.
$lockStr = "LOCK TABLES sbmFUNCTIONS READ";
$lockRes = mysql_query($lockStr);
$functionsQuery = mysql_query($string);
if($lockRes)
{
# Release the locks...
$unlockRes = mysql_query("UNLOCK TABLES");
unset($lockStr);
} # END if
if($functionsQuery) # If the query executed successfully
{
# If rows were returned by the query (i.e. if the
# current action on the current doctype includes the
# function being tested for...
if(mysql_num_rows($functionsQuery) > 0)
{
# If the headerDrawn flag is not set (i.e. the
# doctype bullet point has not yet been displayed
# on the screen...
if(!$headerDrawn)
{
# Write the document type on the screen, and
# then open another HTML unordered list to
# contain action titles...
print("<UL TYPE='disc'>\n<LI><STRONG>"
. "<SMALL>$doctypeName</S"
. "MALL></STRONG></LI>\n"
. "\t<UL TYPE='square'>\n");
# Set the header flag to indicate that the
# doctype title has now been written on the
# screen...
$headerDrawn = 1;
} // END if
# Display the action name as part of the inner
# list...
print("<A HREF='func.php?functionName=$function"
. "&doctype=$doctypeItem&action=$actItem"
. "&returnTo=funcUsage.php'>"
. "<LI>$actItem</LI></A>\n");
} // END if
} // END if
else
{
/**************************************************
This error condition will be reached if for some
reason the query to retrieve functions for the
current action of the current doctype, from the
functions table has failed to execute. This
condition should never really be reached, but it
is my suggestion that if it has, it could be
because field names have been changed in the
functions table, or, more likely, because the
current action is an action that has been created
whereby a corresponding table in the WebSubmit database
has not been created. (All actions must have a
corresponding functions table in WebSubmit.
**************************************************/
# Make a query string to contain the error message to
# be displayed in the alert box...
$funcAlertString = "ERROR:\\n\\n"
. "Unable To Query The functions Table.\\n\\nIt"
. "is possible that field names in this table have"
. " been changed since this\\napplication was "
. "developed."
. "\\n\\nIt is also possible however, that "
. "the WebSubmit action ($actItem) being queried for "
. "functions\\ndoes not have a corresponding "
. "functions table in the WebSubmit database.\\n\\n"
. "All actions in WebSubmit must have corresponding"
. " functions tables.";
# Display the error in an alert box...
print("<SCRIPT TYPE='text/javascript'>alert('"
. "$funcAlertString');</SCRIPT>");
/*********
It would be possible to terminate this script at
this point, but given that it may only be one
functions table that is unqueryable, processing
shall not be terminated, but left to display
other potential results
*********/
} // END else
} // END while
if($headerDrawn)
{
# Reset the headerDrawn flag so that the next document
# type can be tested appropriately...
$headerDrawn = 0;
print("</UL>\n</UL>\n");
} // END if
} // END if
else
{
# This error condition will be reached if for some reason
# the query to select actions belonging to a given doctype
# from the sbmIMPLEMENT table has failed. It should not
# ever really occurr, but it is my suggestion that if it
# has occurred, it is possible that field names in the
# table have been changed, or the sbmIMPLEMENT table name
# has been changed.
# Make an error query string...
$actErrorString = "Error:\\n\\nUnable to query the "
. "sbmIMPLEMENT table.\\n\\nIt is possible that the "
. "names"
. " of the fields in the sbmIMPLEMENT table\\nhave "
. "been changed since the WebSubmit Administrator "
. "application was developed.\\n\\nContact the system"
. " administrator about this problem.";
print("<SCRIPT TYPE='text/javascript'>alert('"
. "$actErrorString');</SCRIPT>\n");
# Terminate the processing of the script...
killThisScript();
} // END else
} // END while
print("</TD>\n</TR>\n</TABLE>\n");
} // END if
else
{
# This error condition will be reached if for some reason the
# query to select doctypes from the sbmDOCTYPE table has failed. It
# should not occur, but is my suggestion that if it has, it is
# possible that field names in the sbmDOCTYPE table have changed, or
# the tablename has changed.
# Make an error query string...
$docErrorString = "ERROR\\n\\nUnable to query the sbmDOCTYPE "
. "table.\\n\\n"
. "It is possible that the names of the fields in the TEST\\n"
. "table have been changed since the WebSubmit Administrator "
. "application was developed.\\n\\nContact the system "
. "administrator about this problem.";
# Output the error in a JavaScript aler box...
print("<SCRIPT TYPE='text/javascript'>alert('$docErrorString');"
. "</SCRIPT>\n");
# Terminate the processing of this script, as nothing further can
# be done if this query has failed...
killThisScript();
} // END else
} // END function makeFuncUsageList($doctypesQuery)
function displayPage()
{
global $function;
#######LOCKS#######
# Place a READ lock on the sbmDOCTYPE table
if($lockRes = mysql_query("LOCK TABLES sbmDOCTYPE READ"))
{
# We must execute a query to return a list of all document types in
# the WebSubmit system. This can be obtained by querying the TEST
# table...
$doctypesQuery = mysql_query("SELECT sdocname, ldocname FROM sbmDOCTYPE ORDER
BY sdocname");
# We must unlock our table...
$unlockRes = mysql_query("UNLOCK TABLES");
# Make the list of doctypes and their actions that the function
# being examined is used in...
makeFuncUsageList($doctypesQuery, $function);
} # END if
else
{
# Could not get a lock...
print("<DIV STYLE='text-align: center; font-weight: bold; "
. "font-size: large; color: navy'>\n<SPAN STYLE='color: red'>"
. "Error:</SPAN> Unable to retrieve information.</DIV>\n".mysql_error()."<BR>\n");
} # END else
# Make a button to go back to the calling page...
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 CELLPADDING=0>\n"
. "<TR><FORM ACTION='listFunctions.php' METHOD='post'>\n<TD>"
. "<INPUT TYPE='button' VALUE='FINISHED' onClick=\"submit()\">"
. "</TD>\n</TR></TABLE>");
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/index.php.wml b/modules/websubmit/web/admin/index.php.wml
index 02b03366c..3f5d29bb0 100644
--- a/modules/websubmit/web/admin/index.php.wml
+++ b/modules/websubmit/web/admin/index.php.wml
@@ -1,130 +1,130 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="WebSubmit Admin" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
</protect>
function displayDoctypeList()
{
$queryResult = mysql_query("SELECT sdocname, ldocname FROM sbmDOCTYPE "
. "ORDER BY ldocname");
if($queryResult)
{
# Query has executed successfully, so we can proceed to display all
# document types in the EDS system...
makeDoctypeTable($queryResult, "documentEDS.php");
} // END if
else
{
# In this case, the query failed, so we can terminate the scripts
# running, and terminate the WebSubmit Administrator session, as no
# further actions can be carried out...
print('<H3>Error: Unable to retrieve data from the sbmDOCTYPE table.'
. '</H3>');
} // END else
}
function makeDoctypeTable($queryResult, $linkTo)
{
/***************************************************************
This function produces the table of hyperlinks for all of the
doctypes in the system. The table is displayed without borders,
and is centered in the page. The function loops through each
row of the query dynaset that is passed to it ($queryResult),
outputting each record as a row in the table.
The function has been adapted to serve both WebSubmit and EDS, so that
the URL of the page to be linked to is passed as an argument to
the function, and therefore the relevant page is linked to,
depending upon whether it is in the WebSubmit Administrator, or the
WebSubmit Administrator.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: Long Ago!!
Last Modified: 06/02/2001
***************************************************************/
# Begin outputting a table to display the document types in.
# The table has no border.
print('<TABLE ALIGN="center" BORDER=0 WIDTH="100%"><TR>'
. '<TH>&nbsp;<SPAN STYLE="color: navy; font-size: large; '
. 'font-weight: bold; text-align: center">Document Type'
. '&nbsp;</SPAN></TH></TR><TR><TD ALIGN="center">'
. '<TABLE ALIGN="center" BORDER=0>');
# While there are still records to retrieve from the query...
# ...get each row, assign the fields to $doctype and $name, then...
# ...display the document type fullname in a table as a hyperlink.
# When the hyperlink is clicked, the details of that document type
# are displayed.
while(list($doctype, $name) = mysql_fetch_row($queryResult))
{
print('<TR>');
print('<TD ALIGN="left"><A ');
print('HREF="'.$linkTo.'?doctype='.$doctype.'" onMouseOver = "window.defaultStatus = \'\'; window.status=\'View Details Of ');
print(htmlspecialchars($name));
print(' Document Type\';');
print(' return true">');
print(htmlspecialchars($name));
print('&nbsp;</A></TD>');
print('</TR>');
} // END while
# Close Table
print('</TABLE></TD></TR></TABLE>');
} // END function makeDoctypeTable($queryResult)
// ***********
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayDoctypeList();
/************************End of main script***************************/
?>
diff --git a/modules/websubmit/web/admin/listFunctions.php.wml b/modules/websubmit/web/admin/listFunctions.php.wml
index 91d34d590..89ef46d4e 100644
--- a/modules/websubmit/web/admin/listFunctions.php.wml
+++ b/modules/websubmit/web/admin/listFunctions.php.wml
@@ -1,179 +1,179 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Available Functions" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listfunctions"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*************************Function Declarations********************/
function makeFunctionTable($queryResult)
{
/*****************************************************************
This function produces a table, which contains a list of all of
the functions in the WebSubmit system database. The function is
passed a query result that points to a list of all functions in
the WebSubmit database (obtained by querying the sbmALLFUNCDESCR table
for function).
The table that is produced contains the functions name, a form
with a graphical input button that when pressed, takes the user
to a page where they can view the usage of the function
throughout WebSubmit, and a form with a graphical input button, which
when pressed, takes the user to a page where they can view/edit
details of that particular function (e.g. adding parameters,
changing the function description, etc...
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 18/09/2000
Last Modified: 25/01/2001
*****************************************************************/
global $IMAGES;
# Open the table, and display the column headings...
print("<TABLE ALIGN='center' BORDER=1 CELLSPACING=0 CELLPADDING=0>"
. "\n<TR BGCOLOR='#CCDDFF'>\n<TH>Function Name</TH>\n"
. "<TH>View<BR>Function Usage</TH>\n<TH>View/Edit<BR>Function "
. "Details</TH>\n</TR>\n");
# For each function in the array, (each function in WebSubmit), display
# its name, and make the input forms...
while(list($funName) = mysql_fetch_row($queryResult))
{
print("<TR BGCOLOR='#FFFFCC'>\n<TD>&nbsp;$funName"
. "&nbsp;</TD>\n"
. "<FORM METHOD='post' ACTION='funcUsage.php'><TD "
. "ALIGN='center'><INPUT TYPE='hidden' NAME='function'"
. " VALUE='$funName'><INPUT TYPE='image' BORDER=0 "
. "SRC='".$IMAGES."/tick.gif'></TD></FORM>\n"
. "<FORM METHOD='post' ACTION='veditFunDets.php'><TD "
. "ALIGN='center'><INPUT TYPE='hidden' NAME='function' "
. "VALUE='$funName'><INPUT TYPE='image' BORDER=0"
. " SRC='".$IMAGES."/tick.gif'></TD></FORM>\n</TR>\n");
} // END for
# Close the table...
print("</TABLE>\n");
} // END function makeFunctionTable($queryResult)
/**************************Start of Main Script*********************/
/**********************************************************************
This script displays a table of all functions in the WebSubmit database
on the browser screen. Effectively, it makes a table, containing
the name of each function, and for each function, a link to a page
that shows the functions usage in WebSubmit, and a link to a page that
allows the user to view and/or edit the details of that function.
It is worth making a note at this stage about the operation of this
script. I had at first thought that the WebSubmit table sbmFUNDESC
contained the details of every function in the WebSubmit database, and
therefore it would be possible to simply query this table to get the
names of all functions in WebSubmit. Further observations however,
revealed that sbmFUNDESC only contains entries for functions that take
parameters, which meant that functions without parameters would not
be listed by querying this table. This meant that it was necessaray
to create a new table that contained the function name, and a
descrtiption of the function.
This table was added to mess, and called sbmALLFUNCDESCR. It was
decided that it would be made compulsary that all functions have an
entry in this new table, so that obtaining a list of all functions
in WebSubmit would be very easy and efficient.
**********************************************************************/
function displayPage()
{
# Place a READ lock on the sbmALLFUNCDESCR table
if($lockRes = mysql_query("LOCK TABLES sbmALLFUNCDESCR READ"))
{
# Run a query to retrieve all of the functions in the WebSubmit...
$funcQuery = mysql_query("SELECT function FROM sbmALLFUNCDESCR ORDER
BY function");
# We must unlock our table...
$unlockRes = mysql_query("UNLOCK TABLES");
if($funcQuery) # If the query to get all functions was successful
{
# Display the query results on the screen...
makeFunctionTable($funcQuery);
# Now print out an action button to give the user to add a
# function...
print("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 "
. "ALIGN='center'>\n"
. "<TR>\n<FORM METHOD='post' ACTION='newFunc.php'><TD "
. "ALIGN='center'><INPUT TYPE='button' VALUE='ADD FUNCTION'"
. " onClick=\"submit();\">\n</TD></FORM>\n</TR>\n"
. "</TABLE>\n");
} // END if
else # If the function did not execute successfully...
{
# Display an error message on the screen in the form of a
# JavaScript alert...
print("<SCRIPT TYPE='text/javascript'>alert('ERROR: Unable"
. " to execute query for all "
. "functions in WebSubmit');</SCRIPT>");
} // END else
} # END if
else
{
# Could not lock the table. No display allowed.
print("<DIV STYLE='text-align: center; font-weight: bold; "
. "font-size: large; color: navy'>\n<SPAN STYLE='color: red'>"
. "Error:</SPAN> Unable to retrieve information.</DIV>\n<BR>".mysql_error()."\n"
. "<A STYLE='text-align: center; font-size: medium' HREF='"
. "listFunctions.php'>Please retry</A>\n<BR>\n");
} # END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/newDoctypeEDS.php.wml b/modules/websubmit/web/admin/newDoctypeEDS.php.wml
index ba7bf083d..98d6ba502 100644
--- a/modules/websubmit/web/admin/newDoctypeEDS.php.wml
+++ b/modules/websubmit/web/admin/newDoctypeEDS.php.wml
@@ -1,807 +1,807 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Create New Document Type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_newdoctype"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT TYPE='text/javascript'>
<!-- hide
function checkRequired(ldocname, sdocname, hurl, combon, combot, description,
docfi2)
// This is a function to ensure that the user enters the required
// parameters for the doctype.
// Author: Nicholas Robinson
// Email: Nicholas.Robinson@cern.ch
// ca8nro@yahoo.co.uk
// Created: Long ago!
// Last Modified: 19/12/2000
{
// If the field is left blank by the user...
if((sdocname == "") || (ldocname == ""))
{ // Alert them, and return false.
alert("Values must be entered into the Doctype Code and "
+ "Long Document Name fields.");
return false;
} // End if
else // If level has been filled by the user...
{
return true;
} // End else
} // End function checkRequired(param)
// -->
</SCRIPT>
<?
function displayDoctypeFormEDS()
{
/*******************************************************************
It is the task of this function to display the form that the user
sees to allow them to enter the details for a new EDS document
type. After all of the details of this document type have been
entered into this form, there is also a select list. This select
list contains the names of all of the other EDS Doctypes. If one
of these doctypes is selected, the new doctype will be cloned
from it.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 19/12/2000
Last Modified: 12/04/2001
*******************************************************************/
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">The form below is"
. "used for entering the details of a new document type.<BR><BR>It"
. " is possible to clone this document type from another EDS "
. "document type by selecting it from the list.<BR>If you do not "
. "wish to clone the document type, simply leave the list on the "
. "selected \"NO CLONE\" option.<BR><BR>When the details have been"
. " entered, click on the \"SAVE DETAILS\" button to commit it to "
. "the database.</P>\n</TD>\n</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now display the form...
print("<FORM ACTION='newDoctypeEDS.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='addDoctype' VALUE='true'>\n");
# Get the columns list
$columns = mysql_list_fields(DOCS_DATABASE, "sbmDOCTYPE");
# Get the number of fields
$numTblFlds = mysql_num_fields($columns);
# Get the current date...
$modifiedDate = makeEDSmdDate();
# Display the system generated fields...
print("<TABLE WIDTH='100%' ALIGN='center' CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0>\n<TR>\n<TH BGCOLOR='#D3DCE3' "
. "ALIGN='right' WIDTH='20%'>\nCreation Date:&nbsp;</TH>\n"
. "<TD WIDTH='80%' ALIGN='left' BGCOLOR='#FFFFCC'><INPUT "
. "TYPE='readonly' NAME='cd' VALUE='$modifiedDate'>\n</TD>\n"
. "</TR>\n<TR>\n<TH WIDTH='20%' BGCOLOR='#D3DCE3' ALIGN='"
. "right'>\nModification Date:&nbsp;</TH>\n<TD WIDTH='80%' "
. "ALIGN='left' BGCOLOR='#FFFFCC'><INPUT TYPE='readonly' "
. "NAME='md' VALUE='$modifiedDate'>\n</TD>\n</TR>\n");
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "Document Type ID:&nbsp;</TH>\n<TD WIDTH='80%' ALIGN='left' "
. "BGCOLOR='#FFFFCC'>\n<INPUT TYPE='text' NAME='sdocname' SIZE="
. mysql_field_len($columns, 1) . ">\n</TD>\n</TR>\n");
# Now add the other fields...
for($indx = 0; $indx < $numTblFlds; $indx++)
{
# Get the name of the current field...
$currentField = mysql_field_name($columns, $indx);
# Ensure that we don't once again print our non-editable
# fields out...
if(($currentField != "sdocname") && ($currentField != "cd")
&& ($currentField != "md"))
{
# First, display the field name...
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\n");
if($currentField == "ldocname")
{
print("Document Type Name:&nbsp;");
} // END if
elseif($currentField == "description")
{
print("Document Type Description:&nbsp;");
} // END elseif
else
{
print("$currentField" . ":&nbsp;");
} // END else
if ($currentField == "description")
{
print "&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<TEXTAREA NAME="
. "'$currentField' cols=60 rows=4></TEXTAREA>"
. "\n</TD>\n</TR>\n";
}
else
{
print("&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<INPUT TYPE='text' NAME="
. "'$currentField' SIZE=");
if(mysql_field_type($columns, $indx) == "blob")
{
print("60");
} // END if
else
{
print(mysql_field_len($columns, $indx));
} // END else
print(">\n</TD>\n</TR>\n");
}
} // END if
} // END for
# Now, we want to create a select list of EDS doctypes...
$queryResult = mysql_query("SELECT sdocname, ldocname FROM sbmDOCTYPE "
. "ORDER BY sdocname");
if($queryResult)
{
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='"
. "20%'>\nDoctype To Clone:&nbsp;</TH>\n<TD ALIGN='left'"
. " WIDTH='80%' BGCOLOR='#FFFFCC'>\n");
print("<SELECT NAME='doc2clone'>\n<OPTION SELECTED VALUE='"
. "NO_CLONE'>None</OPTION>\n");
while($dox = mysql_fetch_array($queryResult))
{
print("<OPTION VALUE='"
. htmlspecialchars($dox["sdocname"])
. "'>" . htmlspecialchars($dox["ldocname"])
. "</OPTION>\n");
} // END while
print("\n</SELECT>\n</TD>\n</TR>\n");
} // END if
# Now close the table...
print("</TABLE>\n");
# Now create the buttons for the form...
print("<TABLE ALIGN='center' CELLSPACING=2 CELLPADDING=2 BORDER=0>"
. "<TR>\n<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='SAVE DETAIL"
. "S' onClick=\"if(checkRequired(ldocname.value, sdocname.value"
. ")) { if(confirm('Really Commit This New Doctype"
. "?')) { submit(); } else { return false; } }\">\n</TD><TD ALIGN='"
. "center'>\n<INPUT TYPE='button' VALUE='RESET' onClick=\"reset();"
. "\">\n</TD>\n</FORM>\n<FORM ACTION='index.php' METHOD='post'>\n"
. "<TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='CANCEL' onClick="
. "\"submit();\">\n</TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // END function displayDoctypeFormEDS()
//*************
function processCloningEDS($doc2clone, $sdocname)
{
/*******************************************************************
This function actually deals with the cloning of a document type
from another document type in EDS. This means that it is
necessary for it to search through the sbmIMPLEMENT table looking
for all submissions that belong to the given doctype that is
being cloned. It then changes the 'cd' and 'md' fields to hold
todays date (the date on which the new doctype is being created),
changes the doctype field to hold the doctype of the new doctype,
and changes the subname field to have the action code combined
with the new doctype code, as opposed to the doctype code of the
doctype being cloned along with the action code. All of this
data is then committed to the database.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 19/12/2000
Last Modified: 25/01/2001
*******************************************************************/
# Run a query to get all of the submission types for the doctype to
# be cloned...
$cloneRes1 = mysql_query("SELECT * FROM sbmIMPLEMENT WHERE docname ="
. " '$doc2clone' ORDER BY actname");
if($cloneRes1)
{
# Fine, the query has worked...
# Get the current date...
$modDate = makeEDSmdDate();
# Okay, for each submission
while($sub2Clone = mysql_fetch_array($cloneRes1))
{
# Clone functions
$res = mysql_query("select * from sbmFUNCTIONS where doctype='$doc2clone' and action='".$sub2Clone["actname"]."'");
while ($row = mysql_fetch_array($res))
{
$res2 = mysql_query("select 1 from sbmFUNCTIONS where doctype='$sdocname' and action='".$row["action"]."' and function='".$row["function"]."' and score='".$row['score']."' and step='".$row['step']."'");
if (mysql_num_rows($res2) < 1)
mysql_query("insert into sbmFUNCTIONS(action, doctype, function, score, step) values ('".$row['action']."','$sdocname','".$row['function']."','".$row['score']."','".$row['step']."')");
}
#clone parameters
$res = mysql_query("select * from sbmPARAMETERS where doctype='$doc2clone'");
while ($row = mysql_fetch_array($res))
{
$res2 = mysql_query("select 1 from sbmPARAMETERS where doctype='$sdocname' and name='".$row['name']."'");
if (mysql_num_rows($res2) < 1)
mysql_query("insert into sbmPARAMETERS(doctype, name, value) values ('$sdocname','".$row['name']."','".$row['value']."')");
}
# Make a query to insert this submission data for the new
# doctype...
$subCloneStr = "INSERT INTO sbmIMPLEMENT (docname, actname, displayed, subname, nbpg, cd, md, buttonorder, statustext, level, score, stpage, endtxt) "
. "VALUES ('"
. ereg_replace("'", "\'", $sdocname) . "', '"
. ereg_replace("'", "\'", $sub2Clone["actname"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["displayed"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["actname"])
. ereg_replace("'", "\'", $sdocname) . "', '"
. ereg_replace("'", "\'", $sub2Clone["nbpg"])
. "', '$modDate', '$modDate', '"
. ereg_replace("'", "\'", $sub2Clone["buttonorder"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["statustext"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["level"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["score"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["stpage"]) . "', '"
. ereg_replace("'", "\'", $sub2Clone["endtxt"]) . "')";
$subCloneRes = mysql_query($subCloneStr);
if($subCloneRes)
{
# Good...no query errors.
if(mysql_affected_rows() == 1)
{
# Good...the query inserted the row! Now we can get the
# elements for this submission, and insert them for the
# new doctype.
# Now conduct a select query to get all of the elements
# for this submission.
$cloneStr2 = "SELECT * FROM sbmFIELD WHERE subname = '"
. $sub2Clone["subname"] . "'";
$cloneRes2 = mysql_query($cloneStr2);
if($cloneRes2)
{
# Fine, the query worked...
# For each element of the submission
while($anElement = mysql_fetch_array($cloneRes2))
{
$eleCloneStr = "INSERT INTO sbmFIELD (subname, "
. "pagenb, fieldnb, fidesc, fitext, level, sdesc,"
. " checkn, cd, md, fiefi1, fiefi2) VALUES ('"
. ereg_replace("'", "\'",
$sub2Clone["actname"])
. ereg_replace("'", "\'",
$sdocname) . "', '"
. ereg_replace("'", "\'",
$anElement["pagenb"]) . "', '"
. ereg_replace("'", "\'",
$anElement["fieldnb"]) . "', '"
. ereg_replace("'", "\'",
$anElement["fidesc"]) . "', '"
. ereg_replace("'", "\'",
$anElement["fitext"]) . "', '"
. ereg_replace("'", "\'",
$anElement["level"]) . "', '"
. ereg_replace("'", "\'",
$anElement["sdesc"]) . "', '"
. ereg_replace("'", "\'",
$anElement["checkn"]) . "', '$modDate', '"
. "$modDate', '"
. ereg_replace("'", "\'",
$anElement["fiefi1"]) . "', '"
. ereg_replace("'", "\'",
$anElement["fiefi2"]) . "')";
# Now we can execute this query...
$eleCloneRes = mysql_query($eleCloneStr);
# Now test that all went well with the insert...
if($eleCloneRes)
{
# Good...the query was correct...
if(mysql_affected_rows() != 1)
{
# For some reason, the element was not
# inserted
# Tell the user...
print("<SCRIPT TYPE='text/javascript'>\n"
. "alert('ERROR: Unable to insert element "
. $anElement["fieldnb"] . " ("
. $anElement["fitext"] . ") of page "
. $anElement["pagenb"] . " of the "
. $sub2Clone["actname"] . "$sdocname "
. "submission.\\nThis may have caused "
. "element numberring errors and should be"
. " corrected immediately.\\n\\nPlease inf"
. "orm the system administrator.');\n"
. "</SCRIPT>\n");
# Email the administrator...
$msgTxt = "An error ocurred during the "
."creation of the new $sdocname document "
."type. It was not possible to commit the "
. "details for the " . $anElement["fidesc"]
. " element (number "
. $anElement["fieldnb"]
. ") on page " . $anElement["pagenb"]
. " of the " . $sub2Clone["actname"]
. "$sdocname submission for somereason. "
. " This means that the element will be "
. "missing, and therefore other elements "
. "could be out of sequence, which could be"
. " dangerous for the EDS system.\n\nYou "
. "should fix this problem at once.\n\nEDS "
."Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname creation "
."Error - " . $anElement["fidesc"]
. " Element Missed from "
. $sub2Clone["actname"] . "$sdocname",
$msgTxt, "From: WebSubmit_Administrator");
} // END else
} // END if
else
{
# Bad news! the query didn't work.
# Inform the user of the missing element
print("<SCRIPT TYPE='text/javascript'>\nalert("
. "'ERROR: It was not possible to commit the "
. "details for the " . $anElement["fidesc"]
. " element (number " . $anElement["fieldnb"]
. ") of the " . $sub2Clone["actname"]
. "$sdocname submission.');\n</SCRIPT>\n");
# Inform the administrator...
$msgTxt = "An error ocurred during the "
."creation of the new $sdocname document type."
." It was not possible to commit the "
. "details for the " . $anElement["fidesc"]
. " element (number " . $anElement["fieldnb"]
. ") on page " . $anElement["pagenb"]
. " of the " . $sub2Clone["actname"]
. "$sdocname submission, due to a query error."
. " This means that the element will be "
. "missing, and therefore other elements "
. "could be out of sequence, which could be "
. "dangerous for the EDS system.\n\nYou should"
. " fix this problem at once.\n\nEDS "
."Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname Creation Error"
." - " . $anElement["fidesc"] . " Element "
. "Missed From " . $sub2Clone["actname"]
. "$sdocname", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END while
} // END if
else
{
# We couldn't get the details of the elements for the
# current submission. This means that we can simply
# ignore them, and let both the user & admin know.
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR"
. ": It was not possible to retrieve details of the "
. "elements for the " . $sub2Clone["subname"]
. "submission.\\nThis meant that it was not possible"
. " to clone these elements\\nfor the new "
. $sub2Clone["actname"] . "$sdocname submission.\\n"
. "\\nIt will therefore be necessary to manually add"
. " any elements to this submission.');\n</SCRIPT>"
. "\n");
# Email the admin...
$msgTxt = "An error ocurred during the creation of "
. "the new $sdocname document type. This new "
. "doctype was being cloned from the $doc2clone "
. "document type. When an attempt was made to read"
. " details of the elements of the "
. $sub2Clone["subname"] . " however, it was not "
. "possible to retrieve these details due to a query"
. " error. This meant that the elements of the new "
. $sub2Clone["actname"] . "$sdocname submission "
. "could not be created, so the submission will have"
. " blank pages. It will be necessary to manually "
. "add these pages to this submission.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname Creation Error - "
.$sub2Clone["actname"] . "$sdocname "
. "Elements Not Cloned", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END if
else
{
# New submission was not inserted. Forget the elements
# for it then!
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: "
. "unable to commit the new " . $sub2Clone["actname"]
. "$sdocname to the sbmIMPLEMENT table. Cloned elements "
. "therefore have not been committed.');\n</SCRIPT>\n");
# Mail the administrator...
# Inform the administrator
$msgTxt = "An error ocurred during the creation of the "
. "new $sdocname document type. This new doctype was "
."being cloned from the $doc2clone document type. When"
." an attempt was made to write details for the new "
. $sub2Clone["actname"] . "$sdocname submission, which "
. "was to be cloned from the " . $sub2Clone["subname"]
. " submission, to the sbmIMPLEMENT table, no data was "
. "written. This meant that the "
. $sub2Clone["actname"] . "$sdocname submission could "
. "not be created, and therefore does not exist for the"
. "$sdocname document type.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname Creation Error - "
. $sub2Clone["actname"] . " Submission Not "
. "Cloned", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END if
else
{
$error = mysql_error();
# query failed.
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: "
. "Could not conduct an insert query on the sbmIMPLEMENT "
. "table.\\n" . $sub2Clone["actname"] . "$sdocname "
. "submission and its elements therefore could not be "
."added.\\n error msg: $error');\n</SCRIPT>\n");
# Inform the administrator
$msgTxt = "An error ocurred during the creation of the new"
. " $sdocname document type. This new doctype was being "
. "cloned from the $doc2clone document type. When an "
. "attempt was made to write details for the new "
. $sub2Clone["actname"] . "$sdocname submission, which was"
. " to be cloned from the " . $sub2Clone["subname"]
. " submission, to the sbmIMPLEMENT table, this attempt "
. "failed due to a query error. This meant that the "
. $sub2Clone["actname"] . "$sdocname submission could not "
. "be created, and therefore does not exist for the "
. "$sdocname document type.";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname Creation Error - "
. $sub2Clone["actname"] . "$sdocname Submission "
. "Not Cloned", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END while
# Now that we have cloned the submissions & their pages, we can
# clone the Categories...
$catCloneRes = mysql_query("SELECT * FROM sbmCATEGORIES WHERE "
. "doctype = '$doc2clone' ORDER BY sname");
if($catCloneRes)
{
# Cool. Query successful.
while($cat = mysql_fetch_array($catCloneRes))
{
$catInsStr = "INSERT INTO sbmCATEGORIES (doctype, sname, "
. "lname) VALUES('$sdocname', '" . $cat["sname"]
. "', '" . $cat["lname"] . "')";
$catInsRes = mysql_query($catInsStr);
if(!$catInsRes)
{
# Insert query didn't work
print("<SCRIPT TYPE='text/javascript'>\nalert('"
. "ERROR: Unable to clone " . $cat["sname"]
. " category from $doc2clone doctype.');\n"
. "</SCRIPT>\n");
} // END if
} // END while
} // END if
else
{
# D'oh! Query unsuccessful.
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: "
. "Couldn't retrieve details of the categories of the "
. "$doc2clone doctype.\\n\\nThis meant it was not possib"
. "le to clone them.');\n</SCRIPT>\n");
# Inform the administrator
$msgTxt = "An error ocurred during the creation of the new"
. " $sdocname document type. This new doctype was being "
. "cloned from the $doc2clone document type. When an "
. "attempt was made to retrieve details of the categories "
. "of the $doc2clone doctype, this attempt "
. "failed due to a query error. This meant that the "
. "categories could not be cloned, and therefore do not "
. "exist for the $sdocname document type.";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname Creation Error - "
."Categories Not Cloned", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END if
else
{
# D'OH! The query didn't work...We can't clone here, so we had
# better just let the user know, and terminate this cloning
# function.
print("<SCRIPT TYPE='text/javascript'>\nalert('ERROR: It was not"
. " possible to conduct a query to retrieve the submissions for "
. "the $doc2clone doctype.\\nThis meant that it was impossible "
. "to clone this doctype, and so the cloning process\\nfor the "
. "new $sdocname doctype was terminated.\\n\\nPlease inform the "
. "system administrator.');\n</SCRIPT>\n");
# Mail the administrator...
$msgTxt = "An error ocurred while attempting to create the "
. "$sdocname document type. The user had opted to clone this "
. "new document type from the $doc2clone document type. "
. "However, when this cloning was attempted, it was not possible"
. " to conduct a query on the sbmIMPLEMENT table in order to obtain"
. " details of the submissions belonging to that doctype.\n\nThi"
. "smeant that the cloning of this doctype was not possible, so "
. "infact the new $sdocname document type has not been cloned "
. "from any other doctypes.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$sdocname Creation Cloning Failure",
$msgTxt, "From: WebSubmit_Administrator");
} // END else
} // END function processCloningEDS()
//*************
function processDoctypeAdditionEDS($ldocname, $sdocname, $cd,
$md, $description, $docfi2, $doc2clone)
{
/*******************************************************************
This function deals with the actions to take after the form to
enter a new doctype has been submitted.
Author: Nicholas Robinson (Adapted from it's WebSubmit Manager
Counterpart (processCloning()), also
written by Nicholas Robinson).
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 19/12/2000
Last Modified: 12/04/2001
*******************************************************************/
# Ensure that the doctype code is in uppercase
$sdocname = strtoupper($sdocname);
# Make a test query to see if the current doctype code already
# exists in sbmDOCTYPE
$duplctRes = mysql_query("SELECT sdocname FROM sbmDOCTYPE WHERE "
. "sdocname = '" . ereg_replace("'", "\'", $sdocname) . "'");
if($duplctRes && mysql_num_rows($duplctRes) < 1)
{
# In this case, the doctype has not been duplicated (and the test
# query worked. We can therefore let them attemp to add the new
# doctype. We wouldn't bother if the test query didn't work, or
# there was already a doctype with this code.
# Insert the new doctype values into the
$qRes1str = "INSERT INTO sbmDOCTYPE (ldocname, sdocname, "
. "cd, md, description) VALUES "
. "('" . ereg_replace("'", "\'", $ldocname) . "', '"
. ereg_replace("'", "\'", $sdocname) . "', '$cd', '$md', '"
. ereg_replace("'", "\'", $description) . "')";
# Execute the above query string...
$qRes1 = mysql_query($qRes1str);
} // END if
# Now test to see if the query was successful...
if(!$qRes1) # If it wasn't...
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN>New Document Type Could Not Be Committed To "
. "Database.<BR>Ensure Doctype Code Is Not Duplicated."
. "</P>\n");
print("<TABLE ALIGN='center' CELLSPACING=0 CELLPADDING=0 BORDER"
. "=0>\n<TR>\n<FORM ACTION='index.php' METHOD='post'>\n<TD ALIGN"
. "='center'>\n<INPUT TYPE='button' VALUE='OK' onClick=\"submit"
. "();\">\n</TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // END if
else # If it was successful...
{
# Mail the administrators to inform of the new doctype addition
# Get the current date and time...
$dateDets = getdate();
# make a message string for the created doctype mail message...
$msgTxt = "Please be advised that the $sdocname document"
. " type was created in EDS on "
. $dateDets['weekday'] . " " . $dateDets['mday'] . " "
. $dateDets['month'] . " " . $dateDets['year']
. ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . "."
. "\n\nThis new doctype was ";
if($doc2clone != "NO_CLONE")
{
$msgTxt .= "cloned from the $doc2clone document type.";
}// END if
else
{
$msgTxt .= "not cloned from another document type.";
} // END else
$msgTxt .= "\n\nWebSubmit Administrator.";
# Mail the administrator(s) to inform them of the deletion...
mail(ADMIN_EMAIL, "$sdocname Document Type Created", $msgTxt,
"From: WebSubmit_Administrator");
# Print a message on the screen informing the user of the
# successful addition of the doctype...
print("<P STYLE=\"color: green; text-align: center; font-size:"
. " medium\">The <EM>$sdocname</EM> document type has been add"
. "ed to EDS.<BR>If the doctype was cloned however, it is "
. "entirely possible that the cloning process may not have been"
. "100% successful.<BR>If you receive any warning messages about"
. "submissions/pages/elements not cloning properly, do not "
. "ignore them.</P>\n");
# Now, if the user opted to clone another doctype, begin the
# process...
if($doc2clone != "NO_CLONE")
{
processCloningEDS($doc2clone, $sdocname);
} // END if
# Now that the process of adding the doctype is complete, we can
# simply redirect the page to the "documentEDS.php" page, so that
# the user can further view or configure the new doctype.
# Redirect the browser...
print("<FORM ACTION='documentEDS.php' METHOD='post' "
. "NAME='referForm'>\n<INPUT TYPE='hidden' NAME='doctyp"
. "e' VALUE='$sdocname'>\n</FORM>\n");
print("<SCRIPT TYPE='text/javascript'>\n"
. "setTimeout(\"document.referForm.submit();\", "
. "1000);\n</SCRIPT>\n");
} // END else
} // END function processDoctypeAdditionEDS()
function displayNewDoctypeForm($addDoctype)
{
global $ldocname, $sdocname, $cd, $md, $description, $docfi2, $doc2clone;
# Test to see what kind of call to the page this actually is...
if($addDoctype)
{
# This is a call to actually commit the details of the new
# doctype
unset($addDoctype);
# Begin the long process!
processDoctypeAdditionEDS($ldocname, $sdocname, $cd, $md,
$description, $docfi2, $doc2clone);
} // END if
else
{
# This is the first call to the page, so just display the input
# form
displayDoctypeFormEDS();
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayNewDoctypeForm($addDoctype);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/newFunc.php.wml b/modules/websubmit/web/admin/newFunc.php.wml
index c5d32679d..6859d1457 100644
--- a/modules/websubmit/web/admin/newFunc.php.wml
+++ b/modules/websubmit/web/admin/newFunc.php.wml
@@ -1,312 +1,312 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Add a function" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listfunctions"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*************************Function Declarations***********************/
function changePageFocusButton($action, $buttonTxt)
{
/**************************************************************
This function has the purpose of outputting a finish button to
allow the user to end the actions that they are carrying out.
The function basically outputs a form with only one input button,
which is clicked by the user to leave the current page. Clicking
the finish button sends the page focus to whatever page name is
passed as an argument to the function.
Created: 01/10/2000
Last Modified: 03/10/2000
**************************************************************/
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"$action\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"button\" VALUE='$buttonTxt' "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
} // END function changePageFocusButton($action, $buttonTxt)
//****************
function displayBlankForm()
{
/***************************************************************
This function will display a blank form that will allow the user
to enter a new function into the WebSubmit system. The function will
produce a form with 2 inputs - one for the function name, and
another for the function description.
Created: 02/10/2000
Last Modified: 03/10/2000
***************************************************************/
global $URLPATH;
// Add a description of the page...
print("<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 "
. "ALIGN=\"center\" BGCOLOR=\"#E0E0E0\">\n<TR><TD "
. "ALIGN=\"left\">\n<SMALL><I>Using this facility, it is"
. " possible to add new functions to the WebSubmit system. "
. "The first stage, is to enter the name and the "
. "description of the function into the form below, and "
. "then submit these details...</I>\n</SMALL>\n"
. "</TD>\n</TR>\n</TABLE>\n");
// Get a list of the fields in the sbmALLFUNCDESCR table
$fields = mysql_list_fields(DOCS_DATABASE, "sbmALLFUNCDESCR");
// Get the length of the function field...
$funcLen = mysql_field_len($fields, 0);
// Now get the length of the description field...
$descLen = mysql_field_len($fields, 1);
// Open an HTML form to allow the user to enter the details of
// the function name, and description fields...
print("<FORM METHOD=\"post\" ACTION=\"newFunc.php\">\n"
. "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>\n"
. "<TR>\n<TD ALIGN=\"right\"><STRONG><H4>"
. "function:</H4></STRONG></TD>\n"
. "<TD>&nbsp;&nbsp;</TD>\n<TD ALIGN=\"left\"><INPUT TYPE="
. "\"text\" NAME=\"thefunction\" SIZE=$funcLen>\n"
. "</TD>\n</TR>\n<TR>\n<TD ALIGN=\"right\"><STRONG>"
. "<H4>description:</H4></STRONG></TD>\n"
. "<TD>&nbsp;&nbsp;</TD>\n<TD ALIGN=\"left\">"
. "<INPUT TYPE=\"text\" NAME=\"description\" "
. " SIZE=60></TD>\n</TR>\n</TABLE>\n");
print("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 "
. "ALIGN=\"center\">\n"
. "<INPUT TYPE=\"hidden\" NAME=\"commitFunction\" "
. "VALUE=\"true\">\n"
. "<TR>\n<TD ALIGN=\"center\">\n<INPUT TYPE=\"button\" "
. "VALUE=\"SAVE DETAILS\" onClick=\"if(thefunction.value =="
. " '') { alert('A function name must be entered!'); }"
. " else if(confirm('Are you sure you wish to commit this"
. " function to WebSubmit?')) { submit(); "
. "}\">\n</TD>\n</FORM>\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD=\"post\">\n<TD>\n"
. "<INPUT TYPE=\"button\" VALUE=\"CANCEL\" "
. "onClick=\"submit();\">\n</TD>\n</FORM>\n</TR>\n"
. "</TABLE>\n");
}
//***************
function displayPage ()
{
global $commitFunction,$thefunction,$description,$tableSelected,$insertParam,$function,$newParam,$theParam,$updateFunDets;
// Test to see which type of call to this page this actually is, and
// take the appropriate action based upon this...
if($commitFunction)
{
// user entered the name &/or description for the new function, and has
// chosen to commit it to the database.
if($lockRes = mysql_query("LOCK TABLES sbmALLFUNCDESCR WRITE"))
{
$commitResult = mysql_query("INSERT INTO sbmALLFUNCDESCR
(function, description) VALUES ('$thefunction',
'$description')");
$unlockRes = mysql_query("UNLOCK TABLES");
if($commitResult)
{
// function has been successfully added to DB
// Send an email to the administrator, informing them
// that a new function has been added to the system..
$dateDets = getDate();
$messageText = "The $thefunction "
. "function was added to the submission system on " . $dateDets['weekday']
. " " . $dateDets['mday'] . " " . $dateDets['month'] . " "
. $dateDets['year'] . ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . ".\n\nWebSubmit Administrator.";
mail(ADMIN_EMAIL, "Warning: $thefunction Function Created",
$messageText, "From: WebSubmit_Administrator");
print("<H3 ALIGN=\"center\">The <EM>$thefunction</EM> "
. "Function Has Been Added</H3>\n<BR>\n");
// Now display all of the functions details, and offer the
// opportunity to add parameters to the function
makePageBody($thefunction, "newFunc.php");
changePageFocusButton("listFunctions.php", "FINISHED");
}
else
{
// unable to insert new function data
print("<DIV STYLE=\"color: navy; font-weight: bold; font-size:"
. " large; text-align: center\"><SPAN STYLE=\"color: red\">Error"
. ":</SPAN> Unable to commit function details.</DIV>\n<BR>\n");
}
}
else
{
// couldn't get write lock -> output error message.
print("<DIV STYLE=\"color: navy; font-weight: bold; font-size:"
. " large; text-align: center\"><SPAN STYLE=\"color: red\">Error"
. ":</SPAN> Unable to commit details.</DIV>\n<BR>\n");
displayBlankForm();
}
}
elseif($tableSelected || $insertParam)
{
// Add parameter to function
if(isset($tableSelected))
{
print("<H3 ALIGN=\"center\">The <EM>$function</EM>"
. " Function</H3>\n<BR>\n");
// Make the page, including the table of parameters
makePageBody($function, "newFunc.php");
changePageFocusButton("listFunctions.php", "FINISHED");
} // END if
elseif($insertParam)
{
// here, we actually commit the new paramater, and then recall
// the whole thing
if($lockRes = mysql_query("LOCK TABLES sbmFUNDESC WRITE"))
{
if ($newParam != "")
$insertParamRes = mysql_query("INSERT INTO sbmFUNDESC
VALUES('$function', '$newParam')");
else
$insertParamRes = mysql_query("INSERT INTO sbmFUNDESC
VALUES('$function', '$theParam')");
$unlockRes = mysql_query("UNLOCK TABLES");
// email admin to let them know that the parameter has been added
$dateDets = getDate();
$messageText = "A parameter was "
. "added to the new $function function on "
. $dateDets['weekday']
. " " . $dateDets['mday'] . " " . $dateDets['month'] . " "
. $dateDets['year'] . ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . ".\n\n"
. "If the function is to be used by any doctypes/actions, rows "
. "should be added for the relevant doctype in the "
. "relevant tables of the various parameters."
. "\n\nWebSubmit Administrator.";
mail(ADMIN_EMAIL, "Parameter Added To New $function "
. "Function",
$messageText, "From: WebSubmit_Administrator");
}
else
{
// Unable to lock table.
print("<DIV STYLE=\"color: navy; font-weight: bold; "
. "font-size: large; text-align: center\"><SPAN "
. "STYLE=\"color: red\">Error:</SPAN> Unable to commit"
. " updates.</DIV>\n<BR>\n");
}
print("<H3 ALIGN=\"center\">The <EM>$function</EM>"
. " Function</H3>\n<BR>\n");
// Display the page again, so more parameters can be added.
makePageBody($function, "newFunc.php");
changePageFocusButton("listFunctions.php", "FINISHED");
} // END elseif($insertParam)
} // END elseif($tableSelected || $insertParam)
elseif($updateFunDets)
{
// update the value of the description field
unset($updateFunDets);
// Place WRITE lock on the sbmALLFUNCDESCR table
if($lockRes = mysql_query("LOCK TABLES sbmALLFUNCDESCR WRITE"))
{
$updateDescRes = mysql_query("UPDATE sbmALLFUNCDESCR SET
description = '$description' WHERE function
= '$function'");
$unlockRes = mysql_query("UNLOCK TABLES");
if(!$updateDescRes)
{
// unable to update the value of description for some reason, and the
// user should be informed of this
print("<SCRIPT TYPE=\"text/javascript\">alert('ERROR:\\n\\n"
. "Unable to update value of description for $function\\n"
. "function in sbmALLFUNCDESCR table.\\n\\n"
. "Please inform administrator.</SCRIPT>\n");
} // END if
mysql_free_result($updateDescRes);
} // END if
else
{
// Couldn't lock table. Output error message.
print("<DIV STYLE=\"color: navy; font-weight: bold; font-size:"
. " large; text-align: center\"><SPAN STYLE=\"color: "
. "red\">Error:</SPAN> Unable to retrieve information.</DIV>\n"
. mysql_error()."<BR>\n");
}
print("<H3 ALIGN=\"center\">The <EM>$function</EM>"
. " Function</H3>\n<BR>\n");
makePageBody($function, "newFunc.php");
changePageFocusButton("listFunctions.php", "FINISHED");
}
else
{
// Display a blank form into which the details of the function can
// be entered by the user
displayBlankForm();
}
}
/**********************Start of main script***************************/
// Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
// Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/newSubmissionEDS.php.wml b/modules/websubmit/web/admin/newSubmissionEDS.php.wml
index b1b34924f..d62984ec2 100644
--- a/modules/websubmit/web/admin/newSubmissionEDS.php.wml
+++ b/modules/websubmit/web/admin/newSubmissionEDS.php.wml
@@ -1,1018 +1,1018 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Create a new action for the <i><protect><?print $doctype;?></protect></I> document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/*********************Function Declarations***************************/
function sendToDocDets($doctype)
{
/*******************************************************************
For many situations in the process of creating a new submission,
it is necessary to redirect the browser focus to the page that
displays the details of a doctype and it's submissions. For this
reason, this function was created. It simply saves on the
duplication of this code.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 12/12/2000
Last Modified: 12/12/2000
*******************************************************************/
# We can now redirect the browser to the the page showing the
# details of this document type & its submissions
print("<FORM ACTION='documentEDS.php' METHOD='post' "
. "NAME='referForm'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "</FORM>\n");
print("<SCRIPT LANGUAGE=\"JavaScript\">\n"
. "setTimeout(\"document.referForm.submit();\", 1000);\n"
. "</SCRIPT>\n");
} // END function sendToDocDets($doctype)
//*************
function addAct($doctype, $formsAction,
$actSelected = 0, $subToAdd = 0)
{
/*****************************************************************
This function has the task of displaying the forms that allow the
user to add a submission to a document type. The function has
been built to know what kind of call to the page it is by means
of hidden inputs in the forms it makes. If this is the first
call to the function (i.e. a call whereby a user must select an
action to add), it only displays the actions that are available
for adding to the document. Otherwise, it also displays the
other document types that have this submission, and offers the
user the chance to clone the submission from one of these other
document types. It also displays the button that is clicked to
submit the submission addition at this point.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
Created: 07/12/2000 (ammended from it's WebSubmit Manager add
a new action to a doctype
counterpart)
Last Modified: 15/03/2001
****************************************************************/
# Make a title for the page, and indeed some sort of informative
# introduction paragraph to explain the purpose of the page to the
# user...
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD ALIGN='center'>\n"
. "<P STYLE=\"color: blue; text-align: center; font-size: small; "
. "font-weight: bold\">The form below is used to add a new "
. "submission to the <EM>$doctype</EM> document type.<BR>The "
. "addition of the new submission is only allowed if it is not "
. "already part of the <EM>$doctype</EM> document type.<BR><BR>It "
. "is also possible to clone a submission from the same submission "
. "as it appears under another doctype.<BR>To do this, the doctype "
. "whose submission is to be cloned must be chosen from the "
. "relevant list box.</P>\n</TD>\n</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# First, output a table to encapsulate the table that will contain
# the list-boxes that allow the user to add a new submission to a
# doctype
print("<TABLE WIDTH='90%' CELLSPACING=0 CELLPADDING=0 BORDER=1 "
. "ALIGN='center' BGCOLOR='#ADD8E6'>\n<TR>\n<TD ALIGN='left'>\n"
. "Select an action to add from the list. If you wish to clone "
. "another action, select the doctype whose action is to be "
. "cloned<BR>\n");
# Now make a unique list of all of the actions in the sbmIMPLEMENT
# table that the current document type already has...
$queryResult = mysql_query("SELECT actname FROM sbmIMPLEMENT WHERE "
. "docname = '$doctype' ORDER BY actname");
if($queryResult)
{
# If this query was successful, continue with the process
# Put the results of the above query into a 2d array...
$gotSubs = resToArray($queryResult);
# Free the resultset pointer occupied by the above query result
mysql_free_result($queryResult);
# Now, conduct another SQL query to get a distinct list of all
# actions in EDS that the current doctype does not have...
# First get the size of the array holding the actions that the
# doctype already has (i.e. the number of actions it already
# has)...
$numActions = sizeof($gotSubs);
$selectStr = "SELECT distinct(sactname), lactname FROM sbmACTION";
# If the current doctype has actions...
if($numActions > 0)
{
$selectStr .= " WHERE sactname != '" . $gotSubs[0][0] . "'";
for($i = 1; $i < $numActions; $i++)
{
$selectStr .= " AND sactname != '" . $gotSubs[$i][0] . "'";
} // END for
} // END if
$selectStr .= " ORDER BY sactname";
# Open a table, in which to place the inputs for adding a new
# submission type
print("<BR><TABLE BORDER=1 BGCOLOR='#FFFFCC' ALIGN='center' "
. "WIDTH='85%' CELLSPACING=0 CELLPADDING=0>\n<TR>\n");
# Execute our 2nd query...
$scndRes = mysql_query($selectStr);
if($scndRes)
{
# Now, we can display the controls for adding the new
# submission type to the current document type...
print("<FORM ACTION='$formsAction' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='actSelected' VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<TD ALIGN='center' VALIGN='top' WIDTH='50%'>\n"
. "<H5>Select an action to add to $doctype:</H5>\n"
. "<BR>\n");
# Now make the select list to choose the action from...
print("<SELECT NAME='subToAdd'"
. " onChange=\"if(this.options[this.selectedIndex].value !="
. " 'NO_SUB') { submit(); }\">\n"
. "<OPTION VALUE='NO_SUB'>Select...</OPTION>\n");
while(list($sub, $nom) = mysql_fetch_row($scndRes))
{
print("<OPTION VALUE='" . ereg_replace("'", "&#39;",
htmlspecialchars($sub)) . "'");
if($actSelected && $sub == $subToAdd)
{
print(" SELECTED");
} // END if
print(">" . ereg_replace("'", "&#39;",
htmlspecialchars($sub))
. " (" . ereg_replace("'", "&#39;",
htmlspecialchars($nom))
. ")</OPTION>\n");
} // END while
# Close up the SELECT list, and the current table cell
print("</SELECT>\n<BR>\n&nbsp;</TD>\n</FORM>\n");
# Make a new form...
print("<FORM ACTION='$formsAction' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE="
. "'$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='subToAdd' VALUE="
. "'$subToAdd'>\n"
. "<INPUT TYPE='hidden' NAME='reqToAdd' VALUE="
. "'true'>\n");
print("<TD ALIGN='center' WIDTH='50%' BGCOLOR='#FFFFCC'>\n");
if($actSelected) # If the call to the script is to offer
# the option to clone a submission...
{
# In this case, we can make a drop-down list of all of the
# other submissions of the same type for a different
# document type. The user will then be able to choose the
# submission to clone...
# Query EDS to obtain this list of submissions...
$docsQuery = mysql_query("SELECT docname, subname FROM "
. "sbmIMPLEMENT WHERE actname = '$subToAdd'");
if($docsQuery)
{
if(mysql_num_rows($docsQuery) < 1)
{
print("<H4 STYLE=\"text-align: center; "
. "background-color:"
. " transparent\">No doctypes use this action"
. "</H4>\n");
} // END if
else
{
# Output a description for the input...
print("<H5>"
. "Clone the submission from that of another "
. "doctype?</H5>\n");
# Open a select list...
print("<SELECT NAME='toClone' SIZE=5>\n"
. "<OPTION SELECTED VALUE='NO_CLONE'>NO CLONE"
. "</OPTION>\n");
# Fill the list with values...
while(list($doc, $subnm) =
mysql_fetch_row($docsQuery))
{
print("<OPTION VALUE='"
. ereg_replace("'", "&#39;",
htmlspecialchars($doc))
. "'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($doc))
. "</OPTION>\n");
} // END while
print("</SELECT>\n");
} // END else
} // END if
# Close up the cell that was used to contain the drop down
# list of doctypes to clone...
print("</TD>\n</TR>\n</TABLE>\n");
# Now, offer a submit button to allow the user to actually
# submit their update.
print("<BR>\n<TABLE ALIGN='center' WIDTH='100%' BORDER=0"
. " CELLSPACING=0 CELLPADDING=0>\n<TR><TD ALIGN='center'"
. ">\n<INPUT TYPE='button' VALUE='ADD SUBMISSION' "
. "onClick=\" if(confirm('Warning:\\n\\nYou are about to"
. " add a submission to the $doctype document type.\\n"
. "\\nAre you sure you wish to undertake this action?'))"
. " { submit(); }\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END if
else
{
# If the user has not yet selected an action to add,
# simply leave the cell for the action to clone blank in
# anticipation of the action to add being selected
print("&nbsp;</TD>\n</TR>\n</TABLE>\n<BR>\n</FORM>\n");
} // END else
} // END if
} // END if
else
{
# In this case, the query to retrieve the list of actions that
# the current doctype does not have submissions for has failed.
# This means that we must terminate processing, as we cannot risk
# allowing impurities to get into the EDS database
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable To Retrieve Data Of <EM>$doctype</EM> Doctypes"
. " Submissions.<BR>Submission Addition Impossible</P>\n");
} // END else
# Now that we have made the main part of the interface for adding a
# new action, we can close up the table, as this part is finished...
print("</TD>\n</TR>\n</TABLE>\n");
# We can now add a "CANCEL" button for the user
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now make the button.
print("<TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0 WIDTH='100%' "
. "ALIGN='center'>\n<TR>\n<FORM ACTION='documentEDS.php' METHOD="
. "'post'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>"
. "<TD ALIGN='center'>\n<INPUT TYPE='button' VALUE='CANCEL' onCli"
. "ck=\"submit();\"></TD>\n</FORM>\n</TR>\n</TABLE>\n");
} // END function addAct()
//*************
function newSubmInputForm($subToAdd, $doctype)
{
/*******************************************************************
This function is called when the user has chosen to add a new
submission type to a given document type, but has chosen not to
clone this new submission from the same submission as it appears
for another doctype. In this situation, it is necessary to
present the user with an input form that contains all of the
fields that are required for inputting the details of the new
submission for the given doctype. The user can then fill in this
form, and submit it to continue with the process.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 08/12/2000 (Modified from actInputForm, a
function in the WebSubmit Manager that
is used for adding a new action
to a doctype without cloning
another).
Last Modified: 08/12/2000
*******************************************************************/
# Get a list of columns in the sbmIMPLEMENT table...
$columns = mysql_list_fields(DOCS_DATABASE, "sbmIMPLEMENT");
print("<FORM ACTION='newSubmissionEDS.php' METHOD='post'>\n"
. "<TABLE ALIGN='center' CELLPADDING=0 BORDER=0 CELLSPACING=0 "
. "WIDTH='100%'>\n");
# Now we can begin to make the input form in which the details of
# the new submission can be entered...
print("<P STYLE=\"font-size: large; color: navy; text-align: "
. "center\">Enter Details For The <EM>$subToAdd"
. "$doctype</EM> Submission</P>\n");
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">You have "
. "chosen to create the <EM>${subToAdd}$doctype</EM> "
. "submission without cloning another submission.<BR>Please "
. "enter the description details for this new submission type"
. " in the form below and click <EM>SAVE</EM>.<BR><BR>If you "
. "have chosen this option erroneously, click cancel and no "
. "new submission will be created.</P>\n</TD>\n</TR>\n"
. "</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Get the date, so that it can be committed for the modification
# date field (md) and the creation date field (cd)...
$theDate = makeEDSmdDate();
# Now make a table in which to enter the submission type dets
# Make some readonly fields in which the details of fields that
# should not be set by the user can be displayed...
print("<FORM ACTION='newSubmissionEDS.php' METHOD='post'>"
. "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 ALIGN='center"
. "' WIDTH='100%'>\n<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN='right'"
. " WIDTH='20%'>\nDoctype Code:&nbsp;</TH>\n<TD ALIGN='left' "
. "BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT TYPE='readonly' NAME='"
. "docname' VALUE='$doctype'>\n</TD>\n</TR>\n<TR>\n<TH BGCOLOR='"
. "#D3DCE3' ALIGN='right' WIDTH='20%'>\nAction Code:&nbsp;</TH>"
. "\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT "
. "TYPE='readonly' NAME='actname' VALUE='$subToAdd'>\n</TD>\n</TR>"
. "\n<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>\n"
. "Submission Name:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC'"
. " WIDTH='80%'><INPUT TYPE='readonly' NAME='subname' VALUE='"
. "${subToAdd}$doctype'>\n</TD>\n</TR>\n<TR>\n<TH BGCOLOR='#D3DCE3'"
. " ALIGN='right' WIDTH='20%'>\nNumber of Pages:&nbsp;</TH>\n<TD "
. "ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT TYPE='"
. "readonly' NAME='nbpg' VALUE='0'>\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>\nCreation Date:"
. "&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><"
. "INPUT TYPE='readonly' NAME='cd' VALUE='$theDate'>\n</TD>\n</TR>"
. "\n<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>\nModifi"
. "cation Date:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFCC' WIDT"
. "H='80%'><INPUT TYPE='readonly' NAME='md' VALUE='$theDate'>\n"
. "</TD>\n</TR>\n");
# Now that we have displayed the non-user-editable fields, we can
# display a set of free input text fields in which the user can
# enter their data.
print("<TR>\n<TH BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\n"
. "On Submission Page:&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' "
. "BGCOLOR='#FFFFCC'>\n<SELECT NAME='displayed'>"
. "<OPTION value='Y'>YES<OPTION value='N'>NO</SELECT>\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nButton Order:"
. "&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n"
. "<INPUT TYPE='text' NAME='buttonorder' SIZE=40>\n"
. "</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nStatus Text:&nbsp;"
. "</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n<INPUT "
. "TYPE='text' NAME='statustext' SIZE=40 "
. ">\n</TD>\n</TR><TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nGroup Number:&nbsp;"
. "</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n<INPUT "
. "TYPE='text' NAME='level' SIZE=40 "
. " value='0'>\n</TD>\n</TR><TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nScore:&nbsp;"
. "</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n<INPUT "
. "TYPE='text' NAME='score' SIZE=40 "
. " value='0'>\n</TD>\n</TR><TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nStarting Page Number:&nbsp;"
. "</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n<INPUT "
. "TYPE='text' NAME='stpage' SIZE=40 "
. " value='1'>\n</TD>\n</TR><TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>\nEnd Text:&nbsp;"
. "</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFCC'>\n<INPUT "
. "TYPE='text' NAME='endtxt' SIZE=40 "
. " value=''>\n</TD>\n</TR>\n</TABLE>\n");
# We have now created the visible inputs of the form, so we must add
# any hidden inputs that are required, and display the set of
# buttons that are required to submit, reset, cancel the submission
# addition action.
print("<INPUT TYPE='hidden' NAME='addSansClone' VALUE='true'>\n"
. "<TABLE ALIGN='center' BORDER=0 CELLSPACING=1 CELLPADDING=1"
. ">\n<TR>\n<TD ALIGN='right'>\n<INPUT TYPE='button' "
. "VALUE='SAVE' onClick=\""
. "if(confirm('Really Add This Submission?')) { submit() }\">"
. "</TD>\n<TD ALIGN='center'>\n<INPUT TYPE='button' VALUE='RESET' "
. "onClick=\"reset();\"></TD>\n</FORM><FORM ACTION='documentEDS."
. "php' METHOD='post'>\n<INPUT TYPE='hidden' NAME='doctype' VALUE='"
. "$doctype'><TD ALIGN='left'>\n<INPUT TYPE='button' VALUE='CANCEL'"
. "onClick=\"submit();\"></TD>\n</TR>\n</FORM>\n</TABLE>\n");
} // END function newSubmInputForm($subToAdd, $doctype)
//***************
function processAdditionSansClone($docname, $actname, $subname,
$nbpg, $cd, $md, $displayed, $buttonorder, $statustext, $level, $score, $stpage, $endtxt)
{
/*******************************************************************
This function has the task of adding a new submission to a given
EDS document type, without cloning the submission from another
doctype. The function is passed several arguments by the calling
function. The first of these arguments is the $link variable.
The second is the $docname variable. The third is the $actname
value. The fourth is the $subname value. The fifth is the $nbpg
value. The sixth is the $cd value. The seventh is the $md
value. The eighth is the $level value. The nineth is the
$buttonorder value. The tenth is the $statustext value. Most of
these values can be commited to the sbmIMPLEMENT table to become
part of the new submission types details.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 08/12/2000 (Adapted from it's
counterpart for adding a
new action to the WebSubmit
database)
Last Modified: 25/01/2001
*******************************************************************/
# Ensure that the value of level is in upper case...
$displayed = strtoupper($displayed);
# Make a query string...
$newSubQStr = "INSERT INTO sbmIMPLEMENT (docname, actname,"
. " displayed, subname, nbpg, cd, md, buttonorder, statustext, level, score, stpage, endtxt) "
. "VALUES('$docname', '$actname', '$displayed', '$subname', '$nbpg', "
. "'$cd', '$md', '$buttonorder', '$statustext', '$level', '$score', '$stpage', '$endtxt')";
# Now, we can actually execute the new query, hence adding the new
# submission to the current doctype...
$addSubRes = mysql_query($newSubQStr);
# Take the relevant action depending upon whether or not the query
# was executed successfully
if($addSubRes)
{
# In this case, the query was executed successfully
# Update the doctype modification date in the sbmDOCTYPE table
updateEDSDOCTYPEmd($docname, $md);
# Now output an alert to state that the new submission has been
# entered, and that the user must add their own actions, pages,
# etc to it.
print("<SCRIPT TYPE='text/javascript'>alert('The $subname "
. "submission has been added to the $docname doctype.\\n"
. "It was not cloned from any other submission, so it will"
. " be necessary\\nto manually add pages and elements to it."
. "');</SCRIPT>\n");
# Now, we can email the administrator to let them know of this
# new submission addition for the current doctype.
$msgTxt = "The $subname submission has been added to the "
. "$docname document type. It was not cloned from another "
. "submission.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "EDS: $subname Submission Added", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
else
{
# In this case, the query failed, and therefore no new submission
# has been created for the current doctype. In this case, we can
# simply display the error, and redirect the browser to
# "documentEDS.php", where the details of the current doctype
# will be displayed.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable to commit the details of the new submission "
. "to the sbmIMPLEMENT table.<BR>Please Inform System Administrator"
. ".</P>\n");
} // END else
# redirect the browser to documentEDS.php...
sendToDocDets($docname);
} // END function processAdditionSansClone()
//****************
function processSubmissionCloning($doctype, $toClone, $subToAdd)
{
/*******************************************************************
This function has the 'broad task' of processing the cloning of a
given submission for a given doctype, from another doctype.
Effectively, the function is passed 4 variables. The first
variable is $link. This contains a link to the MySQL database
server. The second variable is $doctype. This variable contains
the unique code of the document that is to have the cloned
submission added to it. The third variable is $toClone. This
variable contains the unique code of the doctype that is to have
one of its actions cloned. The fourth variable is the $subToAdd
variable. This variable contains the unique code of the
submission that is to be added (and hence cloned) to the doctype
referenced by the contents of $doctype.
Author: Nicholas Robinson
Email: Nicholas.Robinson@cern.ch
ca8nro@yahoo.co.uk
Created: 11/12/2000 (This functions has
been adapted from
its WebSubmit counterpart
for cloning actions)
Last Modified: 25/01/2001
*******************************************************************/
# The first step is to get the details of the submission to be
# cloned from the doctype to which it belongs, out of the
# sbmIMPLEMENT table.
$subQStrng = "SELECT * FROM sbmIMPLEMENT WHERE actname = '$subToAdd'"
. " AND docname = '$toClone'";
# Now that we have made the query string, we can execute the query
# to get the details of this given submission for the given doctype.
$subQRes = mysql_query($subQStrng);
# Ensure that the query executed properly, as if it was not
# executed, we don't want to begin committing values to the DB and
# corrupting it.
if($subQRes)
{
# In this case, the query has executed fine
if(mysql_num_rows($subQRes) > 0)
{
# In this case, there are rows for the given submission type
# for the given doctype, and we can proceed with the cloning.
# Read the information from the query into an array...
$cloneSubDets = mysql_fetch_array($subQRes);
# Now that we have this information from the sbmIMPLEMENT table,
# we can commit the same information, but for the doctype that
# the submission is to be added to, into the sbmIMPLEMENT table.
# It is worth noting here that if a submission that is to be
# added appears twice for a doctype from whom it is to be
# cloned, (this should not happen if DB consistency is good),
# this script will clone the first ocurrence of this
# submission. This should not matter for the rest of the
# action cloning, such as the functions etc).
# Get the date, so that it can be committed for the
# modification date field (md) and the creation date field
# (cd)
$theDate = makeEDSmdDate();
# Now make the insert query string.
$submInsStr = "INSERT INTO sbmIMPLEMENT (docname, actname,"
. " displayed, subname, nbpg, cd, md, buttonorder, statustext, level, score, stpage, endtxt) "
. "VALUES('$doctype', '$subToAdd', '" . $cloneSubDets["displayed"]
. "', '${subToAdd}$doctype', '" . $cloneSubDets["nbpg"]
. "', '$theDate', '" . "$theDate', '"
. $cloneSubDets["buttonorder"] . "', '"
. $cloneSubDets["statustext"] . "', '"
. $cloneSubDets["level"] . "', '"
. $cloneSubDets["score"] . "', '"
. $cloneSubDets["stpage"] . "', '"
. $cloneSubDets["endtxt"] . "')";
# Now execute the query to insert this data into the database
$submInsRes = mysql_query($submInsStr);
# Test it worked...
if($submInsRes)
{
# Cool...the query worked, and we can proceed to clone all
# of the submissions details.
# Free the result set of the $submInsRes query, as it is no
# longer needed. We can also now begin to clone all of the
# details for all of the pages and elements of this new
# submission...
mysql_free_result($submInsRes);
# Now, we need to query the field table, and obtain the
# details of all elements that belong to the given
# submission (that to be added) of the doctype from which
# it is to be cloned...
$elmntsQStr = "SELECT * FROM sbmFIELD WHERE subname = '"
. "${subToAdd}$toClone' ORDER BY pagenb, fieldnb";
$elmntsQRes = mysql_query($elmntsQStr);
# Ensure this query worked...
if($elmntsQRes)
{
# The query to retrieve all elements executed fine
# Now, for each of the elements, change the subname to
# reflect that of the new submission, the creation date
# and modification date to the current date (that when
# the new submission was created - today!!). Then
# commit the new details (of the new element for the new
# submission to the EDS database into the sbmFIELD table.
while($element = mysql_fetch_array($elmntsQRes))
{
$eleInsStr = "INSERT INTO sbmFIELD (subname, pagenb, "
. "fieldnb, fidesc, fitext, level, sdesc, checkn, "
. "cd, md, fiefi1, fiefi2) VALUES('"
. "${subToAdd}$doctype', '" . $element["pagenb"]
. "', '" . mysql_escape_string($element["fieldnb"]) . "', '"
. mysql_escape_string($element["fidesc"]) . "', '" . mysql_escape_string($element["fitext"])
. "', '" . mysql_escape_string($element["level"]) . "', '"
. mysql_escape_string($element["sdesc"]) . "', '" . mysql_escape_string($element["checkn"])
. "', '$theDate', '$theDate', '" . mysql_escape_string($element["fiefi1"])
. "', '" . mysql_escape_string($element["fiefi2"]) . "')";
# Now execute the above query string...
$eleInsRes = mysql_query($eleInsStr);
# Test that the query worked...
if($eleInsRes && mysql_affected_rows($eleInsRes) < 1)
{
# In this case, the query was successful, and we
# can delete the query result pointer to stop
# memory wastage...
mysql_free_result($eleInsRes);
} // END if
else
{
# In this case our query to add the element has
# failed. We must therefore output an alert for
# our users benefit, and then inform the
# administrator that an element could not be
# commited. We can however carry on cloning the
# other elements.
print("<SCRIPT TYPE=\"text/javascript\">alert('"
. "ERROR: Unable to commit a value for the "
. $element["fidesc"] . " element\\nwhich should"
. " appear in position " . $element["fieldnb"]
. " of page " . $element["pagenb"] . "\\nfor "
. "the new ${subToAdd}$doctype submission.\\n\\n"
. "Please inform the system administrator.');"
. "</SCRIPT>\n");
# Now make a message to send to the administrator
$msgTxt = "An error ocurred when a new submission"
. " was added to the $doctype document type. Thi"
. "s new submission is the ${subToAdd}$doctype "
. "submission and was cloned from the $toClone "
. "document type.\n\nIt was not possible to add "
. "the " . $element["fidesc"] . " element which "
. "should appear in position "
. $element["fieldnb"] . " on page "
. $element["pagenb"] . " of this new submission."
. "\n\nThe cloning of the rest of this submission"
. " was however continued, which means that there"
. " may be problems with elements being out of or"
. "der on this page of the submission.\n\nYou sho"
. "uld examine this and correct any problems imme"
. "diately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: Unable to Add "
. $element["fidesc"] . " Element "
. "to ${subToAdd}$doctype", $msgTxt,
"From: WebSubmit_Administrator");
} // END else
} // END while
# Now we also clone the functions used in this submission
$res = mysql_query("SELECT action,function,score,step FROM sbmFUNCTIONS WHERE action='$subToAdd' and doctype='$toClone'");
while ($row = mysql_fetch_array($res))
{
$res2 = mysql_query("SELECT 1 from sbmFUNCTIONS where action='".$row['action']."' and doctype='$doctype' and function='".$row['function']."' and score='".$row['score']."' and step='".$row['step']."'");
if (mysql_num_rows($res2) < 1)
mysql_query("INSERT INTO sbmFUNCTIONS (action,doctype,function,score,step) VALUES ('".$row['action']."','$doctype','".$row['function']."','".$row['score']."','".$row['step']."')");
}
#clone parameters
$res = mysql_query("select * from sbmPARAMETERS where doctype='$toClone'");
while ($row = mysql_fetch_array($res))
{
$res2 = mysql_query("select * from sbmPARAMETERS where doctype='$doctype' and name='".$row['name']."'");
if (mysql_num_rows($res2) < 1)
mysql_query("insert into sbmPARAMETERS(doctype, name, value) values ('$doctype','".$row['name']."','".$row['value']."')");
}
# Now that the submission has been cloned, it is
# possible to present the user with a message saying
# this, and redirect their browser to the
# "documentEDS.php" page so that they can look into the
# details of this new submission, and change anything
# that they might feel appropriate. A javascript alert
# should also be displayed however, advising them to
# check all of the values for their new submission and
# ensure that they are correct. We can then mail the
# administrator to let them know that a new submission
# has been created, and that it was cloned from another
# doctype.
print("<SCRIPT TYPE=\"text/javascript\">alert('The "
. "${subToAdd}$doctype has been created. However, "
. "it should be noted that\\nit may not have been poss"
. "ible to clone all elements for this submission,\\n"
. "and you should check that the new submission contai"
. "ns all of the desired elements.\\nYour browser has "
. "been directed to the page where you can do this.');"
. "</SCRIPT>\n");
# Now mail the administrator...
$msgTxt = "The ${subToAdd}$doctype submission type has"
. " been created for the $doctype document type. This"
. " new submission was cloned from the $toClone docume"
. "nt type.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "${subToAdd}$doctype Submission Added"
. " to $doctype", $msgTxt, "From: WebSubmit_Administrator");
# Now redirect the browser to documentEDS.php
sendToDocDets($doctype);
} // END if
else
{
# Oh dear! We were unable to retrieve the details of
# any elements belonging to the given submission to be
# cloned. We had better terminate the new submission
# addition process here, warn the user that the details
# of the new submission have been added to sbmIMPLEMENT but
# we couldn't get the element details from sbmFIELD, and
# then we should also mail the administrator to inform
# them of this problem.
print("<SCRIPT TYPE=\"text/javascript\">alert('"
. "ERROR: It was not possible to retrieve details for "
. "any of the elements of the ${subToAdd}$toClone "
. "submission from the sbmFIELD table.\\nThis means "
. "that none of the pages or elements for this "
. "submission could be cloned.\\nThere was however a "
. "row commited to the sbmIMPLEMENT table for the new "
. "${subToAdd}$doctype submission.\\nThis means that "
. "the submission will now exist for the new doctype, "
. "but\\nit will be necessary to manually add elements "
. "to the pages.');</SCRIPT>\n");
# Now make a message to send to the administrator
$msgTxt = "An error ocurred when a new submission"
. " was being added to the $doctype document type. Thi"
. "s new submission is the ${subToAdd}$doctype "
. "submission and was to be cloned from the $toClone "
. "document type.\n\nHowever, it was not possible to "
. "retrieve the details of the submission pages and "
. "elements of the $toClone document type from the "
. "sbmFIELD table. This means that it has not been "
. "possible to clone these details. An entry was "
. "however made for the new doctype in the new "
. "submission (${subToAdd}$doctype) in the sbmIMPLEMENT "
. "table, so this new submission will exist, but it "
. "will have empty pages.\n\nThis problem should be "
. "examined, and any inconsistencies in the data for "
. "this new submission should be corrected.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: ${subToAdd}${doctype}: Unable"
. "$toClone Details For Cloning", $msgTxt, "From: "
. "WebSubmit_Administrator");
# Now redirect the browser to documentEDS.php
sendToDocDets($doctype);
} // END else
# Update the doctype modification date in the sbmDOCTYPE table
# so that the actual doctype reflects having been modified
updateEDSDOCTYPEmd($doctype, $theDate);
} // END if
else
{
# In this case, our query to add the details of this newly
# cloned submission failed, so we must output an alert to
# signify this to the user, email the administrators to let
# them know, and terminate the addition of the new
# submission.
print("<SCRIPT TYPE=\"text/javascript\">alert('"
. "ERROR: It was not possible to commit details for "
. "the new ${subToAdd}$doctype submission to the "
. "sbmIMPLEMENT table.\\nThis means that the new "
. "submission could not be created.\\n\\nPlease inform"
. " the system administrator of this problem.');</SCRI"
. "PT>\n");
# Now make a message to send to the administrator
$msgTxt = "An error ocurred when a new submission"
. " was being added to the $doctype document type. Thi"
. "s new submission is the ${subToAdd}$doctype "
. "submission and was to be cloned from the $toClone "
. "document type.\n\nHowever, it was not possible to "
. "commit the details of this new submission to the "
. "sbmIMPLEMENT table. This means that it was not possibl"
. "e to create this new submission.\n\nThis problem "
. "should be examined and corrected ASAP.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: Unable to Commit "
. "${subToAdd}$doctype Submission Details", $msgTxt,
"From: WebSubmit_Administrator");
# Now redirect the browser focus to documentEDS.php
sendToDocDets($doctype);
} // END else
} // END if
} // END if
else
{
# In this case the query to retrieve details of the submission to
# be cloned has failed. We must therefore alert the user and
# redirect the browser.
print("<SCRIPT TYPE=\"text/javascript\">alert('ERROR: It was not"
. " possible to retrieve the details of ${subToAdd}$toClone "
. "submission from the sbmIMPLEMENT table.\\nThis meant that it "
. "could not be cloned, and hence no new submission addition for"
. "\\nthe $doctype document type has been created.');"
. "</SCRIPT>\n");
# Now redirect the browser to the documentEDS.php page
sendToDocDets($doctype);
} // END else
} // END function processSubmissionCloning()
function displayNewSubmissionForm($doctype,$actSelected,$addSansClone,$reqToAdd)
{
global $toClone,$subToAdd,$actSelected,$docname, $actname, $subname,$nbpg, $cd, $md, $displayed, $buttonorder, $statustext, $level, $score, $stpage, $endtxt;
if($actSelected)
{
# In this case, the submission to be added to the current doctype
# has been selected. This means that the offer to clone the same
# submission as it appears for another doctype can now be
# presented to the user...
addAct($doctype, "newSubmissionEDS.php", $actSelected,
$subToAdd);
# We can now also display a cancel button.
} // END if
elseif($addSansClone)
{
# In this case, the user has chosen the submission that they wish
# to add to the current document type, but they have also opted
# not to clone the submission from the same submission as it
# appears for another doctype. This means that we can now build
# a query string, and commit the details of the new submission
# for the current doctype to the database.
processAdditionSansClone($docname, $actname, $subname,
$nbpg, $cd, $md, $displayed, $buttonorder, $statustext, $level, $score, $stpage, $endtxt);
} // END elseif
elseif($reqToAdd)
{
# In this case, the user has chosen to add the new submission,
# with or without cloning it from another doctype. If the choice
# is to clone the submission from another doctype, then we can
# now process the cloning, and commit the relevant values to the
# database.
# Otherwise, if the user has opted to create the new submission
# without cloning it from another doctype, we can display a form
# in which the user will need to enter the relevant details of
# the new submission.
if($toClone == "NO_CLONE")
{
# In this case, the user does not wish to clone the new
# submission type from another doctype. This means that we
# must present them with a form in which to enter the details
# of the submission type.
newSubmInputForm($subToAdd, $doctype);
} // END if
elseif($toClone)
{
# In this case, the user has opted to clone the new submission
# from the same submission under another doctype. This means
# that it is possible to process the cloning of this new
# submission, and then redirect the browser to the
# "documentEDS.php" page so that the user can see the details
# of the new submission and explore them.
processSubmissionCloning($doctype, $toClone,
$subToAdd);
} // END elseif
else
{
# In this case, the user has erroneously failed to select the
# option of either cloning or not, and we must therefore just
# assume that they do not wish to clone anything, and treat
# the addition as a none clone submission addition...
newSubmInputForm($subToAdd, $doctype);
} // END else
} // END elseif
else
{
# This is the default call to the page. It is the first call to
# the page, whereby we simply need to display the first part of
# the forms (that which lists all of the actions that it is legal
# to add as submission types for the current doctype).
addAct($doctype, "newSubmissionEDS.php");
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1]. "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayNewSubmissionForm($doctype,$actSelected,$addSansClone,$reqToAdd);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/pageDetsEDS.php.wml b/modules/websubmit/web/admin/pageDetsEDS.php.wml
index 68b7a1018..6d18feb76 100644
--- a/modules/websubmit/web/admin/pageDetsEDS.php.wml
+++ b/modules/websubmit/web/admin/pageDetsEDS.php.wml
@@ -1,1177 +1,1177 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Details of Submission Page <protect><?print "$pageNumber of $subname"?></protect>" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function makeSubmPgePrev($res, $pageNumber)
{
/******************************************************************
This function has the task of creating and displaying the table
that contains a preview of the elements that make up a submission
page. The function is passed a result pointer that points to a
given submission pages contents. For each row of this pointer
(which indicates a given element that appears on the relevant
page), this function retrieves the configuration information for
this element from the sbmFIELDDESC table, and uses this information
to display the element.
******************************************************************/
# Open an outer table, in which another table will be placed. The
# inner table will contain the preview of the appearance of the page
# with its current elements can be shown...
print("<P STYLE=\"color: navy; font-size: large; text-align: "
. "left\">Page Preview\n<br>&nbsp;");
print("<TABLE WIDTH='100%' ALIGN='center' BORDER=1 CELLSPACING=0 "
. "CELLPADDING=0 BGCOLOR='papayawhip'>\n<TR><TD ALIGN='center'>\n");
# Open the inner table, and a dummy form so that the input elements
# can be shown
print("<TABLE ALIGN='center' BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<FORM NAME='Dummy'>\n");
if(mysql_num_rows($res) < 1)
{
# This submission page is empty. Just place a nice RED text
# message in the table to let the user know this.
print("<TR>\n<TD ALIGN='center'>\n<P STYLE=\"font-size: large;"
. " color: red; text-align: center\">[Page Has No Elements]"
. "</P>\n</TD>\n</TR>\n");
} // END if
else
{
# In this case, the page has elements to display...
# Open the current row and cell of the table
print("<TR>\n<TD ALIGN='left'>\n");
while($anItem = mysql_fetch_array($res))
{
# For each row (which is an item), determine the properties
# that should be used to display the item by querying the
# sbmFIELDDESC table for data regarding it...
$configRes = mysql_query("SELECT * FROM sbmFIELDDESC WHERE name"
. " = '" . $anItem["fidesc"] . "'");
if($configRes)
{
$numItemConfigs = mysql_num_rows($configRes);
$anItemsProperties = mysql_fetch_array($configRes);
# Display the text that will accompany the image...
print($anItem["fitext"] . "&nbsp;");
if($anItemsProperties["type"] == "T")
{
# Our item is an HTML textarea input type.
# Display it...
print("<TEXTAREA NAME=\"" . $anItem["fidesc"] . "\""
. "ROWS=" . $anItemsProperties["rows"] . " COLS="
. $anItemsProperties["cols"] . ">"
. $anItemsProperties["val"] . "</TEXTAREA>");
} // END if
elseif($anItemsProperties["type"] == "I")
{
# Our item is a text input type.
# Display it...
print("<INPUT TYPE=\"text\" NAME=\"" . $anItem["fidesc"]
. "\" SIZE=" . $anItemsProperties["size"] . " VALUE=\""
. $anItemsProperties["val"] . "\">");
} // END elseif
elseif($anItemsProperties["type"] == "H")
{
# Our item is a hidden input field.
print("<INPUT TYPE=\"hidden\" NAME=\""
. $anItem["fidesc"] . "\" VALUE=\""
. $anItemsProperties["val"] . "\">");
} // END elseif
elseif($anItemsProperties["type"] == "F")
{
# Our item is a file input type.
# Display it
print("<INPUT TYPE=\"file\" NAME=\"" . $anItem["fidesc"]
. "\" SIZE=" . $anItemsProperties["size"]
. ">");
} // END elseif
elseif($anItemsProperties["type"] == "D")
{
# Our item is some other form of input (e.g. a select
# list, or a radio button, etc). Basically, it has a
# description in the database, which is to be used.
print($anItemsProperties["fidesc"]);
} // END elseif
elseif($anItemsProperties["type"] == "S")
{
# Our item is some other form of input (e.g. a select
# list, or a radio button, etc). Basically, it has a
# description in the database, which is to be used.
print($anItemsProperties["fidesc"]);
} // END elseif
elseif($anItemsProperties["type"] == "R")
{
# Our item is some other form of input (e.g. a select
# list, or a radio button, etc). Basically, it has a
# description in the database, which is to be used.
print("<SPAN STYLE=\"color: red; font-size: medium; "
. "text-align: left\">[Response Input Type: evaluate only at runtime]"
. "</SPAN>\n");
} // END elseif
else
{
# Oh dear! This is a field type that we don't recognise
print("<SPAN STYLE=\"color: red; font-size: medium; "
. "text-align: left\">[Unrecognised Input Type]"
. "</SPAN>\n");
} // END else
# If the number of rows returned by the query of the
# sbmFIELDDESC table was greater than 1, we can display a
# small GREEN message so that the user to be aware of this
# error
if($numItemConfigs > 1)
{
print("&nbsp;&nbsp;&nbsp;&nbsp;More than one row of "
. "configuration information retrieved. Using first.");
} // END if
} // END if
else
{
# Oh dear! We couldn't query the sbmFIELDDESC table. Better
# give the user an error message, which will sit in the
# place of the expected element...
print("<SPAN STYLE=\"color: red; text-align: left; "
. "font-size: medium\">ERROR: Unable to Execute A Query on"
. " the sbmFIELDDESC Table for this Element.</SPAN>\n");
} // END else
} // END while
# We can now close the current row, as we are finished with it
print("</TD>\n</TR>\n");
} // END else
# Close the form and the inner table...
print("</FORM></TABLE>\n");
# Now close the page preview table...
print("</TD>\n</TR>\n</TABLE>\n");
} // END function makeSubmPgePrev($res)
//*****************
function buildPgeElemntTbl($res, $subname, $pageNumber, $nPgs,
$doctype)
{
/******************************************************************
This function has the task of making the second section of the
page to display the details of a given submission page. The
section created by this function, displays a table of elements
that make up the submission page. Using the tables created by
this function, the user can move individual elements to different
positions on the page, delete elements from the submission page,
click buttons to add new elements to the page, click buttons to
edit the details of individual elements, etc.
The function is passed several parameters, many of which are used
for making the various forms located within the table that the
function creates. The first parameter is the "$res" parameter.
This is a result pointer that contains a reference to several
rows relating to the current page of the current submission.
Each row effectively references an element of the page. The
function is also passed the $link variable, the $subname value
(which is the unique identifier for a submission), the
$pageNumber value (which is the number of the page of the
submission that the given element appears on), the $nPgs value
(which is the number of pages that make up the given submission),
and the $doctype variable (which is the document type that the
submission belongs to).
******************************************************************/
global $IMAGES;
print("<P STYLE=\"color: navy; font-size: large; text-align: "
. "left\">Elements on this Page\n");
# Now that we have displayed the "preview page", we need to reset
# the query result set that held the details of each page element
# on the given page back to the first row, so that we can loop
# throught it again in order to display the configuration of the
# elements on the page.
mysql_data_seek($res, 0);
# Okay, $res is now pointing at the first result, so we can begin
# making a table of details for each of the elements...
# Get a list of all fields in the sbmFIELD table...
$fieldCols = mysql_list_fields(DOCS_DATABASE, "sbmFIELD");
# Get the number of fields in the sbmFIELD table...
$noFields = mysql_num_rows($fieldCols);
# Get the number of elements on the page...
$noElements = mysql_num_rows($res);
# we want to output the fields of the result set in a certain
# order. To do this, we don't want to have to write the code many
# times. This means that we can simply make an array, whereby each
# cell has an index number (corresponding to a certain field of the
# result set), and loop through the cells of this array (0 to
# whatever). Using the integer value contained within each cell of
# the array, we can display that row in the order we want to.
$colOrder = array(2, 3, 1, 4, 5, 6, 7, 8, 9);
# Make another array, that contains the names to be given to each
# column in the table. This array corresponds with the above
# indexes one.
$colNames = array("Item No", "Name", "Page No", "Element Label",
"Level", "Short Desc", "Check", "Creation Date",
"Modification Date");
# get the size of the array, to determine where to end our loop
$noCols2show = count($colOrder);
print("<TABLE WIDTH='100%' ALIGN='center' BORDER=1 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR BGCOLOR='#CCDDFF'>\n");
# Now, display the titles for the table...
for($count = 0; $count < $noCols2show; $count++)
{
if($count == 1)
{
# If we have displayed the first field, we must now include
# another field for some arrow buttons to be placed in...
print("<TH>&nbsp;</TH>\n");
} // END if
print("<TH>" . $colNames[$count] . "</TH>\n");
} // END for
# Now make two more cells (the last 2 columns), for the edit button
# an the delete button (1 column for edit, 1 for delete)
print("<TH>&nbsp;</TH>\n<TH>&nbsp;</TH>\n</TR>\n");
# Set a row counter....
$aCounter = 0;
# Now, put all of the query dynaset rows into an array...
while($element = mysql_fetch_array($res))
{
$allElements[$aCounter] = $element;
$aCounter++;
} // END while
# Now fill in the table with the details of each element...
for($i = 0; $i < $noElements; $i++)
{
print("<TR BGCOLOR='#FFFFCC'>\n");
for($count = 0; $count < $noCols2show; $count++)
{
if($count == 0)
{
# In this place, we want to put a select list containing
# the numbers of each page element. These numbers
# determine the order on the page in which the elements
# appear. The number that the element is currently
# desegnated will be "checked", but the numbers of the
# other elements are also available for selection. If the
# user selects another number, the element is moved into
# that position, and the element that was in this position
# is moved down a place, as are the others below it.
print("<FORM ACTION='pageDetsEDS.php' METHOD='post'>\n"
. "<TD ALIGN='center'><INPUT TYPE='hidden' NAME='"
. "moveDigital' VALUE='true'><INPUT TYPE='hidden' NAME='"
. "subname' VALUE='$subname'><INPUT TYPE='hidden' NAME='"
. "pageNumber' VALUE='$pageNumber'><INPUT TYPE='hidden' "
. "NAME='currFieldnb' VALUE='"
. ($i+1) . "'><INPUT TYPE='hidden'"
. " NAME='fidesc' VALUE='" . $allElements[$i][$colOrder[1]]
. "'><INPUT TYPE='hidden' NAME='maxRowNo' VALUE='"
. "$noElements'><INPUT TYPE='hidden' NAME='nPgs' VALUE='"
. "$nPgs'><INPUT TYPE='hidden' NAME='doctype' VALUE='"
. "$doctype'><SELECT NAME='elementPos' onChange=\""
. "if(this.options[this.selectedIndex].value != "
. ($i+1) . ") { submit(); }\">");
for($index = 1; $index <= $noElements; $index++)
{
print("<OPTION VALUE='$index'");
if($i+1 == $index)
{
print(" SELECTED");
} // END if
print(">$index</OPTION>\n");
} // END for
print("</SELECT>\n</TD>\n</FORM>");
} // END if
elseif($count == 1)
{
# Add the "up" arrow element...
print("<TD ALIGN='center'><TABLE WIDTH='100%' BORDER=0 "
. "CELLPADDING=0 CELLSPACING=0><TR>"
. "<FORM ACTION='pageDetsEDS.php' METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='moveUp' VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>"
. "<INPUT TYPE='hidden' NAME='pageNumber' VALUE="
. "'$pageNumber'><INPUT TYPE='hidden' NAME='currFieldnb' "
. "VALUE='" . $allElements[$i][$colOrder[0]] . "'><INPUT"
. " TYPE='hidden' NAME='fidesc' VALUE='"
. $allElements[$i][$colOrder[1]] . "'>"
. "<INPUT TYPE='hidden' NAME='nPgs' VALUE='$nPgs'>"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>");
if($i == 0)
{
# In this case, this is the first element on the page
print("<TD ALIGN='center'><IMG SRC='".$IMAGES."/up.gif' "
. "BORDER=0 WIDTH=11 HEIGHT=15 ALT='Element Already "
. "First On Page!'>");
} // END if
else
{
print("<INPUT TYPE='hidden' NAME='previousfiDesc' VALUE"
. "='" . $allElements[$i - 1][$colOrder[1]] . "'>"
. "<INPUT TYPE='hidden' NAME='previousFieldnb' VALUE='"
. $allElements[$i - 1][$colOrder[0]] . "'><TD ALIGN='"
. "center'><INPUT TYPE='image' SRC='".$IMAGES
. "/up.gif' BORDER=0 WIDTH=11 HEIGHT=15>");
} // END else
# Now, we can add the "down" arrow element...
print("</TD></FORM></TR>"
. "<FORM ACTION='pageDetsEDS.php' METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='moveDown' VALUE='true'>"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>"
. "<INPUT TYPE='hidden' NAME='pageNumber' VALUE="
. "'$pageNumber'><INPUT TYPE='hidden' NAME='currFieldnb' "
. "VALUE='" . $allElements[$i][$colOrder[0]] . "'><INPUT"
. " TYPE='hidden' NAME='fidesc' VALUE='"
. $allElements[$i][$colOrder[1]] . "'>"
. "<INPUT TYPE='hidden' NAME='nPgs' VALUE='$nPgs'>"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>");
if($i == ($noElements - 1))
{
# In this case, this is the last element on the page
print("<TD ALIGN='center'><IMG SRC='".$IMAGES."/down.gif'"
. "BORDER=0 WIDTH=11 HEIGHT=15 ALT='Element Is Already "
. "Last On Page!'>");
} // END if
else
{
print("<INPUT TYPE='hidden' NAME='nextfiDesc' VALUE"
. "='" . $allElements[$i + 1][$colOrder[1]] . "'>"
. "<INPUT TYPE='hidden' NAME='nextFieldnb' VALUE='"
. $allElements[$i + 1][$colOrder[0]] . "'><TD ALIGN='"
. "center'><INPUT TYPE='image' SRC='".$IMAGES
. "/down.gif' BORDER=0 WIDTH=11 HEIGHT=15>");
} // END else
print("</TD></FORM></TR></TABLE></TD>");
# Now, we want to make this field a link to the page
# allowing the editing of these dets...
print("<TD ALIGN='center'>\n<A HREF='"
. "elementConfigDetsEDS.php?"
. "name=" . ereg_replace("'", "&#39;",
htmlspecialchars($allElements[$i][$colOrder[$count]]))
. "&subname=$subname&pageNumber=$pageNumber&nPgs=$nPgs&"
. "doctype=$doctype&caller=pageDetsEDS.php'>"
. ereg_replace("'", "&#39;",
htmlspecialchars($allElements[$i][$colOrder[$count]]))
. "</A>&nbsp;</TD>");
} // END elseif
else
{
# Print the relevant element of the result set...
print("<TD ALIGN='center'>\n"
. ereg_replace("'", "&#39;",
htmlspecialchars($allElements[$i][$colOrder[$count]]))
. "&nbsp;</TD>\n");
} // END else
} // END for
# Now that we have output all of our actual data, we can output
# a form, and an image button in the 2nd last column, which will
# allow the user to edit the given page elements details...
print("<FORM ACTION='editPageElementEDS.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='fidesc' VALUE='"
. $allElements[$i][$colOrder[1]] . "'><INPUT TYPE='hidden' "
. "NAME='fieldnb' VALUE='" . $allElements[$i][$colOrder[0]]
. "'><INPUT TYPE='hidden' NAME='pageNumber' VALUE='$pageNumber'>"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>"
. "<INPUT TYPE='hidden' NAME='nPgs' VALUE='$nPgs'>"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>"
. "<TD ALIGN='center' VALIGN='middle'>\n<INPUT TYPE='image' "
. "SRC='".$IMAGES."/edit1.gif' BORDER=0 onClick=\"submit();\""
. " ALIGN='center'></TD>\n</FORM>\n");
# Now that we have output the "edit details" button, we can make
# one last column that, when clicked, allows us to delete an
# element from the current page.
print("<FORM ACTION='pageDetsEDS.php' METHOD='post' onSubmit=\""
. "if(confirm('The " . $allElements[$i][$colOrder[1]]
. " Element Will Be Permenantly Deleted From This Page.\\n"
. "Are You Sure You Wish To Continue?')) { return true; } else {"
. " return false; }\">\n<INPUT "
. "TYPE='hidden' NAME='deleteElement' VALUE='true'><INPUT TYPE"
. "='hidden' NAME='subname' VALUE='$subname'><INPUT TYPE='hidden"
. "' NAME='pageNumber' VALUE='$pageNumber'><INPUT TYPE='hidden' "
. "NAME='currFieldnb' VALUE='" . $allElements[$i][$colOrder[0]]
. "'><INPUT TYPE='hidden' NAME='fidesc' VALUE='"
. $allElements[$i][$colOrder[1]] . "'><INPUT TYPE='hidden' "
. "NAME='maxRowNo' VALUE='$noElements'><INPUT TYPE='hidden' "
. "NAME='nPgs' VALUE='$nPgs'><INPUT TYPE='hidden' NAME='doctype'"
. " VALUE='$doctype'><TD ALIGN='center' VALIGN='middle'>\n<INPUT"
. " TYPE='image' SRC='".$IMAGES."/answer_bad.gif' BORDER=0 ALIGN='"
. "center' WIDTH=14 HEIGHT=14></TD>"
. "\n</FORM>\n");
# Now we can close the current row of the table
print("</TR>\n");
} // END for
# Now, close up the table...
print("</TABLE>\n");
# Now that the table of elements has been displayed, provide a
# button, which when clicked, will allow the user to add an element
# to the current page of the submission.
print("<FORM ACTION='addElement2PageEDS.php' METHOD='post'>"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>\n"
. "<INPUT TYPE='hidden' NAME='nPgs' VALUE='$nPgs'>\n"
. "<INPUT TYPE='hidden' NAME='pageNumber' VALUE='$pageNumber'>\n"
. "<INPUT TYPE='hidden' NAME='noElements' VALUE='$noElements'>\n"
. "<TABLE WIDTH='100%' ALIGN='center' CELLSPACING=0 CELLPADDING=0 "
. "BORDER=0>\n<TR>\n<TD ALIGN='center'>\n<INPUT TYPE='button' "
. "VALUE='ADD ELEMENT TO PAGE' onClick=\"submit();\">\n</TD>\n</TR>"
. "\n</TABLE>\n</FORM>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now that we have displayed all of the details of the elements, it
# is possible to display a series of links to the other pages of the
# given submission...
print("<TABLE BORDER=0 ALIGN='center' WIDTH='100%' CELLSPACING=0"
. " CELLPADDING=0>\n<TR>\n<TD ALIGN='center'>\n");
# Now, display links to all of the other pages...
for($c = 1; $c <= $nPgs; $c++)
{
if($c == $pageNumber)
{
# Just display the name of the current page...
print("<SMALL>[$subname Page $c]&nbsp;</SMALL>");
} // END if
else
{
# Display an actual link to the page details...
print("[<A HREF='pageDetsEDS.php?subname=$subname"
. "&pageNumber=$c&nPgs=$nPgs&doctype=$doctype'>$subname Page"
. " $c</A>]&nbsp;\n");
} // END else
} // END for
# Now close the table and be done with it...
print("\n</TD>\n</TR>\n</TABLE>\n");
# Make a horizontal rule to divide the page sections...
drawSeparator();
# Now simply display a finish button, which when clicked, will
# return the user to the "viewEditSubmissionEDS.php" page.
print("<FORM ACTION='viewEditSubmissionEDS.php' METHOD='post'>"
. "\n<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='subname' VALUE='$subname'>\n"
. "<TABLE ALIGN='center' CELLSPACING=0 CELLPADDING=0 BORDER=0 "
. "WIDTH='100%'>\n<TR><TD ALIGN='center'>\n<INPUT TYPE='button' "
. "VALUE='FINISHED' onClick=\"submit();\">\n</TD>\n</TR>\n</TABLE>"
. "\n</FORM>\n");
} // END function buildPgeElemntTbl()
//**************
function constructSubmPge($subname, $pageNumber, $nPgs,
$doctype)
{
/*******************************************************************
This function has the task of producing the interface for the
"pageDetsEDS.php" page. The function conducts a query to get a
list of all of the elements that appear on the given page of the
given submission type (whose details we are to display). If the
query to retrieve a list of elements was executed without error,
it calls the relevant functions to display the different sections
of the page. Otherwise, it displays a relevant error message on
the screen.
The function is passsed several arguments. It is passed the
$link variable, the $subname value (which is the unique
identifier for a submission), the $pageNumber value (which is the
number of the page of the submission that the given element
appears on), the $nPgs value (which is the number of pages that
make up the given submission), and the $doctype variable (which
is the document type that the submission belongs to).
*******************************************************************/
# Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD ALIGN='center'>\n"
. "<P STYLE=\"color: blue; text-align: center; font-size: small; "
. "font-weight: bold\">This page allows you to view and modify page"
. " $pageNumber of the <EM>$subname</EM> submission.<BR><BR>The "
. "page is composed of 2 main sections:<BR><OL STYLE=\"text-align: "
. "left\"><LI>The preview section. This allows you to obtain a "
. "preview of the shape and form that the page will take with the "
. "current elements and configuration.</LI>\n<LI>\nThe elements "
. "section. This section allows you to view, modify or add "
. "elements to the page. You can also alter the order of "
. "appearance that elements take on the submission page.</LI>\n"
. "</OL>\n</P>\n</TD>\n</TR>\n</TABLE>\n");
drawSeparator();
$res = mysql_query("SELECT * FROM sbmFIELD WHERE subname = '$subname'"
. " AND pagenb = $pageNumber ORDER BY fieldnb");
if(res)
{
makeSubmPgePrev($res, $pageNumber);
# Now that we have produced a nice preview of the current page of
# the submission, it is possible to actually give the details of
# each element.
drawSeparator();
buildPgeElemntTbl($res, $subname, $pageNumber, $nPgs,
$doctype);
} // END if
else
{
# Oh dear, our query failed for one reason or another. We must
# now display an error message...
print("<P CLASS='errorMsg'><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable to retrieve details of the elements for "
. "<EM>page $pageNumber</EM> of the <EM>$subname</EM> submission"
. " type.<BR>Please inform the system administrator.</P>\n");
} // END else
} // END function constructSubmPge()
//***********
function moveElementUp($previousFieldnb, $subname, $pageNumber,
$fidesc, $currFieldnb, $previousfiDesc, $doctype)
{
/******************************************************************
The task of this function is to process the situation whereby a
user has opted to move an element of a given submission page up
the page by using the "up" arrow button. This function basically
swaps the positions of the element to move, and the element above
it.
The function is passed several parameters. These are the
$previousFieldnb value, the $subname value, the $pageNumber
value, the $fidesc value, the $currFieldnb value, the $link
pointer, the $nPgs value, the $doctype value, and the
$previousfiDesc value.
******************************************************************/
# Get the current date so that an elements modification date can be
# updated when we move it around the page in its order
# Get the data, so that it can be committed for the modification
# date field (md)...
$modifiedDate = makeEDSmdDate();
# make a query string to alter the elements position.
$queryStringA = "UPDATE sbmFIELD SET fieldnb = '$previousFieldnb', "
. "md = '$modifiedDate' WHERE subname = '$subname' AND pagenb = "
. "'$pageNumber' AND fidesc = '$fidesc' AND fieldnb = "
. "'$currFieldnb'";
# Now make a query string to alter the position of the element above
# the element that we are moving, to that of the element that we are
# moving...
$queryStringB = "UPDATE sbmFIELD SET fieldnb = '$currFieldnb', "
. "md = '$modifiedDate' WHERE subname = '$subname' AND pagenb = "
. "'$pageNumber' AND fidesc = '$previousfiDesc' AND fieldnb = "
. "'$previousFieldnb'";
# Execute the query A
$queryResultA = mysql_query($queryStringA);
if($queryResultA)
{
# If the first query has been successful, execute the 2nd
$queryResultB = mysql_query($queryStringB);
if($queryResultB)
{
# In this case, both queries have executed successfully.
mysql_free_result($queryResultA);
mysql_free_result($queryResultB);
# we must update the "modified date" field in the sbmIMPLEMENT
# table, to reflect the fact that certain changes have been
# made to the given submission, even if they are just moving
# elements around the page.
$mdResult = mysql_query("UPDATE sbmIMPLEMENT SET md = "
. "'$modifiedDate' WHERE subname = '$subname'");
if($mdResult)
{
mysql_free_result($mdResult);
} // END if
else
{
# The update the date query has failed for some reason
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't update the md in sbmIMPLEMENT!');</SCRIPT>\n");
} // END else
# We must also modify the md field of the doctype record to
# which this submission belongs
updateEDSDOCTYPEmd($doctype, $modifiedDate);
# Now, we can send a quick email to the administrator, saying
# that the given submission has been modified.
$msgTxt = "An update has been carried out on the $subname "
. "submission type in the " . DOCS_DATABASE
. " database. An element was moved to another position "
. "on page $pageNumber.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$subname Submission Type Updated", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
else
{
# In this case, the 2nd query has failed for some reason
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't move an element! (qstringb)');</SCRIPT>\n");
} // END else ($queryStringB)
} // END if
else
{
# The query string A has failed for some reason!
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't move an element (qstringA)');</SCRIPT>\n");
} // END else ($queryResA)
} // END function moveElementUp()
//************
function moveElementDown($nextFieldnb, $subname, $pageNumber, $fidesc,
$currFieldnb, $nextfiDesc, $doctype)
{
/******************************************************************
This function has the task of handling the moving of an element
of a submission page down by one place on the page. This
basically means that it swaps the places of a given element with
the element below it. It then sends the relevant mails to let
the administrators know that this has been done.
The function is passed several paramaters. These are the
$nextFieldnb value, the $subname value, the $pageNumber value,
the $fidesc value, the $currFieldnb value and the $nextfiDesc
value. These are all needed for the execution of the queries to
move the elements.
******************************************************************/
# Get the current date so that an elements modification date can be
# updated when we move it around the page in its order
# Get the data, so that it can be committed for the modification
# date field (md)...
$modifiedDate = makeEDSmdDate();
# make a query string to alter the elements position.
$queryStringA = "UPDATE sbmFIELD SET fieldnb = '$nextFieldnb', "
. "md = '$modifiedDate' WHERE subname = '$subname' AND pagenb = "
. "'$pageNumber' AND fidesc = '$fidesc' AND fieldnb = "
. "'$currFieldnb'";
# Now make a query string to alter the position of the element above
# the element that we are moving, to that of the element that we are
# moving...
$queryStringB = "UPDATE sbmFIELD SET fieldnb = '$currFieldnb', "
. "md = '$modifiedDate' WHERE subname = '$subname' AND pagenb = "
. "'$pageNumber' AND fidesc = '$nextfiDesc' AND fieldnb = "
. "'$nextFieldnb'";
# Execute the query A
$queryResultA = mysql_query($queryStringA);
if($queryResultA)
{
# If the first query has been successful, execute the 2nd
$queryResultB = mysql_query($queryStringB);
if($queryResultB)
{
# In this case, both queries have executed successfully.
# Free the 2 update query results..
mysql_free_result($queryResultA);
mysql_free_result($queryResultB);
# we must update the "modified date" field in the sbmIMPLEMENT
# table, to reflect the fact that certain changes have been
# made to the given submission, even if they are just moving
# elements around the page.
$mdResult = mysql_query("UPDATE sbmIMPLEMENT SET md = "
. "'$modifiedDate' WHERE subname = '$subname'");
if($mdResult)
{
# Free the result left by this update
mysql_free_result($mdResult);
} // END if
else
{
# The update the date query has failed for some reason
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't update the md in sbmIMPLEMENT!');</SCRIPT>\n");
} // END else
# Now update the modified date field for the actual doctype
# record that this submission belongs to
updateEDSDOCTYPEmd($doctype, $modifiedDate);
# Now, we can send a quick email to the administrator, saying
# that the given submission has been modified.
$msgTxt = "An update has been carried out on the $subname "
. "submission type in the " . DOCS_DATABASE
. " database. An element was moved to another position "
. "on page $pageNumber.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$subname Submission Type Updated", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
else
{
# In this case, the 2nd query has failed for some reason
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't move an element! (qstringb)');</SCRIPT>\n");
} // END else ($queryStringB)
} // END if
else
{
# The query string A has failed for some reason!
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't move an element (qstringA)');</SCRIPT>\n");
} // END else ($queryResA)
} // END function moveElementDown()
//************
function moveElementDigital($subname, $pageNumber, $currFieldnb,
$fidesc, $elementPos, $doctype)
{
/******************************************************************
This function has the task of moving an element of the current
submission page to another position on the page. The movement is
done digitally (i.e. the user selects the position to move the
element to from a select list, and the element appears to slot
right into the position). This function has the job of
re-numbering all of the elements that are affected by this move
(as some other elements may need to be moved up or down to fit
into the place of the moved function. It then moves the element
that is to be moved into the target position.
The function also updates the relevant modified dates for the
moved elements, and the submission type itsself. It also emails
the administrators to let them know of the elements movement.
The function is passed several parameters. These are the
$subname value, the $pageNumber value, the $currFieldnb value,
the $fidesc value, the $maxRowNo value, the $nPgs value, the
$doctype value and the $elementPos value.
******************************************************************/
$modifiedDate = makeEDSmdDate();
# Now get a list of all of the elements on the page
$qResult = mysql_query("SELECT * FROM sbmFIELD WHERE subname = "
. "'$subname' AND pagenb = $pageNumber ORDER BY fieldnb");
# Now, put all of the query dynaset rows into an array...
$idx = 1;
$currentPos = 1;
while($anElement = mysql_fetch_row($qResult))
{
if ($idx == $elementPos && $currFieldnb > $elementPos)
$currentPos++;
if ($idx == $currFieldnb)
$currentPos--;
if ($idx != $currFieldnb)
mysql_query("
UPDATE sbmFIELD
SET fieldnb='$currentPos',
md='$modifiedDate'
WHERE subname='$subname' and
pagenb='$pageNumber' and
fieldnb='".$anElement[2]."' and
fidesc='".$anElement[3]."'");
else
mysql_query("
UPDATE sbmFIELD
SET fieldnb='$elementPos',
md='$modifiedDate'
WHERE subname='$subname' and
pagenb='$pageNumber' and
fieldnb='".$anElement[2]."' and
fidesc='".$anElement[3]."'");
if ($idx == $elementPos && $currFieldnb < $elementPos)
$currentPos++;
$idx++;
$currentPos++;
} // END while
} // END function moveElementDigital()
//*************
function deletePageElement($subname, $pageNumber, $currFieldnb,
$fidesc, $doctype)
{
/******************************************************************
This function has the task of deleting a given element from a
given submission page. When this element is deleted, it is often
necessary to renumber certain other elements on the same page
(those that appeared below the deleted element), as there will be
a gap where the element was removed from. This function deals
with this task when it is necessary. The function also emails
the administrators to let them know that the element has been
deleted from the given page.
The function is passed several parameters. These are the
$subname value, the $pageNumber value, the $currFieldnb value and
the $fidesc value.
******************************************************************/
$dateDets = getdate();
# Now put the date into a variable in a nice MySQL friendly format
$modifiedDate = $dateDets['year'] . "-" . $dateDets['mon'] . "-"
. $dateDets['mday'];
# Now get a list of all of the elements on the page
$qResult = mysql_query("SELECT * FROM sbmFIELD WHERE subname = "
. "'$subname' AND pagenb = $pageNumber ORDER BY fieldnb");
# Now, put all of the query dynaset rows into an array...
$idx = 0;
$numRows = mysql_num_rows($qResult);
while($anElement = mysql_fetch_array($qResult))
{
$elementList[$idx] = $anElement;
$idx++;
} // END while
if($currFieldnb < $numRows)
{
for($k = $currFieldnb; $k < $numRows; $k++)
{
# Make a query string to deal with moving each element
# below the element to move (up until the position to move
# to) up one place in the page elements order.
$moveStr = "UPDATE sbmFIELD SET fieldnb = '"
. ($elementList[$k][2] - 1) . "', md = '$modifiedDate' "
. "WHERE subname = '$subname' AND pagenb = '$pageNumber' "
. "AND fieldnb = '" . $elementList[$k][2] . "'";
# Execute the query to remove the element
$moveRes = mysql_query($moveStr);
if($moveRes)
{
mysql_free_result($moveRes);
} // END if
else
{
# Query hasn't worked
print("<SCRIPT TYPE='text/javascript'>alert('Error: "
. "Couldn't move an element!');</SCRIPT>\n");
}// END else
} // END for
# Make the query string to remove the element
$finalDelStr = "DELETE FROM sbmFIELD WHERE subname = '$subname' "
. "AND pagenb ='$pageNumber' AND fieldnb = '$currFieldnb' "
. "AND fidesc = '$fidesc'";
# Execute the query to remove the element
$finalDelRes = mysql_query($finalDelStr);
if($finalDelRes)
{
# Free the result pointer left by this deletion
mysql_free_result($finalDelRes);
# Now, we can send a quick email to the administrator, saying
# that the given submission has been modified.
$msgTxt = "An update has been carried out on the $subname "
. "submission type in the " . DOCS_DATABASE
. " database. An element was deleted from page $pageNumber"
. ".\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "$subname Submission Type Updated", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
else
{
# Query hasn't worked
print("<SCRIPT TYPE='text/javascript'>alert('Error: "
. "Couldn't delete an element!');</SCRIPT>\n");
}// END else
} // END if
else
{
# In this case, the item to be deleted must be the last in the
# list, so we don't need to move any elements around, just delete
# the it.
# Make the query string to remove the element
$finalDelStr = "DELETE FROM sbmFIELD WHERE subname = '$subname' "
. "AND pagenb ='$pageNumber' AND fieldnb = '$currFieldnb' "
. "AND fidesc = '$fidesc'";
$finalDelRes = mysql_query($finalDelStr);
if($finalDelRes)
{
mysql_free_result($finalDelRes);
# Now, we can send a quick email to the administrator, saying
# that the given submission has been modified.
$msgTxt = "An update has been carried out on the $subname "
. "submission type in the " . DOCS_DATABASE
. " database. An element was deleted from page $pageNumber"
. ".\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Type Updated", $msgTxt,
"From: WebSubmit_Administrator");
} // END if
else
{
# Query hasn't worked
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't delete an element!');</SCRIPT>\n");
}// END else
} // END else
# we must update the "modified date" field in the sbmIMPLEMENT
# table, to reflect the fact that certain changes have been
# made to the given submission, even if they are just moving
# elements around the page.
$mdResult = mysql_query("UPDATE sbmIMPLEMENT SET md = "
. "'$modifiedDate' WHERE subname = '$subname'");
if($mdResult)
{
# Free the result left by this update
mysql_free_result($mdResult);
} // END if
else
{
# The update the date query has failed for some reason
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't update the md in sbmIMPLEMENT!');</SCRIPT>\n");
} // END else
# Update the doctype modification date
updateEDSDOCTYPEmd($doctype, $modifiedDate);
} // END function deletePageElement()
function displayPage()
{
global $moveUp,$x,$y,$previousFieldnb,$subname,$pageNumber,$fidesc,$currFieldnb,$previousfiDesc,$doctype,$nPgs,$moveDown,$moveDigital,$elementPos,$deleteElement;
# Conduct a test to see what kind of call to this page this actually
# is, and then take the appropriate action based upon this
# outcome...
if(isset($moveUp))
{
# If the $up variable is set, it means that the user has pressed
# the up arrow button to move an element up in the order in which
# it is placed on the page...
unset($x);
unset($y);
unset($moveUp);
# Process the element movement...
moveElementUp($previousFieldnb, $subname, $pageNumber, $fidesc,
$currFieldnb, $previousfiDesc, $doctype);
# Redisplay the page...
constructSubmPge($subname, $pageNumber, $nPgs, $doctype);
} // END if
elseif(isset($moveDown))
{
# If this variable is set, it means that the user has pressed the
# down arrow button to move an element down in the order in which
# it is located on the page.
unset($x);
unset($y);
unset($moveDown);
# Process the element movement...
moveElementDown($nextFieldnb, $subname, $pageNumber, $fidesc,
$currFieldnb, $nextfiDesc, $doctype);
# Redisplay the page...
constructSubmPge($subname, $pageNumber, $nPgs, $doctype);
} // END elseif
elseif(isset($moveDigital))
{
/***************************************************************
In this case, the user has opted to move an element to another
position by selecting the position to move it to from the
select list (the item is then moved directly to this position
in the page element order, hence the reason for calling this a
digital move). When this move is accomplished, the other
elements cascade down/up to fill the vacant position left by
the element to be moved.
***************************************************************/
unset($moveDigital);
# Process the element movement
moveElementDigital($subname, $pageNumber, $currFieldnb, $fidesc,
$elementPos, $doctype);
# Redisplay the page...
constructSubmPge($subname, $pageNumber, $nPgs, $doctype);
} // END elseif
elseif(isset($deleteElement))
{
# In this case, the user has opted to delete a given element from
# the page. This means that we must delete the element, and then
# reorder the item numbers of all of the other items in order to
# fill the gap left by this element. We also need to alter the
# modified date of the given submission.
unset($deleteElement);
# Process the element deletion...
deletePageElement($subname, $pageNumber, $currFieldnb, $fidesc,
$doctype);
# Redisplay the page...
constructSubmPge($subname, $pageNumber, $nPgs, $doctype);
} // END elseif
else
{
# In this case, it is the first call to the page (a
# non-self-referential call), and we just need to display the
# details of the submission page...
constructSubmPge($subname, $pageNumber, $nPgs, $doctype);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1]. "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/parameterUpdate.php.wml b/modules/websubmit/web/admin/parameterUpdate.php.wml
index 24e8a7660..1bc4b51ff 100644
--- a/modules/websubmit/web/admin/parameterUpdate.php.wml
+++ b/modules/websubmit/web/admin/parameterUpdate.php.wml
@@ -1,407 +1,407 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Update value of parameter <I><protect><?print $param;?></protect></i> for the <I><protect><?print $doctype;?></protect></i> document type" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function displayParamToUpdate($doctype, $param,
$functionName, $action, $returnTo)
{
/*****************************************************************
This function is used by the "parameterUpdate.php" script. It
executes a select query on the relevant table, retrieving the
value of the required parameter, and placing it into a text input
box in a form. A submit button is also produced for the form.
The purpose of this form is so that the user can alter the value
of the given parameter, and submit the alterations to the
database for update. When the form is submitted, it recursively
calls itself, updates the parameter value, and then redirects to
the 'func.php' script.
*****************************************************************/
# LOCK the given table as READ...
if(!$lockRes = mysql_query("LOCK TABLES sbmPARAMETERS READ"))
{
# We couldn't get a lock, so we just display the error message
# and return from this function.
print("<DIV STYLE='color: navy; font-weight: bold; font-size:"
. " large; text-align: center'><SPAN STYLE='color: "
. "red'>Error:</SPAN> Unable to retrieve information.</DIV>\n"
. "<BR>\n");
print("<TABLE ALIGN='center' CELLSPACING=0 CELLPADDING=0 "
. "BORDER=0>\n<TR>\n<FORM ACTION='func.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='action' VALUE='$action'>\n"
. "<INPUT TYPE='hidden' NAME='functionName' "
. "VALUE='$functionName'>\n"
. "<INPUT TYPE='hidden' NAME='returnTo' VALUE='$returnTo'>\n"
. "<TD ALIGN='center'>\n<INPUT TYPE='button' VALUE='OK' onClick"
. "='submit();'>\n</TD>\n</FORM>\n</TR>\n</TABLE>\n");
return;
}
# Execute a select query on the WebSubmit2 database, getting the value of
# the required parameter...
$queryResult = mysql_query("SELECT value FROM sbmPARAMETERS WHERE
doctype='$doctype' and name='$param'");
# We must unlock our table...
$unlockRes = mysql_query("UNLOCK TABLES");
/******************************************************************
Now, we can test to see if any rows were retrieved by this query.
If there were, then the function has parameters, and we can
display them in a table. If no rows were returned by the query,
then the function has no parameters, and there is no point in
displaying a table. Instead, we can display an appropriate
informative message stating that there are no parameters stored
for the function.
*******************************************************************/
$numRows = mysql_num_rows($queryResult);
if($numRows == 0)
{
/**************************************************************
This query should have returned rows. If none have been
returned, it means that when the function is called for this
doctype, it will search for a value for its parameter in the
column of the table that this query was performed on, but
won't be able to find a result. I.e. the tables are out of
sync.
There could be different reasons for this occurring, but the
most likely is that the user has just added this parameter to
the function, but has not yet updated all of the rows that
utilise it. The best course of action in this case is to give
a message stating that the database stores no value for this
parameter, and that the user should enter one asap. A text
input can also be provided to take care of this.
**************************************************************/
print("<TABLE ALIGN='center' WIDTH='95%' BORDER=1 CELLPADDING=0"
. " CELLSPACING=0 BGCOLOR='#E0E0E0'>\n<TR>\n<TD>\n");
print("<H4>WARNING: There is no value stored in the $param"
. " column of the parameters table for the $doctype document"
. " type. This means that there is no value for this "
. "parameter when the function is used on the $doctype "
. "document type. It is strongly advisable that "
. "a value for the parameter be entered now:</H4>\n");
print("</TD>\n</TR>\n</TABLE>\n<BR>\n");
# Now that the user has been informed about the need for updating
# the parameter value, an input box can be displayed, which the
# user can then use to enter & submit a value for the parameter.
print("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 "
. "ALIGN='center'>\n"
. "<FORM ACTION='parameterUpdate.php' METHOD='post'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($doctype))
. "'>\n"
. "<INPUT TYPE='hidden' NAME='param' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($param))
. "'>\n"
. "<INPUT TYPE='hidden' NAME='functionName' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($functionName))
. "'>\n"
. "<INPUT TYPE='hidden' NAME='action' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($action))
. "'>\n"
. "<INPUT TYPE='hidden' NAME='calledBefore' "
. "VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='newValue' VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='returnTo' "
. "VALUE='$returnTo'>\n");
if ($param == "textMailFTT")
{
print("<TR>\n<TD>\n"
. "<TEXTAREA NAME='paramValue' COLS=60 ROWS=6 "
. "></TEXTAREA>\n</TD>\n</TR>\n</TABLE>\n");
}
else
{
print("<TR>\n<TD>\n"
. "<INPUT TYPE='text' NAME='paramValue' SIZE=60 "
. ">\n</TD>\n</TR>\n</TABLE>\n");
}
# Now display buttons to allow the user to save the new parameter
# value, or to exit from this form...
print("<TABLE ALIGN='center' BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0>\n<TR>\n<TD>\n"
. "<INPUT TYPE='button' VALUE='SAVE PARAMETER'"
. " onClick=\"submit();\"></FORM>\n</TD>\n");
print("<TD>&nbsp;</TD>\n");
print("<TD>");
displayparamEditFinishedButton($doctype, $action,
$functionName, $returnTo);
print("</TD>\n</TR>\n</TABLE>\n");
}
elseif($numRows ==1) # If 1 row was returned, everything is fine!
{
print("<H3 ALIGN='center'>Value Of The <EM>$param");
print("</EM> Parameter:</H3>\n");
list($item) = mysql_fetch_row($queryResult);
$item=htmlspecialchars($item);
/***********************************************************
Find the length of the parameter field as defined in the WebSubmit2
database. This field length will be used in the JavaScript
input validation.
***********************************************************/
$fieldLength = mysql_field_len($queryResult, 0);
# Here, we can display the value of the parameter in a text input
# field in a form. There is also a submit button to allow the
# user to submit updates. There are also many hidden fields that
# contain data that is needed elsewhere in the system when the
# FINISHED buttons are used to return to other areas.
print("<TABLE ALIGN='center'><TR><TD>");
print("<FORM ACTION='parameterUpdate.php' METHOD='post'>");
if ($param == "textMailFTT")
{
print("<TR>\n<TD>\n"
. "<TEXTAREA NAME='paramValue' COLS=60 ROWS=6 "
. ">$item</TEXTAREA>\n</TD>\n</TR>\n</TABLE>\n");
}
else
{
print("<INPUT TYPE='text' NAME='paramValue' SIZE=60 VALUE=");
print("\"$item\"></TD>\n</TR>\n</TABLE>\n");
}
# Now open a new table in which to place the hidden fields and
# the submit buttons. This table will be located below the table
# with the text input form
print("<TABLE ALIGN='center' CELLPADDING=0 CELLSPACING=0 "
. "BORDER=0>\n<TR>\n");
print("<INPUT TYPE='hidden' NAME='doctype' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($doctype))
. "'>");
print("<INPUT TYPE='hidden' NAME='param' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($param))
. "'>");
print("<INPUT TYPE='hidden' NAME='functionName' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($functionName))
. "'>");
print("<INPUT TYPE='hidden' NAME='action' VALUE='"
. ereg_replace("'", "&#39;", htmlspecialchars($action))
. "'>");
print("\n<INPUT TYPE='hidden' NAME='calledBefore' "
. "VALUE='true'>\n"
. "<INPUT TYPE='hidden' NAME='returnTo' "
. "VALUE='$returnTo'>\n");
print("<TD><INPUT TYPE=button VALUE='UPDATE PARAMETER'");
print(" onClick=");
print( "\"submit()\"></FORM>\n</TD>\n");
print("<TD>&nbsp;</TD>\n");
print("<TD>");
displayparamEditFinishedButton($doctype, $action,
$functionName, $returnTo);
print("</TD>\n</TR>\n</TABLE>\n");
}
else
{
print("<P>\n<H3 ALIGN='center'>SQL Error: Too Many");
print(" Rows Returned From Query!</H3>\n</P>\n");
}
}
//***********************
function displayparamEditFinishedButton($doctype, $action,
$functionName, $returnTo)
{
/*****************************************************************
This function is used by the "parameterUpdate.php" script. It
displays a "Finished" button, which returns the administrator to
the "func.php" script.
*****************************************************************/
print("<FORM ACTION='func.php' METHOD='post'>\n");
print("<INPUT TYPE='hidden' NAME='doctype' VALUE='$doctype'>");
print("<INPUT TYPE='hidden' NAME='action' VALUE='$action'>");
print("<INPUT TYPE='hidden' NAME='functionName' "
. "VALUE='$functionName'>"
. "<INPUT TYPE='hidden' NAME='returnTo' VALUE='$returnTo'>");
print("<INPUT TYPE='button' VALUE='FINISHED' onClick=\"");
print("submit()\">\n</FORM>\n");
}
// ******************************
function displayPage()
{
global $calledBefore,$doctype,$param,$functionName,$action,$returnTo,$paramValue,$newValue;
if(!($calledBefore))
{
# If the page has not been called before, we must offer the user
# the opportunity to alter the parameter...
# Get the value of the parameter which is to be updated, and put
# it in a text input box in a form, along with an update button.
# The user will be able to update and save changes to this
# parameters value by using this form...
displayParamToUpdate($doctype, $param, $functionName,
$action, $returnTo);
}// End if
else
{
/*******************************************************
We must now execute the update query on the database. The
update query will update the parameter value that is held in
the relevant table, to that which was entered by the user
before the "UPDATE" button was pressed. Incidentally, if this
calling of the page is to insert a value in a table for a
parameter that does not have a value, the query will be an
insert query instead of an update query...
*******************************************************/
if($lockRes = mysql_query("LOCK TABLES sbmPARAMETERS WRITE"))
{
if($newValue)
{
# If this is a call to add a parameter to the system,
# execute an insert query on WebSubmit
$queryResult = mysql_query("INSERT INTO sbmPARAMETERS
(doctype, name, value) VALUES('$doctype','$param','$paramValue')");
}
else
{
# If this is a call to update the parameters value
# Execute the update query on the WebSubmit2 database.
$queryResult = mysql_query("UPDATE sbmPARAMETERS SET
value='$paramValue'
WHERE doctype = '$doctype' and name='$param'");
}
if(mysql_affected_rows() == 1)
{
$unlockRes = mysql_query("UNLOCK TABLES");
print("<BR><H3 STYLE='color: red; text-align: "
. "center'>Parameter Updated</H3>");
# Now redirect the browser to the "func.php" page once
# more, in order to display all parameter values for the
# function concerned
print("<FORM ACTION='func.php' METHOD='post' "
. "NAME='referForm'>\n"
. "<INPUT TYPE='hidden' NAME='doctype' "
. "VALUE='$doctype'>\n"
. "<INPUT TYPE='hidden' NAME='action' VALUE='$action'>\n"
. "<INPUT TYPE='hidden' NAME='functionName' "
. "VALUE='$functionName'>\n"
. "<INPUT TYPE='hidden' NAME='returnTo' "
. "VALUE='$returnTo'>\n"
. "</FORM>\n");
print("<SCRIPT TYPE='text/javascript'>\n"
. "setTimeout(\"document.referForm.submit();\", 0);\n"
. "</SCRIPT>\n");
}
elseif(mysql_affected_rows() > 1)
{
# If the number of rows updated was greater than 1, there
# has been some DB consistency error
$unlockRes = mysql_query("UNLOCK TABLES");
print("<SCRIPT TYPE='text/javascript'>alert('ERROR:\\n\\n"
. "More than 1 row was affected by this update.');"
. "</SCRIPT>");
}
else
{
# the query has not updated any rows, which is an error, as a
# row should have been updated.
$unlockRes = mysql_query("UNLOCK TABLES");
print("<SCRIPT TYPE='text/javascript'>alert('ERROR:\\n\\n"
. "No parameter value was updated');</SCRIPT>\n");
displayParamToUpdate($doctype, $param,
$functionName, $action, $returnTo);
}
}
else
{
print("<DIV STYLE='color: navy; font-weight: bold; font-size:"
. " large; text-align: center'><SPAN STYLE='color: "
. "red'>Error:</SPAN> Unable to commit updates.</DIV>\n"
. "<BR>\n");
displayParamToUpdate($doctype, $param,
$functionName, $action, $returnTo);
}
}
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1]. "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/referees.py b/modules/websubmit/web/admin/referees.py
index 2880687af..b0abd9a0e 100644
--- a/modules/websubmit/web/admin/referees.py
+++ b/modules/websubmit/web/admin/referees.py
@@ -1,222 +1,222 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
import MySQLdb
import shutil
from cdsware.config import cdsname,cdslang
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, list_registered_users
from cdsware.messages import wash_language
from cdsware.websubmit_config import *
def index(req,c=cdsname,ln=cdslang,todo="",id="",doctype="",categ="",addusers="",warningText="",role=""):
ln = wash_language(ln)
# get user ID:
try:
uid = getUid(req)
uid_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value,req)
(auth_code, auth_message) = acc_authorize_action(uid, "cfgwebsubmit",verbose=0)
if auth_code != 0:
return errorMsg(auth_message, req, uid)
# request for deleting a user
if todo == "deleteuser":
acc_deleteUserRole(id,name_role=role)
# request for adding user(s)
if todo == "adduser":
role = "referee_%s_%s" % (doctype,categ[1])
roleId = acc_getRoleId(role)
# if the role does not exists, we create it
if roleId == 0:
if acc_addRole(role,"referees for document type %s category %s" % (doctype,categ[1])) == 0:
return errorMsg("Cannot create referee role",req)
else:
roleId = acc_getRoleId(role)
# if the action does not exist, we create it
actionId = acc_getActionId("referee")
if actionId == 0:
if acc_addAction("referee","","no",("doctype","categ")) == 0:
return errorMsg("Cannot create action 'referee'",req)
else:
actionId = acc_getActionId("referee")
#create arguments
arg1Id = acc_addArgument("doctype",doctype)
arg2Id = acc_addArgument("categ",categ[1])
# then link the role with the action
if acc_addRoleActionArguments(roleId,actionId,-1,0,0,[arg1Id,arg2Id]) == 0:
return errorMsg("Cannot link role with action",req)
roleId = acc_getRoleId(role)
# For each id in the array
if isinstance(addusers,types.ListType):
for adduser in addusers:
# First check whether this id is not already associated with this rule
myRoles = acc_getUserRoles(adduser)
if not roleId in myRoles:
# Actually add the role to the user
acc_addUserRole(adduser,roleId)
else:
warningText = "<font color=red>Sorry... This user is already a referee for this category.</font>"
else:
# First check whether this id is not already associated with this rule
myRoles = acc_getUserRoles(addusers)
if not roleId in myRoles:
# Actually add the role to the user
acc_addUserRole(addusers,roleId)
else:
warningText = "<font color=red>Sorry... This user is already a referee for this category.</font>"
return page(title="websubmit admin - referee selection",
body=displayRefereesPage(doctype,warningText),
description="",
keywords="",
uid=uid,
language=ln,
urlargs=req.args)
def displayRefereesPage(doctype,warningText):
t=""
if doctype == "*":
docname = "all catalogues"
else:
res = run_sql("SELECT * FROM sbmDOCTYPE WHERE sdocname=%s", (doctype,))
docname = res[0][0]
t+=warningText
t+="""
<FORM ACTION='referees.py' METHOD='POST'>
<INPUT TYPE='hidden' NAME='todo' VALUE=''>
<INPUT TYPE='hidden' NAME='id' VALUE=''>
<INPUT TYPE='hidden' NAME='doctype' VALUE='%s'>
<INPUT TYPE='hidden' NAME='categ' VALUE=''>
<INPUT TYPE='hidden' NAME='role' VALUE=''>
<!-- Role: referee -->
<TABLE><TR><TD valign=top>""" %doctype
# call the function to display the table containing the list of associated emails
t+=displayUserTable(doctype)
t+="""
</TD>
<TD valign=top>"""
# call the function to display the form allowing the manager to add new users
t+=displayAddUser(doctype)
t+= """
</TD></TR></TABLE>
<!-- End submissionuser rule -->
<SMALL>
<INPUT class=\"adminbutton\" TYPE=submit VALUE='FINISHED' onclick="document.forms[0].action='documentEDS.php';document.forms[0].submit();">
</SMALL>
</FORM>"""
return t
def displayUserTable(doctype):
t=""
# start displaying the table which will contain the list of email addresses.
t+= """
<table class="searchbox" summary="">
<tr>
<th class="portalboxheader" colspan="2">Referees</th>
</tr>"""
roles = acc_getAllRoles()
referees = {}
for role in roles:
role_name = role[1]
role_id = role[0]
if re.match("^referee_%s_" % doctype,role_name):
# Try to retrieve the referee's email from the referee's database
if acc_getRoleUsers(role_id) != None:
referees[role_name] = acc_getRoleUsers(role_id)
if len(referees) == 0:
t+= "<TR><TD align=center colspan=2><IMG SRC=\"%s/noway.gif\" height=16 width=16></TD></TR>" % images
i=0
for role in referees.keys():
categ = re.match("referee_%s_(.*)" % doctype,role).group(1)
res = run_sql("SELECT lname FROM sbmCATEGORIES WHERE sname=%s and doctype=%s", (categ,doctype,))
if len(res) > 0:
categname = "Referee(s) for category: %s" % res[0][0]
else:
categname = "General Referee(s)"
t+= "<TR><TD colspan=2><small><b>%s</b> </small></TD></TR>" % categname
for referee in referees[role]:
if int(i/2) == i/2:
bgcolor="#eeeeee"
else:
bgcolor="#dddddd"
t+= "<TR bgcolor=%s>" % bgcolor
t+= "<TD align=right><small>"
t+= referee[1]
t+= "</small></TD>"
t+= "<TD><a href=\"\" onClick=\"if (confirm('Are you sure you want to delete this referee?')){document.forms[0].todo.value='deleteuser';document.forms[0].id.value='%s';document.forms[0].role.value='%s';document.forms[0].submit();return false;}else{return false;}\">" % (referee[0],role)
t+= "<IMG SRC=\"%s/iconcross.gif\" border=0></a>" % images
t+= "</TD>";
t+= "</TR>";
i+=1
# close table
t+="</TABLE>"
return t
def displayAddUser(doctype):
t=""
# start displaying the table which will contain the add form
t+= """
<table class="searchbox" summary="">
<tr>
<th class="portalboxheader">Add</th>
</tr>
<tr>
<td>
User:<br>"""
users = list_registered_users()
if len(users) < 20:
numrows = len(users)
else:
numrows = 20
t+= "<SELECT multiple name=addusers size=%s>" % numrows
for user in users:
if user[1] != "":
t+= "<OPTION value=%s>%s" % (user[0],user[1])
t+= "</SELECT><br>"
t+= "<SELECT name=categ>"
t+= "<OPTION value='*'>All categories"
res = run_sql("SELECT lname,sname FROM sbmCATEGORIES WHERE doctype=%s ORDER BY lname", (doctype,))
for row in res:
t+= "<OPTION value=%s>%s" % (row[1],row[0])
t+= "</SELECT><br>"
t+= "<INPUT class=\"adminbutton\" type=button onClick=\"document.forms[0].todo.value='adduser';document.forms[0].submit();\" VALUE=\"ADD\">"
t+= "</small></TD></TR></TABLE>"
return t
def errorMsg(title,req,uid,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
uid=uid,
urlargs=req.args)
diff --git a/modules/websubmit/web/admin/removeDoctypeEDS.php.wml b/modules/websubmit/web/admin/removeDoctypeEDS.php.wml
index 3a5d1ad4c..6cf782152 100644
--- a/modules/websubmit/web/admin/removeDoctypeEDS.php.wml
+++ b/modules/websubmit/web/admin/removeDoctypeEDS.php.wml
@@ -1,333 +1,333 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Referees" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_deldoctype"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function displayRemoveDoctypePage($killIt)
{
global $doc2delete;
if($killIt)
{
# In this case, this is the second call to this script, and the
# user has selected the doctype that they wish to kill, and have
# confirmed that they indeed wish to kill it. We can therefore
# begin the removing process. We need to delete from the
# "sbmCATEGORIES", "sbmDOCTYPE", "sbmIMPLEMENT", and "sbmFIELD" tables.
# Get all rows of the sbmIMPLEMENT table relating to this doctype...
$q1Res = mysql_query("SELECT subname FROM sbmIMPLEMENT WHERE "
. "docname = '$doc2delete'");
if($q1Res)
{
while($sub = mysql_fetch_array($q1Res))
{
# Delete all elements & pages for the given submission.
$q2Str = "DELETE FROM sbmFIELD WHERE subname = '"
. $sub["subname"] . "'";
$q2Res = mysql_query($q2Str);
if(!$q2Res)
{
# Query failed. Output detailed error message
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:"
. "\\n\\nIt was not possible to conduct a delete query"
. " in order to remove any rows belonging to the "
. $sub["subname"] . " submission\\nof the $doc2delete "
. "document type from the sbmFIELD table.\\n\\nWhen the "
. "delete query was executed, it produced an error. "
. "This means that it is necessary\\nto manually remove"
. " any rows belonging to the " . $sub["subname"]
. " submission of the $doc2delete document type from "
. "the sbmFIELD table.');\n</SCRIPT>\n");
} // END if
} // END while
# Now delete all of the submissions for the current document
# type from the sbmIMPLEMENT table...
$q3Str = "DELETE FROM sbmIMPLEMENT WHERE docname = "
. "'$doc2delete'";
$q3Res = mysql_query($q3Str);
if(!$q3Res)
{
# query failed
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to conduct a delete query in "
. "order to remove any rows belonging to the $doc2delete"
. " document type from the sbmIMPLEMENT table.\\nWhen the "
. "delete query was executed, it produced an error. This"
. " means that it is necessary\\nto manually remove any "
. "rows belonging to the $doc2delete doctype that may be "
. "present in the sbmIMPLEMENT table.');\n</SCRIPT>\n");
} // END if
# Now delete the record of the doctype from the "sbmCATEGORIES"
# table
$q4Res = mysql_query("DELETE FROM sbmCATEGORIES WHERE doctype = "
. "'$doc2delete'");
if(!$q4Res)
{
# Unable to delete doctype details from
# sbmCATEGORIES table. Alert user
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to conduct a delete query in "
. "order to remove any rows belonging to the $doc2delete "
. "document type from the sbmCATEGORIES table.\\nWhen the "
. "delete query was executed, it produced an error. This "
. "means that it is necessary\\nto manually remove any "
. "rows belonging to the $doc2delete doctype that may be "
. "present in the sbmCATEGORIES table.');\n</SCRIPT>\n");
} // END if
# Now delete the entries for the doctype's function in the actual functions
# table.
$q6Res = mysql_query("DELETE FROM sbmFUNCTIONS WHERE doctype = '"
. "$doc2delete'");
if(!$q6Res)
{
# Unable to delete. Alert the user.
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to delete the functions\\nof the "
. "$doc2delete document type from the functions table.\\n"
. "\\nThis means that it will be necessary to manually "
. "delete any rows in this table relating to the "
. "$doc2delete doctype.');\n</SCRIPT>\n");
} // END if
# Now delete the entries for the doctype's parameters in the actual parameters
# table.
$q7Res = mysql_query("DELETE FROM sbmPARAMETERS WHERE doctype = '"
. "$doc2delete'");
if(!$q7Res)
{
# Unable to delete. Alert the user.
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to delete the parameters\\nof the "
. "$doc2delete document type from the parameters table.\\n"
. "\\nThis means that it will be necessary to manually "
. "delete any rows in this table relating to the "
. "$doc2delete doctype.');\n</SCRIPT>\n");
} // END if
# Now delete the entry for the doctype in the "sbmSUBMISSIONS"
# table.
$q8Res = mysql_query("DELETE FROM sbmSUBMISSIONS WHERE doctype = '"
. "$doc2delete'");
if(!$q8Res)
{
# Unable to delete. Alert the user.
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to delete the details\\nof the "
. "$doc2delete document type from the sbmSUBMISSIONS table.\\n"
. "\\nThis means that it will be necessary to manually "
. "delete any rows in this table relating to the "
. "$doc2delete doctype.');\n</SCRIPT>\n");
} // END if
# Now delete the entry for the doctype in the "sbmCOLLECTION_sbmDOCTYPE"
# table.
$q9Res = mysql_query("DELETE FROM sbmCOLLECTION_sbmDOCTYPE WHERE id_son = '"
. "$doc2delete'");
if(!$q9Res)
{
# Unable to delete. Alert the user.
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to delete the details\\nof the "
. "$doc2delete document type from the sbmCOLLECTION_sbmDOCTYPE table.\\n"
. "\\nThis means that it will be necessary to manually "
. "delete any rows in this table relating to the "
. "$doc2delete doctype.');\n</SCRIPT>\n");
} // END if
# Now delete the entry for the doctype in the actual "sbmDOCTYPE"
# table.
$q5Res = mysql_query("DELETE FROM sbmDOCTYPE WHERE sdocname = '"
. "$doc2delete'");
if(!$q5Res)
{
# Unable to delete the record of the doctype from the
# sbmDOCTYPE table. Alert the user.
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n"
. "\\nIt was not possible to delete the details\\nof the "
. "$doc2delete document type from the sbmDOCTYPE table.\\n"
. "\\nThis means that it will be necessary to manually "
. "delete any rows in this table relating to the "
. "$doc2delete doctype.');\n</SCRIPT>\n");
} // END if
print("<P STYLE=\"text-size: medium; color: green; text-align"
. ": center; font-weight: bold\">The $doc2delete document typ"
. "e has been deleted from the " . DOCS_DATABASE
. " database.</P>\n");
print("<SCRIPT TYPE=\"text/javascript\">\nalert('The "
. "$doc2delete document type has been deleted from the "
. DOCS_DATABASE . " database.\\n\\nYou should not ignore any "
. "warnings that you may have received on the screen during "
. "the process of this deletion, as these may refer to\\nrows"
. " that could not be deleted for this doctype.');\n"
. "</SCRIPT>\n");
print("<FORM ACTION=\"index.php\" METHOD=\"post\" "
. "NAME=\"referForm\">\n"
. "<INPUT TYPE=\"hidden\">\n</FORM>\n");
print("<SCRIPT TYPE=\"text/javascript\">\n"
. "setTimeout(\"document.referForm.submit();\", 0);\n"
. "</SCRIPT>\n");
} // END if
else
{
# Alert the user, and redirect browser
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR:\\n\\n"
. "It was not possible to conduct a query to retrieve the "
. "details of the submissions belonging\\nto the $doc2delete "
. "document type from the sbmIMPLEMENT table of the "
. DOCS_DATABASE . " database.\\n\\nWhen the query to retrieve "
. "this information was executed, it produced an error.\\n\\n"
. "This meant that it was not possible to delete the details "
. "of the $doc2delete document type from the " . DOCS_DATABASE
. " database,\\nas if it has any submissions, they could not "
. "be deleted, and as a result, data inconsistencies would be"
. " created.\\n\\nAs no further action can be taken by the "
. "WebSubmit Administrator regarding this doctype deletion, your "
. "browser has\\nbeen redirected to the main page. However, "
. "you should look into the cause of this query error,\\nas "
. "it should not have occurred.');\n</SCRIPT>\n");
} // END else
} // END if
else
{
# first call to page
print("<P CLASS=\"errorMsg\">Delete A Doctype</P>\n");
# Get all doctypes
$myRes = mysql_query("SELECT sdocname, ldocname FROM sbmDOCTYPE "
. "ORDER BY ldocname");
if($myRes)
{
print("<TABLE WIDTH=\"90%\" BGCOLOR=\"#D3DCE3\" ALIGN=\"center\" "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN=\"center\">\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">You can "
. "delete a doctype and all of its submissions and their "
. "elements.<BR>Simply choose the doctype from the list, "
. "and click on the \"REMOVE DOCTYPE\" button.</P>\n</TD>\n"
. "</TR>\n</TABLE>\n");
# Make the input form for the element deletion
print("<FORM ACTION=\"removeDoctypeEDS.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"hidden\" NAME=\"killIt\" VALUE=\"true\">\n"
. "<TABLE ALIGN=\"center\" CELLSPACING=0 CELLPADDING=0 "
. "BORDER=0>\n<TR>\n<TH ALIGN=\"right\" BGCOLOR=\"#87CEFA\">"
. "Document Type:&nbsp;</TH>\n<TD BGCOLOR=\"#FFFFCC\" "
. "ALIGN=\"center\"><SELECT NAME=\"doc2delete\"><OPTION SELECTED "
. "VALUE=\"DO_NOT_DELETE\">Select A Doctype To Delete"
. "</OPTION>");
# Now fill the select list with all of the doctype values
while(list($code, $desc) = mysql_fetch_row($myRes))
{
print("<OPTION VALUE=\""
. ereg_replace("\"","&#34;",ereg_replace("'", "&#39;",
htmlspecialchars($code)))
. "\">"
. ereg_replace("\"","&#34;",ereg_replace("'", "&#39;",
htmlspecialchars($desc)))
. "</OPTION>\n");
} // END while
print("</SELECT></TD>\n</TR>\n</TABLE>\n");
print("<TABLE ALIGN=\"center\" BORDER=0>\n<TR>\n<TD ALIGN=\""
. "center\"><INPUT TYPE=\"button\" VALUE=\"REMOVE DOCTYPE\" "
. "onClick=\"for(i=0; i < doc2delete.length; i++) { "
. "if(doc2delete[i].selected) { break; } }"
. " if(doc2delete[i].value != 'DO_NOT_DELETE') { "
. "if(confirm('WARNING! YOU ARE ABOUT TO REMOVE THIS "
. "DOCTYPE FROM EDS!\\n ARE YOU SURE?')) { submit(); }}"
. " else { alert('Select A document Type from the list!'); "
. "}\">\n</TD>\n</TR>\n</TABLE>\n</FORM>\n");
} // END if
else
{
# query failed
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERRO"
. "R:</SPAN> It was not possible to obtain a list of documen"
. "t types from the sbmDOCTYPE table.<BR>This means that it is "
. "not possible to delete a doctype.</P>\n");
print("<FORM ACTION=\"index.php\" METHOD=\"post\">\n<TABLE ALIG"
. "N=\"center\" BORDER=0 CELLSPACING=0 CELLPADDING=0>\n<TR>\n<"
. "TD ALIGN=\"center\">\n<INPUT TYPE=\"button\" VALUE=\"OK\" "
. "onClick=\"submit();\">\n</TD>\n</TR>\n</TABLE>\n</FORM>"
. "\n");
} // END else
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayRemoveDoctypePage($killIt);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/veditFunDets.php.wml b/modules/websubmit/web/admin/veditFunDets.php.wml
index c3acc1d46..712dad083 100644
--- a/modules/websubmit/web/admin/veditFunDets.php.wml
+++ b/modules/websubmit/web/admin/veditFunDets.php.wml
@@ -1,295 +1,295 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="View <i><protect><?print $function;?></protect></i> function details" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listfunctions"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
function displayPage()
{
global $function,$deleteParam,$param,$updateFunDets,$description,$insertParam,$newParam,$theParam;
/******************************************************************
This script produces a page that is used for viewing or configuring
the details of a function in the WebSubmit database. When the page is
called for the first time, i.e. from the 'listFunctions.php' page,
it displays the name of the function, the description of the
function, any parameters that the function may have, and also offers
the ablility to add parameters to the function by presenting a drop
down selection list of tables in WebSubmit.
The page allows the user to alter the description of the function.
This can be done by typing into the description text field, and
clicking on the submit button. The page will then recursively call
itself, update this value in the sbmALLFUNCDESCR table of WebSubmit, and
then redisplay all of the functions details with the new description
The page also allows the user to add a parameter to the function.
In this case, the user must first of all select a table name from
the selection drop down list box. The page will then recursively
call itself again, but this time, also displaying a drop down select
list of fields in the table that the user selected. The user can
then select one of these fields, and click a submit button to add
the new parameter to the function. At this point, the page will
recursively call itself again, but this time adding the new
parameter to the function, and emailing the administrators to
inform them that this action has been carried out. The page will
then redirect to the 'funcUsage.php', which will display the usage
of the function, and the user will be informed that they must update
all of the actions and doctypes that use this function, as they will
need values inserting into the relevant tables for the new
parameter.
******************************************************************/
if(isset($updateFunDets))
{
unset($updateFunDets);
if($lockRes = mysql_query("LOCK TABLES sbmALLFUNCDESCR WRITE"))
{
$updateDescRes = mysql_query("UPDATE sbmALLFUNCDESCR SET "
. "description = '$description' WHERE function = "
. "'$function'");
$unlockRes = mysql_query("UNLOCK TABLES");
if(!$updateDescRes)
{
// unable to update the value of description: inform user
print("<DIV STYLE=\"color: navy; font-weight: bold; "
. "text-align: center; font-size: large\"><SPAN STYLE=\"color: "
. "red\">Error:</SPAN> Unable to update value of description for $function"
. "function</DIV>\n<BR>\n");
}
}
else
{
// Couldn't get lock - no update allowed - tell user
print("<DIV STYLE=\"color: navy; font-weight: bold; "
. "text-align: center; font-size: large\"><SPAN STYLE=\"color: "
. "red\">Error:</SPAN> Unable to update description.</DIV>\n"
. "<BR>\n");
}
mysql_free_result($updateDescRes);
makePageBody($function, "veditFunDets.php");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
elseif(isset($insertParam))
{
// call to add a new parameter to the function...
if($lockRes = mysql_query("LOCK TABLES sbmFUNDESC WRITE"))
{
if ($newParam != "")
$insertParamRes = mysql_query("INSERT INTO sbmFUNDESC
VALUES('$function', '$newParam')");
else
$insertParamRes = mysql_query("INSERT INTO sbmFUNDESC
VALUES('$function', '$theParam')");
$unlockRes = mysql_query("UNLOCK TABLES");
if($insertParamRes)
{
// Now that the parameter has been added, it is necessary to
// display an message informing the user that the parameter
// has been added, but that they must also update all
// doctypes that use the function to have an actual value
// in the relevant table
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: medium; color: navy\">The $function function will now "
. "use the parameter $theParam.<br>You will need to provide a value "
. "for this parameter for every doctype that uses the function.<br>"
. "Click the Continue button to see the usage of this function.</DIV>\n");
// Email the administrator, and warn them that a
// function has been added to WebSubmit
$dateDets = getDate();
$messageText = "A parameter was "
. "added"
. " to the $function function on " . $dateDets['weekday']
. " " . $dateDets['mday'] . " " . $dateDets['month'] . " "
. $dateDets['year'] . ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . ".\n\n"
. "The function will search for the value of the new "
. "parameter in the $theParam column of the $theTable "
. "table.\n\nYou should ensure that all document types "
. "that"
. " use this function have a corresponding row in this "
. "table.\n\nInformation about the document types that "
. "utilise this function can be found under the 'WebSubmit "
. "Functions' section of the WebSubmit Administrator "
. "menu.\n\nWebSubmit Administrator.";
mail(ADMIN_EMAIL, "Parameter Added To $function Function",
$messageText, "From: WebSubmit_Administrator");
print("<br><br><TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"funcUsage.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"hidden\" NAME=\"function\" VALUE=\"$function\">\n"
. "<INPUT TYPE=\"submit\" VALUE=\"Continue\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
else
{
// If the insert query did not execute
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: large; color: navy\"><SPAN STYLE=\"color: red\">"
. "Error:</SPAN> Unable to insert parameter.</DIV>\n");
makePageBody($function, "veditFunDets.php");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
}
else
{
// Unable to get a lock
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: large; color: navy\"><SPAN STYLE=\"color: red\">"
. "Error:</SPAN> Unable to insert parameter.</DIV>\n");
makePageBody($function, "veditFunDets.php");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
}
elseif(isset($deleteParam))
{
// delete a parameter from a function.
if($lockRes = mysql_query("LOCK TABLES sbmFUNDESC WRITE"))
{
$delRes = mysql_query("DELETE FROM sbmFUNDESC WHERE function = '"
. "$function' AND param = '$param'");
if($delRes)
{
if(mysql_affected_rows() < 1)
{
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: large; color: navy\"><SPAN STYLE=\"color: red\">"
. "Error:</SPAN> Unable to delete parameter.</DIV>\n");
} // END if
else
{
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: large; color: navy\">"
. "Parameter Deleted!</DIV>\n");
$dateDets = getdate();
$msgTxt = "A parameter has been deleted from the "
. "$function"
. " function in the " . DOCS_DATABASE . "database. This "
. "parameter was taken from the $param field of the "
. "$tablename Table. When the function is called by "
. "the WebSubmit system in the future, it will not search "
. "for this parameter.\n\nThis deletion was carried "
. "out on "
. $dateDets['weekday'] . " " . $dateDets['mday'] . " "
. $dateDets['month'] . " " . $dateDets['year']
. ", at " . $dateDets['hours'] . ":"
. $dateDets['minutes'] . ".\n\nWebSubmit Administrator.";
mail(ADMIN_EMAIL, "Parameter Deleted From $function",
$msgTxt, "From: WebSubmit_Administrator");
}
}
else
{
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: large; color: navy\"><SPAN STYLE=\"color: red\">"
. "Error:</SPAN> Unable to delete parameter.</DIV>\n");
}
}
else
{
// Unable to get lock - don't allow deletion.
print("<DIV STYLE=\"text-align: center; font-weight: bold; "
. "font-size: large; color: navy\"><SPAN STYLE=\"color: red\">"
. "Error:</SPAN> Unable to delete parameter.</DIV>\n");
}
makePageBody($function, "veditFunDets.php");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
else
{
if(isset($tableSelected))
{
makePageBody($function, "veditFunDets.php",
$tableSelected, $theTable);
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD='post'>\n"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
else
{
// Make the page once more, as a first call to it
makePageBody($function, "veditFunDets.php");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLPADDING=0 "
. "CELLSPACING=0>\n<TR>\n<TD ALIGN=\"center\">\n"
. "<FORM ACTION=\"listFunctions.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" "
. "onClick=\"submit();\">\n"
. "</FORM>\n</TD>\n</TR>\n</TABLE>\n");
}
}
}
/**********************Start of main script***************************/
// Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
// Select the database
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/viewActionEDS.php.wml b/modules/websubmit/web/admin/viewActionEDS.php.wml
index c43f1fb96..81e495fc9 100644
--- a/modules/websubmit/web/admin/viewActionEDS.php.wml
+++ b/modules/websubmit/web/admin/viewActionEDS.php.wml
@@ -1,434 +1,434 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Details of the <i><protect><?print "$actname";?></protect></I> action" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listactions"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT LANGUAGE="JavaScript">
<!-- hide
function validateIsInt(param)
// This function validates its parameter to ensure that it is an integer
// value.
{
// Create a flag to indicate that we have found a non-digit value
var nonDigit = false;
for(index = 0; index < param.length; index++)
{
if(!(param[index] >= 0 && param[index] <= 9))
{
// In this case, we've found a non-digit value, and can stop
// searching, as the parameter is clearly not an integer
nonDigit = true;
break;
}
}
return true;
}
function verifyChanges(curLactname, sugLactname, curDir, sugDir,
curActionbutton, sugActionbutton, curStatustext, sugStatustext)
// Function to test whether the values for the parameters to be changed
// have actually been changed by the user when they submit them to the
// database for update. If not, the function returns false. If so, the
// function returns true.
{
if((curLactname == sugLactname) &&
(curDir == sugDir) && (curActionbutton == sugActionbutton) &&
(curStatustext == sugStatustext))
{
alert("No Change In The Data Has Been Made! Cannot Submit.");
return false;
}
else
{
return true;
}
}
// -->
</SCRIPT>
<?
function makeButtons($dataRow, $caller, $doctype = "")
{
/**************************************************************
This function has the simple task of creating and displaying the
"SAVE CHANGES" button and the "FINISHED" button for the action
details form. It is bundled into a function, as it is quite a
messy piece of code due to the large parameters to the
JavaScript function "verifyChanges".
**************************************************************/
print("<P>\n");
print("<TABLE ALIGN=\"center\" BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0 WIDTH=\"100%\">\n<TR>\n<TD ALIGN=\"right\">"
. "\n<INPUT TYPE=\"button\" VALUE=\"SAVE CHANGES\" onClick=\""
. "if(verifyChanges(escape('" . ereg_replace("'","\\'",
htmlspecialchars($dataRow["lactname"]))
. "'), escape(lactname.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["dir"]))
. "'), escape(dir.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["actionbutton"]))
. "'), escape(actionbutton.value), escape('"
. ereg_replace("'","\\'",
htmlspecialchars($dataRow["statustext"]))
. "'), escape(statustext.value))) { submit(); }\">\n</TD>\n</FORM>\n<FORM ACTION=\"$caller"
. "\" METHOD=\"post\">\n");
if($caller == "documentEDS.php")
{
// Pass a doctype back to it...
print("<INPUT TYPE=\"hidden\" NAME=\"doctype\" VALUE=\"$doctype\">\n");
}
print("<TD ALIGN=\"left\">\n<INPUT TYPE=\"submit\" VALUE=\"FINISHED\">"
. "</TD>\n</FORM>\n</TR>\n</TABLE>\n</P>\n");
}
//*************
function displayEDSaction($actname, $caller, $doctype = "")
{
/*******************************************************************
This function has the task of displaying the details of an EDS
action. The details are displayed in a form, so that they can be
modified and resubmitted to the database. This function
basically has the task of producing the page to be displayed for
the 'viewActionEDS.php' page.
*******************************************************************/
// Execute a query on the sbmACTION table for the given action
$queryResult = mysql_query("SELECT * from sbmACTION WHERE sactname = "
. "'$actname'");
if($queryResult)
{
if(mysql_num_rows($queryResult) == 1)
{
// as expected there is one entry for the given
// action in the sbmACTION table
print("<TABLE WIDTH=\"90%\" BGCOLOR=\"#D3DCE3\" ALIGN=\"center\" "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN=\"center\">\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below are "
. "the details of the <EM>$actname</EM> action.<BR>You can "
. "edit them by alterring values in boxes, and clicking on "
. "\"SAVE CHANGES\".</P>\n</TD>\n</TR>\n</TABLE>\n");
drawSeparator();
print("<FORM ACTION=\"viewActionEDS.php\" METHOD=\"post\">\n"
. "<INPUT TYPE=\"hidden\" NAME=\"update\" VALUE=\"true\">\n"
. "<INPUT TYPE=\"hidden\" NAME=\"caller\" VALUE=\"$caller\">\n");
if($caller == "documentEDS.php")
{
// Add a doctype
print("<INPUT TYPE=\"hidden\" NAME=\"doctype\" VALUE=\"$doctype\">\n");
}
print("<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=\"center\" WIDTH=\"100%\">\n");
$columns = mysql_list_fields(DOCS_DATABASE, "sbmACTION");
$numTblFlds = mysql_num_fields($columns);
$dataRow = mysql_fetch_array($queryResult);
// Before we display most of the table, we can first display
// the upper part of the table, which will be the sactname, cd,
// and md fields, that can't be modified...
print("<TABLE WIDTH=\"100%\" ALIGN=\"center\" CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0>\n<TR>\n<TH BGCOLOR=\"#D3DCE3\" ALIGN"
. "=\"right\" WIDTH=\"20%\">\nAction Code:&nbsp;</TH>\n<TD "
. "ALIGN=\"left\" BGCOLOR=\"#FFFFCC\" WIDTH=\"80%\"><INPUT "
. "TYPE=\"readonly\" NAME=\"sactname\" VALUE=\""
. $dataRow["sactname"] . "\">\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR=\"#D3DCE3\" ALIGN=\"right\" WIDTH=\"20%\">\nCreation "
. "Date:&nbsp;</TH>\n<TD WIDTH=\"80%\" ALIGN=\"left\" BGCOLOR="
. "\"#FFFFCC\"><INPUT TYPE=\"readonly\" NAME=\"cd\" VALUE=\""
. $dataRow["cd"] . "\">\n</TD>\n</TR>\n<TR>\n<TH WIDTH=\"20%\""
. " BGCOLOR=\"#D3DCE3\" ALIGN=\"right\">\nModification "
. "Date:&nbsp;</TH>\n<TD WIDTH=\"80%\" ALIGN=\"left\" "
. "BGCOLOR=\"#FFFFCC\"><INPUT TYPE=\"readonly\" NAME=\"md\" "
. "VALUE=\"" . $dataRow["md"] . "\">\n</TD>\n</TR>\n");
print("<input type=\"hidden\" name=\"actionbutton\" value=\"\">");
// Now fill this new table with all of the details
for($indx = 0; $indx < $numTblFlds; $indx++)
{
$currentField = mysql_field_name($columns, $indx);
if(($currentField != "sactname") && ($currentField != "cd")
&& ($currentField != "md") && ($currentField != "actionbutton"))
{
print("<TR>\n<TH BGCOLOR=\"#87CEFA\" ALIGN=\"right\" WIDTH=\"20%\">\n");
if($currentField == "lactname")
{
print("Action Description:&nbsp;");
}
else
{
print("$currentField" . ":&nbsp;");
}
print("&nbsp;</TH>\n<TD ALIGN=\"left\" WIDTH=\"80%\" "
. "BGCOLOR=\"#FFFFCC\">\n<INPUT TYPE=\"text\" NAME="
. "\"$currentField\" SIZE=");
if(mysql_field_type($columns, $indx) == "blob")
{
print("60");
}
else
{
print(mysql_field_len($columns, $indx));
}
print(" VALUE=\"" . ereg_replace("'", "&#39;",
htmlspecialchars($dataRow[$indx]))
. "\">\n</TD>\n</TR>\n");
}
}
print("</TABLE>\n</TABLE>\n");
// "SAVE" button, and a "FINISHED button:
if($caller == "documentEDS.php")
{
makeButtons($dataRow, $caller, $doctype);
}
else
{
makeButtons($dataRow, $caller);
}
}
elseif(mysql_num_rows($queryResult) > 1)
{
// too many rows for the action
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> More than one row of data concerning the <EM>$actname</EM> "
. "action was returned from the <EM>sbmACTION</EM> table of "
. "the" . DOCS_DATABASE . ".<BR>This indicates primary key "
. "duplication in this table.<BR>Please inform system administrator.</P>\n");
$msgTxt = "When a user attempted to look at the details of "
. "the $actname action using the WebSubmit Administrator, several "
. "rows were returned for this action from the sbmACTION table."
. " The query was made using the \"sactname\" as the search"
. " key. As the \"sactname\" field is the primary key for "
. "the sbmACTION table, this means that there must be key "
. "violations in this table.\n\nThis problem should be "
. "corrected immediately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "sbmACTION Table Key Violation!", $msgTxt,
"From: WebSubmit_Administrator");
}
elseif(mysql_num_rows($queryResult) == 0)
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No data concerning the <EM>$actname</EM> action was found in the"
. " <EM>sbmACTION</EM> table.<BR>This suggests a data "
. "consistency error in the " . DOCS_DATABASE . " database."
. "<BR>Please inform the system administrator.</P>\n");
$dateDets = getdate();
$msgTxt = "When a user attempted to look at the details of "
. "the $actname action using the WebSubmit Administrator, no rows "
. "were returned from the sbmACTION table for this "
. "action.\n\nBecause the user had to click a link to view "
. "the details of this action, it must be referred to in "
. "other tables of EDS. This means that there are data "
. "inconsistencies within EDS.\n\nThis should be investigated"
. " and corrected ASAP.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Data Inconsistency Error!", $msgTxt,
"From: WebSubmit_Administrator");
}
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to correctly retrieve data from the <EM>sbmACTION</EM> "
. "table of " . DOCS_DATABASE . ".<BR>Please inform system "
. "administrator.</P>\n");
}
}
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to conduct a query on the "
. "<EM>sbmACTION</EM> table of " . DOCS_DATABASE . ".<BR>Please"
. " inform system administrator.</P>\n");
}
}
function displayPage($update,$actname)
{
global $lactname,$sactname,$dir,$actionbutton,$statustext,$caller,$doctype;
if($update)
{
// update the actions details
unset($update);
$dateDets = getdate();
$modifiedDate = $dateDets['year'] . "-" . $dateDets['mon'] . "-"
. $dateDets['mday'];
$queryString = "UPDATE sbmACTION SET lactname = '$lactname', dir ="
. " '$dir', md = '$modifiedDate', actionbutton = '$actionbutton'"
. ", statustext = '$statustext' "
. "WHERE sactname = '$sactname'";
$updateResult = mysql_query($queryString);
if($updateResult)
{
if(mysql_affected_rows() == 1)
{
$dateDets = getdate();
$msgTxt = "An update has been carried out on the $sactname"
. " action in the " . DOCS_DATABASE . " database.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "EDS Action Updated", $msgTxt,
"From: WebSubmit_Administrator");
// now redisplay all of the details for the action
if($caller == "documentEDS.php")
{
displayEDSaction($sactname, $caller, $doctype);
}
else
{
displayEDSaction($sactname, $caller);
}
}
elseif(mysql_affected_rows() > 1)
{
// More than 1 row was updated
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Multiple rows have been updated in the "
. "<EM>sbmACTION</EM> table.<BR>This has resulted from an "
. "attempt to update the <EM>$sactname</EM> action.<BR>"
. "Please inform the system administrator.</P>\n");
$msgTxt = "When a user updated the details of "
. "the $sactname action using the WebSubmit Administrator, seve"
. "ral rows were affected in the sbmACTION table. The update"
. " was conducted using the \"sactname\" field as the key."
. " As the \"sactname\" field is the primary key for the "
. "sbmACTION table, this means that there must be key violati"
. "ons in this table. There should only have been 1 row "
. "affected by this update.\n\nThis problem should be "
. "investigated and corrected immediately.\n\nEDS Administ"
. "rator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "ERROR: sbmACTIONS Table Multiple Row "
. "Update!", $msgTxt, "From: WebSubmit_Administrator");
}
else
{
// No rows were updated
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>"
. "sbmACTION</EM> table.<BR>This suggests that there could "
. "be data inconsistencies or concurrency problems.<BR>"
. "Please inform the system administrator.</P>\n");
$msgTxt = "When a user attempted to update the details of "
. "the $sactname action using the WebSubmit Administrator, no "
. "rows were affected in the sbmACTION table by this update."
. "\n\nBecause the user must have altered an actions "
. "details to submit an update on it, it must have been "
. "present at around the time that the user submitted thei"
. "r update.\n\n"
. "This suggests the possibility of concurrency or data "
. "inconsistency problems in this table.\n\nThis should be"
. " investigated and corrected ASAP.\n\nWebSubmit Administrator "
. "(";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Error: Possible Concurrency Problems",
$msgTxt, "From: WebSubmit_Administrator");
}
}
else
{
// The query couldn't be executed
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable to update deatails for <EM>$sactname</EM> "
. "action in <EM>sbmACTION</EM> table.<BR>Please inform system "
. "administrator.</P>\n");
}
}
else
{
if($caller == "documentEDS.php")
{
displayEDSaction($actname, $caller, $doctype);
}
else
{
displayEDSaction($actname, $caller);
}
}
}
/**********************Start of main script***************************/
// Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
// Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage($update,$actname);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/viewChecksEDS.php.wml b/modules/websubmit/web/admin/viewChecksEDS.php.wml
index 8c99f34c1..d2a518250 100644
--- a/modules/websubmit/web/admin/viewChecksEDS.php.wml
+++ b/modules/websubmit/web/admin/viewChecksEDS.php.wml
@@ -1,294 +1,294 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Edit the <I><protect><?print $chname;?></protect></i> javascript checking function" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit_listchecks"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
/********************Function Declarations****************************/
function errorOKbutton()
{
/*******************************************************************
This function has the simple task of creating an "OK" button,
which when pressed, sends the browser back to the
"allChecksEDS.php" page. It will only be displayed when there has
been some sort of error ocurrence.
Created: 19/12/2000
Last Modified: 19/12/2000
*******************************************************************/
print("<TABLE ALIGN='center' CELLSPACING=0 CELLPADDING=0 BORDER=0>"
. "\n<FORM ACTION='allChecksEDS.php' METHOD='post'>\n<TR><TD ALIGN"
. "='center'>\n<INPUT TYPE='button' VALUE='OK' onClick=\"submit();"
. "\">\n</TD>\n</TR>\n</FORM>\n</TABLE>\n");
} // END function errorOKbutton()
//*************
function displayEDScheckDetsForm($chname)
{
/*****************************************************************
This function has the task of constructing the form that contains
the details of a given check that is to be viewed or editied. It
first conducts a query on the CHECK table to retrieve the details
of the check. If it can't, it displays the relevant error
messages. Otherwise, it displays all of the details of the check
in an HTML form. It also of course displays the buttons to
submit the form, or go back to another page.
Created: 19/12/2000
Last Modified: 19/12/2000
*****************************************************************/
# Execute a query to retrieve the details of the given check...
$qRes = mysql_query("SELECT * FROM sbmCHECKS WHERE chname = "
. "'$chname'");
if($qRes)
{
# In this case, the query worked sans probleme
if(mysql_num_rows($qRes) < 1)
{
# Oh dear, the current check doesn't seem to exist.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERR"
. "OR:</SPAN> The $chname Checking Function Does Not Exist "
. "In " . DOCS_DATABASE . ".<BR>Inform System Administrator."
. "</P>\n");
# Display a button...
errorOKbutton();
# Now mail the admin to tell them this news.
$msgTxt = "An error has ocurred while attempting to retrieve "
. "the details of the $chname checking function from "
. DOCS_DATABASE . ". The query to select the details of this "
. "checking function returned no rows. There must have been "
. "a record for this checking function however, because the "
. "use must have clicked on a link for it to retrieve the "
. "details of it.\n\nThis suggests that there is a problem "
. "with concurrency. Perhaps another user deleted the check "
. "from " . DOCS_DATABASE . " just before the user who tried "
. "to view its details clicked on the link to it.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
# Now send the mail..
mail(ADMIN_EMAIL, "ERROR: Cannot Retrieve $chname Check "
. "Details", $msgTxt, "From: WebSubmit_Administrator");
} // END if
elseif(mysql_num_rows($qRes) > 1)
{
# several instances of the check
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERR"
. "OR:</SPAN> Several Rows Have Been Retrieved For The "
. "<EM>$chname</EM> Checking Function.<BR>Inform System "
. "Administrator.</P>\n");
errorOKbutton();
# mail admin
$msgTxt = "An error has ocurred while attempting to retrieve "
. "the details of the $chname checking function from "
. DOCS_DATABASE . ". The query to select the details of this "
. "checking function returned several rows. The 'chname' "
. "field of the sbmCHECKS table should be unique, as it is used "
. "as the key of the table. This means that there should "
. "only ever be 1 row in the sbmCHECKS table for a given chname "
. "value.\n\nThis means that there must be key violations in "
. "the sbmCHECKS table, and this problem should be examined and "
. "corrected immediately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "ERROR: sbmCHECKS Table Key Violation "
. "($chname)", $msgTxt, "From: WebSubmit_Administrator");
} // END elseif
else
{
# Provide a quick description of the pages function...
print("<TABLE WIDTH='90%' BGCOLOR='#D3DCE3' ALIGN='center' "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN='center'>\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Below, is a"
. " table that allows you to view or edit the details of an "
. "EDS JavaScript checking function.<BR><BR>If you wish to "
. "edit the checking function, you can edit the details of "
. "the <EM>Check Description</EM> field, and then click on"
. " the \"SAVE CHANGES\" button.<BR>If you do not wish to "
. "make any changes to the checking function, simply click on"
. " the \"FINISHED\" button, which will return you to the "
. "page<BR>displaying a list of all checks.</P>\n</TD>\n</TR>"
. "\n</TABLE>\n");
# divide page sections
drawSeparator();
# Get a list of the fields in the sbmCHECKS table
$columns = mysql_list_fields(DOCS_DATABASE, "sbmCHECKS");
$dataRow = mysql_fetch_array($qRes);
# Now begin making the form...
print("<TABLE WIDTH='100%' ALIGN='center' BORDER=0 "
. "CELLSPACING=0 CELLPADDING=0>\n<FORM ACTION='viewChecksEDS"
. ".php' METHOD='post'>\n<INPUT TYPE='hidden' NAME='update"
. "Check' VALUE='true'>\n<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN"
. "='right' WIDTH='20%'>Creation Date:&nbsp;</TH>\n<TD ALI"
. "GN='left' BGCOLOR='#FFFFCC' WIDTH='80%'><INPUT TYPE='"
. "readonly' NAME='cd' VALUE='". $dataRow["cd"] . "'></TD>\n"
. "<TR>\n<TH BGCOLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>"
. "Modification Date:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='"
. "#FFFFCC' WIDTH='80%'><INPUT TYPE='readonly' NAME='md' "
. "VALUE='" . $dataRow["md"] . "'></TD>\n</TR>\n<TR>\n<TH BG"
. "COLOR='#D3DCE3' ALIGN='right' WIDTH='20%'>Check Name:"
. "&nbsp;</TH>\n<TD ALIGN='left' WIDTH='80%' BGCOLOR='#FFFFC"
. "C'><INPUT TYPE='readonly' NAME='chname' VALUE='"
. $dataRow["chname"] . "'>\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR='#87CEFA' ALIGN='right' WIDTH='20%'>Check "
. "Description:&nbsp;</TH>\n<TD ALIGN='left' BGCOLOR='#FFFFC"
. "C' WIDTH='80%'><TEXTAREA COLS=50 ROWS=20 NAME='chdesc'>"
. $dataRow["chdesc"] . "</TEXTAREA></TD>\n</TR>\n</TABLE>\n");
# Now make an other table to hold the various buttons...
print("<TABLE BORDER=0 CELLPADDING=2 CELLSPACING=2 ALIGN='"
. "center'>\n<TR>\n<TD ALIGN='right'><INPUT TYPE='button' "
. "VALUE='SAVE CHANGES' onClick=\"if(confirm('Are You Sure "
. "That You Wish To Alter This Checking Function Descriptio"
. "n?')) { submit(); }\"></TD>\n<TD ALIGN='center'><INPUT "
. "TYPE='button' "
. "VALUE='RESET' onClick=\"reset();\"></TD>\n</FORM>\n<FORM "
. "ACTION='allChecksEDS.php' METHOD='post'>\n<TD ALIGN='left"
. "'><INPUT TYPE='button' VALUE='CANCEL' onClick=\"submit();"
. "\"></TD>\n</TR>\n</TABLE>\n");
} // END else
} // END if
else
{
# query to retrieve the details of the
# check failed, so we can simply output an error message
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Could not query the <EM>sbmCHECKS</EM> table of "
. DOCS_DATABASE . ".<BR>Contact System Administrator.</P>\n");
errorOKbutton();
} // END else
} // END function displayEDScheckDetsForm()
function displayPage()
{
global $updateCheck,$chdesc,$chname;
if($updateCheck)
{
# In this case, this call to the script is a call to commit
# updated details of the given check to the database.
# Get the date for the md field...
$modifiedDate = makeEDSmdDate();
# Make an update string...
$updStr = "UPDATE sbmCHECKS SET md = '$modifiedDate', chdesc = '"
. "$chdesc' WHERE chname = '$chname'";
$updRes = mysql_query($updStr);
if($updRes)
{
if(mysql_affected_rows() == 1)
{
# check has been updated
print("<div style=\"color: green; font-weight: bold; font-size: large; text-align: center;"
. "\">Check Updated</div>\n");
$msgTxt = "The $chname checking function has been updated"
. " in " . DOCS_DATABASE . ".\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$chname Check Updated",
$msgTxt, "From: WebSubmit_Administrator");
mysql_free_result($updRes);
# Redisplay the form with the check in it
displayEDScheckDetsForm($chname);
} // END if
else
{
# The query didn't actually update anything.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">Error: Check Could Not Be Updated!</span></p>\n");
displayEDScheckDetsForm($chname);
} // END else
} // END if
else
{
# update failed, so we can just inform
# the user of this, and redisplay the details of the check in
# the form
print("<p class=\"errorMsg\"><span style=\"color: red\">Error: Check Could Not Be Updated!</span></p>\n");
displayEDScheckDetsForm($chname);
} // END else
} // END if
else
{
# Display the interface...
displayEDScheckDetsForm($chname);
} // END else
}
/**********************Start of main script***************************/
# Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
# Select the CDS Search database...
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid);
if (!$auth[0])
outWarning($auth[1]);
else
displayPage();
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml b/modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml
index c9eaf8ea1..9ae97f238 100644
--- a/modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml
+++ b/modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml
@@ -1,1223 +1,1223 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
<?
require("commonPhpFunctions.php");
?>
#include "cdspage.wml" \
title="Submission Pages of <protect><?print "$subname";?></protect>" \
navtrail_previous_links="<a class=navtrail href=<WEBURL>/admin/<lang:star: index.*.html>>_(Admin Area)_</a> &gt; <a class=navtrail href=<WEBURL>/admin/websubmit/>_(WebSubmit Administration)_</a>" \
navbar_name="admin" \
navbar_select="websubmit"
<?
<protect>
## $Id$
## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.
?>
<SCRIPT LANGUAGE="JavaScript">
<!-- hide
function checkRequired(param)
// This is a function to ensure that the user enters the required
// parameter for the action.
{
// If the field is left blank by the user...
if((param == "") || ((param.toUpperCase() != "Y") &&
(param.toUpperCase() != "N") && (param.toUpperCase() != "O")))
{ // Alert them, and return false.
alert("You must enter a value of Y, N, or O in the displayed field.");
return false;
} // End if
else // If displayed has been filled by the user...
{
return true;
} // End else
} // End function checkRequired(param)<
function verifyChanges(curLevel, sugLevel, curButtonorder, sugButtonorder,
curStatustext, sugStatustext)
// Function to test whether the values for the parameters to be changed
// have actually been changed by the user when they submit them to the
// database for update. If not, the function returns false. If so, the
// function returns true.
{
if(((curLevel == sugLevel) || (sugLevel == curLevel.toLowerCase())) &&
(curButtonorder == sugButtonorder) &&
(curStatustext == sugStatustext))
{
alert("No Change In The Data Has Been Made! Cannot Submit.");
return false;
} // End if
else
{
return true;
} // End else
} // End function verifyChanges()
// -->
</SCRIPT>
<?php
/*********************Function Descriptions***************************/
function displayEDSsubDetsForm($subname, $doctype)
{
/*******************************************************************
This function has the task of actually creating the main page
that shows the details of a submission. It conducts the query,
and from this data, builds an HTML form containing the details of
the given submission type. The user can then alter these details
as they see fit. Links to the pages that the submission is
composed of are also provided. The user can follow these links
to see the details of each of these pages.
*******************************************************************/
global $IMAGES;
// Execute a select query top get the data for the given submission
$queryResult = mysql_query("SELECT * FROM sbmIMPLEMENT WHERE subname ="
. " '$subname'");
if($queryResult)
{
if(mysql_num_rows($queryResult) == 1)
{
// Now, display a quick set of page instructions for the user..
print("<TABLE WIDTH=\"90%\" BGCOLOR=\"#D3DCE3\" ALIGN=\"center\" "
. "CELLSPACING=0 CELLPADDING=0 BORDER=1>\n<TR><TD "
. "ALIGN=\"center\">\n<P STYLE=\"color: blue; text-align: "
. "center; font-size: small; font-weight: bold\">Shown below,"
. " are the details of the \"$subname\" EDS submission.<BR>"
. "Each page number is a link that when clicked, allows you "
. " to further view and or edit the details of that page.<BR>"
. "<BR><BR>It is "
. "also possible to add another page to this submission. "
. "Click \"ADD PAGE\" to do this.</P>\n"
. "</TD>\n</TR>\n</TABLE>\n");
drawSeparator();
print("<FORM ACTION=\"viewEditSubmissionEDS.php\" METHOD=\"post\""
. ">\n<INPUT TYPE=\"hidden\" NAME=\"update\" VALUE=\"true\">\n"
. "<INPUT TYPE=\"hidden\" NAME=\"doctype\" VALUE=\"$doctype\">"
. "<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=\"center"
. "\" WIDTH=\"100%\">\n");
// Now make the table: names & fields...
// Get a list of the columns in the sbmIMPLEMENT table...
$columns = mysql_list_fields(DOCS_DATABASE, "sbmIMPLEMENT");
$numTblFlds = mysql_num_fields($columns);
$dataRow = mysql_fetch_array($queryResult);
// Before we display most of the table, we can first display
// the upper part of the table, which will contain fields
// should be seen, but not be modifiable
print("<TABLE WIDTH=\"100%\" ALIGN=\"center\" CELLSPACING=0 "
. "CELLPADDING=0 BORDER=0>\n<TR>\n<TH BGCOLOR=\"#D3DCE3\" ALIGN"
. "=\"right\" WIDTH=\"20%\">\nSubmission Code:&nbsp;</TH>\n<TD "
. "ALIGN=\"left\" BGCOLOR=\"#FFFFCC\" WIDTH=\"80%\"><INPUT "
. "TYPE=\"readonly\" NAME=\"subname\" VALUE=\""
. $dataRow["subname"] . "\">\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR=\"#D3DCE3\" ALIGN=\"right\" WIDTH=\"20%\">\nNumber of "
. "Pages:&nbsp;</TH>\n<TD WIDTH=\"80%\" ALIGN=\"left\" BGCOLOR="
. "\"#FFFFCC\"><INPUT TYPE=\"readonly\" NAME=\"nbpg\" VALUE=\""
. $dataRow["nbpg"] . "\">\n</TD>\n</TR>\n<TR>\n<TH "
. "BGCOLOR=\"#D3DCE3\" ALIGN=\"right\" WIDTH=\"20%\">\nCreation "
. "Date:&nbsp;</TH>\n<TD WIDTH=\"80%\" ALIGN=\"left\" BGCOLOR="
. "\"#FFFFCC\"><INPUT TYPE=\"readonly\" NAME=\"cd\" VALUE=\""
. $dataRow["cd"] . "\">\n</TD>\n</TR>\n<TR>\n<TH WIDTH=\"20%\""
. " BGCOLOR=\"#D3DCE3\" ALIGN=\"right\">\nModification "
. "Date:&nbsp;</TH>\n<TD WIDTH=\"80%\" ALIGN=\"left\" "
. "BGCOLOR=\"#FFFFCC\"><INPUT TYPE=\"readonly\" NAME=\"md\" "
. "VALUE=\"" . $dataRow["md"] . "\">\n</TD>\n</TR>\n");
for($indx = 0; $indx < $numTblFlds; $indx++)
{
$currentField = mysql_field_name($columns, $indx);
} // END for
// Now add the list of pages
print("<TR>\n<TH BGCOLOR=\"#87CEFA\" ALIGN=\"right\" WIDTH=\"20%\">"
. "\nSubmission Pages:&nbsp;</TH>\n<TD ALIGN=\"left\" WIDTH="
. "\"80%\" BGCOLOR=\"#FFFFCC\">\n");
print("<TABLE BORDER=0 ALIGN=\"left\" CELLPADDING=0 CELLSPACING"
. "=0><TR>");
for($count = 1; $count <= $dataRow["nbpg"]; $count++)
{
print("<TD ALIGN=\"center\">[<A HREF=\"pageDetsEDS.php?subna"
. "me=" . $dataRow["subname"] . "&pageNumber=$count&nPgs="
. $dataRow["nbpg"] . "&doctype=$doctype\">"
. $dataRow["subname"] . " Page $count</A>]&nbsp;</TD>");
} // END for
print("</TR>\n<TR>\n");
// Now add "move a page higher in the order" and "move a page
// lower in the order" buttons
for($count = 1; $count <= $dataRow["nbpg"]; $count++)
{
print("<TD ALIGN=\"center\"><TABLE BORDER=0 CELLSPACING=0 "
. "CELLPADDING=0 ALIGN=\"center\"><TR><TD ALIGN=\"center\">");
// Test to see if this is the first page or the last page.
// If so, then we must only print an image <IMG> of an
// arrow, as opposed to an <A><IMG></A> arrow, as we don't
// want the page to be moved beyond the page 1, or page x
// (at the end) boundaries.
// Add the "left" arrow
if($count == 1)
{
print("<IMG SRC=\"".$IMAGES."/forbidden_left.gif\" ALT=\""
. "Unable To Increase Page Order Weighting: Already "
. "First Page!\" HEIGHT=14 WIDTH=14>");
}
else
{
print("<A HREF=\"viewEditSubmissionEDS.php?doctype="
. "$doctype&pageNumber=$count&nPgs=" . $dataRow["nbpg"]
. "&subname=" . $dataRow["subname"] . "&pageLeft=true'"
. " onClick=\"if(confirm('Taking this action will move "
. "a page and all of its elements one page sooner in "
. "the page order sequence.\\nAre you sure you want to "
. "do this?')) { return true; } else { return false; "
. "}\"><IMG BORDER=0 SRC=\"".$IMAGES."/left.gif\" ALT=\"Incre"
. "ase Page Weighting Order\" HEIGHT=14 WIDTH=14>"
. "</A>");
}
print("</TD><TD ALIGN=\"center\">");
// Add the "right" arrow
if($count == $dataRow["nbpg"])
{
print("<IMG SRC=\"".$IMAGES."/forbidden_right.gif\" ALT=\""
. "Unable To Decrease Page Order Weighting: Already "
. "Last Page!\" HEIGHT=14 WIDTH=14>");
}
else
{
print("<A HREF=\"viewEditSubmissionEDS.php?doctype="
. "$doctype&pageNumber=$count&nPgs=" . $dataRow["nbpg"]
. "&subname=" . $dataRow["subname"] . "&pageRight=true'"
. " onClick=\"if(confirm('Taking this action will move "
. "a page and all of its elements one page later in the"
. " page order sequence.\\nAre you sure you want to do "
. "this?')) { return true; } else { return false; }\">"
. "<IMG BORDER=0 SRC=\"".$IMAGES."/right.gif\" ALT=\"Decreas"
. "e Page Weighting Order\" HEIGHT=14 WIDTH=14></A>");
}
print("</TD></TR></TABLE></TD>\n");
}
print("</TR>\n<TR>\n");
// Now add a delete button for each page of the submission
for($count = 1; $count <= $dataRow["nbpg"]; $count++)
{
print("<TD ALIGN=\"center\"><A HREF=\"viewEditSubmissionEDS."
. "php?doctype=$doctype&pageNumber=$count&nPgs="
. $dataRow["nbpg"] . "&subname=" . $dataRow["subname"]
. "&deletePage=true' onClick=\"if(confirm('Warning: Taking"
. " this action will delete this submission page and all "
. "of the elements on it.\\nThis action is irreversable!"
. "\\nAre you sure you want to do this?'))"
. "{ return true; } else { return false; }\"><IMAGE "
. "SRC=\"".$IMAGES."/answer_bad.gif\" BORDER=0 WIDTH=12 HEIGHT="
. "12 ALT=\"Delete Page And All Elements\"></A></TD>");
}
print("</TR>\n</TABLE>");
print("&nbsp;</TD>\n</TR>\n</TABLE>\n</TABLE>\n");
print("<TABLE ALIGN=\"center\" CELLSPACING=2 CELLPADDING=0 "
. "BORDER=0><TR><TD ALIGN=\"center\"></TD></FORM>"
. "<FORM ACTION=\"viewEditSubmissionEDS.php\" METHOD=\"post\">"
. "<INPUT TYPE=\"hidden\" NAME=\"nPgs\" VALUE=\""
. $dataRow["nbpg"] . "\">"
. "<INPUT TYPE=\"hidden\" NAME=\"addPage\" VALUE=\"true\"><INPUT "
. "TYPE=\"hidden\" NAME=\"subname\" VALUE=\"$subname\"><INPUT TYPE="
. "\"hidden\" NAME=\"doctype\" VALUE=\"$doctype\"><TD><INPUT "
. "TYPE=\"button\" VALUE=\"ADD A PAGE\" onClick=\"if(confirm('Are"
. " You Certain You Wish To Add Another Page To This "
. "Submission?')) { submit(); } else { return false; }\">"
. "</TD></FORM><FORM ACTION=\"documentEDS.php\" METHOD=\"post\">"
. "<INPUT TYPE=\"hidden\" NAME=\"doctype\" VALUE=\"$doctype\"><TD>"
. "<INPUT TYPE=\"button\" VALUE=\"FINISHED\" onClick=\"submit();"
. "\"></TD></FORM></TR></TABLE>");
}
elseif(mysql_num_rows($queryResult) > 1)
{
// too many rows in the result set. This
// indicates some sort of key duplication in the sbmIMPLEMENT
// table.
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> More "
. "than one row of data concerning the <EM>$subname</EM> "
. "action was returned from the <EM>sbmIMPLEMENT</EM> table of "
. "the" . DOCS_DATABASE . " database.<BR>This indicates "
. "primary key duplication in this table.<BR>Please inform "
. "system administrator.</P>\n");
// warn admin
$msgTxt = "When a user attempted to look further into the "
. "details of the $subname submission using the EDS "
. "Administrator, several rows were returned for this "
. "submission from the sbmIMPLEMENT table."
. " The query was made using the \"subname\" as the search"
. " key. As the \"subname\" field is the primary key for "
. "the sbmIMPLEMENT table, this means that there must be key "
. "violations in this table.\n\nThis problem should be "
. "corrected immediately.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "sbmIMPLEMENT Table Key Violation!", $msgTxt,
"From: WebSubmit_Administrator");
}
elseif(mysql_num_rows($queryResult) == 0)
{
// no rows returned
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No data concerning the <EM>$subname</EM> "
. "submission was found in the <EM>sbmIMPLEMENT</EM> table.<BR>"
. "This suggests a data consistency error in the "
. DOCS_DATABASE . " database.<BR>Please inform the system "
. "administrator.</P>\n");
// warn admin
$msgTxt = "When a user attempted to look further into the "
. "details of the $subname submission using the EDS "
. "Administrator, no rows were returned from the sbmIMPLEMENT "
. "table for this submission.\n\nBecause the user had to "
. "click a link to view the details of this submission, it "
. "must be referred to in other tables of EDS. This suggests"
. " that there are data inconsistencies within EDS.\n\nThis "
. "should be investigated and corrected ASAP.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Possible Data Inconsistency Error!",
$msgTxt, "From: WebSubmit_Administrator");
}
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to correctly retrieve data from the "
. "<EM>sbmIMPLEMENT</EM> table of " . DOCS_DATABASE
. ".<BR>Please inform system administrator.</P>\n");
}
}
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">ERROR:"
. "</SPAN> Unable to query the <EM>sbmIMPLEMENT</EM> table.<BR>"
. "Please inform system administrator.</P>\n");
}
} // END function displayEDSsubDetsForm($subname, $doctype)
//**************
function moveSubPage($doctype, $pageNumber, $nPgs, $subname,
$page2move2)
{
/*****************************************************************
This function has the task of moving a page either to the left,
or to the right, depending upon which direction button the user
has pressed for the movement. The function is passed a variable
$page2move2, which holds the value of the page that the current
page is to be moved to. This must always be either $pageNumber
+ 1, or $pageNumber - 1. This is important, and the way that I
have written this script will only call this function in the
correct manner. This function should not be used for swapping
pages that are separated by other pages, as that should not be
done. If a page is ever to be moved to a location several pages
away, the other pages should be displaced like dominos into the
position to fill the gap!
This function saves a lot of code duplication, as there are many
errors that could happen during the execution of a page movement.
Some of these errors could be rather serious, and so it is
necessary to give both the user amd the system administrator a
detailed explanation of what has happened in each case. This
means big error message sections.
In the EDS database, there is no such entity as a "submission
page". Instead, there are elements, which have a page number and
a submission name. This means that when we move a page, we must
first move all of the elements on it to a temporary page. In
this case, the chosen temporary page number is 0. Next, all
elements on the page whose position our page is being moved to
are given a page number of that of the page that we are moving.
Finally, all of the elements with a page number of 0 are given a
page number of the position that we wanted to move the page to.
This is how this function works - a simple "swap" algorithm.
In the even of an error occurring, the function attempts to put
everything back to the way it was when it started the movement.
Of course this may not be possible. The function gives error
message feedback at all stages possible, letting the admin/user
know whether or not recovery succeeded etc, or where it failed,
and offers suggestions on how to correct the problems.
*****************************************************************/
// Get the current date for the "md" field...
$modifiedDate = makeEDSmdDate();
// Make a query string to set the 'pagenb' field of all elements on
// the current page to '0' (zero). Done as a temporary measure for
// swapping pages around.
$qStr1 = "UPDATE sbmFIELD SET pagenb = '0' WHERE subname = '$subname'"
. " AND pagenb = '$pageNumber'";
$qRes1 = mysql_query($qStr1);
if($qRes1)
{
// Set the value of the pagenb field for all elements of the page
// before the page to be moved to have a pagenb value of the
// current page (that which we are moving).
$qStr2 = "UPDATE sbmFIELD SET pagenb = '$pageNumber', md = '"
. "$modifiedDate' WHERE subname = '$subname' AND pagenb = '"
. "$page2move2'";
$qRes2 = mysql_query($qStr2);
if($qRes2)
{
// have moved all elements of the page that was before the page we are moving
// to effectively be in the place of the page that we are
// moving. i.e. the page before it now sits in its place.
// Now make a query string to move the elements that are on
// "page zero" to their final position...
$qStr3 = "UPDATE sbmFIELD SET pagenb = '$page2move2"
. "', md = '$modifiedDate' WHERE subname = '$subname' AND "
. "pagenb = '0'";
$qRes3 = mysql_query($qStr3);
if($qRes3)
{
// we should now have fully switched our pages around. We
// should now update the md field of the submission in
// sbmIMPLEMENT, and the doctype in sbmDOCTYPE...
$mdResult = mysql_query("UPDATE sbmIMPLEMENT SET md = "
. "'$modifiedDate' WHERE subname = '$subname'");
if($mdResult)
{
mysql_free_result($mdResult);
}
else
{
// The update the date query failed
print("<SCRIPT LANGUAGE=\"JavaScript\">alert('Error: "
. "Couldn't update the md in sbmIMPLEMENT!');</SCRIPT>\n");
}
// We must also modify the md field of the doctype record to
// which this submission belongs
updateEDSDOCTYPEmd($doctype, $modifiedDate);
}
else
{
// Failure. Attempt to recover by moving things back to their
// original positions:
$majorRecoveryStr1 = "UPDATE sbmFIELD SET pagenb = '"
. "$page2move2' WHERE subname = '$subname' AND "
. "pagenb = '$pageNumber'";
$majorRecoveryRes1 = mysql_query($majorRecoveryStr1);
if($majorRecoveryRes1)
{
// first step recovered. Now attempt to return
// the elements on page 0 to their original page...
$majorRecoveryStr2 = "UPDATE sbmFIELD SET pagenb = '"
. "$pageNumber' WHERE subname = '$subname' AND pagenb ="
. " '0'";
$majorRecoveryRes2 = mysql_query($majorRecoveryStr2);
if($majorRecoveryRes2)
{
// completely recovered
print("<SCRIPT TYPE=\"text/javascript\">\nalert('An "
. "error occurred when an attempt was made to move "
. "the requested submission page.\\nWhen a "
. "submission page is moved, all of "
. "the elements on the page to be moved are given a"
. " temporary page number of 0.\\nThe elements of "
. "the page whose position it is to be moved to are"
. " then given a page number of the current page\\n"
. "and then the elements with a page number of 0 are"
. " then given a page number of the page that they "
. "are to be moved to.\\n\\nWhen this page movent "
. "was carried out however, the elements of page to"
. " be moved were moved to\\npage 0 without trouble."
. " The elements of the page whose position the "
. "page to be moved to was to be moved to\\nwere "
. "moved to the position of the page to be moved "
. "without any problem.\\nHowever, when an attempt "
. "was made to move the elements of the temporary "
. "page 0\\nto their new location, this was not "
. "possible.\\n\\nTo rectify this situation, an "
. "attempt was made to return the elements that were"
. " moved to page $pageNumber\\nback to page "
. "$page2move2, which suceeded. An attempt"
. " was then made to move all elements from\\nthe "
. "temporary page 0 back to page $pageNumber (the "
. "page on which they were originally positioned)."
. "\\nThis attempt succeeded.\\n\\nThis means that "
. "the $subname submission should appear as if it "
. "were never changed.\\nYou should however ensure "
. "that the pages of this submission are "
. "un-corrupted by checking each page manually.\\n"
. "\\nYou should inform the system administrator of "
. "this problem.');\n</SCRIPT>\n");
// email the administrator
$msgTxt = "A major problem has ocurred with the data"
. " for the $subname submission. An attempt was "
. "made to move page $pageNumber to another position"
. ".\n\nWhen a page is moved, all of the elements on"
. " the page to be moved are given a temporary page "
. "number of 0. The elements of the page whose "
. "position it is to be moved to are then given a "
. "page number of the current page and then the "
. "elements with a page number of 0 are then given a"
. " page number of the page that they are to be "
. "moved to.\n\nWhen this page movent was carried "
. "out for page $pageNumber however, the "
. "elements of page to be moved were moved to page 0"
. " without trouble. The elements of the page whose"
. "position page $pageNumber was to be moved to were"
. " moved to the position of page $pageNumber "
. "without any problem. However, when an attempt "
. "was made to move the elements of the temporary "
. "page 0 to their new location, this was not "
. "possible.\n\nTo rectify this situation, an "
. "attempt was made to return the "
. "elements that were moved to page $pageNumber back"
. " to page $page2move2, which suceeded. "
. " When an attempt was made to move the elements of"
. " the temporary page 0 back to page $pageNumber, "
. "this also succeeded.\n\nThis all means that the "
. "submission SHOULD look as though it were never "
. "altered, and the pages should appear as normal, "
. "as the system correction of the problem appears "
. "to have succeeded. However, you should manually"
. " check this submission to ensure that this is the"
. " case, as it is possible that some elements from "
. "the pages may have been lost.\n\nEDS "
. "Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Page Movement"
. " Error", $msgTxt, "From: WebSubmit_Administrator");
}
else
{
// Couldnt return our page 0 elements to their original page
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR"
. ": A major problem has ocurred with the data for "
. "this submission.\\nWhen a page is moved, all of "
. "the elements on the page to be moved are given a"
. " temporary page number of 0.\\nThe elements of "
. "the page whose position it is to be moved to are"
. " then given a page number of the current page\\n"
. "and then the elements with a page number of 0 are"
. " then given a page number of the page that they "
. "are to be moved to.\\n\\nWhen this page movent "
. "was carried out however, the elements of page to"
. " be moved were moved to\\npage 0 without trouble."
. " The elements of the page whose position the "
. "page to be moved to was to be moved to\\nwere "
. "moved to the position of the page to be moved "
. "without any problem.\\nHowever, when an attempt "
. "was made to move the elements of the temporary "
. "page 0\\nto their new location, this was not "
. "possible.\\n\\nTo rectify this situation, an "
. "attempt was made to return the elements that were"
. " moved to page $pageNumber\\nback to page "
. "$page2move2, which suceeded. When an "
. " attempt was made to move the elements of the "
. "temporary page 0 back to page $pageNumber,\\nthis"
. " failed, therefore the elements that were "
. "origionally on page $pageNumber before the move "
. "was attempted\\nare now sitting on the temporary"
. " page 0. This means that when an attempt is made "
. "to view the elements of page $pageNumber,\\nthere"
. " will be nothing there.\\n\\nPlease inform the "
. "system administrator of this problem immediately "
. "so that it can be corrected.');\n</SCRIPT>\n");
$msgTxt = "A major problem has ocurred with the data"
. " for the $subname submission. An attempt was "
. "made to move page $pageNumber to another position"
. ".\n\nWhen a page is moved, all of the elements on"
. " the page to be moved are given a temporary page "
. "number of 0. The elements of the page whose "
. "position it is to be moved to are then given a "
. "page number of the current page and then the "
. "elements with a page number of 0 are then given a"
. " page number of the page that they are to be "
. "moved to.\n\nWhen this page movent was carried "
. "out for page $pageNumber however, the "
. "elements of page to be moved were moved to page 0"
. " without trouble. The elements of the page whose"
. "position page $pageNumber was to be moved to were"
. " moved to the position of page $pageNumber "
. "without any problem. However, when an attempt "
. "was made to move the elements of the temporary "
. "page 0 to their new location, this was not "
. "possible.\n\nTo rectify this situation, an "
. "attempt was made to return the "
. "elements that were moved to page $pageNumber back"
. " to page $page2move2, which suceeded. "
. " When an attempt was made to move the elements of"
. " the temporary page 0 back to page $pageNumber, "
. "this failed, therefore the elements that were "
. "origionally on page $pageNumber before the move "
. "was attempted are now sitting on the temporary "
. "page 0.\n\nYou can probably correct this problem "
. "by using the following query. However, you "
. "should investigate first, as this is only a "
. "suggestion.\n\nUPDATE sbmFIELD SET pagenb = '"
. "$pageNumber' WHERE pagenb = '0' AND subname = '"
. "$subname';\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Page Movement"
. " Error", $msgTxt, "From: WebSubmit_Administrator");
}
}
else
{
// could not recover from error
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: "
. "A major problem has ocurred with the data for "
. "this submission.\\nWhen a page is moved, all of "
. "the elements on the page to be moved are given a"
. " temporary page number of 0.\\nThe elements of "
. "the page whose position it is to be moved to are"
. " then given a page number of the current page\\n"
. "and then the elements with a page number of 0 are"
. " then given a page number of the page that they "
. "are to be moved to.\\n\\nWhen this page movent "
. "was carried out however, the elements of page to"
. " be moved were moved to\\npage 0 without trouble."
. " The elements of the page whose position the "
. "page to be moved to was to be moved to\\nwere "
. "moved to the position of the page to be moved "
. "without any problem.\\nHowever, when an attempt "
. "was made to move the elements of the temporary "
. "page 0\\nto their new location, this was not "
. "possible.\\n\\nTo rectify this situation, an "
. "attempt was made to return the elements that were"
. " moved to page $pageNumber\\nback to page "
. "$page2move2.\\nThis attempt failed, "
. "which meant that the elements on page 0 could not"
. " be moved to page $pageNumber\\nas there are "
. "already elements belonging to another page on "
. "there.\\n\\nThe system can do no more to fix this"
. " problem, and you should contact the system "
. "administrator immediately\\nto ensure that this "
. "situation is rectified.');\n</SCRIPT>\n");
$msgTxt = "A major problem has ocurred with the data"
. " for the $subname submission. An attempt was "
. "made to move page $pageNumber to another position"
. ".\n\nWhen a page is moved, all of the elements on"
. " the page to be moved are given a temporary page "
. "number of 0. The elements of the page whose "
. "position it is to be moved to are then given a "
. "page number of the current page and then the "
. "elements with a page number of 0 are then given a"
. " page number of the page that they are to be "
. "moved to.\n\nWhen this page movent was carried "
. "out for page $pageNumber however, the "
. "elements of page to be moved were moved to page 0"
. " without trouble. The elements of the page whose"
. "position page $pageNumber was to be moved to were"
. " moved to the position of page $pageNumber "
. "without any problem. However, when an attempt "
. "was made to move the elements of the temporary "
. "page 0 to their new location, this was not "
. "possible.\n\nTo rectify this situation, an "
. "attempt was made to return the "
. "elements that were moved to page $pageNumber back"
. " to page $page2move2. This however"
. " failed, which meant that the elements on page 0 "
. "had to remain on page 0.\n\nThis means that there"
. " is a situation where by the elements that belong"
. " on page $pageNumber are now on page 0, and the "
. "elements that belong on page $page2move2"
. " are now on page $pageNumber.\n\nYou should "
. "ensure that this situation is corrected ASAP.\n\n"
. "WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Page Movement "
. "Error", $msgTxt, "From: WebSubmit_Administrator");
}
}
}
else
{
// have altered the current pages
// elements to be on page zero, but can't seem to alter the
// position of the elements on the page before current
// page. put back our page zero elements to
// the current page, and leave the whole
// thing unchenged.
$errorCorrect = mysql_query("UPDATE sbmFIELD SET pagenb = '"
. "$pageNumber' WHERE subname = '$subname' AND pagenb = '"
. "0'");
if($errorCorrect)
{
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: It"
. " was not possible to move the elements of the page that"
. "\\nwhose position page $pageNumber is to be moved to."
. "\\nThis has meant that it is not possible to move page "
. "$pageNumber.\\n\\nPlease inform the system "
. "administrator of this problem.');\n</SCRIPT>\n");
}
else
{
// failed to recover
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: A "
. "major problem has ocurred with the data for this "
. "submission.\\nWhen a page is moved, all of the elements"
. " on the page to be moved are given a temporary page "
. "number of 0.\\nThe elements of the page whose position "
. "it is to be moved to are then given a page number of "
. "the current page\\nand then the elements with a page "
. "number of 0 are then given a page number of the page "
. "that they are to be moved to.\\n\\nHowever, in this "
. "case we moved the current pages elements to page 0, but"
. " when we attempted to move the elements\\nof the page, "
. "whose sequence number is the destination of the current"
. " page, to the current page\\nwe were unable to do this."
. " Then when we recognised this error, and attempted "
. "to\\ncorrect it by moving the page 0 elements back to "
. "their original page, we were\\nunable to do this!\\n\\n"
. "This means that the page that you have tried to move "
. "will now have no elements, as they are all on page 0!"
. "\\n\\nThe administrator should be informed of this "
. "immediately!');\n</SCRIPT>\n");
$msgTxt = "A serious error has ocurred while trying to "
. "move a page of a submission to another position.\n\n"
. "When a page is moved, all of the elements on the page "
. "to be moved are given a temporary page number of 0. "
. "The elements of the page whose position it is to be "
. "moved to are then given a page number of that of the "
. "page that we are actually moving, and then the elements"
. " with a page number of 0 are then given a page number "
. "of the page that they are to be moved to.\n\nHowever, "
. "when an attempt was made to move page $pageNumber of "
. "the $subname submission of the $doctype document type "
. "to another position, the elements of page $pageNumber "
. "were moved to 'page 0', but when an attempt was made "
. "to move the elements of the page whose sequence number "
. "is the destination of the current page to the current "
. "page, it was not possible to do this. When this error "
. "was reconised, an attempt was made to correct the "
. "problem by moving all elements of page 0 of the "
. "$subname submission (the temporary page) back to page "
. "$pageNumber. The query to do this also failed, which "
. "effectively left the elements of page $pageNumber of "
. "the $subname submission stranded on page 0.\n\nThis is "
. "a serious problem, but can be corrected by running an "
. "update query to move the elements back to the correct "
. "page. Use the following query to do this manually:\n\n"
. "UPDATE sbmFIELD SET pagenb = '$pageNumber' WHERE subname ="
. " '$subname' and pagenb = '0';\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Page Movement "
. "Error", $msgTxt, "From: WebSubmit_Administrator");
}
}
}
else
{
// couldn't change the pagenb field for the elements on the
// current field
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: It was not"
. " possible to alter the page numbers for the elements on the "
. "page to be moved.\\nThis error ocurred in the sbmFIELD table.\\n"
. "Unable to carry out page movement - inform system "
. "administrator.');\n</SCRIPT>\n");
$msgTxt = "An error has ocurred while attempting to move a "
. "submission page. The submission was the $subname submission "
. "of the $doctype document type, and an attempt was made to "
. "move page $pageNumber.\n\nIt was not possible to assign a "
. "temporary value of 0 (zero) to the 'pagenb' field of the "
. "elements belonging to this page in the sbmFIELD table. This "
. "meant that it was not possible to carry out the movement of "
. "the page.\n\nThis problem should be investigated as soon as "
. "possible.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Page Movement Error",
$msgTxt, "From: WebSubmit_Administrator");
}
} // END function moveSubPage()
//*************
function deleteSubmissionPage($subname, $pageNumber, $nPgs, $doctype)
{
/******************************************************************
The task of this function is to delete a page from a given
submission of a given doctype. The function is passed several
variables which allow it to do this.
The function deletes the given page, and then renumbers all
elements for each page after the deleted page. It then the value
for the number of pages that the submission has by 1. It also
updates all relevant modified date fields (elements, submission
and doctype).
In the event of an error occurring, the relevant people are
informed. If an error ocurrs during the renumberring, the
renumberring is terminated to avoid further data corruption. The
admin is informed of this situation, and told what actions should
be taken.
******************************************************************/
$updStr = "DELETE FROM sbmFIELD WHERE subname = '$subname' AND "
. "pagenb = '$pageNumber'";
$updRes = mysql_query($updStr);
if($updRes)
{
$modifiedDate = makeEDSmdDate();
$errorOn = 0;
for($i = $pageNumber + 1; $i <= $nPgs; $i++)
{
$reorderStr = "UPDATE sbmFIELD SET pagenb = '" . ($i - 1)
. "', md = '$modifiedDate' WHERE subname = '$subname' AND"
. " pagenb = '$i'";
$reorderRes = mysql_query($reorderStr);
if($reorderRes)
{
mysql_free_result($reorderRes);
}
else
{
// could not reorder the elements of this page to
// appear on another.
print("<SCRIPT TYPE=\"text/javascript\">\nalert('Error: "
. "During the process of deleting the page, it is "
. "necessary to first delete the elements of the current"
. "\\npage, and then move the elements of all pages after"
. " the deleted page down one page in turn in order to "
. "fill\\nin the gap left by the deleted page. When page"
. " $pageNumber was deleted however, during the process "
. "of moving the pages after it down into the gaps,\\nit "
. "was not possible to move the elements of page $i onto "
. "page " . ($i - 1) . ".\\nThis meant that it was "
. "necessary to stop the process of reordering, as it "
. "would have resulted in further corruption if the "
. "process had been continued.\\n\\nThis problem should "
. "be corrected manually, and you should inform the system"
. " administrator ASAP.');\n</SCRIPT>\n");
$msgTxt = "An error has ocurred during the deletion of a "
. "page from the $subname submission of the $doctype "
. "document type. When a page is deleted from a "
. "submission, the first step is to delete the page to "
. "be deleted. The next step is to move any pages, after"
. " the deleted page, down by 1 position. This involves "
. "renumberring any elements of these pages to have a "
. "value of pagenb - 1.\n\nDuring the renumberring of "
. "elements after the deletion of page $pageNumber from "
. "the $subname submission however, an error ocurred which"
. " meant it was not possible to give the elements that "
. " currently lie on page $i a value of pagenb = "
. ($i - 1) . ".\n\nTo avoid further data corruption, the "
. "re-numberring was terminated after this error, so it "
. "will be necessary to manually decrement by 1 the "
. "'pagenb field for all elements on page $i and each page"
. " after this. It will then be necessary to decrement "
. "the value of the 'nbpg' field in the 'sbmIMPLEMENT' table "
. "for the '$subname' submission.\n\nBEFORE TAKING THESE "
. "ACTIONS, EXAMINE THE DATA TO ENSURE THAT THE USER HAS "
. "NOT ALREADY DONE THIS.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Page Deletion Error",
$msgTxt, "From: WebSubmit_Administrator");
$errorOn = 1;
break;
}
}
// if $errorOn has not been set, decrement the value of the
// nbpg field in sbmIMPLEMENT for the current submission, and update
// the md field of the current doctype & submission
if(!$errorOn)
{
// Update the number of pages for this submission
$nmPgUpdtStr = "UPDATE sbmIMPLEMENT SET nbpg = '" . ($nPgs - 1)
. "', md = '$modifiedDate' WHERE subname = '$subname'";
$nmPgUpdtRes = mysql_query($nmPgUpdtStr);
if(!$nmPgUpdtRes)
{
// In this case, the query has failed, so we must inform the
// administrator that they must decrement the number of
// pages for the submission by 1
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: The"
. " page has been deleted successfully, but it was not "
. "possible\\nto decrement the number of submission pages "
. "for this submission.\\n\\nPlease inform the system "
. "administrator of this.');\n</SCRIPT>\n");
$msgTxt = "An error has ocurred during the deletion of "
. "page $pageNumber of the $subname submission. The page"
. " was successfully deleted, but it was not possible to "
. "decrement the value of the 'nbpg' field for this "
. "submission in the sbmIMPLEMENT table.\n\nThis should be "
. "done manually as soon as possible, as there is now a "
. "blank page in the submission.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Page Deletion Error",
$msgTxt, "From: WebSubmit_Administrator");
}
updateEDSDOCTYPEmd($doctype, $modifiedDate);
}
}
else
{
# unable to delete page
print("<SCRIPT TYPE=\"text/javascript\">\nalert('An error ocurred"
. " when trying to delete this page, which meant that its "
. "deletion was impossible.\\nNo change to the submission data "
. "has been made.\\n\\nTry again, or inform the system "
. "administrator.');\n</SCRIPT>\n");
}
} // END function deleteSubmissionPage()
function displayPage($update)
{
global $buttonorder,$displayed,$statustext,$subname,$doctype,$addPage,$nPgs,$pageNumber,$pageLeft,$pageRight,$deletePage;
if(isset($update))
{
// If this variable has been set, it means that this call to the
// page is a call to update the detials of a submission type.
// Ensure that "displayed" is storedin the database in uppercase...
$displayed = strtoupper($displayed);
// Get the data, so that it can be committed for the modification
// date field (md)...
$modifiedDate = makeEDSmdDate();
$updStr = "UPDATE sbmIMPLEMENT SET displayed = '$displayed', buttonorder =";
// Ensure that we don't accidentally put the value '0' into the
// buttonorder field, when we actually want to put a NULL into it
// (and vice- versa)...
if(!$buttonorder)
{
if($buttonorder == '0')
$updStr .= " '$buttonorder', ";
else
$updStr .= " NULL, ";
}
else
{
$updStr .= " '$buttonorder', ";
}
$updStr .= "statustext = '$statustext', md = "
. "'$modifiedDate' WHERE subname = '$subname'";
$updateRs = mysql_query($updStr);
if($updateRs)
{
if(mysql_affected_rows() == 1)
{
updateEDSDOCTYPEmd($doctype, $modifiedDate);
print("<SMALL STYLE=\"color: green; font-weight: bold; "
. "text-align: center\">Update Complete</SMALL>\n<BR>\n");
$msgTxt = "An update has been carried out on the $subname "
. "submission type in the " . DOCS_DATABASE
. " database.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "$subname Submission Type Updated",
$msgTxt, "From: WebSubmit_Administrator");
displayEDSsubDetsForm($subname, $doctype);
}
elseif(mysql_affected_rows() > 1)
{
// More than 1 row was updated
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Multiple rows have been updated in the "
. "<EM>sbmIMPLEMENT</EM> table.<BR>This has resulted from an "
. "attempt to update the <EM>$subname</EM> submission "
. "type.<BR>Please inform the system administrator."
. "</P>\n");
updateEDSDOCTYPEmd($doctype, $modifiedDate);
$msgTxt = "When a user updated the details of "
. "the $subname submission type using the EDS Administra"
. "tor, several rows were affected in the sbmIMPLEMENT table."
. " The update was conducted using the \"subname\" field "
. "as the key. As the \"subname\" field is the primary "
. "key for the sbmIMPLEMENT table, this means that there must"
. " be key violations in this table. There should only "
. "have been 1 row affected by this update.\n\nThis proble"
. "m should be investigated and corrected immediately.\n\n"
. "WebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "ERROR: sbmIMPLEMENT Table Multiple Row "
. "Update!", $msgTxt, "From: WebSubmit_Administrator");
}
else
{
// No rows were updated
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>"
. "sbmIMPLEMENT</EM> table.<BR>This suggests that there could"
. " be data inconsistencies or concurrency problems.<BR>"
. "Please inform the system administrator.</P>\n");
$msgTxt = "When a user attempted to update the details of "
. "the $subname submission type using the EDS Administrat"
. "or, no rows were affected in the sbmIMPLEMENT table by "
. "this update.\n\nBecause the user must have altered a "
. "submission types details to submit an update on it, it "
. "must have been present at around the time that the user"
. " submitted their update.\n\nThis suggests the possibili"
. "ty of concurrency or data inconsistency problems in thi"
. "s table.\n\nThis should be investigated and corrected "
. "ASAP.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Error: Possible Concurrency Problems",
$msgTxt, "From: WebSubmit_Administrator");
}
}
else
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> No rows have been updated in the <EM>"
. "sbmIMPLEMENT</EM> table.<BR>This suggests that there could"
. " be data inconsistencies or concurrency problems.<BR>Plea"
. "se inform the system administrator.</P>\n");
}
}
elseif($addPage)
{
// add page to submission. get the current
// number of pages in the document, increment it by 1, and then
// redirect the browser focus to the "pageDetsEDS.php" for the new page
$nPgs++;
$modifiedDate = makeEDSmdDate();
// Now, we can update the "nbpg" field in the sbmIMPLEMENT table to
// the value of this "$nPgs" variable, to reflect the addition of
// the new page.
$updRes = mysql_query("UPDATE sbmIMPLEMENT SET nbpg = '$nPgs', md ="
. " '$modifiedDate' WHERE subname = '$subname'");
if($updRes)
{
// query executed without error
// ensure that it has only updated one row.
if(mysql_affected_rows() > 1)
{
// too many rows have been updated
updateEDSDOCTYPEmd($doctype, $modifiedDate);
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: "
. "Several rows were updated in the sbmIMPLEMENT table for "
. "the $subname submission when we added a page to "
. "it.\\nBecause the \"subname\" field is the primary key"
. "for the sbmIMPLEMENT table, this suggests a primary key "
. "violation.\\n\\nPlease inform the system administrator "
. "administrator');</SCRIPT>\n");
$msgTxt = "An error has ocurred when a new page was added "
. "to the $subname submission. When this action was under"
. "taken, more than 1 rows was updated in the sbmIMPLEMENT "
. "table. This means that there must be more than 1 "
. "instance of this submission in this table.\n\nBecause "
. "the \"subname\" field is the primary key for the "
. "sbmIMPLEMENT table, this it is illegal to have more than "
. "one row for the same submission, and this is therefore "
. "a primary key violation.\n\nYou should look into this "
. "situation immediately, as it is a serious error, and "
. "could cause system problems.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Error - $subname Submission "
. "Duplication",
$msgTxt, "From: WebSubmit_Administrator");
displayEDSsubDetsForm($subname, $doctype);
}
elseif(mysql_affected_rows() <= 0)
{
print("<P CLASS=\"errorMsg\"><SPAN STYLE=\"color: red\">"
. "ERROR:</SPAN> Unable to update $subname submission det"
. "ails. No page added.</P>");
$msgTxt = "An error has ocurred when trying to add a new "
. "page to the $subname submission of the $doctype documen"
. "t type. When an attempt was made to increment the valu"
. "e of the nbpg field in the sbmIMPLEMENT table by 1 for "
. "this submission, no rows were affected by the update.\n"
. "\nThis suggests that the submission does not exist in "
. "this table. There could be concurrency problems, as it"
. " is possible that during the time between the details "
. "of the submission being displayed, and the 'ADD PAGE' "
. "button being pressed by the user, the submission was "
. "deleted by another user.\n\nThis situation should be "
. "investigated.\n\nWebSubmit Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "EDS Error - $subname Not Found",
$msgTxt, "From: WebSubmit_Administrator");
// instead of redisplaying the details of this
// submission, redirect the browser to the
// "documentEDS.php" page, as there is no point in
// redisplaying the submission details if it is possible
// that another user has deleted it. If it still exists,
// the user can simply look at the submission again.
print("<FORM NAME=\"referForm\" ACTION=\"documentEDS.php\" "
. "METHOD=\"post\">\n<INPUT TYPE=\"hidden\" NAME=\"doctype\" "
. "VALUE=\"$doctype\">\n</FORM>\n<SCRIPT TYPE=\"text/javas"
. "cript\">\nsetTimeout(\"document.referForm.submit();\","
. " 1000);\n</SCRIPT>\n");
}
else
{
updateEDSDOCTYPEmd($doctype, $modifiedDate);
print("<P STYLE=\"color: green; text-align: center; font-"
. "size: large\">New Page Added To <EM>$subname</EM> "
. "Submission.</P>\n");
$msgTxt = "A new page has been added to the $subname "
. "submission of the $doctype document type. This new "
. "page has been inserted as the last page in the "
. "submission and therefore is page number $nPgs.\n\nEDS"
. " Administrator (";
$msgTxt .= makeDate();
$msgTxt .= ")";
mail(ADMIN_EMAIL, "Page $nPgs Added To $subname "
. "Submission", $msgTxt, "From: WebSubmit_Administrator");
// Now redirect the browser to "pageDetsEDS.php"
sendToPageDets($subname, $nPgs, $nPgs, $doctype);
}
}
else
{
// query failed
print("<SCRIPT TYPE=\"text/javascript\">\nalert('ERROR: It was "
. "not possible to add a page to the $subname submission of "
. "the $doctype document type.\\nThe system administrator "
. "should be informed of this problem.');\n</SCRIPT>\n");
displayEDSsubDetsForm($subname, $doctype);
}
}
elseif(isset($pageLeft))
{
// move submission page to the left
// i.e. give it a lower page number, and hence give it a higher priority in
// the page order sequence.
moveSubPage($doctype, $pageNumber, $nPgs, $subname,
$pageNumber - 1);
displayEDSsubDetsForm($subname, $doctype);
}
elseif(isset($pageRight))
{
// move a page to the right
// i.e. give it a higher page number, and hence a lower priority in the order sequence)
moveSubPage($doctype, $pageNumber, $nPgs, $subname,
$pageNumber + 1);
displayEDSsubDetsForm($subname, $doctype);
}
elseif(isset($deletePage))
{
// delete a page and its contents
deleteSubmissionPage($subname, $pageNumber, $nPgs, $doctype);
displayEDSsubDetsForm($subname, $doctype);
}
else
{
displayEDSsubDetsForm($subname, $doctype);
}
}
/**********************Start of main script***************************/
// Connect to the MySQL server
serverConnect(MYSQLDOCMACHINE, MYSQLDOCUSERID, MYSQLDOCPASSWORD);
// Select the Search database
dbSelect(DOCS_DATABASE);
$auth = canUseWebSubmitAdmin($uid,$doctype);
if (!$auth[0])
outWarning($auth[1][1] . "<br><br>" . "You are not allowed to access WebSubmit Admin for this type of documents");
else
displayPage($update);
/************************End of main script***************************/
</protect>
?>
diff --git a/modules/websubmit/web/approve.py b/modules/websubmit/web/approve.py
index d946e3fda..a8d9f4689 100644
--- a/modules/websubmit/web/approve.py
+++ b/modules/websubmit/web/approve.py
@@ -1,73 +1,73 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
from mod_python import apache
from cdsware.config import cdsname,cdslang
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.websubmit_config import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, page_not_authorized
from cdsware.messages import wash_language
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
def index(req,c=cdsname,ln=cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../approve.py/index")
ln = wash_language(ln)
form = req.form
if form.keys():
access = form.keys()[0]
if access == "":
return errorMsg("approve.py: cannot determine document reference",req)
res = run_sql("select doctype,rn from sbmAPPROVAL where access=%s",(access,))
if len(res) == 0:
return errorMsg("approve.py: cannot find document in database",req)
else:
doctype = res[0][0]
rn = res[0][1]
res = run_sql("select value from sbmPARAMETERS where name='edsrn' and doctype=%s",(doctype,))
edsrn = res[0][0]
url = "%s/sub.py?%s=%s&password=%s@APP%s" % (urlpath,edsrn,rn,access,doctype)
req.err_headers_out.add("Location", url)
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
return ""
else:
return errorMsg("Sorry parameter missing...", req, c, ln)
def errorMsg(title,req,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/modules/websubmit/web/direct.py b/modules/websubmit/web/direct.py
index 32b400bee..ede09f864 100644
--- a/modules/websubmit/web/direct.py
+++ b/modules/websubmit/web/direct.py
@@ -1,87 +1,87 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
from urllib import quote
from mod_python import apache
from cdsware.config import cdsname,cdslang
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.websubmit_config import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, page_not_authorized
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
def index(req,c=cdsname,ln=cdslang,sub=""):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../direct.py/index")
myQuery = req.args
if sub == "":
return errorMsg("Sorry parameter missing...",req)
res = run_sql("select docname,actname from sbmIMPLEMENT where subname=%s", (sub,))
if len(res)==0:
return errorMsg("Sorry. Can't analyse parameter",req)
else:
# get document type
doctype = res[0][0]
# get action name
action = res[0][1]
# retrieve other parameter values
params = re.sub("sub=[^&]*","",myQuery)
# find existing access number
result = re.search("access=([^&]*)",params)
if result != None:
access = result.group(1)
params = re.sub("access=[^&]*","",params)
else:
# create 'unique' access number
pid = os.getpid()
now = time.time()
access = "%i_%s" % (now,pid)
# retrieve 'dir' value
res = run_sql ("select dir from sbmACTION where sactname=%s",(action,))
dir = res[0][0]
try:
mainmenu = req.headers_in['Referer']
except:
mainmenu = ""
url = "submit.py?doctype=%s&dir=%s&access=%s&act=%s&startPg=1%s&mainmenu=%s" % (
doctype,dir,access,action,params,quote(mainmenu))
req.err_headers_out.add("Location", url)
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
return ""
def errorMsg(title,req,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/modules/websubmit/web/getfile.py b/modules/websubmit/web/getfile.py
index e42ab1f65..ab4095219 100644
--- a/modules/websubmit/web/getfile.py
+++ b/modules/websubmit/web/getfile.py
@@ -1,112 +1,112 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import time
import types
import re
from mod_python import apache
import sys
from cdsware.config import cdsname,cdslang
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, page_not_authorized
from cdsware.websubmit_config import *
from cdsware.file import *
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
from cdsware.messages import gettext_set_language
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
def index(req,c=cdsname,ln=cdslang,recid="",docid="",version="",name="",format=""):
# load the right message language
_ = gettext_set_language(ln)
# get user ID:
try:
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../getfile.py/index")
uid_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value,req)
docfiles = []
t=""
filelist=""
ip=str(req.get_remote_host(apache.REMOTE_NOLOOKUP))
# if a precise file is requested, we stream it
if name!="":
if docid=="":
return errorMsg(_("Parameter docid missing"), req, c, ln)
else:
doc = BibDoc(bibdocid=docid)
docfile=doc.getFile(name,format,version)
if docfile == None:
return warningMsg(_("can't find file..."),req, c, ln)
else:
res = doc.registerDownload(ip, version, format, uid)
return docfile.stream(req)
# all files attached to a record
elif recid!="":
bibarchive = BibRecDocs(recid)
filelist = bibarchive.display(docid, version, ln = ln)
# a precise filename
elif docid!="":
bibdoc = BibDoc(bibdocid=docid)
recid = bibdoc.getRecid()
filelist = bibdoc.display(version, ln = ln)
t = websubmit_templates.tmpl_filelist(
ln = ln,
recid = recid,
docid = docid,
version = version,
filelist = filelist,
)
p_navtrail = _("Access to Fulltext")
return page(title="",
body=t,
navtrail = p_navtrail,
description="",
keywords="keywords",
uid=uid,
language=ln,
urlargs=req.args
)
def errorMsg(title,req,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
def warningMsg(title,req,c=cdsname,ln=cdslang):
return page(title="warning",
body = title,
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/modules/websubmit/web/publiline.py b/modules/websubmit/web/publiline.py
index dd8e0dfec..887739a28 100644
--- a/modules/websubmit/web/publiline.py
+++ b/modules/websubmit/web/publiline.py
@@ -1,361 +1,361 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
import MySQLdb
import shutil
from cdsware.config import cdsname,cdslang,supportemail,pylibdir
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, list_registered_users, page_not_authorized
from cdsware.messages import gettext_set_language, wash_language
from cdsware.websubmit_config import *
from cdsware.search_engine import search_pattern
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
execfile("%s/cdsware/websubmit_functions/Retrieve_Data.py" % pylibdir)
execfile("%s/cdsware/websubmit_functions/mail.py" % pylibdir)
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
def index(req,c=cdsname,ln=cdslang,doctype="",categ="",RN="",send=""):
global uid
ln = wash_language(ln)
# load the right message language
_ = gettext_set_language(ln)
t=""
# get user ID:
try:
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../publiline.py/index")
uid_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value,req, ln = ln)
if doctype == "":
t = selectDoctype(ln)
elif categ == "":
t = selectCateg(doctype, ln)
elif RN == "":
t = selectDocument(doctype,categ, ln)
else:
t = displayDocument(doctype,categ,RN,send, ln)
return page(title="publication line",
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
body=t,
description="",
keywords="",
uid=uid,
language=ln,
urlargs=req.args)
def selectDoctype(ln = cdslang):
res = run_sql("select DISTINCT doctype from sbmAPPROVAL")
docs = []
for row in res:
res2 = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s", (row[0],))
docs.append({
'doctype' : row[0],
'docname' : res2[0][0],
})
t = websubmit_templates.tmpl_publiline_selectdoctype(
ln = ln,
docs = docs,
)
return t
def selectCateg(doctype, ln = cdslang):
t=""
res = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s",(doctype,))
title = res[0][0]
sth = run_sql("select * from sbmCATEGORIES where doctype=%s order by lname",(doctype,))
if len(sth) == 0:
categ = "unknown"
return selectDocument(doctype,categ, ln = ln)
categories = []
for arr in sth:
waiting = 0
rejected = 0
approved = 0
sth2 = run_sql("select COUNT(*) from sbmAPPROVAL where doctype=%s and categ=%s and status='waiting'", (doctype,arr[1],))
waiting = sth2[0][0]
sth2 = run_sql("select COUNT(*) from sbmAPPROVAL where doctype=%s and categ=%s and status='approved'",(doctype,arr[1],))
approved = sth2[0][0]
sth2 = run_sql("select COUNT(*) from sbmAPPROVAL where doctype=%s and categ=%s and status='rejected'",(doctype,arr[1],))
rejected = sth2[0][0]
categories.append({
'waiting' : waiting,
'approved' : approved,
'rejected' : rejected,
'id' : arr[1],
})
t = websubmit_templates.tmpl_publiline_selectcateg(
ln = ln,
categories = categories,
doctype = doctype,
title = title,
images = images,
)
return t
def selectDocument(doctype,categ, ln = cdslang):
t=""
res = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s", (doctype,))
title = res[0][0]
if categ == "":
categ == "unknown"
docs = []
sth = run_sql("select rn,status from sbmAPPROVAL where doctype=%s and categ=%s order by status DESC,rn DESC",(doctype,categ))
for arr in sth:
docs.append({
'RN' : arr[0],
'status' : arr[1],
})
t = websubmit_templates.tmpl_publiline_selectdocument(
ln = ln,
doctype = doctype,
title = title,
categ = categ,
images = images,
docs = docs,
)
return t
def displayDocument(doctype,categ,RN,send, ln = cdslang):
# load the right message language
_ = gettext_set_language(ln)
t=""
res = run_sql("select ldocname from sbmDOCTYPE where sdocname=%s", (doctype,))
docname = res[0][0]
if categ == "":
categ = "unknown"
sth = run_sql("select rn,status,dFirstReq,dLastReq,dAction,access from sbmAPPROVAL where rn=%s",(RN,))
if len(sth) > 0:
arr = sth[0]
rn = arr[0]
status = arr[1]
dFirstReq = arr[2]
dLastReq = arr[3]
dAction = arr[4]
access = arr[5]
else:
return warningMsg(_("This document has never been requested for approval!") + "<BR>&nbsp;", ln = ln)
(authors,title,sysno,newrn) = getInfo(doctype,categ,RN)
confirm_send = 0
if send == _("Send Again"):
if authors == "unknown" or title == "unknown":
SendWarning(doctype,categ,RN,title,authors,access, ln = ln)
else:
# @todo - send in different languages
SendEnglish(doctype,categ,RN,title,authors,access,sysno)
run_sql("update sbmAPPROVAL set dLastReq=NOW() where rn=%s",(RN,))
confirm_send = 1
if status == "waiting":
(auth_code, auth_message) = acc_authorize_action(uid, "referee",verbose=0,doctype=doctype, categ=categ)
else:
(auth_code, auth_message) = (None, None)
t = websubmit_templates.tmpl_publiline_displaydoc(
ln = ln,
docname = docname,
doctype = doctype,
categ = categ,
rn = rn,
status = status,
dFirstReq = dFirstReq,
dLastReq = dLastReq,
dAction = dAction,
access = access,
images = images,
accessurl = accessurl,
confirm_send = confirm_send,
auth_code = auth_code,
auth_message = auth_message,
authors = authors,
title = title,
sysno = sysno,
newrn = newrn,
)
return t
# Retrieve info about document
def getInfo(doctype,categ,RN):
result = getInPending(doctype,categ,RN)
if not result:
result = getInAlice(doctype,categ,RN)
return result
#seek info in pending directory
def getInPending(doctype,categ,RN):
PENDIR="%s/pending" % storage
if os.path.exists("%s/%s/%s/AU" % (PENDIR,doctype,RN)):
fp = open("%s/%s/%s/AU" % (PENDIR,doctype,RN),"r")
authors=fp.read()
fp.close()
else:
authors = ""
if os.path.exists("%s/%s/%s/TI" % (PENDIR,doctype,RN)):
fp = open("%s/%s/%s/TI" % (PENDIR,doctype,RN),"r")
title=fp.read()
fp.close()
else:
title = ""
if os.path.exists("%s/%s/%s/SN" % (PENDIR,doctype,RN)):
fp = open("%s/%s/%s/SN" % (PENDIR,doctype,RN),"r")
sysno=fp.read()
fp.close()
else:
sysno = ""
if title == "" and os.path.exists("%s/%s/%s/TIF" % (PENDIR,doctype,RN)):
fp = open("%s/%s/%s/TIF" % (PENDIR,doctype,RN),"r")
title=fp.read()
fp.close()
if title == "":
return 0
else:
return (authors,title,sysno,"")
#seek info in Alice database
def getInAlice(doctype,categ,RN):
# initialize sysno variable
sysno = ""
searchresults = search_pattern(req=None, p=RN, f="reportnumber").items().tolist()
if len(searchresults) == 0:
return 0
sysno = searchresults[0]
if sysno != "":
title = Get_Field('245__a',sysno)
emailvalue = Get_Field('8560_f',sysno)
authors = Get_Field('100__a',sysno)
authors += "\n%s" % Get_Field('700__a',sysno)
newrn = Get_Field('037__a',sysno)
return (authors,title,sysno,newrn)
else:
return 0
def SendEnglish(doctype,categ,RN,title,authors,access,sysno):
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
# retrieve useful information from webSubmit configuration
res = run_sql("select value from sbmPARAMETERS where name='categformatDAM' and doctype=%s", (doctype,))
categformat = res[0][0]
categformat = re.sub("<CATEG>","([^-]*)",categformat)
categs = re.match(categformat,RN)
if categs != None:
categ = categs.group(1)
else:
categ = "unknown"
res = run_sql("select value from sbmPARAMETERS where name='addressesDAM' and doctype=%s",(doctype,))
if len(res) > 0:
otheraddresses = res[0][0]
otheraddresses = otheraddresses.replace("<CATEG>",categ)
else:
otheraddresses = ""
# Build referee's email address
refereeaddress = ""
# Try to retrieve the referee's email from the referee's database
for user in acc_getRoleUsers(acc_getRoleId("referee_%s_%s" % (doctype,categ))):
refereeaddress += user[1] + ","
# And if there are general referees
for user in acc_getRoleUsers(acc_getRoleId("referee_%s_*" % doctype)):
refereeaddress += user[1] + ","
refereeaddress = re.sub(",$","",refereeaddress)
# Creation of the mail for the referee
addresses = ""
if refereeaddress != "":
addresses = refereeaddress + ","
if otheraddresses != "":
addresses += otheraddresses
else:
addresses = re.sub(",$","",addresses)
if addresses=="":
SendWarning(doctype,categ,RN,title,authors,access)
return 0
if authors == "":
authors = "-"
res = run_sql("select value from sbmPARAMETERS where name='directory' and doctype=%s", (doctype,))
directory = res[0][0]
message = """
The document %s has been published as a Communication.
Your approval is requested for it to become an official Note.
Title: %s
Author(s): %s
To access the document(s), select the file(s) from the location:
<%s/getfile.py?recid=%s>
To approve/reject the document, you should go to this URL:
<%s/approve.py?%s>
---------------------------------------------
Best regards.
The submission team.""" % (RN,title,authors,urlpath,sysno,urlpath,access)
# send the mail
body = forge_email(FROMADDR,addresses,adminemail,"Request for Approval of %s" % RN,message)
send_email(FROMADDR,addresses,body,0)
return ""
def SendWarning(doctype,categ,RN,title,authors,access):
FROMADDR = '%s Submission Engine <%s>' % (cdsname,supportemail)
message = "Failed sending approval email request for %s" % RN
# send the mail
body = forge_email(FROMADDR,adminemail,"","Failed sending approval email request",message)
send_email(FROMADDR,adminemail,body,0)
return ""
def errorMsg(title,req,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
def warningMsg(title,req,c=cdsname,ln=cdslang):
return page(title="warning",
body = title,
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/modules/websubmit/web/sub.py b/modules/websubmit/web/sub.py
index 4fd493558..442a67e7b 100644
--- a/modules/websubmit/web/sub.py
+++ b/modules/websubmit/web/sub.py
@@ -1,55 +1,55 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
from mod_python import apache
from cdsware.config import cdsname,cdslang
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.websubmit_config import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, page_not_authorized
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
def index(req,c=cdsname,ln=cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../sub.py/index")
myQuery = req.args
if myQuery:
if re.search("@",myQuery):
param = re.sub("@.*","",myQuery)
IN = re.sub(".*@","",myQuery)
else:
IN = myQuery
url = "%s/direct.py?sub=%s&%s" % (urlpath,IN,param)
req.err_headers_out.add("Location", url)
raise apache.SERVER_RETURN, apache.HTTP_MOVED_PERMANENTLY
return ""
else:
return "<html>Illegal page access</html>"
diff --git a/modules/websubmit/web/submit.py b/modules/websubmit/web/submit.py
index b732ef7b4..c315c6425 100644
--- a/modules/websubmit/web/submit.py
+++ b/modules/websubmit/web/submit.py
@@ -1,53 +1,53 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
from mod_python import apache
from cdsware.config import cdsname,cdslang
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import acc_isRole
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, page_not_authorized
from cdsware.websubmit_config import *
from cdsware.websubmit_engine import *
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
def index(req,c=cdsname,ln=cdslang, doctype="", act="", startPg=1, indir="", access="",mainmenu="",fromdir="",file="",nextPg="",nbPg="",curpage=1,step=0,mode="U"):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../submit.py/index")
if doctype=="":
return home(req,c,ln)
elif act=="":
return action(req,c,ln,doctype)
elif int(step)==0:
return interface(req,c,ln, doctype, act, startPg, indir, access,mainmenu,fromdir,file,nextPg,nbPg,curpage)
else:
return endaction(req,c,ln, doctype, act, startPg, indir, access,mainmenu,fromdir,file,nextPg,nbPg,curpage,step,mode)
diff --git a/modules/websubmit/web/summary.py b/modules/websubmit/web/summary.py
index 7ee86eacf..74c1ccffd 100644
--- a/modules/websubmit/web/summary.py
+++ b/modules/websubmit/web/summary.py
@@ -1,74 +1,74 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
from cdsware.config import cdsname,cdslang
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.websubmit_config import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid,get_email, page_not_authorized
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
from cdsware.messages import gettext_set_language
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
def index(req,doctype="",act="",access="",indir="", ln=cdslang):
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../summary.py/index")
t=""
curdir = "%s/%s/%s/%s" % (storage,indir,doctype,access)
subname = "%s%s" % (act,doctype)
res = run_sql("select sdesc,fidesc,pagenb,level from sbmFIELD where subname=%s order by pagenb,fieldnb", (subname,))
nbFields = 0
values = []
for arr in res:
if arr[0] != "":
val = {
'mandatory' : (arr[3] == 'M'),
'value' : '',
'page' : arr[2],
'name' : arr[0],
}
if os.path.exists("%s/%s" % (curdir,arr[1])):
fd = open("%s/%s" % (curdir,arr[1]),"r")
value = fd.read()
fd.close()
value = value.replace("\n"," ")
value = value.replace("Select:","")
else:
value = ""
val['value'] = value
values.append(val)
return websubmit_templates.tmpl_submit_summary(
ln = ln,
values = values,
images = images,
)
diff --git a/modules/websubmit/web/yourapprovals.py b/modules/websubmit/web/yourapprovals.py
index 349093256..371a9e178 100644
--- a/modules/websubmit/web/yourapprovals.py
+++ b/modules/websubmit/web/yourapprovals.py
@@ -1,113 +1,113 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import os
import sys
from cdsware.config import weburl,cdsname,cdslang
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, list_registered_users, page_not_authorized
from cdsware.messages import gettext_set_language, wash_language
from cdsware.websubmit_config import *
from cdsware.search_engine import search_pattern
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
def index(req,c=cdsname,ln=cdslang,order="",doctype="",deletedId="",deletedAction="",deletedDoctype=""):
global uid
ln = wash_language(ln)
# load the right message language
_ = gettext_set_language(ln)
t=""
# get user ID:
try:
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yourapprovals.py/index")
u_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value,req, ln = ln)
res = run_sql("select sdocname,ldocname from sbmDOCTYPE")
referees = []
for row in res:
doctype = row[0]
docname = row[1]
reftext = ""
if isReferee(uid,doctype,"*"):
referees.append ({'doctype': doctype,
'docname': docname,
'categories': None})
else:
res2 = run_sql("select sname,lname from sbmCATEGORIES where doctype=%s",(doctype,))
categories = []
for row2 in res2:
category = row2[0]
categname = row2[1]
if isReferee(uid,doctype,category):
categories.append({
'id' : category,
'name' : categname,
})
referees.append({
'doctype' : doctype,
'docname' : docname,
'categories' : categories
})
t = websubmit_templates.tmpl_yourapprovals(
ln = ln,
referees = referees
)
return page(title=_("Your Approvals"),
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
body=t,
description="",
keywords="",
uid=uid,
language=ln,
urlargs=req.args)
def isReferee(uid,doctype="",categ=""):
(auth_code, auth_message) = acc_authorize_action(uid, "referee",verbose=0,doctype=doctype, categ=categ)
if auth_code == 0:
return 1
else:
return 0
def errorMsg(title,req,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/modules/websubmit/web/yoursubmissions.py b/modules/websubmit/web/yoursubmissions.py
index 6153ce013..8bf1ee559 100644
--- a/modules/websubmit/web/yoursubmissions.py
+++ b/modules/websubmit/web/yoursubmissions.py
@@ -1,204 +1,204 @@
## $Id$
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## import interesting modules:
import string
import os
import sys
import time
import types
import re
import MySQLdb
import shutil
import operator
from cdsware.config import weburl,cdsname,cdslang
from cdsware.dbquery import run_sql
from cdsware.access_control_engine import acc_authorize_action
from cdsware.access_control_admin import *
from cdsware.webpage import page, create_error_box
from cdsware.webuser import getUid, get_email, list_registered_users, page_not_authorized
from cdsware.messages import gettext_set_language, wash_language
from cdsware.websubmit_config import *
from cdsware.search_engine import search_pattern
from cdsware.access_control_config import CFG_ACCESS_CONTROL_LEVEL_SITE
import cdsware.template
websubmit_templates = cdsware.template.load('websubmit')
def index(req,c=cdsname,ln=cdslang,order="",doctype="",deletedId="",deletedAction="",deletedDoctype=""):
global uid
ln = wash_language(ln)
# load the right message language
_ = gettext_set_language(ln)
t=""
# get user ID:
try:
uid = getUid(req)
if uid == -1 or CFG_ACCESS_CONTROL_LEVEL_SITE >= 1:
return page_not_authorized(req, "../yoursubmissions.py/index")
u_email = get_email(uid)
except MySQLdb.Error, e:
return errorMsg(e.value, req, ln)
if u_email == "guest" or u_email == "":
return warningMsg(websubmit_templates.tmpl_warning_message(
ln = ln,
msg = _("You first have to login before using this feature. Use the left menu to log in."),
),req, ln = ln)
if deletedId != "":
t += deleteSubmission(deletedId,deletedAction,deletedDoctype,u_email)
# doctypes
res = run_sql("select ldocname,sdocname from sbmDOCTYPE order by ldocname")
doctypes = []
for row in res:
doctypes.append({
'id' : row[1],
'name' : row[0],
'selected' : (doctype == row[1]),
})
# submissions
# request order default value
reqorder = "sbmSUBMISSIONS.md DESC, lactname"
# requested value
if order == "actiondown":
reqorder = "lactname ASC, sbmSUBMISSIONS.md DESC"
elif order == "actionup":
reqorder = "lactname DESC, sbmSUBMISSIONS.md DESC"
elif order == "refdown":
reqorder = "reference ASC, sbmSUBMISSIONS.md DESC, lactname DESC"
elif order == "refup":
reqorder = "reference DESC, sbmSUBMISSIONS.md DESC, lactname DESC"
elif order == "cddown":
reqorder = "sbmSUBMISSIONS.cd DESC, lactname"
elif order == "cdup":
reqorder = "sbmSUBMISSIONS.cd ASC, lactname"
elif order == "mddown":
reqorder = "sbmSUBMISSIONS.md DESC, lactname"
elif order == "mdup":
reqorder = "sbmSUBMISSIONS.md ASC, lactname"
elif order == "statusdown":
reqorder = "sbmSUBMISSIONS.status DESC, lactname"
elif order == "statusup":
reqorder = "sbmSUBMISSIONS.status ASC, lactname"
if doctype != "":
docselect = " and doctype='%s' " % doctype
else:
docselect = ""
res = run_sql("SELECT sbmSUBMISSIONS.* FROM sbmSUBMISSIONS,sbmACTION WHERE sactname=action and email=%s and id!='' "+docselect+" ORDER BY doctype,"+reqorder,(u_email,))
currentdoctype = ""
currentaction = ""
currentstatus = ""
submissions = []
for row in res:
if currentdoctype != row[1]:
currentdoctype = row[1]
currentaction = ""
currentstatus = ""
res2 = run_sql("SELECT ldocname FROM sbmDOCTYPE WHERE sdocname=%s",(currentdoctype,))
if res2:
ldocname = res2[0][0]
else:
ldocname = """***Unknown Document Type - (%s)""" % (currentdoctype,)
if currentaction != row[2]:
currentaction = row[2]
res2 = run_sql("SELECT lactname FROM sbmACTION WHERE sactname=%s",(currentaction,))
if res2:
lactname = res2[0][0]
else:
lactname = "\""
else:
lactname = "\""
if currentstatus != row[3]:
currentstatus = row[3]
status=row[3]
else:
status = "\""
submissions.append({
'docname' : ldocname,
'actname' : lactname,
'status' : status,
'cdate' : row[6],
'mdate' : row[7],
'reference' : row[5],
'id' : row[4],
'act' : currentaction,
'doctype' : currentdoctype,
'pending' : (row[3] == "pending")
})
# display
t += websubmit_templates.tmpl_yoursubmissions(
ln = ln,
weburl = weburl,
images = images,
order = order,
doctypes = doctypes,
submissions = submissions,
)
return page(title="Your Submissions",
navtrail= """<a class="navtrail" href="%(weburl)s/youraccount.py/display">%(account)s</a>""" % {
'weburl' : weburl,
'account' : _("Your Account"),
},
body=t,
description="",
keywords="",
uid=uid,
language=ln,
urlargs=req.args)
def deleteSubmission(id, action, doctype, u_email):
global storage
run_sql("delete from sbmSUBMISSIONS WHERE doctype=%s and action=%s and email=%s and status='pending' and id=%s",(doctype,action,u_email,id,))
res = run_sql("select dir from sbmACTION where sactname=%s",(action,))
dir = res[0][0]
if not ('..' in doctype or '..' in id) and id != "":
full = os.path.join(storage, dir, doctype, id)
if os.path.isdir(full):
shutil.rmtree(full)
return ""
def warningMsg(title,req,c=cdsname,ln=cdslang):
return page(title="warning",
body = title,
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
def errorMsg(title,req,c=cdsname,ln=cdslang):
return page(title="error",
body = create_error_box(req, title=title,verbose=0, ln=ln),
description="%s - Internal Error" % c,
keywords="%s, CDSware, Internal Error" % c,
language=ln,
urlargs=req.args)
diff --git a/po/ca.po b/po/ca.po
index 3bbd3491e..7fccd8a82 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -1,3897 +1,3897 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:10+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: CA <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Aquest lloc està també disponible en els següents idiomes:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Cercar"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Ajuda"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Àrea de l&quot;admistrador"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Ajuda a la cerca"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Administració de trameses"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Trametre"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalitzar"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Centre d&quot;ajuda"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Darrera actualització"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Ajuda per la tramesa"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guia"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "febrer"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Consells de cerca"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Pàgina inicial"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Mantingut per"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "col·leccions"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guia"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Històric de cites:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Històric de baixades:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "juny"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "maig"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "qualsevol dia"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "maig"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "qualsevol dia"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "qualsevol dia"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "qualsevol mes"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "gener"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "març"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "abril"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "maig"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "juny"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "juliol"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "agost"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "octubre"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "gener"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "febrer"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "març"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "abril"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "juny"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "juliol"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "agost"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "setembre"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "octubre"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "novembre"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "desembre"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "maig"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Cercar"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "El registre ha estat esborrat."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "complet"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "col·leccions"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "col·leccions"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "alertes"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "qualsevol mes"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "complet"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Proveu la vostra cerca a..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Proveu la vostra cerca a..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "cistells"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "col·leccions"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "més"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "maig"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "sessió"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Darrera actualització"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Visualitzar els resultats:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "compte"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Visualitzar els resultats:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalitzar"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Darrera actualització"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Registres semblants"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Darrera actualització"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "més"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Registre complet"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "El registre ha estat esborrat."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Ordenar per:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "maig"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "compte"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "El registre ha estat esborrat."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Registres semblants"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Registres semblants"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "compte"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Registre complet"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "cistells"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Resultats de la cerca"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Visualitzar els resultats:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "cistells"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "cistells"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "cistells"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "setembre"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Citat por: %s registres"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "setembre"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "abril"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "abril"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "cistells"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "saltar al registre:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "El registre ha estat esborrat."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "complet"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "complet"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "El registre ha estat esborrat."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "més"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Citat per"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "cistells"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "cistells"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "compte"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "més"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "compte"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Registre complet"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "No s'ha trobat la col·lecció %s"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "identificació"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "El registre ha estat esborrat."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Cercar"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Trametre"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Trametre"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Trametre"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Limitar per col·lecció:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Enfocat a:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "el darrer primer"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "desc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "O"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "prioritzar per"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "resultats"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "dividit per col·lecció"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "llista única"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "breu"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Cercar en %s registres per"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Resultats de la cerca"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "qualsevol dia"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "qualsevol mes"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "qualsevol any"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "totes les col·leccions"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "afegir una altra col·lecció"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "breu"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "I"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "I NO"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Totes les paraules:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Qualsevol de les paraules:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Frase exacta:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Part de la frase:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Expressió regular:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr "."
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Llista"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"No s'ha trobat cap coincidència exacta per <em>%s</em>, però en canvi usant "
"<em>%s</em> ..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"No s'ha trobat cap coincidència dins la col·lecció %s. Altres col·leccions "
"públiques han donat <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d "
"resultats</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"No s'ha trobat cap coincidència en col·leccions públiques. Si esteu cercant "
"documents no públics, escolliu primer la col·lecció restringida."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "No hi ha cap índex de paraules disponible per a"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "No hi ha cap índex de frases disponible per a"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "El terme de cerca <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "dins l'índex <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"no s'ha trobat en cap registre. Els termes aproximats en totes les "
"col·leccions són:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "El registre ha estat esborrat."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Registre complet"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"No s'ha trobat cap coincidència en l'intèrval de temps especificat. "
"Descartant aquesta condició..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"No s'ha trobat cap coincidència en les limitacions que heu especificat. "
"Descartant aquesta condició..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Cerca avançada"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Cerca simple"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Opcions de cerca:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Afegit des de:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "fins:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Ordenar per:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Visualitzar els resultats:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Format de visualizació:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "restringit"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Darreres entrades:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Els continguts d'aquesta col·lecció són restringits."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Aquesta col·lecció encara no conté cap document."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "més"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Registres semblants"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Citat per"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "totes les col·leccions"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Proveu la vostra cerca a..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "col·leccions"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "dins"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "No heu trobat el que estaveu cercant? Proveu la vostra cerca a:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> registres trobats"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "identificació"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "saltar al registre:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "La cerca s'ha fet en %.2f segons."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "AFEGIR AL CISTELL"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Registre creat el %s, modificat el %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Citat por: %s registres"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-citat amb: %s registres"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Els usuaris que han baixat aquest document també han baixat:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Els usuaris que han vist aquesta pàgina també han vist:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Resultats globals:</strong> Trobats <strong>%s</strong> registres em "
"%.2f segonss."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"La cerca booleana no ha donat cap resultat. Proveu de combinar els vostres "
"termes de cerca d'una altra manera."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Vegeu també: autors amb noms similars"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Error intern"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "No s'ha trobat la col·lecció %s"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Ho sentim, la col·lecció <strong>%s</strong> no existeix. <p>Proveu-ho "
"començant des de <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "qualsevol dia"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "cistells"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "cistells"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Cercar"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "cistells"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "aprovacions"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Cercar"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "trameses"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "trameses"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "aprovacions"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "aprovacions"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "compte"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "identificació"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "alertes"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "identificació"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "El terme de cerca <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Cercar"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Cercar"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "visitant"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "sessió"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "alertes"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "cistells"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "compte"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "trameses"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "aprovacions"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administració"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "sortir"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "compte"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "alertes"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "compte"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "sortir"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Llista"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Si us plau contacteu amb <a href=\"mailto:%s\">%s</a> citant la següent "
"informació:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Aquesta col·lecció encara no conté cap document."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Aquesta col·lecció encara no conté cap document."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "trameses"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "trameses"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "sessió"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "més"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "més"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "sessió"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "sessió"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "més"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "aprovacions"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "restringit"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "aprovacions"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "aprovacions"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "setembre"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "aprovacions"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "restringit"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "TRADUCCIÓ CATALANA EN CURS"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "De moment, la versión en català d'aquesta pàgina no està disponible. Us "
#~ "preguem que consulteu la versió en anglès que veureu a continuació. "
#~ "Gràcies por la vostra compresió."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "AFEGIR AL CISTELL"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "El registre ha estat esborrat."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "cistells"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "cistells"
#, fuzzy
#~ msgid "Move"
#~ msgstr "més"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "AFEGIR AL CISTELL"
#, fuzzy
#~ msgid "Until"
#~ msgstr "fins:"
diff --git a/po/cs.po b/po/cs.po
index dc38ed2d3..2bb3d332f 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -1,3895 +1,3895 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:11+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: CS <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Tato stránka je také dostupná v následujících jazycích:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Hledej"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Nápověda"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Areál Administrátora"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Nápověda pro vyhledávaní"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Administrace Přidávání"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Přidej"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalizace"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Centrála Nápovědy"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Poslední aktualizace"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Nápověda pro přidávání"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Příručka"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "únor"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Tipy pro vyhledávaní"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Hlavní stránka"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Spravuje"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "kolekce"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Příručka"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citační historie:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Historie stahování:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "červen"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "květen"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "jakýkoli den"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "květen"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "jakýkoli den"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "jakýkoli den"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "jakýkoli měsíc"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "leden"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "březen"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "duben"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "květen"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "červen"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "červenec"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "srpen"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "říjen"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "leden"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "únor"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "březen"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "duben"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "červen"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "červenec"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "srpen"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "září"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "říjen"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "listopad"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "prosinec"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "květen"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Hledej"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "Záznam byl vymazán."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "podrobný"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "kolekce"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "kolekce"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "avíza"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "jakýkoli měsíc"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "podrobný"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Zkuste hledat na..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Zkuste hledat na..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "košíky"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "kolekce"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "více"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "květen"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "seance"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Poslední aktualizace"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Zobrazit výsledky:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "konto"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Zobrazit výsledky:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalizace"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Poslední aktualizace"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Podobné záznamy"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Poslední aktualizace"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "více"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Úplný záznam"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "Záznam byl vymazán."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Setřídit podle:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "květen"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "Záznam byl vymazán."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Podobné záznamy"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Podobné záznamy"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Úplný záznam"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Výsledky hledání"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Zobrazit výsledky:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "košíky"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "košíky"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "košíky"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "září"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Citováno: %s záznamy"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "září"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "duben"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "duben"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "košíky"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "skoč na záznam:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "Záznam byl vymazán."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "podrobný"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "podrobný"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "Záznam byl vymazán."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "více"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Citováno"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "košíky"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "košíky"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "více"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Úplný záznam"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Kolekcia %s Nenalezena"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "přihlásit"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "Záznam byl vymazán."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Hledej"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Přidej"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Přidej"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Přidej"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Zúžit podle kolekcе:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Zaměřit se na:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "poslední záznam nejdříve"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "vzest."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "sest."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "NEBO"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "seřadit podle"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "výsledky"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "seskupené podle kolekcí"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "jediný list"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "stručný"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Hledej v %s záznamech:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Výsledky hledání"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "jakýkoli den"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "jakýkoli měsíc"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "jakýkoli rok"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "všechny kolekce"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "přidat kolekci"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "stručný"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "A"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "A NE"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "VÅ¡echna tato slova:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Jedno ze slov:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Přesná věta:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Částečná věta:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regulární výraz:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Prolistuj"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Žádný přesný výsledek pro <em>%s</em> nebyl nalezen, zkusme místo něj použít "
"<em>%s</em>..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Žádný záznam nebyl nalezen v kolekci %s. Ostatní veřejně dostupné kolekce "
"dali <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d záznamů</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Žádná veřejně přístupná kolekce nevyhovuje Vašemu dotazu. Jestliže jste "
"hledali dokumenty veřejně nepřístupné, zvolte prosím nejdříve příslušnou "
"neveřejnou kolekci."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Index slov není k dispozici pro"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Index frází není k dispozici pro"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Hledaný výraz <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "v indexu <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"neodpovídá žádnému záznamu. Nejbližší termíny nezávisle na kolekci jsou:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "Záznam byl vymazán."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Úplný záznam"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Žádný výsledek nevyhovuje Vašim časovým kritériím, podmínka není vzata v "
"úvahu..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Žádný výsledek nevyhovuje Vašim omezujícím kritériím, podmínky nejsou vzaty "
"v úvahu..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Rozšířené Hledání"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Jednoduché Hledání"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Volby hledání:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Přidánо od:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "do:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Setřídit podle:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Zobrazit výsledky:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Výstupní formát:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "chráněno"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Posledně přidáno:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Obsah této kolekce je chráněn."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Tato kolekce ješte neobsahuje žádné záznamy."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "více"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Podobné záznamy"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Citováno"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "všechny kolekce"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Zkuste hledat na..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "kolekce"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "v"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Nenalezli jste co jste hledali? Zkuste Váš dotaz na jiných servrech:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> záznamů nalezeno"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "přihlásit"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "skoč na záznam:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Hledání trvalo %.2f vteřin."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "PŘIDAT DO KOŠÍKU"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Záznam vytvořen %s, modifikován %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Citováno: %s záznamy"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Spolu citováno s: %s záznamy"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Uživatelé kteří si stáhli tento dokument si též stáhli:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Uživatelé kteří prohlédli tuhle stránku si též prohlédli:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Přehled výsledků:</strong> Nalezeno <strong>%s</strong> záznamů za "
"%.2f vteřin."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Booleovský dotaz nevrátil žádný výsledek. Zkuste zkombinovat dané termíny "
"jiným způsobem."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Viz též: podobná jména autorů"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Vnitřní Chyba"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Kolekcia %s Nenalezena"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Litujeme, kolekce <strong>%s</strong> neexistuje. <p>Zkuste začít hledat "
"od <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "jakýkoli den"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Hledej"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "schválení"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Hledej"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "přidání"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "přidání"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "schválení"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "schválení"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "přihlásit"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "avíza"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "přihlásit"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Hledaný výraz <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Hledej"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Hledej"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "host"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "seance"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "avíza"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "přidání"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "schválení"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administrace"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "odhlásit"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "konto"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "avíza"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "konto"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "odhlásit"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Prolistuj"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Prosíme kontaktujte <a href=\"mailto:%s\">%s</a> a uveďte následující "
"informace:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Tato kolekce ješte neobsahuje žádné záznamy."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Tato kolekce ješte neobsahuje žádné záznamy."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "přidání"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "přidání"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "seance"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "více"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "více"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "seance"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "seance"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "více"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "schválení"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "chráněno"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "schválení"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "schválení"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "září"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "schválení"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "chráněno"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "PŘEKLAD DO ČEŠTINY SE PŘIPRAVUJE"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Český překlad této stránky není ukončen. Prosíme použijte anglickou verzi "
#~ "uvedenou níže. Děkujeme za pochopení."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "PŘIDAT DO KOŠÍKU"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "Záznam byl vymazán."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "košíky"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "košíky"
#, fuzzy
#~ msgid "Move"
#~ msgstr "více"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "PŘIDAT DO KOŠÍKU"
#, fuzzy
#~ msgid "Until"
#~ msgstr "do:"
diff --git a/po/de.po b/po/de.po
index 2569f3e4b..1536ce4e3 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1,3899 +1,3899 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:11+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: DE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Diese Seite gibt es auch in den folgenden Sprachen:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Suchen"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Hilfe"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Verwaltungsraum"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Suchhilfe"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "WebSubmit Verwaltung"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Eintragen"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalisieren"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Hilfezentrale"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Letzte Aktualisierung"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Eintragehilfe"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Führer"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "Februar"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Suchtipps"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Hauptseite"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Verwaltet von"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "Sammlungen"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Führer"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Historie der Zitationen:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Historie der Herunterladen:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "Juni"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "Mai"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "beliebiger Tag"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "Mai"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "beliebiger Tag"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "beliebiger Tag"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "beliebiger Monat"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "Januar"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "März"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "April"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "Mai"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "Juni"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "Juli"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "August"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "October"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "Januar"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "Februar"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "März"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "April"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "Juni"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "Juli"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "August"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "September"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "October"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "November"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "Dezember"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "Mai"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Suchen"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "Der Datensatz wurde gelöscht."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "detailliert"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "Sammlungen"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "Sammlungen"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "Anzeigen"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "beliebiger Monat"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "detailliert"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Versuchen Sie Ihre Suche mit..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Versuchen Sie Ihre Suche mit..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "Körbe"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "Sammlungen"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "mehr"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "Mai"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "Session"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Letzte Aktualisierung"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Ergebnisse darstellen:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "Konto"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Ergebnisse darstellen:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalisieren"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Letzte Aktualisierung"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Ähnliche Datensätze"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Letzte Aktualisierung"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "mehr"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Details vom Eintrag"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "Der Datensatz wurde gelöscht."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Sortieren nach:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "Mai"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "Konto"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "Der Datensatz wurde gelöscht."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Ähnliche Datensätze"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Ähnliche Datensätze"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "Konto"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Details vom Eintrag"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "Körbe"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Suchergebnisse"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Ergebnisse darstellen:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "Körbe"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "Körbe"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "Körbe"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "September"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Zitiert von: %s Datensätzen"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "September"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "April"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "April"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "Körbe"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "gehen zum Satz:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "Der Datensatz wurde gelöscht."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "detailliert"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "detailliert"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "Der Datensatz wurde gelöscht."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "mehr"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Zitiert von"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "Körbe"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "Körbe"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "Konto"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "mehr"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "Konto"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Details vom Eintrag"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Sammlung %s nicht gefunden"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "Anmelden"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "Der Datensatz wurde gelöscht."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Suchen"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Eintragen"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Eintragen"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Eintragen"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Einschränken nach Sammlungen:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Hinweis auf:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "das Letzte zuerst"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "aufw."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "abw."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "ODER"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ranking"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "Ergebnisse"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "verteilen in Sammlungen"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "einzige Liste"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "kurz"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Suchen durch %s Datensätze nach:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Suchergebnisse"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "beliebiger Tag"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "beliebiger Monat"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "beliebiges Jahr"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "alle Sammlungen"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "Neue Sammlung hinzufügen"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "kurz"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "UND"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "UND NICHT"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Alle Worte:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Mindestens die Worte:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Genaue Phrase:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Partielle Phrase:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regulärer Ausdruck:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr "."
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Durchblättern"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Kein genaues Resultat für <em>%s</em> wurde gefunden, <em>%s</em> wird "
"verwendet anstatt..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Kein genaues Resultat in der Sammlung %s. Andere offentliche Sammlungen "
"ergaben <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d Ergebnisse</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"In keiner allgemein zugänglichen Sammlung wurde Ihre Suche gefunden. Wenn "
"Sie private Dokumente durchsuchen möchten, wählen Sie bitte zuerst eine "
"private Sammlung aus."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Kein Wortindex steht zur Verfügung für"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Kein Begriffindex steht zur Verfügung für"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Suchbegriff <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "im Index von <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"hat keine Datensätze gefunden. Die nächsten Begriffe in allen Sammlungen "
"sind:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "Der Datensatz wurde gelöscht."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Details vom Eintrag"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Kein Resultat in der eingegebene Zeitbeschränkung, Bedingung wird "
"ignoriert..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Kein Resultat in der eingegebene Suchebeschränkung, Bedingung wird "
"ignoriert..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Erweiterte Suche"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Einfache Suche"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Suchoptionen:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Hinzufügt seit:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "nach:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Sortieren nach:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Ergebnisse darstellen:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Darstellungsformat:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "privat"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Letzte Einträge:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Der Inhalt von dieser Sammlung ist privat."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Diese Sammlung enthält zur Zeit keine Dokumente."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "mehr"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Ähnliche Datensätze"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Zitiert von"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "alle Sammlungen"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Versuchen Sie Ihre Suche mit..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "Sammlungen"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "in"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
"Haben Sie nicht gefunden was Sie suchten? Versuchen Sie Ihre Suche mit:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> Datensätze gefunden"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "Anmelden"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "gehen zum Satz:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Die Suche hat %.2f Sekunden gedauert."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "IN DEN KORB HINZUFÜGEN"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Datensatz erzeugt %s, letzte Änderung %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Zitiert von: %s Datensätzen"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-zitiert mit: %s Datensätzen"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr ""
"Benutzer, die diesen Dokument herunterladeten, haben auch herunterladet:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Benutzer, die diese Seite sahen, haben auch angeschaut:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Übersicht von Ergebnissen:</strong> <strong>%s</strong> Datensätze "
"wurden in %.2f Sekunden gefunden."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Die boolsche Suchfrage hat keine Datensätze gefunden. Bitte kombinieren Sie "
"Ihre Suchfrage anders."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Sehen Sie auch: ähnliche Autornamen"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Interner Fehler"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Sammlung %s nicht gefunden"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Entschuldigung, Sammlung <strong>%s</strong> scheint nicht zu existieren. "
"<p>Sie können erneut beginnen von <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "beliebiger Tag"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "Körbe"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "Körbe"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Suchen"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "Körbe"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "Bestätigungen"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Suchen"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "Eintragungen"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "Eintragungen"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "Bestätigungen"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "Bestätigungen"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "Konto"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "Anmelden"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "Anzeigen"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "Anmelden"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Suchbegriff <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Suchen"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Suchen"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "Gast"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "Session"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "Anzeigen"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "Körbe"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "Konto"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "Eintragungen"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "Bestätigungen"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "Verwaltung"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "Abmelden"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "Konto"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "Anzeigen"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "Konto"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "Abmelden"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Durchblättern"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Bitte kontaktieren Sie <a href=\"mailto:%s\">%s</a> und geben folgende "
"Auskunft:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Diese Sammlung enthält zur Zeit keine Dokumente."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Diese Sammlung enthält zur Zeit keine Dokumente."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "Eintragungen"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "Eintragungen"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "Session"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "mehr"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "mehr"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "Session"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "Session"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "mehr"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "Bestätigungen"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "privat"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "Bestätigungen"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "Bestätigungen"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "September"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "Bestätigungen"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "privat"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "ÜBERSETZUNG AUF DEUTSCH WIRD GERADE VORBEREITET"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Zur Zeit gibt es keine deutsche Übersetzung von dieser Seite. Wir bitten "
#~ "Sie inzwischen sich der englischen Version zu bedienen. Wir danken Ihnen "
#~ "für Ihr Verständnis."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "IN DEN KORB HINZUFÜGEN"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "Der Datensatz wurde gelöscht."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "Körbe"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "Körbe"
#, fuzzy
#~ msgid "Move"
#~ msgstr "mehr"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "IN DEN KORB HINZUFÜGEN"
#, fuzzy
#~ msgid "Until"
#~ msgstr "nach:"
diff --git a/po/el.po b/po/el.po
index 94f74bed7..2e2777b9d 100644
--- a/po/el.po
+++ b/po/el.po
@@ -1,3895 +1,3895 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:11+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: EL <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Η σελίδα αυτή είναι διαθέσιμη και στις εξής γλώσσες:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Αναζήτηση"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Βοήθεια"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Περιοχή Διαχειριστή"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Βοήθεια αναζήτησης"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Διαχείριση WebSubmit"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Υποβολή"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Ρυθμίσεις"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Βοήθεια"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Τελευταία ενημέρωση"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Υποβολή Βοήθειας"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Οδηγός"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "Φεβρουάριος"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Ατζέντα"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Παραδείγματα αναζήτησης"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Αρχική Σελίδα"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Συντηρείται από"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "συλλογές"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Βασίζεται στο"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Οδηγός"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Ιστορικό παραπομπών:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Ιστορικό downloads:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "Ιούνιος"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "Μάιος"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Ατζέντα"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "οποιαδήποτε ημέρα"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "Μάιος"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "οποιαδήποτε ημέρα"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "οποιαδήποτε ημέρα"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "οποιονδήποτε μήνα"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "Ιανουάριος"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "Μάρτιος"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "Απρίλιος"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "Μάιος"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "Ιούνιος"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "Ιούλιος"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "Άυγουστος"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "Οκτώβριος"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "Ιανουάριος"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "Φεβρουάριος"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "Μάρτιος"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "Απρίλιος"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "Ιούνιος"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "Ιούλιος"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "Άυγουστος"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "Σεπτέμβριος"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "Οκτώβριος"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "Νοέμβριος"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "Δεκέμβριος"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "Μάιος"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Αναζήτηση"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "αναλυτική"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "συλλογές"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "συλλογές"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "ειδοποιήσεις"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "οποιονδήποτε μήνα"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "αναλυτική"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Δοκιμάστε την έρευνά σας στο..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Δοκιμάστε την έρευνά σας στο..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "καλάθι"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "συλλογές"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "περισσότερα"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "Μάιος"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "συνεδρία"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Τελευταία ενημέρωση"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Παρουσίαση αποτελεσμάτων:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "Λογαριασμός"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Παρουσίαση αποτελεσμάτων:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Ρυθμίσεις"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Τελευταία ενημέρωση"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Παρόμοιες εγγραφές"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Τελευταία ενημέρωση"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "περισσότερα"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Αναλυτική εγγραφή"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Ταξινόμηση με:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "Μάιος"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "Λογαριασμός"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Παρόμοιες εγγραφές"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Ατζέντα"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Παρόμοιες εγγραφές"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "Λογαριασμός"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Αναλυτική εγγραφή"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "καλάθι"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Αποτελέσματα αναζήτησης"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Παρουσίαση αποτελεσμάτων:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "καλάθι"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "καλάθι"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "καλάθι"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "Σεπτέμβριος"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Χρησιμοποιείται από: %s εγγραφές"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "Σεπτέμβριος"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "Απρίλιος"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "Απρίλιος"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "καλάθι"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "μετάβαση στην εγγραφή:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "αναλυτική"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "αναλυτική"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "περισσότερα"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Χρησιμοποιείται από"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "καλάθι"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "καλάθι"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "Λογαριασμός"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "περισσότερα"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "Λογαριασμός"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Αναλυτική εγγραφή"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Η συλλογή %s δεν βρέθηκε"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "είσοδος"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Αναζήτηση"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Υποβολή"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Ατζέντα"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Υποβολή"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Ατζέντα"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Υποβολή"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Περιορισμός αναζήτησης:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Επικέντρωση σε:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "Το τελευταίο, πρώτο"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "αύξ."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "φθίν."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "Ή"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ταξινόμηση με"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "αποτελέσματα"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "διαχωρισμός κατά συλλογή"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "απλή λίστα"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "σύντομη"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Αναζήτηση σε %s εγγραφές για:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Αποτελέσματα αναζήτησης"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "οποιαδήποτε ημέρα"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "οποιονδήποτε μήνα"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "οποιονδήποτε χρόνο"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "οποιαδήποτε συλλογή"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "προσθήκη συλλογής"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "σύντομη"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "ΚΑΙ"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "ΚΑΙ ΟΧΙ"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Όλες οι λέξεις"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Οποιαδήποτε από τις λέξεις"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Ακριβής φράση:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Επιμέρους φράση:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regular expression:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Φυλλομέτρηση"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Δεν βρέθηκε κανένα αποτέλεσμα για <em>%s</em>, θα γίνει χρήση του <em>%s</"
"em> στην θέση του..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Κανένα αποτέλεσμα στην συλλογή %s. Άλλες συλλογές έδωσαν <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d αποτελέσματα</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Καμιά ανοιχτή συλλογή δεν ικανοποίησε την έρευνά σας. Άν ψάχνετε και σε "
"κλειστές συλλογές, παρακαλώ επιλέξτε τις στην αρχή."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Δεν υπάρχει ευρετήριο λέξεων για"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Δεν υπάρχει ευρετήριο φράσεων για"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Όρος αναζήτησης <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "στο <em>%s</em> ευρετήριο"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr "δεν ταίριαξε με κάποια εγγραφή. Παραπλήσιοι όροι σε όλες τις συλλογές:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "Η εγγραφή έχει διαγραφεί."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Αναλυτική εγγραφή"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Κανένα αποτέλεσμα στα χρονικά περιθώρια, θα γίνει παράβλεψη του κριτηρίου "
"αυτού..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Κανένα αποτέλεσμα στα όρια έρευνας, θα γίνει παράβλεψη του κριτηρίου αυτού..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Σύνθετη αναζήτηση"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Απλή αναζήτηση"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Επιλογές αναζήτησης:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Προστέθηκαν από:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "έως:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Ταξινόμηση με:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Παρουσίαση αποτελεσμάτων:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Μορφή αποτελεσμάτων:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "περιορισμένο"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Πρόσφατες προσθήκες:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Τα περιεχόμενα της παρούσας συλλογής είναι προστατευμένα"
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Η συλλογή αυτή δεν περιέχει κάποιο έγγραφο ακόμη."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "περισσότερα"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Παρόμοιες εγγραφές"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Χρησιμοποιείται από"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "οποιαδήποτε συλλογή"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Δοκιμάστε την έρευνά σας στο..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "συλλογές"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "σε"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
"Δεν βρήκατε αυτό που αναζητούσατε; Δοκιμάστε την έρευνά σας σε άλλους "
"servers:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> εγγραφές βρέθηκαν"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "είσοδος"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Ατζέντα"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "μετάβαση στην εγγραφή:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Η έρευνα πήρε %.2f δευτερόλεπτα."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "ΠΡΟΣΘΗΚΗ ΣΤΟ ΚΑΛΑΘΙ"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Δημιουργία εγγραφής %s, τελευταία αλλαγή %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Χρησιμοποιείται από: %s εγγραφές"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Χρησιμοποιείται σε συνδιασμό από: %s εγγραφές"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Όσοι κατέβασαν το έγγραφο αυτό, κατέβασαν επίσης:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Όσοι είδαν την σελίδα αυτή, είδαν επίσης:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Αποτελέσμα έρευνας:</strong> Βρέθηκαν <strong>%s</strong> εγγραφές "
"σε %.2f δευτερόλεπτα."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Η λογική ερώτηση δεν επέστρεψε αποτελέσματα. Παρακαλούμε δοκιμάστε "
"διαφορετικό συνδιασμό των όρων."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Δείτε ακόμη: παρόμοια ονόματα συγγραφέων"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Εσωτερικό Σφάλμα"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Η συλλογή %s δεν βρέθηκε"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Δυστυχώς η συλλογή <strong>%s</strong> δεν υπάρχει. <p>Ενδεχομένως να "
"ενδιαφέρεστε να ξεκινήσετε την έρευνα από <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "οποιαδήποτε ημέρα"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "καλάθι"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "καλάθι"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Αναζήτηση"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "καλάθι"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "εγκρίσεις"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Αναζήτηση"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "εγκρίσεις"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "εγκρίσεις"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "Λογαριασμός"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "είσοδος"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "ειδοποιήσεις"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "είσοδος"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Όρος αναζήτησης <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Αναζήτηση"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Αναζήτηση"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "επισκέπτης"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "συνεδρία"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "ειδοποιήσεις"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "καλάθι"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "Λογαριασμός"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "εγκρίσεις"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "διαχείριση"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "αποσύνδεση"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "Λογαριασμός"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "ειδοποιήσεις"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "Λογαριασμός"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "αποσύνδεση"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Φυλλομέτρηση"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Παρακαλώ επικοινωνήστε με τον <a href=\"mailto:%s\">%s</a> αναφέροντας τα "
"παρακάτω στοιχεία:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Η συλλογή αυτή δεν περιέχει κάποιο έγγραφο ακόμη."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Η συλλογή αυτή δεν περιέχει κάποιο έγγραφο ακόμη."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "submissions"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "submissions"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "συνεδρία"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "περισσότερα"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "περισσότερα"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "συνεδρία"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "συνεδρία"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "περισσότερα"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Ατζέντα"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "εγκρίσεις"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "περιορισμένο"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "εγκρίσεις"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "εγκρίσεις"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "Σεπτέμβριος"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Ατζέντα"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "εγκρίσεις"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "περιορισμένο"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "ΕΛΛΗΝΙΚΗ ΜΕΤΑΦΡΑΣΗ ΣΕ ΕΞΕΛΙΞΗ"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Η Ελληνική μετάφραση της παρούσας σελίδας δεν είναι διαθέσιμη. "
#~ "Παρακαλούμε συμβουλευτείτε την Αγγλική σελίδα. Ευχαριστούμε για την "
#~ "καταννόηση."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "ΠΡΟΣΘΗΚΗ ΣΤΟ ΚΑΛΑΘΙ"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "Η εγγραφή έχει διαγραφεί."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "καλάθι"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "καλάθι"
#, fuzzy
#~ msgid "Move"
#~ msgstr "περισσότερα"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "ΠΡΟΣΘΗΚΗ ΣΤΟ ΚΑΛΑΘΙ"
#, fuzzy
#~ msgid "Until"
#~ msgstr "έως:"
diff --git a/po/en.po b/po/en.po
index 0f3aaa9fe..c5c8d7cec 100644
--- a/po/en.po
+++ b/po/en.po
@@ -1,3887 +1,3887 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:12+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: EN <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "This site is also available in the following languages:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Search"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Help"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Admin Area"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Search Help"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "WebSubmit Administration"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Submit"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalize"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Help Central"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Last updated"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Submit Help"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guide"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "February"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Search Tips"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Home"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Maintained by"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "collections"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guide"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citation history:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Downloads history:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "June"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "May"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "any day"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "May"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "any day"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "any day"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "any month"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "January"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "March"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "April"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "May"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "June"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "July"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "August"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "October"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "January"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "February"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "March"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "April"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "June"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "July"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "August"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "September"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "October"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "November"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "December"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "May"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Search"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "The record has been deleted."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "detailed"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "collections"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "collections"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "alerts"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "any month"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "detailed"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Try your search on..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Try your search on..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "baskets"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "collections"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "more"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "May"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "session"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Last updated"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Display results:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "account"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Display results:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalize"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Last updated"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Last updated"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "more"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Detailed record"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Sort by:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "May"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "account"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "account"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Detailed record"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "baskets"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Search Results"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Display results:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "baskets"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "baskets"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "baskets"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "September"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Cited by: %s records"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "September"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "April"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "April"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "baskets"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "jump to record:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "detailed"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "detailed"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "more"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Cited by"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "baskets"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "baskets"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "account"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "more"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "account"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Detailed record"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Collection %s Not Found"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "login"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "The record has been deleted."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Search"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Submit"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Submit"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Submit"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Narrow by collection:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Focus on:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "latest first"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "desc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "OR"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "rank by"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "results"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "split by collection"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "single list"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "brief"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Search %s records for:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Search Results"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "any day"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "any month"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "any year"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "any collection"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "add another collection"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "brief"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "AND"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "AND NOT"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "All of the words:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Any of the words:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Exact phrase:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Partial phrase:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regular expression:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Browse"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "No words index available for"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "No phrase index available for"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Search term <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "inside <em>%s</em> index"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr "did not match any record. Nearest terms in any collection are:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "The record has been deleted."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Detailed record"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr "No match within your time limits, discarding this condition..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr "No match within your search limits, discarding this condition..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Advanced Search"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Simple Search"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Search options:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Added since:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "until:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Sort by:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Display results:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Output format:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "restricted"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Latest additions:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "The contents of this collection is restricted."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "This collection does not contain any document yet."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "more"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Similar records"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Cited by"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "any collection"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Try your search on..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "collections"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "in"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
"Haven't found what you were looking for? Try your search on other servers:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> records found"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "login"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "jump to record:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Search took %.2f seconds."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "ADD TO BASKET"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Record created %s, last modified %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Cited by: %s records"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-cited with: %s records"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "People who downloaded this document also downloaded:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "People who viewed this page also viewed:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Boolean query returned no hits. Please combine your search terms differently."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "See also: similar author names"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Internal Error"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Collection %s Not Found"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "any day"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "baskets"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "baskets"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Search"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "baskets"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Search"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "account"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "login"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "alerts"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "login"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Search term <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Search"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Search"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "guest"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "session"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "alerts"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "baskets"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "account"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administration"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "logout"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "account"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "alerts"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "account"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "logout"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Browse"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "This collection does not contain any document yet."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "This collection does not contain any document yet."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "submissions"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "submissions"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "session"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "more"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "more"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "session"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "session"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "more"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "restricted"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "September"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "restricted"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "ENGLISH TRANSLATION UNDER WAY"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "ADD TO BASKET"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "baskets"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "baskets"
#, fuzzy
#~ msgid "Move"
#~ msgstr "more"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "ADD TO BASKET"
#, fuzzy
#~ msgid "Until"
#~ msgstr "until:"
diff --git a/po/es.po b/po/es.po
index 2d2213f96..013c57a7a 100644
--- a/po/es.po
+++ b/po/es.po
@@ -1,3900 +1,3900 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:12+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: ES <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Este sitio también está disponible en los siguientes idiomas:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Buscar"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Ayuda"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Área del Administrador"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Ayuda a la Búsqueda"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Administración de WebSubmit"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Enviar"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalizar"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Ayuda"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Última actualización"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Ayuda para el Envio"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guía"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "Febrero"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Consejos para la Búsqueda"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Página principal"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Mantenido por"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "colecciones"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guía"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Historia de citas:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Historia de descargas:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "Junio"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "Mayo"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "cualquier día"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "Mayo"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "cualquier día"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "cualquier día"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "cualquier mes"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "Enero"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "Marzo"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "Abril"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "Mayo"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "Junio"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "Julio"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "Agosto"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "Octubre"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "Enero"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "Febrero"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "Marzo"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "Abril"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "Junio"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "Julio"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "Agosto"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "Septiembre"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "Octubre"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "Noviembre"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "Diciembre"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "Mayo"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Buscar"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "The record has been deleted."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "detallado"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "colecciones"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "colecciones"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "avisos"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "cualquier mes"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "detallado"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Intentar la búsqueda en..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Intentar la búsqueda en..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "cestas"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "colecciones"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "más"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "Mayo"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "sesión"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Última actualización"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Mostrar resultados:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "cuenta"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Mostrar resultados:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalizar"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Última actualización"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Registros similares"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Última actualización"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "más"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Registro completo"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Ordenar por:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "Mayo"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "cuenta"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Registros similares"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Registros similares"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "cuenta"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Registro completo"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Resultados de la búsqueda"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Mostrar resultados:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "cestas"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "cestas"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "cestas"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "Septiembre"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Citado por: %s registros"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "Septiembre"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "Abril"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "Abril"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "cestas"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "ir al registro:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "detallado"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "detallado"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "más"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Citado por"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "cestas"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "cestas"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "cuenta"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "más"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "cuenta"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Registro completo"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Colección %s no encontrada"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "identificación"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "The record has been deleted."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Buscar"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Enviar"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Enviar"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Enviar"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Búsqueda por colección:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Enfocado a:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "el último primero"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "desc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "O"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ordenar por"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "resultados"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "reagrupar por colección"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "lista única"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "breve"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Buscar en %s registros por:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Resultados de la búsqueda"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "cualquier día"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "cualquier mes"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "cualquier año"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "todas las colecciones"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "añadir otra colección"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "breve"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "Y"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "Y NO"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Todas las palabras:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Al menos una de las palabras:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Frase exacta:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Parte de la frase:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Expresión regular:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Explorar"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"No se han encontrado coincidencias con <em>%s</em>, en cambio usando <em>%s</"
"em> ..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"No hay documentos que respondan a la búsqueda en la coleción %s. Other "
"public collections gave <a class=\"nearestterms\" href=\"%s/search.py?%s\">%"
"d hits</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Ninguna colección pública coincide con su búsqueda. Si estaba buscando "
"documentos no públicos, por favor escoga primero la opción collección "
"restringida."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "No hay ningún índice de palabras disponible"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "No hay ningún índice de frases disponible"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Término de búsqueda <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "en el índice <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"no se han encontrado ningún registro. Los términos aproximados en todas las "
"colección son:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "The record has been deleted."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Registro completo"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"No se han encontrado resultados dentro de los límites de tiempo "
"especificados, descartando esta condición..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"No se han encontrado resultados dentro de los límites especificados, "
"descartando esta condición..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Búsqueda Avanzada"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Búsqueda Simple"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Opciones de búsqueda:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Añadido a partir de:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "hasta:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Ordenar por:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Mostrar resultados:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Formato de visualización:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "reservado"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Últimas adquisiciones:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "El contenido de esta colección es reservado."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Esta colección no contiene aún ningún documento."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "más"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Registros similares"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Citado por"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "todas las colecciones"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Intentar la búsqueda en..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "colecciones"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "en"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
"¿No ha encontrado lo que estaba buscando? Intente su búsqueda en otros "
"servidores:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> registros encontrados"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "identificación"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "ir al registro:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "La búsqueda tardó %.2f segundos."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "AÑADIR A LA CESTA"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Registro creado %s, modificado %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Citado por: %s registros"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-citado con: %s registros"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "La gente que descargó este documento también descargó:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "La gente que vió esta página también vió:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Todos los resultados:</strong> Encontrados <strong>%s</strong> "
"registros en %.2f segundos."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"La combinación booleana no ha dado resultados. Por favor combien los "
"términos de búsqueda de otra manera."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Vea también: autores con nombres similares"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Error Interno"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Colección %s no encontrada"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Lo sentimos, la colección <strong>%s</strong> no existe. <p>Inténtelo "
"empezando desde <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "cualquier día"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "envios"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "envios"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "cuenta"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "identificación"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "avisos"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "identificación"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Término de búsqueda <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "visitante"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "sesión"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "avisos"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "cuenta"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "envios"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "approvals"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administración"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "salir"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "cuenta"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "avisos"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "cuenta"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "salir"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Explorar"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Por favor contacte <a href=\"mailto:%s\">%s</a> indicando la siguiente "
"información:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Esta colección no contiene aún ningún documento."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Esta colección no contiene aún ningún documento."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "envios"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "envios"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "sesión"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "más"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "más"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "sesión"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "sesión"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "más"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "reservado"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "Septiembre"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "approvals"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "reservado"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "VERSIÓN EN ESPAÑOL ESTARÁ DISPONIBLE PRÓXIMAMENTE"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Por el momento, la versión en español de esta página no está disponible. "
#~ "Le rogamos consultar la versión en inglés mostrada a continuación. "
#~ "Gracias por su compresión."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "AÑADIR A LA CESTA"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "cestas"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "cestas"
#, fuzzy
#~ msgid "Move"
#~ msgstr "más"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "AÑADIR A LA CESTA"
#, fuzzy
#~ msgid "Until"
#~ msgstr "hasta:"
diff --git a/po/fr.po b/po/fr.po
index 58d2873f3..aeb0ba1e2 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,3899 +1,3899 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:12+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: FR <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Ce site est aussi disponible dans les langues suivantes:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Recherche"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Aide"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Coin administrateur"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Aide de recherche"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Administration des soumissions"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Soumission"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personnaliser"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Centre d&rsquo;aide"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Dernière mise à jour"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Aide pour soumission"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guide"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "février"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Conseils de recherche"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Accueil"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Maintenu par"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "collections"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guide"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Historique des citations:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Historique des téléchargements:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "juin"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "tous les jours"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "tous les jours"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "tous les jours"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "tous les mois"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "janvier"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "mars"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "avril"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "juin"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "juillet"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "août"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "octobre"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "janvier"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "février"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "mars"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "avril"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "juin"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "juillet"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "août"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "septembre"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "octobre"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "novembre"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "décembre"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Recherche"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "La notice a été supprimée."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "détaillé"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "collections"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "collections"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "alertes"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "tous les mois"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "détaillé"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Essayer votre requête sur..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Essayer votre requête sur..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "paniers"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "collections"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "davantage"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "mai"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "session"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Dernière mise à jour"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Afficher:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "compte"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Afficher:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personnaliser"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Dernière mise à jour"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Notices similaires"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Dernière mise à jour"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "davantage"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Notice détaillée"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "La notice a été supprimée."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Trier par:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "mai"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "compte"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "La notice a été supprimée."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Notices similaires"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Notices similaires"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "compte"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Notice détaillée"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "paniers"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Résultats de recherche"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Afficher:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "paniers"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "paniers"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "paniers"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "septembre"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Cité par: %s notices"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "septembre"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "avril"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "avril"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "paniers"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "aller sur la notice:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "La notice a été supprimée."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "détaillé"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "détaillé"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "La notice a été supprimée."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "davantage"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Cité par"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "paniers"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "paniers"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "compte"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "davantage"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "compte"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Notice détaillée"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Collection %s introuvable"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "login"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "La notice a été supprimée."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Recherche"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Soumission"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Soumission"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Soumission"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Limiter par collection:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Focaliser sur:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "derniers en premier"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "desc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "OU"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ranger par"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "résultats"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "regroupés par collection"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "liste unique"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "bref"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Chercher dans %s notices:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Résultats de recherche"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "tous les jours"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "tous les mois"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "toutes les années"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "toutes les collections"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "ajouter une nouvelle collection"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "bref"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "ET"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "ET NON PAS"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Tous les mots:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Au moins un des mots:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Phrase exacte:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Phrase partielle:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Expression régulière:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr "'"
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Liste"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Aucun résultat précis pour <em>%s</em> n'a été trouvé, utilisons <em>%s</em> "
"à la place..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Aucun résultat n'a été trouvé dans la collection %s. Les autres collections "
"publiques ont donné <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d "
"résultats</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Aucune collection publique ne satisfait votre requête. Si vous avez cherché "
"des documents non publics, veuillez choisir d'abord la collection restreinte."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Aucun index de mots n'est disponible pour"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Aucun index de phrases n'est disponible pour"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Le terme de recherche <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "dans l'index <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"ne se trouve dans aucune notice. Les termes les plus proches de toutes les "
"collections sont:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "La notice a été supprimée."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Notice détaillée"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Pas de résultat pour l'intervalle de temps spécifé, la condition n'est pas "
"prise en compte..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Pas de résultat pour les limites spécifiées, les conditions ne sont pas "
"prises en compte..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Recherche avancée"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Recherche simple"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Options de recherche:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Ajouté depuis:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "jusqu'à:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Trier par:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Afficher:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Format de sortie:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "restreint"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Derniers ajouts:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Le contenu de cette collection est restreint."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Cette collection ne contient pas encore de document."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "davantage"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Notices similaires"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Cité par"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "toutes les collections"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Essayer votre requête sur..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "collections"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "dans"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
"Vous n'avez pas trouvé ce que vous avez cherché? Essayez votre requête sur "
"d'autres serveurs:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> notices trouvées"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "login"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "aller sur la notice:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "La recherche a duré %.2f secondes."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "AJOUTER DANS PANIER"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Notice créée %s, modifiée %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Cité par: %s notices"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-cité avec: %s notices"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Les utilisateurs qui ont téléchargé ce document ont aussi téléchargé:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Les utilisateurs qui ont vu cette page ont aussi vu:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Vue d'ensemble sur des résultats:</strong> Trouvé <strong>%s</"
"strong> notices en %.2f secondes."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"La requête booléenne n'a rien donné. Essayez de combiner les termes de "
"recherche différemment."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Voir aussi: noms d'auteurs similaires"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Erreur interne"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Collection %s introuvable"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Désolé, la collection <strong>%s</strong> n'existe pas. <p>Essayez de "
"naviguer à partir de <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "tous les jours"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "paniers"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "paniers"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Recherche"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "paniers"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "approbations"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Recherche"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "soumissions"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "soumissions"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "approbations"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "approbations"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "compte"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "login"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "alertes"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "login"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Le terme de recherche <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Recherche"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Recherche"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "visiteur"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "session"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "alertes"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "paniers"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "compte"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "soumissions"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "approbations"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administration"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "logout"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "compte"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "alertes"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "compte"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "logout"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Liste"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Veuillez contacter <a href=\"mailto:%s\">%s</a> en mentionnant l'information "
"suivante:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Cette collection ne contient pas encore de document."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Cette collection ne contient pas encore de document."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "soumissions"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "soumissions"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "session"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "davantage"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "davantage"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "session"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "session"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "davantage"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "approbations"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "restreint"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "approbations"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "approbations"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "septembre"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "approbations"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "restreint"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "TRADUCTION FRANÇAISE EN COURS"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Pour le moment, la traduction française de cette page n'est pas achevée. "
#~ "Nous vous prions de bien vouloir consulter la version anglaise qui suit. "
#~ "Merci de votre compréhension."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "AJOUTER DANS PANIER"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "La notice a été supprimée."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "paniers"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "paniers"
#, fuzzy
#~ msgid "Move"
#~ msgstr "davantage"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "AJOUTER DANS PANIER"
#, fuzzy
#~ msgid "Until"
#~ msgstr "jusqu'à:"
diff --git a/po/i18n_extract_from_wml_source.py b/po/i18n_extract_from_wml_source.py
index 1fa51c90e..01c98d21a 100644
--- a/po/i18n_extract_from_wml_source.py
+++ b/po/i18n_extract_from_wml_source.py
@@ -1,149 +1,149 @@
## $Id$
##
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""
This tool extracts sentences to be translated from HTML / WML source
files.
The sentences to translate are marked with the following tag:
Blah blah _(To be translated)_ blah.
These tags can span several lines. Extra whitespace is discarded.
"""
import sys, re, os
_tag_re = re.compile(r'_\((.*?)\)_', re.M)
_nl_re = re.compile('\n')
_ws_re = re.compile('\s+')
def print_usage():
"""Print usage info."""
print """Usage: %s <dirname> <potfiles-filename>
Description: Extract translatable strings from the list of files read
from potfiles-filename. The files specified there are
relative to dirname. Print results on stdout.
"""
return
def quote(text):
"""Normalize and quote a string for inclusion in the po file."""
return text.\
replace('\\', '\\\\').\
replace('\n', '\\\\n').\
replace('\t', '\\\\t').\
replace('"', '\\"')
def extract_from_wml_files(dirname, potfiles_filename):
"""Extract translatable strings from the list of files read from
potfiles_filename. The files specified there are relative to
dirname. Print results on stdout.
"""
## extract messages and fill db:
db = {}
for f in [ f.strip() for f in open(potfiles_filename) ]:
if not f or f.startswith('#'):
continue
f = f.rstrip(' \\')
data = open(dirname + "/" + f).read()
lines = [0]
for m in _nl_re.finditer(data):
lines.append(m.end())
for m in _tag_re.finditer(data.replace('\n', ' ')):
word = m.group(1)
pos = m.start()
line = len([x for x in lines if x < pos])
ref = '%s:%d' % (f, line)
# normalize the word a bit, as it comes from a file where
# whitespace is not too significant.
word = _ws_re.sub(' ', word.strip())
db.setdefault(word, []).append(ref)
## print po header:
print r'''
# # This file is part of the CERN Document Server Software (CDSware).
- # # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+ # # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"POT-Creation-Date: Tue Nov 22 16:44:03 2005\n"
"PO-Revision-Date: 2005-11-22 11:20+0100\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
'''
## print po content from db:
for original, refs in db.items():
for ref in refs:
print "#: %s" % ref
print 'msgid "%s"' % quote(original)
print 'msgstr ""'
print
return
if __name__ == "__main__":
if len(sys.argv) == 3:
dirname = sys.argv[1]
potfiles_filename = sys.argv[2]
if not os.path.isdir(dirname):
print "ERROR: %s is not a directory." % dirname
print_usage()
sys.exit(1)
elif not os.path.isfile(potfiles_filename):
print "ERROR: %s is not a file." % potfiles_filename
print_usage()
sys.exit(1)
else:
extract_from_wml_files(sys.argv[1], sys.argv[2])
else:
print_usage()
diff --git a/po/i18n_update_wml_target.py b/po/i18n_update_wml_target.py
index 0334e3980..ed9e68826 100644
--- a/po/i18n_update_wml_target.py
+++ b/po/i18n_update_wml_target.py
@@ -1,66 +1,66 @@
## This file is part of the CERN Document Server Software (CDSware).
-## Copyright (C) 2002, 2003, 2004, 2005 CERN.
+## Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
##
## The CDSware 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.
##
## The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
"""This tool updates WML target file still containing sentences to be
translated. The sentences to translate are marked with the following
tag:
Blah blah _(To be translated)_ blah.
These tags can span several lines. Extra whitespace is discarded.
"""
import sys
import os
import re
import gettext
lang = sys.argv[1]
files = sys.argv[2:]
charset = 'utf-8'
# a translation file is located in the source directory, along with
# this script. This makes it easy to find its path.
podir = os.path.dirname(__file__)
translation_file = os.path.join(podir, lang+'.gmo')
translation = gettext.GNUTranslations(open(translation_file))
# This matches the strings to be translated
_tag_re = re.compile(r'_\((.*?)\)_', re.DOTALL)
_ws_re = re.compile('\s+')
# we perform the substitution on the whole file at once, as they are
# not expected to be multi-gigabyte long.
def replace(match):
"""This function is called for each replacement, and fetches the
translation from the gettext catalog.
"""
text = match.group(1).decode(charset)
text = _ws_re.sub(' ', text.strip())
return translation.ugettext(text).encode('utf-8')
for filename in files:
content = open(filename).read()
content = _tag_re.sub(replace, content)
open (filename,'w').write(content)
diff --git a/po/it.po b/po/it.po
index d0b42e167..60dfed8b4 100644
--- a/po/it.po
+++ b/po/it.po
@@ -1,3896 +1,3896 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:12+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: IT <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Questo sito è disponibile anche nelle lingue seguenti:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Ricercare"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Aiuto"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Area dell&quot;Amministratore"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Aiuto alla Ricerca"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Amministrazione Websubmit"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Sottomettere"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalizzazione"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Aiuto"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Ultimo aggiornamento"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Aiuto per la Sottomissione"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guida"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "Febbraio"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Consigli per la Ricerca"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Pagina principale"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Mantenuto da"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "collezioni"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guida"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Cronaca delle citazioni:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Cronaca dei downloads:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "Giugno"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "Maggio"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "qualsiasi giorno"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "Maggio"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "qualsiasi giorno"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "qualsiasi giorno"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "qualsiasi mese"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "Gennaio"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "Marzo"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "Aprile"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "Maggio"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "Giugno"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "Luglio"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "Agosto"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "Ottobre"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "Gennaio"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "Febbraio"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "Marzo"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "Aprile"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "Giugno"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "Luglio"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "Agosto"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "Settembre"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "Ottobre"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "Novembre"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "Dicembre"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "Maggio"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Ricercare"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "The record has been deleted."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "dettagliato"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "collezioni"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "collezioni"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "allerta"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "qualsiasi mese"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "dettagliato"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Provate la ricerca su..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Provate la ricerca su..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "paniere"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "collezioni"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "ancora"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "Maggio"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "sessione"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Ultimo aggiornamento"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Visualizzare:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "conto"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Visualizzare:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalizzazione"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Ultimo aggiornamento"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Ultimo aggiornamento"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "ancora"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Registrazione dettagliata"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Ordinamento per:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "Maggio"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "conto"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "conto"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Registrazione dettagliata"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "paniere"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Risultato della ricerca"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Visualizzare:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "paniere"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "paniere"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "paniere"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "Settembre"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Citato da: %s articoli"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "Settembre"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "Aprile"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "Aprile"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "paniere"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "andare alla registrazione:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "dettagliato"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "dettagliato"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "ancora"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Citato da"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "paniere"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "paniere"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "conto"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "ancora"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "conto"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Registrazione dettagliata"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Collezione %s Non Trovata"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "login"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "The record has been deleted."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Ricercare"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Sottomettere"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Sottomettere"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Sottomettere"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Ricerca ristretta:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Focus on:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "Le ultime all'inizio"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "disc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "OPPURE"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ordinare per"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "risultati"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "raggruppati per collezione"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "lista unica"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "breve"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Ricerca in %s registrazioni:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Risultato della ricerca"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "qualsiasi giorno"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "qualsiasi mese"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "qualsiasi anno"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "tutte le collezioni"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "aggiungere un'altra collezione"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "breve"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "E"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "E NON"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Tutte le parole:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Almeno una parola:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Frase esatta:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Parte di frase:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regular expression:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr "."
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Sfogliare"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Nessun risultato trovato cercando <em>%s</em>, uso <em>%s</em> al suo "
"posto..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Nessun risultato trovato nelle collezioni %s. Le altre collezioni pubbliche "
"hanno dato <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d risultati</"
"a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Nessuna collezione pubblica ha dato risultati. Se cercate un documento non "
"pubblico, vi preghiamo di interrogare la collezione riservata di vostro "
"interesse."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Nessun indice per parola è disponibile per"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Nessun indice per frase è disponibile per"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Termine di ricerca <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "nell'indice <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"non ha dato risultati. I termini piu` prossimi in tutte le collezioni sono:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "The record has been deleted."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Registrazione dettagliata"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Nessun risultato nell'arco di tempo specificato, il criterio viene "
"ignorato..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Nessun risultato trovato nei limiti specificati, i criteri vengono "
"ignorati..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Ricerca Avanzata"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Ricerca Semplice"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Opzioni di ricerca:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Aggiunto dal:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "fino al:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Ordinamento per:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Visualizzare:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Formato di visualizzazione:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "riservato"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Ultimi arrivi:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Il contenuto di questa collezione è riservato."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Questa collezione non contiene ancora alcun documento."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "ancora"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Similar records"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Citato da"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "tutte le collezioni"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Provate la ricerca su..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "collezioni"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "on"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Non avete trovato quello che cercavate? Provate la ricerca su:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> registrazioni trovate"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "login"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "andare alla registrazione:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "La ricerca ha preso %.2f secondi."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "AGGIUNGERE AL PANIERE"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Record created %s, last modified %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Citato da: %s articoli"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Citato con: %s articoli"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Gli utenti che hanno scaricato questo documento hanno anche scaricato:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Gli utenti che hanno visitato questa pagina hanno anche visitato:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Risultato globale:</strong> Trovate <strong>%s</strong> "
"registrazioni in %.2f secondi."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"La ricerca booleana non ha dato risultati. Vi preghiamo di combinare "
"differentemente i termini."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Vedi anche: autori con nomi simili"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Errore Interno"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Collezione %s Non Trovata"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Spiacenti, la collezione <strong>%s</strong> non sembra esistere. "
"<p>Provate a cercare a partire da <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "qualsiasi giorno"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "paniere"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "paniere"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Ricercare"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "paniere"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "approvazioni"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Ricercare"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "approvazioni"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "approvazioni"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "conto"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "login"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "allerta"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "login"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Termine di ricerca <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Ricercare"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Ricercare"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "guest"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "sessione"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "allerta"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "paniere"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "conto"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "submissions"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "approvazioni"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "amministrazione"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "logout"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "conto"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "allerta"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "conto"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "logout"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Sfogliare"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Vi preghiamo di contattare <a href=\"mailto:%s\">%s</a> citando "
"l'informazione seguente:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Questa collezione non contiene ancora alcun documento."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Questa collezione non contiene ancora alcun documento."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "submissions"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "submissions"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "sessione"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "ancora"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "ancora"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "sessione"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "sessione"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "ancora"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "approvazioni"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "riservato"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "approvazioni"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "approvazioni"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "Settembre"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "approvazioni"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "riservato"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "TRADUZIONE ITALIANA DISPONIBILE PROSSIMAMENTE"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Attualmente la traduzione italiana di questa pagina non è disponibile. Vi "
#~ "preghiamo di consultare la versione inglese. Grazie per la comprensione."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "AGGIUNGERE AL PANIERE"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "paniere"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "paniere"
#, fuzzy
#~ msgid "Move"
#~ msgstr "ancora"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "AGGIUNGERE AL PANIERE"
#, fuzzy
#~ msgid "Until"
#~ msgstr "fino al:"
diff --git a/po/ja.po b/po/ja.po
index 86bc2540e..dd09112e9 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -1,3702 +1,3702 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.9\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2006-01-11 17:39+0100\n"
"Last-Translator: Tibor Simko <tibor.simko@cern.ch>\n"
"Language-Team: JA <cds.support@cern.ch>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "この場所は次の言語でまた利用できる:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "調査"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "助け"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "管理区域"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "調査助け"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr ""
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "堤出しなさい"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "個人化しなさい"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "助け中央"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
msgid "Last updated:"
msgstr "更新"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "堤出しなさい助け"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr ""
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "2月"
#: config/cdspage.wml:56
msgid "Agenda"
msgstr ""
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "調査先端"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "家"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "維持しなさい"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "コレクション"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "動力を与えられる"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
msgid "See Guide"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "参照の歴史:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "ダウンロードの歴史:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
msgid "Sun"
msgstr ""
#: modules/miscutil/lib/dateutils.py:140
msgid "Mon"
msgstr ""
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
msgid "Wed"
msgstr ""
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
msgid "Sunday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:148
msgid "Monday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:149
msgid "Tuesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
msgid "Saturday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
msgid "Month"
msgstr ""
#: modules/miscutil/lib/dateutils.py:168
msgid "Jan"
msgstr "1月"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr "2月"
#: modules/miscutil/lib/dateutils.py:170
msgid "Mar"
msgstr "3月"
#: modules/miscutil/lib/dateutils.py:171
msgid "Apr"
msgstr "4月"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "5月"
#: modules/miscutil/lib/dateutils.py:173
msgid "Jun"
msgstr "6月"
#: modules/miscutil/lib/dateutils.py:174
msgid "Jul"
msgstr "7月"
#: modules/miscutil/lib/dateutils.py:175
msgid "Aug"
msgstr "8月"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr "9月"
#: modules/miscutil/lib/dateutils.py:177
msgid "Oct"
msgstr "10月"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr "11月"
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr "12月"
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "1月"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "2月"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "3月"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "4月"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "6月"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "7月"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "8月"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "9月"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "10月"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "11月"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "12月"
#: modules/miscutil/lib/dateutils.py:211
msgid "Day"
msgstr ""
#: modules/miscutil/lib/dateutils.py:262
msgid "Year"
msgstr ""
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "記録は削除された"
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
msgid "detailed list"
msgstr "詳しい list"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
msgid "Collections"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:90
msgid "Collection"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
msgid "alert name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
msgid "monthly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
msgid "daily"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
msgid "your searches"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:282
msgid "most popular searches"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
msgid "Result in basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
msgid "Action"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:351
msgid "Remove"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:352
msgid "Modify"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
msgid "Question"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:432
msgid "Last Run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
msgid "Display searches"
msgstr ""
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
msgid "Your Account"
msgstr ""
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
msgid "Display alerts"
msgstr ""
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "個人化しなさい"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket.py:858
#, python-format
msgid "%i other's baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:182
#, python-format
msgid "There are %i baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "更新"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "ほとんど同じ記録"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "更新"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
msgid "Non shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
msgid "Remove item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "詳しい 記録"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "種類"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "on"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
msgid "Delete comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
msgid "Create new basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
msgid "Select topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:873
msgid "New basket's name"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
msgid "Create a new basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "バスケット"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
msgid "Select a topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1120
msgid "New topic's name"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "ほとんど同じ記録"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "1月"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "ほとんど同じ記録"
#: modules/webbasket/lib/webbasket_templates.py:1224
msgid "delete comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "詳しい 記録"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
msgid "no basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "調査は生じる"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "表示は生じる:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
msgid "Your Baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
msgid "Delete a basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "バスケット"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
msgid "Report abuse"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "引用される: %s は記録する"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
msgid "(Report abuse)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "4月"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "4月"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
msgid "Select a score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "記録することを行きなさい"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
msgid "View all users who have been reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
msgid "Email"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
msgid "email"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1140
#, python-format
msgid "This %s has been reported %i times"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "引用される"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
msgid "Select"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1233
#, python-format
msgid "Delete selected %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
msgid "Delete Comment"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Reviews"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
msgid "Delete comments"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "詳しい 記録"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "コレクション %s 見つけられない"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
msgid "Login"
msgstr "ログイン"
#: modules/webmessage/lib/webmessage.py:141
msgid "The message could not be deleted"
msgstr ""
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
msgid "Your Messages"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
msgid "Subject"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Sender"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
msgid "[No subject]"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
msgid "Send later?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
msgid "Subject:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "によって コレクション:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "焦点:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "最も遅く最初に"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "desc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "または"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ランク"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "結果"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "コレクションによる割れ目"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "単一のリスト"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "報告書"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "調査 %s 記録 のため"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "調査は生じる"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "日"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "月"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "å¹´"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "コレクション"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "別のコレクションを加えなさい"
#: modules/websearch/lib/search_engine.py:538
msgid "HTML brief"
msgstr "HTML 報告書"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "そして"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "そして ない"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "すべての単語:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "単語:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "厳密な句<:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "部分的な句:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "規則的 表現:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "拾い読みしなさい"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"完全一致は<em>%s</em> を使用して <em>%s</em> のために、代りに見つけなかっ"
"た... (FIXME)"
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"マッチはコレクション %s で見つけなかった.\n"
" 他の公共のコレクションは <a class=\"nearestterms\" href=\"%s/search.py?%s"
"\">%d 衝突を与えた</a>"
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"公共のコレクションはあなたの問い合わせに一致させなかった\n"
" 文書を捜したら、望ましい限られたコレクションを最初に選びなさい."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "単語は利用できるのための指示しない"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "のために利用できる句の索引無し"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "調査の言葉 <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "中の <em>%s</em> の索引"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"記録を一致させなかった. あらゆるコレクションの近い将来は次のとおりである:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "記録は削除された"
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "詳しい 記録"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr "マッチは制限時間で見つけなかった"
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr "あなたの調査の限界のマッチ無し, この条件の退去"
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "高度調査"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "簡単な調査"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "調査の選択:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "その後加えられる:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "まで:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "種類"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "表示は生じる:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "出力フォーマット:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "限られた"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "ほとんどの最近の付加:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "このコレクションの内容は限られている"
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "このコレクションはまだ文書を含んでいない"
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "多く"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "ほとんど同じ記録"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "引用される"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
msgid "in any collection are:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "試み あなたの調査..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "コレクション"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "中の"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
"捜していたものを見つけなかったか。他のサーバーのあなたの調査を試みなさい"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> 記録は見つけた"
#: modules/websearch/lib/websearch_templates.py:1803
msgid "begin"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
msgid "end"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "記録することを行きなさい"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "調査は %.2f の秒を取った"
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "バスケットに加えなさい"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "記録は %s, の最終変更 %s を作成した"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "引用される: %s は記録する"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "%s とCo 引用されて記録する"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "この文書をまたダウンロードした人々はダウンロードした:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "このページをまた見た人々は見た:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>結果の概観:</strong> 見つけられた <strong>%s</strong> の記録 %.2f の"
"秒."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"ブール問い合わせは何も見つけなかった.\n"
" あなたの調査の言葉を別様に結合しなさい."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "また見なさい: 同じような著者の名前"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "内部エラー"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "コレクション %s 見つけられない"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>残念, コレクション <strong>%s</strong> 存在するかもしれなくない. \n"
"<p><a href=\"%s\">%s</a> から拾い読みし始めることができる."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
msgid "mandatory"
msgstr ""
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
msgid "Select method"
msgstr ""
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
msgid "Your Settings"
msgstr ""
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
msgid "Your Searches"
msgstr ""
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
msgid "Your Alerts"
msgstr ""
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
msgid "Your Loans"
msgstr ""
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
msgid "Your Alert Searches"
msgstr ""
#: modules/websession/lib/websession_templates.py:413
msgid "Your Submissions"
msgstr ""
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
msgid "your submissions"
msgstr ""
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
msgid "Your Approvals"
msgstr ""
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
msgid "your approvals"
msgstr ""
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
msgid "Deleting your account"
msgstr ""
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
msgid "Login via:"
msgstr ""
#: modules/websession/lib/websession_templates.py:590
msgid "Username"
msgstr ""
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "ログイン"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, python-format
msgid "You seem to be <em>%s</em>."
msgstr ""
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
msgid "Configure WebComment"
msgstr ""
#: modules/websession/lib/websession_templates.py:724
msgid "Configure WebSearch"
msgstr ""
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "ゲスト"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "会議"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "警報"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "バスケット"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "記述"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "提出"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "承認"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "管理"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "ログアウト"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
msgid "Show account"
msgstr ""
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
msgid "username"
msgstr ""
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
msgid "Delete Account"
msgstr ""
#: modules/websession/web/youraccount.py:291
msgid "Logout"
msgstr "ログアウト"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "拾い読みしなさい"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr "次の情報を引用する接触 <a href=\\\"mailto:%s\\\">%s</a>:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
msgid "this action does not apply on this type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
msgid "Your chosen action is not supported by the document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
msgid "Submission no(1)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
msgid "Submission no"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
msgid "Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:990
msgid "Score"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
msgid "or"
msgstr "または"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, python-format
msgid " version #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
msgid "version"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1335
msgid "For"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
msgid "pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
msgid "approved"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
msgid "rejected"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
msgid "waiting for approval"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
msgid "already approved"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
msgid "Report Number"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1732
msgid "Pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1733
msgid "Approved"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1734
msgid "Rejected"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "JAPANESE TRANSLATION UNDER WAY"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "At the moment the Japanese version of this page isn't available yet. "
#~ "Please\n"
#~ "use the version presented below. Thanks for your understanding."
diff --git a/po/no.po b/po/no.po
index cd59fdc8f..17475c4c7 100644
--- a/po/no.po
+++ b/po/no.po
@@ -1,3889 +1,3889 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:12+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: IT <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Denne siden er også tilgjengelig på følgende språk:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Søk"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Hjelp"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Administratorområde"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Søkehjelp"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Innsendingsadministrasjon"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Send inn"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Brukerinnstillinger"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Hjelpesentral"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Sist oppdatert"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Innsendingshjelp"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guide"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "februar"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Søketips"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Hovedsiden"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Vedlikeholdt av"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "samlinger"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guide"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citation history:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Downloads history:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "juni"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "alle dager"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "alle dager"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "alle dager"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "alle måneder"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "januar"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "mars"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "april"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "juni"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "juli"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "august"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "oktober"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "januar"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "februar"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "mars"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "april"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "juni"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "juli"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "august"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "september"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "oktober"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "november"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "desember"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "mai"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Søk"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "Posten har blitt slettet."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "detaljert"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "samlinger"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "samlinger"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "varsler"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "alle måneder"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "detaljert"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Prøv søket på..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Prøv søket på..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "kurver"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "samlinger"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "mer"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "mai"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "økt"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Sist oppdatert"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Vis resultater:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "konto"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Vis resultater:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Brukerinnstillinger"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Sist oppdatert"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Lignende sider"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Sist oppdatert"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "mer"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Full post"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "Posten har blitt slettet."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Sorter etter:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "mai"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "Posten har blitt slettet."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Lignende sider"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Lignende sider"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Full post"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "kurver"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Søkeresultater"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Vis resultater:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "kurver"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "kurver"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "kurver"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "september"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Cited by: %s records"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "september"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "april"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "april"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "kurver"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "gå til post:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "Posten har blitt slettet."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "detaljert"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "detaljert"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "Posten har blitt slettet."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "mer"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Cited by"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "kurver"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "kurver"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "mer"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Full post"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Samling %s ikke funnet"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "logg inn"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "Posten har blitt slettet."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Søk"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Send inn"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Send inn"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Send inn"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Begrens til samling:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Utvalgte samlinger:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "siste først"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "stigende"
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "synkende"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "ELLER"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ranger etter"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "resultater"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "oppdelt etter samling"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "enkel liste"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "kort"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Søk i %s poster etter:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Søkeresultater"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "alle dager"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "alle måneder"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "alle år"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "alle samlinger"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "legg til ny samling"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "kort"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "OG"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "OG IKKE"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Alle ordene:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Minst ett av ordene:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Nøyaktig uttrykk:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Delvis uttrykk:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regulært uttrykk:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Bla gjennom"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Ingen nøyaktige treff funnet for <em>%s</em>, bruker <em>%s</em> i stedet..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Ingen nøyaktige treff funnet i samling %s. Andre offentlige samlinger gav <a "
"class=\"nearestterms\" href=\"%s/search.py?%s\">%d treff</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Ingen offentlige samlinger passet ditt søk. Dersom du så etter et ikke-"
"offentlig dokument, vennligst velg den ønskede adgangsbegrensede samlingen "
"først."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Ingen ordindeks tilgjengelig for"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Ingen uttrykksindeks tilgjengelig for"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Søketerm <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "innen <em>%s</em>indeks"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr "passet ingen poster. Næreste term i hvilken som helst samling er:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "Posten har blitt slettet."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Full post"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr "Ingen treff innen angitt tidsbegrensning, forkaster dette kriteriet..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr "Ingen treff innen dine søkebegrensninger, forkaster dette kriteriet..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Avansert Søk"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Enkelt Søk"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Søkevalg:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Lagt til fra:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "til:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Sorter etter:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Vis resultater:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Visningsformat:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "adgangsbegrenset"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Siste tillagte poster:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Innholdet i denne samlingen er adgangsbegrenset."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Denne samlingen inneholder fremdeles ingen dokumenter."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "mer"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Lignende sider"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Cited by"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "alle samlinger"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Prøv søket på..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "samlinger"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "i"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Ikke funnet hva du søkte etter? Prøv søket på:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> poster funnet"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "logg inn"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "gå til post:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Søket tok %.2f sekunder."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "LEGG TIL I KURV"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Posten vart laget %s, sist endret %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Cited by: %s records"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-cited with: %s records"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "People who downloaded this document also downloaded:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "People who viewed this page also viewed:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Resultatoversikt:</strong> Fant <strong>%s</strong> poster på %.2f "
"sekunder."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Bolske søk returnerte ingen treff. Vennligst kombiner søketermenene dine "
"annerledes."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Se også: lignende forfatternavn"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Intern Feil"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Samling %s ikke funnet"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Beklager, samlingen <strong>%s</strong> ser ikke ut til å finnes. <p>Du "
"ønsker kanskje å starte å søket fra <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "alle dager"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "kurver"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "kurver"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Søk"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "kurver"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "godkjente"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Søk"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "innsendte"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "innsendte"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "godkjente"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "godkjente"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "logg inn"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "varsler"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "logg inn"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Søketerm <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Søk"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Søk"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "gjest"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "økt"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "varsler"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "kurver"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "innsendte"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "godkjente"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administrasjon"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "logg ut"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "konto"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "varsler"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "konto"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "logg ut"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Bla gjennom"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Vennligst kontakt <a href=\"mailto:%s\">%s</a> og ta med følgenede "
"informasjon:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Denne samlingen inneholder fremdeles ingen dokumenter."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Denne samlingen inneholder fremdeles ingen dokumenter."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "innsendte"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "innsendte"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "økt"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "mer"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "mer"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "økt"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "økt"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "mer"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "godkjente"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "adgangsbegrenset"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "godkjente"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "godkjente"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "september"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "godkjente"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "adgangsbegrenset"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "NORSK OVERSETTELSE UNDERVEIS"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "For øyeblikket er ikke den norske oversettelsen klar. Vennligst bruk "
#~ "versjonen som er presentert under."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "LEGG TIL I KURV"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "Posten har blitt slettet."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "kurver"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "kurver"
#, fuzzy
#~ msgid "Move"
#~ msgstr "mer"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "LEGG TIL I KURV"
#, fuzzy
#~ msgid "Until"
#~ msgstr "til:"
diff --git a/po/pl.po b/po/pl.po
index 5c145b04f..91314a421 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,3646 +1,3646 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.9\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2006-01-13 14:58+0100\n"
"Last-Translator: Tibor Simko <tibor.simko@cern.ch>\n"
"Language-Team: PL <cds.support@cern.ch>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Ta strona jest również dostępna w następujących językach:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr ""
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr ""
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr ""
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr ""
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr ""
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr ""
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr ""
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr ""
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
msgid "Last updated:"
msgstr ""
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr ""
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr ""
#: config/cdspage.wml:59
msgid "Library"
msgstr ""
#: config/cdspage.wml:56
msgid "Agenda"
msgstr ""
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr ""
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr ""
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr ""
#: config/cdspage.wml:58
msgid "Bulletin"
msgstr ""
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
msgid "See Guide"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr ""
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr ""
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
msgid "Sun"
msgstr ""
#: modules/miscutil/lib/dateutils.py:140
msgid "Mon"
msgstr ""
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
msgid "Wed"
msgstr ""
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
msgid "Sunday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:148
msgid "Monday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:149
msgid "Tuesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
msgid "Saturday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
msgid "Month"
msgstr ""
#: modules/miscutil/lib/dateutils.py:168
msgid "Jan"
msgstr ""
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
msgid "Mar"
msgstr ""
#: modules/miscutil/lib/dateutils.py:171
msgid "Apr"
msgstr ""
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr ""
#: modules/miscutil/lib/dateutils.py:173
msgid "Jun"
msgstr ""
#: modules/miscutil/lib/dateutils.py:174
msgid "Jul"
msgstr ""
#: modules/miscutil/lib/dateutils.py:175
msgid "Aug"
msgstr ""
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
msgid "Oct"
msgstr ""
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr ""
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr ""
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr ""
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr ""
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr ""
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr ""
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr ""
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr ""
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr ""
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr ""
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr ""
#: modules/miscutil/lib/dateutils.py:211
msgid "Day"
msgstr ""
#: modules/miscutil/lib/dateutils.py:262
msgid "Year"
msgstr ""
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, python-format
msgid "The alert %s has been successfully updated."
msgstr ""
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
msgid "detailed list"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
msgid "Collections"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:90
msgid "Collection"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
msgid "alert name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
msgid "monthly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
msgid "daily"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
msgid "your searches"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:282
msgid "most popular searches"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
msgid "Result in basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
msgid "Action"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:351
msgid "Remove"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:352
msgid "Modify"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
msgid "Question"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:432
msgid "Last Run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
msgid "Display searches"
msgstr ""
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
msgid "Your Account"
msgstr ""
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
msgid "Display alerts"
msgstr ""
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
msgid "Personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
msgid "Group baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:830
msgid "Other's baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, python-format
msgid "%i group baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:858
#, python-format
msgid "%i other's baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
msgid "Others' baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:182
#, python-format
msgid "There are %i baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:189
msgid "updated on"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
msgid "Public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
msgid "records"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
msgid "last update"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
msgid "Non shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
msgid "Shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
msgid "Delete basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
msgid "Remove item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:496
msgid "Extern record"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:578
msgid "Sort by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
msgid "Back to baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "on"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
msgid "Delete comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
msgid "Create new basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
msgid "Select topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:873
msgid "New basket's name"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
msgid "Create a new basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
msgid "Select basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, python-format
msgid "%i baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
msgid "Add to baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1024
#, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
msgid "Select a topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1120
msgid "New topic's name"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
msgid "View records"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "and"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
msgid "add records"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1224
msgid "delete comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1226
msgid "remove records"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
msgid "no basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
msgid "(Back to search results)"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:66
msgid "Display baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
msgid "Your Baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
msgid "Delete a basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
msgid "Create basket"
msgstr ""
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
msgid "Report abuse"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:360
#, python-format
msgid "Reviewed by %s on %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
msgid "(Report abuse)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
msgid "Article:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
msgid "Article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
msgid "Select a score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
msgid "Back to record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
msgid "View all users who have been reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
msgid "Email"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
msgid "email"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1140
#, python-format
msgid "This %s has been reported %i times"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1217
msgid "Written by"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
msgid "Select"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1233
#, python-format
msgid "Delete selected %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
msgid "Delete Comment"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Reviews"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
msgid "Delete comments"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, python-format
msgid "Detailed record #%s"
msgstr ""
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
msgid "Record Not Found"
msgstr ""
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
msgid "Login"
msgstr ""
#: modules/webmessage/lib/webmessage.py:141
msgid "The message could not be deleted"
msgstr ""
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
msgid "Your Messages"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
msgid "Subject"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Sender"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
msgid "[No subject]"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
msgid "Send later?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
msgid "Subject:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr ""
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr ""
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr ""
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr ""
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr ""
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr ""
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr ""
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr ""
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr ""
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr ""
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr ""
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr ""
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr ""
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr ""
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr ""
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr ""
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr ""
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr ""
#: modules/websearch/lib/search_engine.py:538
msgid "HTML brief"
msgstr ""
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr ""
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr ""
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr ""
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr ""
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr ""
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr ""
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr ""
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ""
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr ""
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr ""
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr ""
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr ""
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr ""
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr ""
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr ""
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
msgid "in any collection are:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1803
msgid "begin"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
msgid "end"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr ""
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr ""
#: modules/websearch/web/index.py:65
#, python-format
msgid "Collection %s Not Found"
msgstr ""
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
msgid "mandatory"
msgstr ""
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
msgid "Select method"
msgstr ""
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
msgid "Your Settings"
msgstr ""
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
msgid "Your Searches"
msgstr ""
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
msgid "Your Alerts"
msgstr ""
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
msgid "Your Loans"
msgstr ""
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
msgid "Your Alert Searches"
msgstr ""
#: modules/websession/lib/websession_templates.py:413
msgid "Your Submissions"
msgstr ""
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
msgid "your submissions"
msgstr ""
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
msgid "Your Approvals"
msgstr ""
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
msgid "your approvals"
msgstr ""
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
msgid "Deleting your account"
msgstr ""
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
msgid "Login via:"
msgstr ""
#: modules/websession/lib/websession_templates.py:590
msgid "Username"
msgstr ""
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr ""
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, python-format
msgid "You seem to be <em>%s</em>."
msgstr ""
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
msgid "Configure WebComment"
msgstr ""
#: modules/websession/lib/websession_templates.py:724
msgid "Configure WebSearch"
msgstr ""
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr ""
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr ""
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr ""
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr ""
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr ""
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr ""
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr ""
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr ""
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr ""
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
msgid "Show account"
msgstr ""
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
msgid "username"
msgstr ""
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
msgid "Delete Account"
msgstr ""
#: modules/websession/web/youraccount.py:291
msgid "Logout"
msgstr ""
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
msgid "Browser"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
msgid "this action does not apply on this type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
msgid "Your chosen action is not supported by the document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
msgid "Submission no(1)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
msgid "Submission no"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
msgid "Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:990
msgid "Score"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
msgid "or"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, python-format
msgid " version #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
msgid "version"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1335
msgid "For"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
msgid "pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
msgid "approved"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
msgid "rejected"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
msgid "waiting for approval"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
msgid "already approved"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
msgid "Report Number"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1732
msgid "Pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1733
msgid "Approved"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1734
msgid "Rejected"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
diff --git a/po/pt.po b/po/pt.po
index c077605b0..bce501a66 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -1,3898 +1,3898 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:13+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: PT <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Esta sita também está disponível nos seguintes idiomas:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Buscar"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Ajuda"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Área do Administrador"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Ajuda de Busca"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Administração de Envios"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Enviar"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalizar"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Central de Ajuda"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Última atualização"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Ajuda sobre Envio"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guia"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "Fevereiro"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Sugestões de busca"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Página principal"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Mantido por"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "coleções"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guia"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Histórico de citações:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Históricos de downloads:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "Junho"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "Maio"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "qualquer dia"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "Maio"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "qualquer dia"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "qualquer dia"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "qualquer mês"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "Janeiro"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "Março"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "Abril"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "Maio"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "Junho"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "Julho"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "Agosto"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "Outubro"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "Janeiro"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "Fevereiro"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "Março"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "Abril"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "Junho"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "Julho"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "Agosto"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "Setembro"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "Outubro"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "Novembro"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "Dezembro"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "Maio"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Buscar"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "O registro foi apagado."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "detalhado"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "coleções"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "coleções"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "avisos"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "qualquer mês"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "detalhado"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Tentar sua busca em..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Tentar sua busca em..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "cestas"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "coleções"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "mais"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "Maio"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "sessão"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Última atualização"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Mostrar resultados:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "conta"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Mostrar resultados:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalizar"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Última atualização"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Registros similares"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Última atualização"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "mais"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Registro detalhado"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "O registro foi apagado."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Ordenar por:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "Maio"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "conta"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "O registro foi apagado."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Registros similares"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Registros similares"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "conta"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Registro detalhado"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "cestas"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Resultados da busca"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Mostrar resultados:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "cestas"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "cestas"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "cestas"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "Setembro"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Citado por: %s registros"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "Setembro"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "Abril"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "Abril"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "cestas"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "ir para o registro:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "O registro foi apagado."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "detalhado"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "detalhado"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "O registro foi apagado."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "mais"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Citado por"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "cestas"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "cestas"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "conta"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "mais"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "conta"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Registro detalhado"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "A coleção %s não foi encontrada"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "identificação"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "O registro foi apagado."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Buscar"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Enviar"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Enviar"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Enviar"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Filtrar por coleção:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Ênfase em:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "Último primeiro"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "asc."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "desc."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "OU"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "ordenado por"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "resultados"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "agrupar por coleção"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "lista única"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "breve"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Buscar %s registros por:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Resultados da busca"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "qualquer dia"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "qualquer mês"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "qualquer ano"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "qualquer coleção"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "adicionar outra coleção"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "breve"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "E"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "E NÃO"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Todas as palavras:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Qualquer das palavras:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Expressão exata:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Expressão aproximada:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Expressão regular:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr "."
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Explorar"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Nenhum resultado exato foi encontrado para <em>%s</em>, usando <em>%s</em> "
"em substituição..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Nenhum resultado foi encontrado na coleção %s. Outras coleções públicas "
"retornaram <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d resultados</"
"a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Nenhuma coleção pública corresponde à sua busca. Se você está procurando um "
"documento que não é público, por favor escolha a coleção restrita desejada "
"primeiro."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Nenhum índice de palavras está disponível para"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Nenhum índice de frases está disponível para"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Termo de busca <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "no <em>%s</em> índice"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"não está presente em nenhum registro. Os termos mais similares em todas as "
"coleções são:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "O registro foi apagado."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Registro detalhado"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Nenhum resultado dentro do período de tempo especificado, desconsiderando "
"esta condição..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Nenhum resultado dentro dos limites de busca especificados, descartando esta "
"condição..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Busca Avançada"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Busca Básica"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Opções de busca:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Adicionada desde:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "até:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Ordenar por:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Mostrar resultados:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Formato de saída:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "restrito"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Ítens mais recentes:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "O conteúdo desta coleção é restrito."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Esta coleção ainda não contém nenhum documento."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "mais"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Registros similares"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Citado por"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "qualquer coleção"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Tentar sua busca em..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "coleções"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "em"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Não encotrou o que estava procurando? Tentar sua busca em:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> registros encontrados"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "identificação"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "ir para o registro:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "A busca levou %.2f segundos."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "ADICIONAR À CESTA"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Registro criado %s, modificado pela última vez %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Citado por: %s registros"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-citado com: %s registros"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Pessoas que baixaram este documento também baixaram:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Pessoas que visitaram esta página também visitaram:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Resultados globais:</strong> Encontrados <strong>%s</strong> "
"registros em %.2f segundos."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"A consulta booleana não gerou resultados. Por favor combine seus termos de "
"outra maneira."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Veja também: nomes de autores similares"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Erro Interno"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "A coleção %s não foi encontrada"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Sinto muito, mas a coleção <strong>%s</strong> parece não existir. "
"<p>Experimente explorar a partir de <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "qualquer dia"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "aprovações"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "envios"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "envios"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "aprovações"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "aprovações"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "conta"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "identificação"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "avisos"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "identificação"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Termo de busca <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Buscar"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "visitante"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "sessão"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "avisos"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "cestas"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "conta"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "envios"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "aprovações"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administração"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "sair"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "conta"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "avisos"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "conta"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "sair"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Explorar"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Por favor entre em contato com <a href=\"mailto:%s\">%s</a> mencionando a "
"seguinte informação:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Esta coleção ainda não contém nenhum documento."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Esta coleção ainda não contém nenhum documento."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "envios"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "envios"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "sessão"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "mais"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "mais"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "sessão"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "sessão"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "mais"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "aprovações"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "restrito"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "aprovações"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "aprovações"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "Setembro"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "aprovações"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "restrito"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "VERSÃO EM PORTUGUÊS ESTARÁ DISPONÍVEL EM BREVE"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "No momento a versão em português desta página não encontra-se disponível. "
#~ "Favor utilizar a versão em inglês apresentada abaixo. Grato por sua "
#~ "compreensão."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "ADICIONAR À CESTA"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "O registro foi apagado."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "cestas"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "cestas"
#, fuzzy
#~ msgid "Move"
#~ msgstr "mais"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "ADICIONAR À CESTA"
#, fuzzy
#~ msgid "Until"
#~ msgstr "até:"
diff --git a/po/ru.po b/po/ru.po
index 5942c9b0b..fa103346e 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -1,3892 +1,3892 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:13+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: RU <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Этот сайт также доступен на следующих языках:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Искать"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Помощь"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Область Администратора"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Помощь для поиска"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Администрация Внесения"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Внести"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Персонализовать"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Центральная Помощь"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Последнее изменение"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Помощь при внесении"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Руководство"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "февраль"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Повестка"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Указания для поиска"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Главная страница"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Поддерживает"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "наборы"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Руководство"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citation history:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Downloads history:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "июнь"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "май"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Повестка"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "любой день"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "май"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "любой день"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "любой день"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "любой месяц"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "январь"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "март"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "апрель"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "май"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "июнь"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "июль"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "август"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "октябрь"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "январь"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "февраль"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "март"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "апрель"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "июнь"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "июль"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "август"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "сентябрь"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "октябрь"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "ноябрь"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "декабрь"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "май"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Искать"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "The record has been deleted."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "подробный"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "наборы"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "наборы"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "сообщения"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "любой месяц"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "подробный"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Попробуйте искать с..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Попробуйте искать с..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "корзины"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "наборы"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "ещё"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "май"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "сеанс"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Последнее изменение"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Представить результаты:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "счёт"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Представить результаты:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Персонализовать"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Последнее изменение"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Последнее изменение"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "ещё"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Подробная запись"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Классифицировать по:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "май"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "счёт"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Повестка"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "счёт"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Подробная запись"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "корзины"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Результаты поиска"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Представить результаты:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "корзины"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "корзины"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "корзины"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "сентябрь"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Cited by: %s records"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "сентябрь"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "апрель"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "апрель"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "корзины"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "идти к записи:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "подробный"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "подробный"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "ещё"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Cited by"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "корзины"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "корзины"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "счёт"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "ещё"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "счёт"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Подробная запись"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Набор %s не существует"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "записаться"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "The record has been deleted."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Искать"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Внести"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Повестка"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Внести"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Повестка"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Внести"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Сократить набор:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Указание на:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "сначала последний запрос"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "восх."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "нисх."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "ИЛИ"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "упорядочить по"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "результаты"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "разделить по наборам"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "один лист"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "краткий"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Искать до %s записей для:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Результаты поиска"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "любой день"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "любой месяц"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "любой год"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "любой набор"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "добавить другой набор"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "краткий"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "И"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "И НЕТ"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Все слова:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Любое из слов:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Точная фраза:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Часть фразы:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Регулярное выражение:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Просмотреть"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Ни один результат не найден для <em>%s</em>, взамен используется <em>%s</"
"em> ..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Не найден результат в наборе %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Ваш запрос не удовлетворён ни одним доступным набором. Для поиска документа "
"ограниченного доступа, выберете сначала ваш набор."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Не найден лексический индекс для"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Не найден фразовый индех для"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Искомый термин <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "в индексе <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr "не найден. Возможные термины:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "The record has been deleted."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Подробная запись"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Не найден ни один результат в пределах данного временного интервала, отмена "
"условия..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Не найден ни один результат для вашего ограничения поиска, отмена условия..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Расширенный Поиск"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Простой Поиск"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Опции поиска:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Добавлено с:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "до:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Классифицировать по:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Представить результаты:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Формат представления:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "ограничено"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Последние добавления:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Содержание етого набора ограничено."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Этот набор не содержит пока ни одной записи."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "ещё"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Similar records"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Cited by"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "любой набор"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Попробуйте искать с..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "наборы"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "в"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Haven't found what you were looking for? Попробуйте искать с:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> найденных записей"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "записаться"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Повестка"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "идти к записи:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Поиск длился %.2f секунд."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "ДОБАВИТь В КОРЗИНУ"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Record created %s, last modified %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Cited by: %s records"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-cited with: %s records"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "People who downloaded this document also downloaded:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "People who viewed this page also viewed:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Представление результатов:</strong> Найдено <strong>%s</strong> "
"записей в %.2f секунды."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Болеанный запрос не дал никакого результата. Пожалуйста сформулируйте ваш "
"запрос иначе."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Смотрите также: similar author names"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Внутренная Ошибка"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Набор %s не существует"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Извините, набор <strong>%s</strong> не существует. <p>Вы можете ещё раз "
"начать с <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "любой день"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "корзины"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "корзины"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Искать"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "корзины"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "подтверждения"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Искать"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "записи"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "записи"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "подтверждения"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "подтверждения"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "счёт"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "записаться"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "сообщения"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "записаться"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Искомый термин <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Искать"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Искать"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "гость"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "сеанс"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "сообщения"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "корзины"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "счёт"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "записи"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "подтверждения"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "администрация"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "выход"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "счёт"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "сообщения"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "счёт"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "выход"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Просмотреть"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Пожалуйста свяжитесь с <a href=\"mailto:%s\">%s</a> и укажите следующую "
"информацию:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Этот набор не содержит пока ни одной записи."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Этот набор не содержит пока ни одной записи."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "записи"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "записи"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "сеанс"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "ещё"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "ещё"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "сеанс"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "сеанс"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "ещё"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Повестка"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "подтверждения"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "ограничено"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "подтверждения"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "подтверждения"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "сентябрь"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Повестка"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "подтверждения"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "ограничено"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "ПЕРЕВОД НА РУССКИЙ ЯЗЫК ГОТОВИТСЯ"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Перевод этой страницы на русский язык в настоящее время не готов. "
#~ "Пожалуйста используйте английский вариант. Спасибо за понимание."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "ДОБАВИТь В КОРЗИНУ"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "корзины"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "корзины"
#, fuzzy
#~ msgid "Move"
#~ msgstr "ещё"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "ДОБАВИТь В КОРЗИНУ"
#, fuzzy
#~ msgid "Until"
#~ msgstr "до:"
diff --git a/po/sk.po b/po/sk.po
index ed6f91fed..d857182c3 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -1,3895 +1,3895 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:13+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: SK <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Táto stránka je tiež dostupná v nasledujúcich jazykoch:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Hľadaj"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Pomoc"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Areál Administrátora"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Pomoc pre vyhľadávanie"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Administrácia Pridávania"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Pridaj"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Personalizácia"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Centrála Pomoci"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Posledná aktualizácia"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Pomoc pre pridávanie"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Príručka"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "február"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Tipy pre vyhľadávanie"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Hlavná stránka"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Spravuje"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "kolekcie"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Príručka"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citačná história:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "História sťahovania:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "jún"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "máj"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "hocaký deň"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "máj"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "hocaký deň"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "hocaký deň"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "hocaký mesiac"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "január"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "marec"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "apríl"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "máj"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "jún"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "júl"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "august"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "október"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "január"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "február"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "marec"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "apríl"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "jún"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "júl"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "august"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "september"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "október"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "november"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "december"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "máj"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Hľadaj"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "Záznam bol vymazaný."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "podrobný"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "kolekcie"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "kolekcie"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "avíza"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "hocaký mesiac"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "podrobný"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Skúste hľadať na..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Skúste hľadať na..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "košíky"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "kolekcie"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "viac"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "máj"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "seansa"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Posledná aktualizácia"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Zobraziť výsledky:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "konto"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Zobraziť výsledky:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Personalizácia"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Posledná aktualizácia"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Podobné záznamy"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Posledná aktualizácia"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "viac"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Úplný záznam"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "Záznam bol vymazaný."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Utriediť podľa:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "máj"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "Záznam bol vymazaný."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Podobné záznamy"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Podobné záznamy"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Úplný záznam"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "košíky"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Výsledky hľadania"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Zobraziť výsledky:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "košíky"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "košíky"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "košíky"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "september"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Citované: %s záznamami"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "september"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "apríl"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "apríl"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "košíky"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "skoč na záznam:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "Záznam bol vymazaný."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "podrobný"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "podrobný"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "Záznam bol vymazaný."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "viac"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Citované"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "košíky"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "košíky"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "viac"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Úplný záznam"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Kolekcia %s Nenájdená"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "prihlásiť"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "Záznam bol vymazaný."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Hľadaj"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Pridaj"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Pridaj"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Pridaj"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Zúžiť podľa kolekciе:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Zamerať sa na:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "posledný záznam najskôr"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "vzost."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "zost."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "ALEBO"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "zoradiť podľa"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "výsledky"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "zoskupené podľa kolekcií"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "jediný list"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "stručný"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Hľadaj v %s záznamoch:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Výsledky hľadania"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "hocaký deň"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "hocaký mesiac"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "hocaký rok"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "všetky kolekcie"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "pridať kolekciu"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "stručný"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "A"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "A NIE"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Všetky tieto slová:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Jedno zo slov:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Presná veta:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Čiastočná veta:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Regulárny výraz:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Prelistuj"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Žiaden presný výsledok pre <em>%s</em> nebol nájdený, skúsme použiť <em>%s</"
"em> namiesto neho..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Žiaden záznam nebol nájdený v kolekcii %s. Ostatné verejne dostupné kolekcie "
"dali <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d záznamov</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Žiadna verejne prístupná kolekcia nevyhovuje Vašej otázke. Ak ste hľadali "
"dokumenty verejne neprístupné, zvoľte prosím najskôr príslušnú neverejnú "
"kolekciu."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Index slov nie je dostupný pre"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Index viet nie je dostupný pre"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Hľadaný výraz <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "v indexe <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr ""
"neodpovedá žiadnemu záznamu. Najbližšie termíny nezávisle na kolekcii sú:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "Záznam bol vymazaný."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Úplný záznam"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Žiaden výsledok nevyhovuje Vašim časovým kritériám, podmienka nie je vzatá "
"do úvahy..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Žiaden výsledok nevyhovuje Vašim limitným kritériám, podmienky nie sú vzaté "
"do úvahy..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Rozšírené Hľadanie"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Jednoduché Hľadanie"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Voľby hľadania:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Pridané od:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "do:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Utriediť podľa:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Zobraziť výsledky:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Výstupný formát:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "chránené"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Posledne pridané:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Obsah tejto kolekcie je chránený."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Táto kolekcia ešte neobsahuje žiadne záznamy."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "viac"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Podobné záznamy"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Citované"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "všetky kolekcie"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Skúste hľadať na..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "kolekcie"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "v"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Nenašli ste čo ste hľadali? Skúste Vašu otázku na iných serveroch:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> záznamov nájdených"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "prihlásiť"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "skoč na záznam:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Hľadanie trvalo %.2f sekúnd."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "PRIDAŤ DO KOŠÍKA"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Záznam vytvorený %s, modifikovaný %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Citované: %s záznamami"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Spolu citované s: %s záznamami"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "Užívatelia ktorí si stiahli tento dokument si tiež stiahli:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "Užívatelia ktorí si prehliadli túto stránku si tiež prehliadli:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Prehľad výsledkov:</strong> Nájdených <strong>%s</strong> záznamov "
"za %.2f sekúnd."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Booleovská otázka nevrátila žiaden výsledok. Skúste skombinovať dané termíny "
"inakšie."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Viď tiež: podobné mená autorov"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Vnútorná Chyba"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Kolekcia %s Nenájdená"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Ľutujeme, kolekcia <strong>%s</strong> neexistuje. <p>Skúste začať hľadať "
"od <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "hocaký deň"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Hľadaj"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "schválenia"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Hľadaj"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "pridania"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "pridania"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "schválenia"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "schválenia"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "prihlásiť"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "avíza"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "prihlásiť"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Hľadaný výraz <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Hľadaj"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Hľadaj"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "hosť"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "seansa"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "avíza"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "košíky"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "pridania"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "schválenia"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administrácia"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "odhlásiť"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "konto"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "avíza"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "konto"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "odhlásiť"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Prelistuj"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Prosíme kontaktujte <a href=\"mailto:%s\">%s</a> a uveďte nasledovné "
"informácie:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Táto kolekcia ešte neobsahuje žiadne záznamy."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Táto kolekcia ešte neobsahuje žiadne záznamy."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "pridania"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "pridania"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "seansa"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "viac"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "viac"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "seansa"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "seansa"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "viac"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "schválenia"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "chránené"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "schválenia"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "schválenia"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "september"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "schválenia"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "chránené"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "PREKLAD DO SLOVENČINY SA PRIPRAVUJE"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Slovenský preklad tejto stránky nie je ukončený. Prosíme použite anglickú "
#~ "verziu uvedenú nižšie. Ďakujeme za pochopenie."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "PRIDAŤ DO KOŠÍKA"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "Záznam bol vymazaný."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "košíky"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "košíky"
#, fuzzy
#~ msgid "Move"
#~ msgstr "viac"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "PRIDAŤ DO KOŠÍKA"
#, fuzzy
#~ msgid "Until"
#~ msgstr "do:"
diff --git a/po/sv.po b/po/sv.po
index 76fc18ec4..3f4bdf42d 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,3891 +1,3891 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:13+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: SV <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Denna webbplats finns även tillgänglig på följande språk:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Sök"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Hjälp"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Administrationsområde"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Hjälp med sökning"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Publiceringsadministration"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Skicka in"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Inställningar"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Hjälpcentral"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Senast uppdaterad"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Hjälp med publicering"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Guide"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "februari"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Agenda"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Söktips"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Första sidan"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Underhålls av"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "samlingar"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Guide"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citation history:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Downloads history:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "juni"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "maj"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Agenda"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "alla dagar"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "maj"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "alla dagar"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "alla dagar"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "alla månader"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "januari"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "mars"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "april"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "maj"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "juni"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "juli"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "augusti"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "oktober"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "januari"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "februari"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "mars"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "april"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "juni"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "juli"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "augusti"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "september"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "oktober"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "november"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "december"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "maj"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Sök"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "The record has been deleted."
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "detaljerat"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "samlingar"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "samlingar"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "alerts"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "alla månader"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "detaljerat"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Pröva att söka efter..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Pröva att söka efter..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "korgar"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "samlingar"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "mer"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "maj"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "användarsession"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Senast uppdaterad"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Visa sökresultat:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "konto"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Visa sökresultat:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Inställningar"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Senast uppdaterad"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Senast uppdaterad"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "mer"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Fullständig post"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Sortera efter:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "maj"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "The record has been deleted."
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Agenda"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Similar records"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "konto"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Fullständig post"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "korgar"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Sökresultat"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Visa sökresultat:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "korgar"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "korgar"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "korgar"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "september"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Cited by: %s records"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "september"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "april"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "april"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "korgar"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "gå till post:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "detaljerat"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "detaljerat"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "The record has been deleted."
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "mer"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Cited by"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "korgar"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "korgar"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "mer"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "konto"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Fullständig post"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Samlingen %s finns inte"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "logga in"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "The record has been deleted."
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Sök"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Skicka in"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Skicka in"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Agenda"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Skicka in"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Avgränsad sökning:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Utvalda samlingar:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "senaste först"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "stigande"
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "fallande"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "ELLER"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "rangordna efter"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "resultat"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "uppdelat efter samling"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "enkel lista"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "kort"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Sök i %s poster efter:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Sökresultat"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "alla dagar"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "alla månader"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "alla år"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "alla samlingar"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "lägg till ny samling"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "kort"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "OCH"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "INTE"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Samtliga ord:"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Minst ett av orden:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Exakt fras:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Del av fras:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Reguljärt uttryck:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Bläddra"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr "Inga träffar för <em>%s</em>, använder <em>%s</em> i stället..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"Inga poster hittades i samling %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Inga öppna samlingar motsvarar din sökning. Välj de åtkomstbegränsade "
"samlingarna först."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Inget index tillgängligt för"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Inget index tillgängligt för"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Sökord <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "i <em>%s</em>index"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr "matchade inga poster. Närmaste term i vilken som helst samling är:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "The record has been deleted."
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Fullständig post"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr ""
"Inga poster hittades inom den angivna tidsramen. Använder ej detta "
"kriterium..."
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr ""
"Inga poster hittades i den begränsade sökningen, använder ej dessa "
"kriterier..."
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Avancerad sökning"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Enkel sökning"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Sökalternativ:"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Tillagt sedan:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "till:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Sortera efter:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Visa sökresultat:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Visningsformat:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "begränsad"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Senast inlagda poster:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Åtkomsten till denna samling är begränsad."
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Denna samling innehåller ännu inga dokument."
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "mer"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Similar records"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Cited by"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "alla samlingar"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Pröva att söka efter..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "samlingar"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "i"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Har du inte funnit vad du söker efter? Försök med:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> poster hittades"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "logga in"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Agenda"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "gå till post:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Sökningen tog %.2f sekunder."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "LÄGG I KORGEN"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Record created %s, last modified %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Cited by: %s records"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-cited with: %s records"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "People who downloaded this document also downloaded:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "People who viewed this page also viewed:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Resultat:</strong> Hittade <strong>%s</strong> poster på %.2f "
"sekunder."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Den booleska sökningen returnerade inga poster. Kombinera dina söktermer "
"annorlunda."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Se också: liknande författarnamn"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Internt Fel"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Samlingen %s finns inte"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Beklager, samlingen <strong>%s</strong> ser ikke ut til å finnes. <p>Du "
"ønsker kanskje å starte å søket fra <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "alla dagar"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "korgar"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "korgar"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Sök"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "korgar"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "godkända"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Sök"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "bidrag"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "bidrag"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "godkända"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "godkända"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "logga in"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "alerts"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "logga in"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Sökord <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Sök"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Sök"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "gäst"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "användarsession"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "alerts"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "korgar"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "konto"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "bidrag"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "godkända"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "administration"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "logga ut"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "konto"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "alerts"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "konto"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "logga ut"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Bläddra"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Vänligen kontakta <a href=\"mailto:%s\">%s</a> och ta med följande "
"information:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Denna samling innehåller ännu inga dokument."
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Denna samling innehåller ännu inga dokument."
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "bidrag"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "bidrag"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "användarsession"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "mer"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "mer"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "användarsession"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "användarsession"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "mer"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "godkända"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "begränsad"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "godkända"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "godkända"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "september"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Agenda"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "godkända"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "begränsad"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "ÖVERSÄTTNING TILL SVENSKA PÅGÅR"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "För närvarande finns ingen svensk översättning. V.g. välj ett annat språk "
#~ "nedan."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "LÄGG I KORGEN"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "The record has been deleted."
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "korgar"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "korgar"
#, fuzzy
#~ msgid "Move"
#~ msgstr "mer"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "LÄGG I KORGEN"
#, fuzzy
#~ msgid "Until"
#~ msgstr "till:"
diff --git a/po/uk.po b/po/uk.po
index d1aaed0bb..b761c88e3 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -1,3890 +1,3890 @@
# # This file is part of the CERN Document Server Software (CDSware).
-# # Copyright (C) 2002, 2003, 2004, 2005 CERN.
+# # Copyright (C) 2002, 2003, 2004, 2005, 2006 CERN.
# #
# # The CDSware 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.
# #
# # The CDSware 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 CDSware; if not, write to the Free Software Foundation, Inc.,
# # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
msgid ""
msgstr ""
"Project-Id-Version: CDSware 0.7\n"
"Report-Msgid-Bugs-To: cds.support@cern.ch\n"
"POT-Creation-Date: 2006-05-02 12:14+0200\n"
"PO-Revision-Date: 2005-11-24 14:13+0100\n"
"Last-Translator: Frédéric Gobry <frederic.gobry@epfl.ch>\n"
"Language-Team: UK <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: config/cdswmllib.wml:90 modules/webstyle/lib/webstyle_templates.py:462
msgid "This site is also available in the following languages:"
msgstr "Цей сайт також доступний наступними мовами:"
#: config/cdspage.wml:53 config/cdspage.wml:139
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/websearch_templates.py:210
#: modules/websearch/lib/websearch_templates.py:314
#: modules/websearch/lib/websearch_templates.py:1142
#: modules/websearch/lib/websearch_templates.py:1235
#: modules/websearch/lib/websearch_templates.py:1293
#: modules/webstyle/lib/webstyle_templates.py:342
#: modules/webstyle/lib/webstyle_templates.py:415
msgid "Search"
msgstr "Пошук"
#: config/cdspage.wml:60 config/cdspage.wml:141
#: modules/webstyle/lib/webstyle_templates.py:345
#: modules/webstyle/lib/webstyle_templates.py:418
msgid "Help"
msgstr "Допомога"
#: modules/bibclassify/doc/admin/index.html.wml:22
#: modules/bibclassify/doc/admin/guide.html.wml:23
#: modules/bibconvert/doc/admin/guide.html.wml:22
#: modules/bibconvert/doc/admin/index.html.wml:22
#: modules/bibedit/doc/admin/guide.html.wml:23
#: modules/bibedit/doc/admin/index.html.wml:22
#: modules/bibformat/doc/admin/guide.html.wml:22
#: modules/bibformat/web/admin/BEH_ACTION_add.php.wml:25
#: modules/bibformat/web/admin/BEH_ACTION_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_COND_edit.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_del.php.wml:25
#: modules/bibformat/web/admin/BEH_OTYPE_showone.php.wml:25
#: modules/bibformat/web/admin/BEH_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_display.php.wml:24
#: modules/bibformat/web/admin/BIBREFORMAT_hand.php.wml:22
#: modules/bibformat/web/admin/BIBREFORMAT_tree.php.wml:22
#: modules/bibformat/web/admin/FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/KB_display.php.wml:25
#: modules/bibformat/web/admin/LINK_FORMAT_display.php.wml:25
#: modules/bibformat/web/admin/LINK_display.php.wml:25
#: modules/bibformat/web/admin/OAIER_SF_add.php.wml:25
#: modules/bibformat/web/admin/OAIER_display.php.wml:24
#: modules/bibformat/web/admin/UDF_display.php.wml:25
#: modules/bibformat/web/admin/index.php.wml:25
#: modules/bibformat/web/admin/test.php.wml:25
#: modules/bibharvest/doc/admin/guide.html.wml:22
#: modules/bibharvest/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/index.html.wml:22
#: modules/bibindex/doc/admin/guide.html.wml:22
#: modules/bibmatch/doc/admin/index.html.wml:22
#: modules/bibmatch/doc/admin/guide.html.wml:23
#: modules/bibrank/doc/admin/index.html.wml:22
#: modules/bibrank/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/guide.html.wml:22
#: modules/bibsched/doc/admin/index.html.wml:22
#: modules/bibupload/doc/admin/guide.html.wml:22
#: modules/bibupload/doc/admin/index.html.wml:22
#: modules/elmsubmit/doc/admin/guide.html.wml:22
#: modules/elmsubmit/doc/admin/index.html.wml:22
#: modules/webalert/doc/admin/guide.html.wml:22
#: modules/webalert/doc/admin/index.html.wml:22
#: modules/webbasket/doc/admin/guide.html.wml:22
#: modules/webbasket/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/index.html.wml:22
#: modules/webcomment/doc/admin/guide.html.wml:23
#: modules/webhelp/web/admin/index.html.wml:21
#: modules/webmessage/doc/admin/guide.html.wml:23
#: modules/webmessage/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/index.html.wml:22
#: modules/websearch/doc/admin/guide.html.wml:23
#: modules/websession/doc/admin/guide.html.wml:22
#: modules/websession/doc/admin/index.html.wml:22
#: modules/webstat/doc/admin/guide.html.wml:22
#: modules/webstat/doc/admin/index.html.wml:22
#: modules/webstyle/doc/admin/guide.html.wml:22
#: modules/webstyle/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/index.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
#: modules/webcomment/lib/webcommentadminlib.py:38
#: modules/websession/lib/websession_templates.py:728
msgid "Admin Area"
msgstr "Область адміністратора"
#: modules/webhelp/web/index.html.wml:48
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:22
#: modules/websearch/doc/tips.html.wml:24
msgid "Search Help"
msgstr "Допомога для пошуку"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:23
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
#: modules/websubmit/web/admin/func.php.wml:24
#: modules/websubmit/web/admin/viewEditSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/viewChecksEDS.php.wml:24
#: modules/websubmit/web/admin/viewActionEDS.php.wml:24
#: modules/websubmit/web/admin/removeDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/parameterUpdate.php.wml:24
#: modules/websubmit/web/admin/newSubmissionEDS.php.wml:24
#: modules/websubmit/web/admin/newFunc.php.wml:24
#: modules/websubmit/web/admin/pageDetsEDS.php.wml:24
#: modules/websubmit/web/admin/funcUsage.php.wml:24
#: modules/websubmit/web/admin/elementConfigDetsEDS.php.wml:24
#: modules/websubmit/web/admin/editRecordFile.php.wml:24
#: modules/websubmit/web/admin/editPageElementEDS.php.wml:24
#: modules/websubmit/web/admin/editDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/editActionDets.php.wml:24
#: modules/websubmit/web/admin/documentEDS.php.wml:24
#: modules/websubmit/web/admin/doctypeCategoriesEDS.php.wml:24
#: modules/websubmit/web/admin/allElementsEDS.php.wml:24
#: modules/websubmit/web/admin/allChecksEDS.php.wml:24
#: modules/websubmit/web/admin/allActionsEDS.php.wml:24
#: modules/websubmit/web/admin/addFunctions.php.wml:24
#: modules/websubmit/web/admin/addElement2PageEDS.php.wml:24
#: modules/websubmit/web/admin/addCheckEDS.php.wml:24
#: modules/websubmit/web/admin/addActionEDS.php.wml:24
#: modules/websubmit/web/admin/addElementDescrEDS.php.wml:24
#: modules/websubmit/web/admin/editCatalogues.php.wml:24
#: modules/websubmit/web/admin/listFunctions.php.wml:24
#: modules/websubmit/web/admin/newDoctypeEDS.php.wml:24
#: modules/websubmit/web/admin/veditFunDets.php.wml:24
#: modules/websubmit/web/admin/actionFunctions.php.wml:24
msgid "WebSubmit Administration"
msgstr "Адміністрування подання"
#: config/cdspage.wml:55
msgid "Convert"
msgstr ""
#: config/cdspage.wml:54 config/cdspage.wml:140
#: modules/webstyle/lib/webstyle_templates.py:343
#: modules/webstyle/lib/webstyle_templates.py:416
#: modules/websubmit/lib/websubmit_engine.py:444
#: modules/websubmit/lib/websubmit_engine.py:684
#: modules/websubmit/lib/websubmit_engine.py:768
#: modules/websubmit/lib/websubmit_engine.py:926
msgid "Submit"
msgstr "Додати"
#: config/cdspage.wml:61 config/cdspage.wml:142
#: modules/webstyle/lib/webstyle_templates.py:344
#: modules/webstyle/lib/webstyle_templates.py:417
msgid "Personalize"
msgstr "Персоналізація"
#: modules/webhelp/web/index.html.wml:22 modules/webhelp/web/index.html.wml:28
#: modules/webhelp/web/index.html.wml:29 modules/webhelp/web/index.html.wml:30
#: modules/webhelp/web/index.html.wml:31 modules/webhelp/web/index.html.wml:32
#: modules/webhelp/web/index.html.wml:33 modules/webhelp/web/index.html.wml:34
#: modules/webhelp/web/index.html.wml:35 modules/webhelp/web/index.html.wml:36
#: modules/webhelp/web/index.html.wml:37 modules/webhelp/web/index.html.wml:38
#: modules/webhelp/web/index.html.wml:39 modules/webhelp/web/index.html.wml:40
#: modules/webhelp/web/index.html.wml:41 modules/webhelp/web/index.html.wml:42
#: modules/webhelp/web/index.html.wml:43
#: modules/websearch/doc/guide.html.wml:24
#: modules/websearch/doc/index.html.wml:24
#: modules/websearch/doc/tips.html.wml:24
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:23
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Help Central"
msgstr "Центр допомоги"
#: config/cdspage.wml:144 modules/webstyle/lib/webstyle_templates.py:150
#: modules/webstyle/lib/webstyle_templates.py:384
#, fuzzy
msgid "Last updated:"
msgstr "Останнє поновлення"
#: modules/webhelp/web/index.html.wml:65
#: modules/websubmit/doc/access.html.wml:23
#: modules/websubmit/doc/actions.html.wml:23
#: modules/websubmit/doc/approval.html.wml:23
#: modules/websubmit/doc/approvals.html.wml:23
#: modules/websubmit/doc/bibliographic_fields.html.wml:23
#: modules/websubmit/doc/description.html.wml:23
#: modules/websubmit/doc/file_transfer.html.wml:23
#: modules/websubmit/doc/index.html.wml:22
#: modules/websubmit/doc/introduction.html.wml:23
#: modules/websubmit/doc/login.html.wml:23
#: modules/websubmit/doc/modification.html.wml:23
#: modules/websubmit/doc/password.html.wml:23
#: modules/websubmit/doc/pending.html.wml:23
#: modules/websubmit/doc/revised_version.html.wml:24
#: modules/websubmit/doc/submission.html.wml:23
#: modules/websubmit/doc/subnumber.html.wml:23
msgid "Submit Help"
msgstr "Допомога в поданні"
#: modules/websubmit/doc/admin/actionimplement.html.wml:23
#: modules/websubmit/doc/admin/actionmodify.html.wml:23
#: modules/websubmit/doc/admin/actionnew.html.wml:23
#: modules/websubmit/doc/admin/actionremove.html.wml:23
#: modules/websubmit/doc/admin/actions.html.wml:23
#: modules/websubmit/doc/admin/bibconvert.html.wml:23
#: modules/websubmit/doc/admin/catalogues.html.wml:23
#: modules/websubmit/doc/admin/description.html.wml:23
#: modules/websubmit/doc/admin/documentmodify.html.wml:23
#: modules/websubmit/doc/admin/documentnew.html.wml:23
#: modules/websubmit/doc/admin/documentremove.html.wml:23
#: modules/websubmit/doc/admin/documents.html.wml:23
#: modules/websubmit/doc/admin/example.html.wml:23
#: modules/websubmit/doc/admin/faq.html.wml:23
#: modules/websubmit/doc/admin/functiondelete.html.wml:23
#: modules/websubmit/doc/admin/functiondescription.html.wml:23
#: modules/websubmit/doc/admin/functionedit.html.wml:23
#: modules/websubmit/doc/admin/functionnew.html.wml:23
#: modules/websubmit/doc/admin/functions.html.wml:23
#: modules/websubmit/doc/admin/implementfunctions.html.wml:23
#: modules/websubmit/doc/admin/implementwebform.html.wml:23
#: modules/websubmit/doc/admin/index.html.wml:22
#: modules/websubmit/doc/admin/introduction.html.wml:23
#: modules/websubmit/doc/admin/philosophy.html.wml:23
#: modules/websubmit/doc/admin/protection.html.wml:23
msgid "Guide"
msgstr "Керівництво"
#: config/cdspage.wml:59
#, fuzzy
msgid "Library"
msgstr "лютий"
#: config/cdspage.wml:56
#, fuzzy
msgid "Agenda"
msgstr "Оголошення"
#: modules/websearch/doc/index.html.wml:48
#: modules/websearch/doc/tips.html.wml:22
#: modules/websearch/lib/websearch_templates.py:212
#: modules/websearch/lib/websearch_templates.py:316
#: modules/websearch/lib/websearch_templates.py:1239
#: modules/websearch/lib/websearch_templates.py:1297
msgid "Search Tips"
msgstr "Вказівки для пошуку"
#: config/cdspage.wml:57
msgid "Webcast"
msgstr ""
#: config/cdspage.wml:64 config/cdspage.wml:66
#: modules/webstyle/lib/webpage.py:84
#: modules/webstyle/lib/webstyle_templates.py:66
#: modules/webstyle/lib/webstyle_templates.py:75
msgid "Home"
msgstr "Головна сторінка"
#: config/cdspage.wml:145 modules/webstyle/lib/webstyle_templates.py:421
msgid "Maintained by"
msgstr "Служба підтримки"
#: config/cdspage.wml:58
#, fuzzy
msgid "Bulletin"
msgstr "розділи"
#: config/cdspage.wml:146 modules/webstyle/lib/webstyle_templates.py:420
msgid "Powered by"
msgstr "Powered by"
#: modules/bibharvest/lib/bibharvest_templates.py:51
#: modules/bibharvest/lib/bibharvest_templates.py:69
#, fuzzy
msgid "See Guide"
msgstr "Керівництво"
#: modules/bibharvest/lib/bibharvest_templates.py:106
msgid "OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:107
msgid "No OAI sources currently present in the database"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:117
msgid "Next oaiharvest task"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:118
msgid "scheduled time:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:119
msgid "current status:"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:120
msgid "No oaiharvest task currently scheduled"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:221
msgid "successfully validated!"
msgstr ""
#: modules/bibharvest/lib/bibharvest_templates.py:222
msgid "does not seem to be a OAI-compliant baseURL..."
msgstr ""
#: modules/bibrank/lib/bibrank_citation_grapher.py:118
msgid "Citation history:"
msgstr "Citation history:"
#: modules/bibrank/lib/bibrank_downloads_grapher.py:95
msgid "Downloads history:"
msgstr "Downloads history:"
#: modules/miscutil/lib/dateutils.py:69 modules/miscutil/lib/dateutils.py:96
#: modules/webbasket/lib/webbasket.py:165
#: modules/webbasket/lib/webbasket.py:686
#: modules/websession/lib/webuser.py:163
#: modules/webstyle/lib/webstyle_templates.py:486
msgid "N/A"
msgstr ""
#: modules/miscutil/lib/dateutils.py:139
#, fuzzy
msgid "Sun"
msgstr "червень"
#: modules/miscutil/lib/dateutils.py:140
#, fuzzy
msgid "Mon"
msgstr "травень"
#: modules/miscutil/lib/dateutils.py:141
msgid "Tue"
msgstr ""
#: modules/miscutil/lib/dateutils.py:142
#, fuzzy
msgid "Wed"
msgstr "Оголошення"
#: modules/miscutil/lib/dateutils.py:143
msgid "Thu"
msgstr ""
#: modules/miscutil/lib/dateutils.py:144
msgid "Fri"
msgstr ""
#: modules/miscutil/lib/dateutils.py:145
msgid "Sat"
msgstr ""
#: modules/miscutil/lib/dateutils.py:147
#, fuzzy
msgid "Sunday"
msgstr "будь-який день"
#: modules/miscutil/lib/dateutils.py:148
#, fuzzy
msgid "Monday"
msgstr "травень"
#: modules/miscutil/lib/dateutils.py:149
#, fuzzy
msgid "Tuesday"
msgstr "будь-який день"
#: modules/miscutil/lib/dateutils.py:150
msgid "Wednesday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:151
msgid "Thursday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:152
msgid "Friday"
msgstr ""
#: modules/miscutil/lib/dateutils.py:153
#, fuzzy
msgid "Saturday"
msgstr "будь-який день"
#: modules/miscutil/lib/dateutils.py:167 modules/miscutil/lib/dateutils.py:181
#, fuzzy
msgid "Month"
msgstr "будь-який місяць"
#: modules/miscutil/lib/dateutils.py:168
#, fuzzy
msgid "Jan"
msgstr "січень"
#: modules/miscutil/lib/dateutils.py:169
msgid "Feb"
msgstr ""
#: modules/miscutil/lib/dateutils.py:170
#, fuzzy
msgid "Mar"
msgstr "березень"
#: modules/miscutil/lib/dateutils.py:171
#, fuzzy
msgid "Apr"
msgstr "квітень"
#: modules/miscutil/lib/dateutils.py:172 modules/miscutil/lib/dateutils.py:186
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "May"
msgstr "травень"
#: modules/miscutil/lib/dateutils.py:173
#, fuzzy
msgid "Jun"
msgstr "червень"
#: modules/miscutil/lib/dateutils.py:174
#, fuzzy
msgid "Jul"
msgstr "липень"
#: modules/miscutil/lib/dateutils.py:175
#, fuzzy
msgid "Aug"
msgstr "серпень"
#: modules/miscutil/lib/dateutils.py:176
msgid "Sep"
msgstr ""
#: modules/miscutil/lib/dateutils.py:177
#, fuzzy
msgid "Oct"
msgstr "жовтень"
#: modules/miscutil/lib/dateutils.py:178
msgid "Nov"
msgstr ""
#: modules/miscutil/lib/dateutils.py:179
msgid "Dec"
msgstr ""
#: modules/miscutil/lib/dateutils.py:182
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "January"
msgstr "січень"
#: modules/miscutil/lib/dateutils.py:183
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "February"
msgstr "лютий"
#: modules/miscutil/lib/dateutils.py:184
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "March"
msgstr "березень"
#: modules/miscutil/lib/dateutils.py:185
#: modules/websearch/lib/search_engine.py:405
#: modules/websearch/lib/websearch_templates.py:511
msgid "April"
msgstr "квітень"
#: modules/miscutil/lib/dateutils.py:187
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "June"
msgstr "червень"
#: modules/miscutil/lib/dateutils.py:188
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "July"
msgstr "липень"
#: modules/miscutil/lib/dateutils.py:189
#: modules/websearch/lib/search_engine.py:406
#: modules/websearch/lib/websearch_templates.py:512
msgid "August"
msgstr "серпень"
#: modules/miscutil/lib/dateutils.py:190
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "September"
msgstr "вересень"
#: modules/miscutil/lib/dateutils.py:191
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "October"
msgstr "жовтень"
#: modules/miscutil/lib/dateutils.py:192
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "November"
msgstr "листопад"
#: modules/miscutil/lib/dateutils.py:193
#: modules/websearch/lib/search_engine.py:407
#: modules/websearch/lib/websearch_templates.py:513
msgid "December"
msgstr "грудень"
#: modules/miscutil/lib/dateutils.py:211
#, fuzzy
msgid "Day"
msgstr "травень"
#: modules/miscutil/lib/dateutils.py:262
#, fuzzy
msgid "Year"
msgstr "Пошук"
#: modules/webalert/lib/webalert.py:53
#, python-format
msgid "You already have an alert which name is <b>%(name)s</b>"
msgstr ""
#: modules/webalert/lib/webalert.py:110
msgid "unknown"
msgstr ""
#: modules/webalert/lib/webalert.py:172
msgid "You already have an alert defined for the specified query and basket"
msgstr ""
#: modules/webalert/lib/webalert.py:191 modules/webalert/lib/webalert.py:289
msgid "The alert name cannot be <b>empty</b>."
msgstr ""
#: modules/webalert/lib/webalert.py:206
#, python-format
msgid "The alert %s has been added to your profile."
msgstr ""
#: modules/webalert/lib/webalert.py:314
#, fuzzy, python-format
msgid "The alert %s has been successfully updated."
msgstr "Запис видалено"
#: modules/webalert/lib/webalert.py:369
#, python-format
msgid ""
"You have made %(number)s queries. A %(detailed_list)s is available with a "
"posibility to (a) view search results and (b) subscribe for automatic email "
"alerting service for these queries"
msgstr ""
#: modules/webalert/lib/webalert.py:370
#, fuzzy
msgid "detailed list"
msgstr "детальний"
#: modules/webalert/lib/webalert_templates.py:72
msgid "Pattern"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:74
msgid "Field"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:76
msgid "Pattern 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:78
msgid "Field 1"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:80
msgid "Pattern 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:82
msgid "Field 2"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:84
msgid "Pattern 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:86
msgid "Field 3"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:88
#, fuzzy
msgid "Collections"
msgstr "розділи"
#: modules/webalert/lib/webalert_templates.py:90
#, fuzzy
msgid "Collection"
msgstr "розділи"
#: modules/webalert/lib/webalert_templates.py:111
msgid "You own following alerts:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:112
#, fuzzy
msgid "alert name"
msgstr "повідомлення"
#: modules/webalert/lib/webalert_templates.py:120
msgid "SHOW"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:162
msgid ""
"This alert will notify you each time/only if a new item satisfy the "
"following query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:163
msgid "QUERY"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:194
msgid "Alert identification name:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:196
msgid "Search-checking frequency:"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:200
#: modules/webalert/lib/webalert_templates.py:317
#, fuzzy
msgid "monthly"
msgstr "будь-який місяць"
#: modules/webalert/lib/webalert_templates.py:201
#: modules/webalert/lib/webalert_templates.py:315
msgid "weekly"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:202
#: modules/webalert/lib/webalert_templates.py:312
#, fuzzy
msgid "daily"
msgstr "детальний"
#: modules/webalert/lib/webalert_templates.py:203
msgid "Send notification e-mail?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:206
#: modules/webalert/lib/webalert_templates.py:320
msgid "yes"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:207
#: modules/webalert/lib/webalert_templates.py:322
msgid "no"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:208
msgid "if <B>no</B> you must specify a basket"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:209
msgid "Store results in basket?"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:228
msgid "SET ALERT"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:229
msgid "CLEAR DATA"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:280
#, python-format
msgid ""
"Set a new alert from %(your_searches)s, the %(popular_searches)s or the "
"input form."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:281
#, fuzzy
msgid "your searches"
msgstr "Спробуйте шукати..."
#: modules/webalert/lib/webalert_templates.py:282
#, fuzzy
msgid "most popular searches"
msgstr "Спробуйте шукати..."
#: modules/webalert/lib/webalert_templates.py:298
#: modules/webcomment/lib/webcomment_templates.py:211
#: modules/webcomment/lib/webcomment_templates.py:455
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:473
msgid "No"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:299
msgid "Name"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:300
msgid "Search checking frequency"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:301
msgid "Notification by e-mail"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:302
#, fuzzy
msgid "Result in basket"
msgstr "кошики"
#: modules/webalert/lib/webalert_templates.py:303
msgid "Date last run"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:304
msgid "Creation date"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:305
msgid "Query"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:306
#: modules/webalert/lib/webalert_templates.py:429
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/websubmit/lib/websubmit_templates.py:1388
#, fuzzy
msgid "Action"
msgstr "розділи"
#: modules/webalert/lib/webalert_templates.py:351
#, fuzzy
msgid "Remove"
msgstr "далі"
#: modules/webalert/lib/webalert_templates.py:352
#, fuzzy
msgid "Modify"
msgstr "травень"
#: modules/webalert/lib/webalert_templates.py:354
#: modules/webalert/lib/webalert_templates.py:447
msgid "Execute search"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:361
#, python-format
msgid "You have defined <B>%(number)s</B> alerts."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:404
#, python-format
msgid "You have not executed any search yet. %(click_here)s for search."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:407
msgid "Click here"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:415
#, python-format
msgid ""
"You have performed <B>%(number)d</B> searches (<strong>%(different)d</"
"strong> different questions) during the last 30 days or so."
msgstr ""
#: modules/webalert/lib/webalert_templates.py:427
msgid "#"
msgstr ""
#: modules/webalert/lib/webalert_templates.py:428
#, fuzzy
msgid "Question"
msgstr "сеанс"
#: modules/webalert/lib/webalert_templates.py:432
#, fuzzy
msgid "Last Run"
msgstr "Останнє поновлення"
#: modules/webalert/lib/webalert_templates.py:448
msgid "Set new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:60
#, fuzzy
msgid "Display searches"
msgstr "Показати результат:"
#: modules/webalert/web/youralerts.py:64 modules/webalert/web/youralerts.py:92
#: modules/webalert/web/youralerts.py:120
#: modules/webalert/web/youralerts.py:141
#: modules/webalert/web/youralerts.py:166
#: modules/webalert/web/youralerts.py:191
#: modules/webalert/web/youralerts.py:212
#: modules/webbasket/web/yourbaskets.py:62
#: modules/webbasket/web/yourbaskets.py:98
#: modules/webbasket/web/yourbaskets.py:132
#: modules/webbasket/web/yourbaskets.py:173
#: modules/webbasket/web/yourbaskets.py:260
#: modules/webbasket/web/yourbaskets.py:299
#: modules/webbasket/web/yourbaskets.py:354
#: modules/webbasket/web/yourbaskets.py:393
#: modules/webbasket/web/yourbaskets.py:439
#: modules/webbasket/web/yourbaskets.py:482
#: modules/webmessage/lib/webmessage_templates.py:438
#: modules/websession/lib/websession_templates.py:407
#: modules/websession/web/youraccount.py:58
#: modules/websession/web/youraccount.py:121
#: modules/websession/web/youraccount.py:139
#: modules/websession/web/youraccount.py:156
#: modules/websession/web/youraccount.py:169
#: modules/websession/web/youraccount.py:192
#: modules/websession/web/youraccount.py:203
#: modules/websession/web/youraccount.py:256
#: modules/websession/web/youraccount.py:274
#: modules/websession/web/youraccount.py:293
#: modules/websession/web/youraccount.py:315
#: modules/websession/web/youraccount.py:344
#: modules/websession/web/youraccount.py:366
#: modules/websession/web/youraccount.py:405
#: modules/websubmit/web/publiline.py:74
#: modules/websubmit/web/yourapprovals.py:90
#: modules/websubmit/web/yoursubmissions.py:169
#, fuzzy
msgid "Your Account"
msgstr "обліковий запис"
#: modules/webalert/web/youralerts.py:88
msgid "Set a new alert"
msgstr ""
#: modules/webalert/web/youralerts.py:116
msgid "Modify alert settings"
msgstr ""
#: modules/webalert/web/youralerts.py:137
#: modules/webalert/web/youralerts.py:162
#: modules/webalert/web/youralerts.py:187
#: modules/webalert/web/youralerts.py:208
#, fuzzy
msgid "Display alerts"
msgstr "Показати результат:"
#: modules/webbasket/lib/webbasket.py:359
msgid "Your comment has been successfully posted"
msgstr ""
#: modules/webbasket/lib/webbasket.py:789
#: modules/webbasket/lib/webbasket_templates.py:88
#, fuzzy
msgid "Personal baskets"
msgstr "Персоналізація"
#: modules/webbasket/lib/webbasket.py:809
#: modules/webbasket/lib/webbasket_templates.py:95
#, fuzzy
msgid "Group baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket.py:830
#, fuzzy
msgid "Other's baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket.py:850
#, python-format
msgid "%i personal baskets"
msgstr ""
#: modules/webbasket/lib/webbasket.py:854
#, fuzzy, python-format
msgid "%i group baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket.py:858
#, fuzzy, python-format
msgid "%i other's baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket.py:862
#, python-format
msgid "You have %s and are subscribed to %s and %s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:102
#, fuzzy
msgid "Others' baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:182
#, fuzzy, python-format
msgid "There are %i baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:189
#, fuzzy
msgid "updated on"
msgstr "Останнє поновлення"
#: modules/webbasket/lib/webbasket_templates.py:222
#: modules/webbasket/lib/webbasket_templates.py:339
msgid "Basket is empty"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:231
#, python-format
msgid ""
"This basket belongs to %s. You can freely subscribe to it by using the link "
"below."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:254
#: modules/webbasket/web/yourbaskets.py:508
#, fuzzy
msgid "Public basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:257
#: modules/webbasket/lib/webbasket_templates.py:410
#: modules/webbasket/lib/webbasket_templates.py:687
#, fuzzy
msgid "records"
msgstr "Подібні записи"
#: modules/webbasket/lib/webbasket_templates.py:258
#: modules/webbasket/lib/webbasket_templates.py:411
#: modules/webbasket/lib/webbasket_templates.py:688
#, fuzzy
msgid "last update"
msgstr "Останнє поновлення"
#: modules/webbasket/lib/webbasket_templates.py:262
msgid "Subscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:294
#: modules/webbasket/lib/webbasket_templates.py:640
#, fuzzy
msgid "Non shared basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:297
#: modules/webbasket/lib/webbasket_templates.py:642
#, fuzzy
msgid "Shared basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:300
#: modules/webbasket/lib/webbasket_templates.py:644
msgid "Group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:306
#: modules/webbasket/web/yourbaskets.py:447
msgid "Manage rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:319
#, fuzzy
msgid "Delete basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:330
#: modules/webbasket/web/yourbaskets.py:399
msgid "Move basket to another topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:368
msgid "You don't have sufficient rights to view this basket's content"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:373
#: modules/webbasket/lib/webbasket_templates.py:649
msgid "Unsubscribe to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
#: modules/webbasket/lib/webbasket_templates.py:525
#: modules/webcomment/lib/webcomment_templates.py:567
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:386
msgid "last comment:"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:448
msgid "Bring item up"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:463
msgid "Bring item down"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:478
msgid "Copy item"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:493
#, fuzzy
msgid "Remove item"
msgstr "далі"
#: modules/webbasket/lib/webbasket_templates.py:496
#, fuzzy
msgid "Extern record"
msgstr "Детальний запис"
#: modules/webbasket/lib/webbasket_templates.py:526
msgid "last"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:527
#: modules/webbasket/web/yourbaskets.py:102
#: modules/webbasket/web/yourbaskets.py:177
msgid "Details and comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:548
#, fuzzy, python-format
msgid "This basket is publicly accessible at this adress: %s."
msgstr "Запис видалено"
#: modules/webbasket/lib/webbasket_templates.py:578
#, fuzzy
msgid "Sort by"
msgstr "Впорядкувати за:"
#: modules/webbasket/lib/webbasket_templates.py:579
#: modules/webbasket/lib/webbasket_templates.py:791
#: modules/websubmit/lib/websubmit_templates.py:1868
msgid "Title"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:580
#: modules/webmessage/lib/webmessage_templates.py:77
msgid "Date"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:634
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
msgid "Comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:635
#, python-format
msgid "There is a total of %i comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:637
#: modules/webbasket/web/yourbaskets.py:136
#: modules/webcomment/lib/webcomment_templates.py:88
msgid "Write a comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:693
#, fuzzy
msgid "Back to baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:720
#: modules/webbasket/lib/webbasket_templates.py:748
msgid "by"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:721
#: modules/webbasket/lib/webbasket_templates.py:748
#, fuzzy
msgid "on"
msgstr "травень"
#: modules/webbasket/lib/webbasket_templates.py:733
#: modules/webcomment/lib/webcomment_templates.py:316
#: modules/webmessage/lib/webmessage_templates.py:97
msgid "Reply"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:734
#, fuzzy
msgid "Delete comment"
msgstr "обліковий запис"
#: modules/webbasket/lib/webbasket_templates.py:790
#: modules/webbasket/lib/webbasket_templates.py:795
#: modules/webcomment/web/comments.py:166
msgid "Add Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:792
#: modules/webcomment/lib/webcomment_templates.py:1216
msgid "Comment"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:811
#: modules/webbasket/lib/webbasket_templates.py:901
#, fuzzy
msgid "Create new basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:862
#: modules/webbasket/lib/webbasket_templates.py:1102
#, fuzzy
msgid "Select topic"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:873
#, fuzzy
msgid "New basket's name"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:875
msgid "or create a new one"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:875
#: modules/webbasket/lib/webbasket_templates.py:1122
msgid "Create a new topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:878
#, fuzzy
msgid "Create a new basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:929
#: modules/webbasket/lib/webbasket_templates.py:952
#: modules/webbasket/lib/webbasket_templates.py:971
#, fuzzy
msgid "Select basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:939
msgid "Add to a personal basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:940
#: modules/webbasket/lib/webbasket_templates.py:964
#: modules/webbasket/lib/webbasket_templates.py:982
#, fuzzy, python-format
msgid "%i baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:963
msgid "Add to a group shared basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:981
msgid "Add to a public basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1012
#, python-format
msgid "Adding %i records to these baskets"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1017
#, fuzzy
msgid "Add to baskets"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:1024
#, fuzzy, python-format
msgid "The selected records have been successfully added to %i baskets"
msgstr "Запис видалено"
#: modules/webbasket/lib/webbasket_templates.py:1027
msgid "No records were added to the selected baskets."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1046
msgid "Are your sure you want to delete this basket?"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1048
#, python-format
msgid "%i users have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1050
#, python-format
msgid "%i usergroups have subscribed to this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1052
#, python-format
msgid "You have set %i alerts on this basket"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1090
#: modules/webcomment/lib/webcomment_templates.py:210
#: modules/webcomment/lib/webcomment_templates.py:453
#: modules/webcomment/lib/webcomment_templates.py:1273
#: modules/webcomment/lib/webcomment_templates.py:1298
#: modules/webmessage/lib/webmessage_templates.py:472
msgid "Yes"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1091
#: modules/webbasket/lib/webbasket_templates.py:1278
msgid "Cancel"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1109
#, fuzzy
msgid "Select a topic"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:1120
#, fuzzy
msgid "New topic's name"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:1145
#, python-format
msgid "Moving %i baskets to this topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1148
msgid "Move to topic"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1170
#: modules/webbasket/lib/webbasket_templates.py:1252
#: modules/webbasket/lib/webbasket_templates.py:1279
msgid "Add group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1172
msgid "Manage groups rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1179
msgid "Manage global sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1198
#, python-format
msgid "Modifying sharing rights for basket \"%s\""
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1205
msgid "Change rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1214
msgid "No rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1216
#, fuzzy
msgid "View records"
msgstr "Подібні записи"
#: modules/webbasket/lib/webbasket_templates.py:1218
#: modules/webbasket/lib/webbasket_templates.py:1220
#: modules/webbasket/lib/webbasket_templates.py:1222
#: modules/webbasket/lib/webbasket_templates.py:1224
#: modules/webbasket/lib/webbasket_templates.py:1226
#: modules/webbasket/lib/webbasket_templates.py:1228
#, fuzzy
msgid "and"
msgstr "Оголошення"
#: modules/webbasket/lib/webbasket_templates.py:1218
msgid "view comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1220
msgid "add comments"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1222
#, fuzzy
msgid "add records"
msgstr "Подібні записи"
#: modules/webbasket/lib/webbasket_templates.py:1224
#, fuzzy
msgid "delete comments"
msgstr "обліковий запис"
#: modules/webbasket/lib/webbasket_templates.py:1226
#, fuzzy
msgid "remove records"
msgstr "Детальний запис"
#: modules/webbasket/lib/webbasket_templates.py:1228
msgid "manage sharing rights"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1250
msgid "You're not member of a group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1272
msgid "Sharing basket to a new group"
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1293
#, fuzzy
msgid "no basket"
msgstr "кошики"
#: modules/webbasket/lib/webbasket_templates.py:1301
#, python-format
msgid ""
"You are logged in as a guest user, so your baskets will disappear at the end "
"of the current session. If you wish you can %slogin or register here%s."
msgstr ""
#: modules/webbasket/lib/webbasket_templates.py:1347
#: modules/webcomment/lib/webcomment_templates.py:604
#, fuzzy
msgid "(Back to search results)"
msgstr "Результати пошуку"
#: modules/webbasket/web/yourbaskets.py:66
#, fuzzy
msgid "Display baskets"
msgstr "Показати результат:"
#: modules/webbasket/web/yourbaskets.py:256
#: modules/websession/lib/websession_templates.py:282
#: modules/websession/lib/websession_templates.py:409
#, fuzzy
msgid "Your Baskets"
msgstr "кошики"
#: modules/webbasket/web/yourbaskets.py:258
msgid "Add records to baskets"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:305
#, fuzzy
msgid "Delete a basket"
msgstr "кошики"
#: modules/webbasket/web/yourbaskets.py:340
msgid "Copy record to basket"
msgstr ""
#: modules/webbasket/web/yourbaskets.py:485
#, fuzzy
msgid "Create basket"
msgstr "кошики"
#: modules/webcomment/lib/webcommentadminlib.py:38
msgid "WebComment Admin"
msgstr ""
#: modules/webcomment/lib/webcomment.py:825
#, python-format
msgid "%s wrote on %s:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:100
#, python-format
msgid "Showing the latest %i comments:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:115
msgid "Discuss this document:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:140
msgid "Discuss this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:141
msgid "Start a discussion about any aspect of this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:157
#, python-format
msgid "Sorry, the record %s does not seem to exist."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:159
#, python-format
msgid "Sorry, the record %s does not seem to be a number."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:161
#, python-format
msgid "Sorry, the record %s is not a valid ID value."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:163
msgid "Sorry, no record ID was provided."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:167
msgid "You may want to start browsing from &s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:229
#: modules/webcomment/lib/webcomment_templates.py:491
msgid "Was this review helpful?"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:240
msgid "Write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:243
#, python-format
msgid "Average review score: %s based on %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:250
#, python-format
msgid "Readers found the following %s reviews to be most helpful."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:253
#, python-format
msgid "View all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:272
#: modules/webcomment/lib/webcomment_templates.py:294
msgid "Rate this document"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:276
#, python-format
msgid "view all %s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:277
msgid "write a review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:295
msgid "Be the first to review this document."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:315
msgid "wrote on"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:318
#, fuzzy
msgid "Report abuse"
msgstr "вересень"
#: modules/webcomment/lib/webcomment_templates.py:360
#, fuzzy, python-format
msgid "Reviewed by %s on %s"
msgstr "Cited by: %s records"
#: modules/webcomment/lib/webcomment_templates.py:361
#, python-format
msgid "%i out of %i people found this review useful"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:492
#, fuzzy
msgid "(Report abuse)"
msgstr "вересень"
#: modules/webcomment/lib/webcomment_templates.py:522
msgid "< Previous"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:538
msgid "< Next"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:542
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:547
msgid "Average review score"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:549
#, python-format
msgid "based on %(nb_comments_total)s reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:556
#: modules/webcomment/lib/webcomment_templates.py:565
#: modules/webcomment/lib/webcomment_templates.py:903
#: modules/webcomment/lib/webcomment_templates.py:1141
msgid "comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:562
#, python-format
msgid "Write a %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:570
#: modules/webcomment/lib/webcomment_templates.py:1231
#: modules/webcomment/lib/webcomment_templates.py:1246
#: modules/webcomment/lib/webcomment_templates.py:1256
msgid "reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:571
#, python-format
msgid "There is a total of %s %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:603
msgid "Record"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:660
msgid "Viewing"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:661
msgid "Page: "
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:779
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as author of this comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:783
#, python-format
msgid ""
"Note: you currently haven't %sdefined a nickname%s.<br /><i>%s</i> will "
"temporarly be displayed as author of this comment."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:801
#, fuzzy
msgid "Article:"
msgstr "квітень"
#: modules/webcomment/lib/webcomment_templates.py:802
msgid "Comment:"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:829
#, python-format
msgid ""
"Note: Your nickname, <i>%s</i>, will be displayed as the author of this "
"review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:875
#, fuzzy
msgid "Article"
msgstr "квітень"
#: modules/webcomment/lib/webcomment_templates.py:876
msgid "Rate this article"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:877
#, fuzzy
msgid "Select a score"
msgstr "кошики"
#: modules/webcomment/lib/webcomment_templates.py:878
msgid "Give a title to your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:879
msgid "Write your review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:885
#: modules/webcomment/web/comments.py:164
msgid "Add Review"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:900
#, python-format
msgid "Your %s was successfully added"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:902
#, fuzzy
msgid "Back to record"
msgstr "перейти до запису:"
#: modules/webcomment/lib/webcomment_templates.py:988
msgid "View all reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:989
msgid "View all reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:990
msgid "Delete a specific comment/review (by ID)"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:991
#, fuzzy
msgid "View all users who have been reported"
msgstr "Запис видалено"
#: modules/webcomment/lib/webcomment_templates.py:994
msgid "Comments and reviews are disabled"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:997
msgid "Menu"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1012
msgid ""
"Please enter the ID of the comment/review so that you can view it before "
"deciding to delete it or not"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1024
msgid "Comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1026
msgid "View Comment"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1051
#, python-format
msgid "View all %s reported comments"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1054
#, python-format
msgid "View all %s reported reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1092
msgid ""
"Here is a list, sorted by total number of reports, of all users who have had "
"at least one report to one of their comments."
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1100
#: modules/webcomment/lib/webcomment_templates.py:1129
msgid "Nickname"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1101
#, fuzzy
msgid "Email"
msgstr "детальний"
#: modules/webcomment/lib/webcomment_templates.py:1102
#: modules/webcomment/lib/webcomment_templates.py:1131
msgid "User ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1104
msgid "Number positive votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1105
msgid "Number negative votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1106
msgid "Total number votes"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1107
msgid "Total number of reports"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1108
msgid "View all user's reported comments/reviews"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1133
#, fuzzy
msgid "email"
msgstr "детальний"
#: modules/webcomment/lib/webcomment_templates.py:1140
#, fuzzy, python-format
msgid "This %s has been reported %i times"
msgstr "Запис видалено"
#: modules/webcomment/lib/webcomment_templates.py:1147
#, python-format
msgid "Record #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1150
#, python-format
msgid "Comment #%s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1216
#, fuzzy
msgid "Review"
msgstr "далі"
#: modules/webcomment/lib/webcomment_templates.py:1217
#, fuzzy
msgid "Written by"
msgstr "Cited by"
#: modules/webcomment/lib/webcomment_templates.py:1218
msgid "General informations"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1219
#, fuzzy
msgid "Select"
msgstr "кошики"
#: modules/webcomment/lib/webcomment_templates.py:1233
#, fuzzy, python-format
msgid "Delete selected %s"
msgstr "кошики"
#: modules/webcomment/lib/webcomment_templates.py:1234
msgid "Suppress selected abuse report"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1241
msgid "Ok"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1246
#, python-format
msgid "Here are the reported %s of user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1249
#, python-format
msgid "Here is comment/review %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1251
#, python-format
msgid "Here is comment/review %s written by user %s"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1255
#, python-format
msgid "Here are all reported %s sorted by most reported"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "comment ID"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1281
msgid "successfully deleted"
msgstr ""
#: modules/webcomment/lib/webcomment_templates.py:1306
msgid "successfully suppressed abuse report"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:41
#: modules/webcomment/web/admin/webcommentadmin.py:50
#: modules/webcomment/web/admin/webcommentadmin.py:71
#: modules/webcomment/web/admin/webcommentadmin.py:107
#: modules/webcomment/web/admin/webcommentadmin.py:139
#: modules/webcomment/web/admin/webcommentadmin.py:171
msgid "Comment Management"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:81
#, fuzzy
msgid "Delete Comment"
msgstr "обліковий запис"
#: modules/webcomment/web/admin/webcommentadmin.py:118
#, python-format
msgid "View all Reported %s"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:118
#: modules/webcomment/web/comments.py:88
#: modules/webcomment/web/comments.py:139
#, fuzzy
msgid "Reviews"
msgstr "далі"
#: modules/webcomment/web/admin/webcommentadmin.py:147
msgid "View all Reported Users"
msgstr ""
#: modules/webcomment/web/admin/webcommentadmin.py:188
#, fuzzy
msgid "Delete comments"
msgstr "обліковий запис"
#: modules/webcomment/web/admin/webcommentadmin.py:191
msgid "Suppress abuse reports"
msgstr ""
#: modules/webcomment/web/comments.py:86
#: modules/webcomment/web/comments.py:137
#, fuzzy, python-format
msgid "Detailed record #%s"
msgstr "Детальний запис"
#: modules/webcomment/web/comments.py:99
#: modules/webcomment/web/comments.py:178
#, fuzzy
msgid "Record Not Found"
msgstr "Розділ %s не існує"
#: modules/webcomment/web/comments.py:150
msgid "Before you add your comment, you need to log in first"
msgstr ""
#: modules/webcomment/web/comments.py:153
#: modules/websession/web/youraccount.py:313
#: modules/websession/web/youraccount.py:342
#, fuzzy
msgid "Login"
msgstr "увійти"
#: modules/webmessage/lib/webmessage.py:141
#, fuzzy
msgid "The message could not be deleted"
msgstr "Запис видалено"
#: modules/webmessage/lib/webmessage.py:143
msgid "Delete successful"
msgstr ""
#: modules/webmessage/lib/webmessage.py:162
msgid "Your mailbox has been emptied"
msgstr ""
#: modules/webmessage/lib/webmessage.py:374
#, python-format
msgid "The chosen date (%(year)i/%(month)i/%(day)i) is invalid"
msgstr ""
#: modules/webmessage/lib/webmessage.py:383
msgid "Please enter a user name or a group name"
msgstr ""
#: modules/webmessage/lib/webmessage.py:387
#, python-format
msgid ""
"Your message is too long, please edit it.\n"
" Max size allowed is %i characters\n"
" "
msgstr ""
#: modules/webmessage/lib/webmessage.py:399
#, python-format
msgid "Group '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:422
#, python-format
msgid "User '%s' doesn't exist\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:434
#: modules/webmessage/web/yourmessages.py:94
#: modules/webmessage/web/yourmessages.py:160
msgid "Write a message"
msgstr ""
#: modules/webmessage/lib/webmessage.py:451
msgid "Your message couldn't be sent to the following recipients\n"
msgstr ""
#: modules/webmessage/lib/webmessage.py:452
msgid "These users are overquota: "
msgstr ""
#: modules/webmessage/lib/webmessage.py:457
msgid "Your message has been sent."
msgstr ""
#: modules/webmessage/lib/webmessage.py:461
#: modules/webmessage/lib/webmessage_templates.py:436
#: modules/webmessage/web/yourmessages.py:56
#: modules/webmessage/web/yourmessages.py:210
#: modules/webmessage/web/yourmessages.py:239
#: modules/websession/lib/websession_templates.py:410
#, fuzzy
msgid "Your Messages"
msgstr "Пошук"
#: modules/webmessage/lib/webmessage_templates.py:77
#: modules/webmessage/lib/webmessage_templates.py:414
#, fuzzy
msgid "Subject"
msgstr "Додати"
#: modules/webmessage/lib/webmessage_templates.py:77
#, fuzzy
msgid "Sender"
msgstr "Оголошення"
#: modules/webmessage/lib/webmessage_templates.py:84
msgid "No new mail"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:87
#, fuzzy
msgid "[No subject]"
msgstr "Додати"
#: modules/webmessage/lib/webmessage_templates.py:100
msgid "Delete"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:128
msgid "Write new message"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:129
msgid "Delete All"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:176
msgid "Re: "
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:266
#, fuzzy
msgid "Send later?"
msgstr "Оголошення"
#: modules/webmessage/lib/webmessage_templates.py:267
msgid "To:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:268
msgid "Users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:269
msgid "Groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:270
#, fuzzy
msgid "Subject:"
msgstr "Додати"
#: modules/webmessage/lib/webmessage_templates.py:271
msgid "Message:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:272
msgid "SEND"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:413
msgid "From"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:415
msgid "Sent on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:416
msgid "Received on"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:417
msgid "Sent to"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:418
msgid "Sent to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:419
msgid "REPLY"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:420
msgid "DELETE"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:470
msgid "Are your sure you want to empty your whole mailbox?"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:531
#, python-format
msgid "Quota: %.1f%%"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:549
msgid "Please select one or more:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:580
msgid "Add to users"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:582
msgid "Add to groups"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:585
msgid "No matching user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:587
msgid "No matching group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:621
msgid "Find users or groups:"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:622
msgid "Find a user"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:623
msgid "Find a group"
msgstr ""
#: modules/webmessage/lib/webmessage_templates.py:638
#, python-format
msgid ""
"You have <b>%i</b> new messages out of <a href=\"%s/yourmessages.py?ln=%s\">%"
"i total messages</a>"
msgstr ""
#: modules/webmessage/web/yourmessages.py:268
msgid "Read a message"
msgstr ""
#: modules/websearch/bin/webcoll.in:345
msgid "Narrow by collection:"
msgstr "Вибрати розділ:"
#: modules/websearch/bin/webcoll.in:346
msgid "Focus on:"
msgstr "Вибрати з:"
#: modules/websearch/bin/webcoll.in:515
#: modules/websearch/lib/search_engine.py:503
msgid "latest first"
msgstr "останні спочатку"
#: modules/websearch/bin/webcoll.in:533
#: modules/websearch/lib/websearch_templates.py:1427
msgid "asc."
msgstr "зрост."
#: modules/websearch/bin/webcoll.in:534
#: modules/websearch/lib/websearch_templates.py:1430
msgid "desc."
msgstr "спад."
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
#: modules/websearch/lib/search_engine.py:645
#: modules/websearch/lib/websearch_templates.py:473
msgid "OR"
msgstr "АБО"
#: modules/websearch/bin/webcoll.in:545
#: modules/websearch/lib/search_engine.py:518
msgid "rank by"
msgstr "впорядкувати за"
#: modules/websearch/bin/webcoll.in:563
#: modules/websearch/lib/websearch_templates.py:1392
msgid "results"
msgstr "результати"
#: modules/websearch/bin/webcoll.in:576
#: modules/websearch/lib/websearch_templates.py:1439
msgid "split by collection"
msgstr "розділити за розділами"
#: modules/websearch/bin/webcoll.in:577
#: modules/websearch/lib/websearch_templates.py:1436
msgid "single list"
msgstr "один список"
#: modules/websearch/bin/webcoll.in:597
msgid "brief"
msgstr "короткий"
#: modules/websearch/bin/webcoll.in:660 modules/websearch/bin/webcoll.in:681
#, python-format
msgid "Search %s records for:"
msgstr "Шукати серед %s записів:"
#: modules/websearch/lib/search_engine.py:345
#: modules/websearch/lib/search_engine.py:370
#: modules/websearch/lib/search_engine.py:3082
#: modules/websearch/lib/search_engine.py:3121
#: modules/websearch/lib/search_engine.py:3155
msgid "Search Results"
msgstr "Результати пошуку"
#: modules/websearch/lib/search_engine.py:398
#: modules/websearch/lib/websearch_templates.py:496
msgid "any day"
msgstr "будь-який день"
#: modules/websearch/lib/search_engine.py:404
#: modules/websearch/lib/websearch_templates.py:508
msgid "any month"
msgstr "будь-який місяць"
#: modules/websearch/lib/search_engine.py:412
#: modules/websearch/lib/websearch_templates.py:522
msgid "any year"
msgstr "будь-який рік"
#: modules/websearch/lib/search_engine.py:483
#: modules/websearch/lib/search_engine.py:498
msgid "any collection"
msgstr "будь-який розділ"
#: modules/websearch/lib/search_engine.py:494
msgid "add another collection"
msgstr "додати інший розділ"
#: modules/websearch/lib/search_engine.py:538
#, fuzzy
msgid "HTML brief"
msgstr "короткий"
#: modules/websearch/lib/search_engine.py:644
#: modules/websearch/lib/websearch_templates.py:472
msgid "AND"
msgstr "ТА"
#: modules/websearch/lib/search_engine.py:646
#: modules/websearch/lib/websearch_templates.py:474
msgid "AND NOT"
msgstr "ТА НЕ"
#: modules/websearch/lib/search_engine.py:664
#: modules/websearch/lib/websearch_templates.py:422
msgid "All of the words:"
msgstr "Всі слова"
#: modules/websearch/lib/search_engine.py:665
#: modules/websearch/lib/websearch_templates.py:424
msgid "Any of the words:"
msgstr "Будь-яке з слів:"
#: modules/websearch/lib/search_engine.py:666
#: modules/websearch/lib/websearch_templates.py:426
msgid "Exact phrase:"
msgstr "Точна фраза:"
#: modules/websearch/lib/search_engine.py:667
#: modules/websearch/lib/websearch_templates.py:428
msgid "Partial phrase:"
msgstr "Частина фрази:"
#: modules/websearch/lib/search_engine.py:668
#: modules/websearch/lib/websearch_templates.py:430
msgid "Regular expression:"
msgstr "Регулярний вираз:"
#: modules/websearch/lib/search_engine.py:678
msgid ","
msgstr ","
#: modules/websearch/lib/search_engine.py:1262
msgid "No values found."
msgstr ""
#: modules/websearch/lib/search_engine.py:1303
#: modules/websearch/lib/search_engine.py:3028
#: modules/websearch/lib/search_engine.py:3062
#: modules/websearch/lib/search_engine.py:3064
#: modules/websearch/lib/websearch_templates.py:211
#: modules/websearch/lib/websearch_templates.py:315
#: modules/websearch/lib/websearch_templates.py:1063
#: modules/websearch/lib/websearch_templates.py:1143
#: modules/websearch/lib/websearch_templates.py:1144
#: modules/websearch/lib/websearch_templates.py:1236
#: modules/websearch/lib/websearch_templates.py:1294
#: modules/websearch/lib/websearch_templates.py:1335
#: modules/websearch/lib/websearch_templates.py:1358
#: modules/websearch/lib/websearch_templates.py:1388
msgid "Browse"
msgstr "Переглянути"
#: modules/websearch/lib/search_engine.py:1392
#, python-format
msgid "No exact match found for <em>%s</em>, using <em>%s</em> instead..."
msgstr ""
"Точних відповідностей запиту <em>%s</em> не знайдено, замсть цього "
"використано <em>%s</em>..."
#: modules/websearch/lib/search_engine.py:1635
#, python-format
msgid ""
"No match found in collection %s. Other public collections gave <a class="
"\"nearestterms\" href=\"%s/search.py?%s\">%d hits</a>."
msgstr ""
"В роділі %s результатів не знайдено. В інших загальнодоступних розділах "
"знайдено <a class=\"nearestterms\" href=\"%s/search.py?%s\">%d співпадінь</a>"
#: modules/websearch/lib/search_engine.py:1642
msgid ""
"No public collection matched your query. If you were looking for a non-"
"public document, please choose the desired restricted collection first."
msgstr ""
"Серед загальнодоступних розділів відповідностей запиту не знайдено. Якщо Ви "
"шукаєте документ з обмеженим доступом, спочатку виберіть відповідий розділ з "
"обмеженим доступом."
#: modules/websearch/lib/search_engine.py:1760
msgid "No words index available for"
msgstr "Не знайдено лексичний вказівник для"
#: modules/websearch/lib/search_engine.py:1764
msgid "No phrase index available for"
msgstr "Не знайдений вказівник фраз для"
#: modules/websearch/lib/search_engine.py:1777
#, python-format
msgid "Search term <em>%s</em>"
msgstr "Термін для пошуку <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1779
#, python-format
msgid "inside <em>%s</em> index"
msgstr "у вказівнику <em>%s</em>"
#: modules/websearch/lib/search_engine.py:1780
msgid "did not match any record. Nearest terms in any collection are:"
msgstr "не знайдено. Найближчі терміни в розділі:"
#: modules/websearch/lib/search_engine.py:2216
#, python-format
msgid ""
"Sorry, sorting is allowed on sets of up to %d records only. Using default "
"sort order (\"latest first\")."
msgstr ""
#: modules/websearch/lib/search_engine.py:2240
#, python-format
msgid ""
"Sorry, '%s' does not seem to be a valid sort option. Choosing title sort "
"instead."
msgstr ""
#: modules/websearch/lib/search_engine.py:2447
msgid "Use different search terms."
msgstr ""
#: modules/websearch/lib/search_engine.py:2606
#: modules/websearch/lib/search_engine.py:2634
#: modules/websearch/lib/search_engine.py:2641
#: modules/websearch/lib/search_engine.py:2648
#: modules/websearch/lib/search_engine.py:2694
msgid "The record has been deleted."
msgstr "Запис видалено"
#: modules/websearch/lib/search_engine.py:3049
#: modules/websearch/lib/websearch_templates.py:818
#: modules/websearch/lib/websearch_templates.py:2353
#: modules/websearch/lib/websearch_templates.py:2356
#: modules/websearch/lib/websearch_templates.py:2359
msgid "Detailed record"
msgstr "Детальний запис"
#: modules/websearch/lib/search_engine.py:3247
msgid "No match within your time limits, discarding this condition..."
msgstr "За відведений час результатів не знайдено, умову скасовано"
#: modules/websearch/lib/search_engine.py:3268
msgid "No match within your search limits, discarding this condition..."
msgstr "За даних обмежень результатів не знайдено, умова скасовується"
#: modules/websearch/lib/websearch_templates.py:213
#: modules/websearch/lib/websearch_templates.py:1302
msgid "Advanced Search"
msgstr "Розширений пошук"
#: modules/websearch/lib/websearch_templates.py:317
#: modules/websearch/lib/websearch_templates.py:1244
msgid "Simple Search"
msgstr "Простий пошук"
#: modules/websearch/lib/websearch_templates.py:335
msgid "Search options:"
msgstr "Опції пошуку"
#: modules/websearch/lib/websearch_templates.py:382
#: modules/websearch/lib/websearch_templates.py:1381
msgid "Added since:"
msgstr "Додано з:"
#: modules/websearch/lib/websearch_templates.py:383
#: modules/websearch/lib/websearch_templates.py:1382
msgid "until:"
msgstr "до:"
#: modules/websearch/lib/websearch_templates.py:387
#: modules/websearch/lib/websearch_templates.py:1421
msgid "Sort by:"
msgstr "Впорядкувати за:"
#: modules/websearch/lib/websearch_templates.py:388
#: modules/websearch/lib/websearch_templates.py:1422
msgid "Display results:"
msgstr "Показати результат:"
#: modules/websearch/lib/websearch_templates.py:389
#: modules/websearch/lib/websearch_templates.py:1423
msgid "Output format:"
msgstr "Формат представлення:"
#: modules/websearch/lib/websearch_templates.py:606
msgid "restricted"
msgstr "обмежено"
#: modules/websearch/lib/websearch_templates.py:641
msgid "Latest additions:"
msgstr "Останні надходження:"
#: modules/websearch/lib/websearch_templates.py:682
msgid "The contents of this collection is restricted."
msgstr "Доступ до змісту цього розділу обмежений"
#: modules/websearch/lib/websearch_templates.py:697
msgid "This collection does not contain any document yet."
msgstr "Цей розділ поки що не містить записів"
#: modules/websearch/lib/websearch_templates.py:731
#: modules/websearch/lib/websearch_templates.py:2015
#: modules/websearch/lib/websearch_templates.py:2029
#: modules/websearch/lib/websearch_templates.py:2045
msgid "more"
msgstr "далі"
#: modules/websearch/lib/websearch_templates.py:819
#: modules/websearch/lib/websearch_templates.py:1998
#: modules/websearch/lib/websearch_templates.py:2361
msgid "Similar records"
msgstr "Подібні записи"
#: modules/websearch/lib/websearch_templates.py:824
#: modules/websearch/lib/websearch_templates.py:2365
msgid "Cited by"
msgstr "Cited by"
#: modules/websearch/lib/websearch_templates.py:894
msgid "Words nearest to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:899
msgid "inside"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:902
#, fuzzy
msgid "in any collection are:"
msgstr "будь-який розділ"
#: modules/websearch/lib/websearch_templates.py:1005
msgid "Hits"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1064
#: modules/websearch/lib/websearch_templates.py:1823
msgid "next"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1151
#: modules/websearch/lib/websearch_templates.py:1252
msgid "Try your search on..."
msgstr "Спробуйте шукати..."
#: modules/websearch/lib/websearch_templates.py:1330
msgid "collections"
msgstr "розділи"
#: modules/websearch/lib/websearch_templates.py:1352
msgid "Limit to"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1470
msgid "MARC tag"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1499
#: modules/websearch/lib/websearch_templates.py:1501
#: modules/websearch/lib/websearch_templates.py:1504
#: modules/websearch/lib/websearch_templates.py:1508
#: modules/websearch/lib/websearch_templates.py:1510
#: modules/websearch/lib/websearch_templates.py:1515
#: modules/websearch/lib/websearch_templates.py:1517
#: modules/websearch/lib/websearch_templates.py:1519
#: modules/websearch/lib/websearch_templates.py:1521
#: modules/websearch/lib/websearch_templates.py:1524
#: modules/websearch/lib/websearch_templates.py:1529
#: modules/websearch/lib/websearch_templates.py:1533
#: modules/websearch/lib/websearch_templates.py:1535
#: modules/websearch/lib/websearch_templates.py:1543
#: modules/websearch/lib/websearch_templates.py:1545
#: modules/websearch/lib/websearch_templates.py:1549
#: modules/websearch/lib/websearch_templates.py:1553
#: modules/websearch/lib/websearch_templates.py:1559
#: modules/websearch/lib/websearch_templates.py:1561
#: modules/websearch/lib/websearch_templates.py:1563
#: modules/websearch/lib/websearch_templates.py:1565
#: modules/websearch/lib/websearch_templates.py:1569
#: modules/websearch/lib/websearch_templates.py:1582
#: modules/websearch/lib/websearch_templates.py:1585
#: modules/websearch/lib/websearch_templates.py:1588
#: modules/websearch/lib/websearch_templates.py:1593
#: modules/websearch/lib/websearch_templates.py:1595
#: modules/websearch/lib/websearch_templates.py:1597
#: modules/websearch/lib/websearch_templates.py:1602
#: modules/websearch/lib/websearch_templates.py:1604
#: modules/websearch/lib/websearch_templates.py:1606
#: modules/websearch/lib/websearch_templates.py:1608
#: modules/websearch/lib/websearch_templates.py:1621
#: modules/websearch/lib/websearch_templates.py:1624
#: modules/websearch/lib/websearch_templates.py:1627
#: modules/websearch/lib/websearch_templates.py:1630
#: modules/websearch/lib/websearch_templates.py:1633
msgid "in"
msgstr "в"
#: modules/websearch/lib/websearch_templates.py:1638
msgid ""
"Haven't found what you were looking for? Try your search on other servers:"
msgstr "Не знайшли потрібного? Спробуйте пошуковий сервер:"
#: modules/websearch/lib/websearch_templates.py:1752
#: modules/websearch/lib/websearch_templates.py:1757
#: modules/websearch/lib/websearch_templates.py:2110
#, python-format
msgid "<strong>%s</strong> records found"
msgstr "<strong>%s</strong> знайдених записів"
#: modules/websearch/lib/websearch_templates.py:1803
#, fuzzy
msgid "begin"
msgstr "увійти"
#: modules/websearch/lib/websearch_templates.py:1811
#: modules/websubmit/lib/websubmit_templates.py:1152
msgid "previous"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1831
#, fuzzy
msgid "end"
msgstr "Оголошення"
#: modules/websearch/lib/websearch_templates.py:1850
msgid "jump to record:"
msgstr "перейти до запису:"
#: modules/websearch/lib/websearch_templates.py:1863
#, python-format
msgid "Search took %.2f seconds."
msgstr "Пошук тривав %.2f секунд."
#: modules/websearch/lib/websearch_templates.py:1936
#: modules/websearch/lib/websearch_templates.py:1999
msgid "ADD TO BASKET"
msgstr "ДОДАТИ ДО КОШИКА"
#: modules/websearch/lib/websearch_templates.py:1968
msgid "Format"
msgstr ""
#: modules/websearch/lib/websearch_templates.py:1994
#, python-format
msgid "Record created %s, last modified %s"
msgstr "Запис створено %s, остання зміна %s"
#: modules/websearch/lib/websearch_templates.py:2008
#, python-format
msgid "Cited by: %s records"
msgstr "Cited by: %s records"
#: modules/websearch/lib/websearch_templates.py:2022
#, python-format
msgid "Co-cited with: %s records"
msgstr "Co-cited with: %s records"
#: modules/websearch/lib/websearch_templates.py:2039
msgid "People who downloaded this document also downloaded:"
msgstr "People who downloaded this document also downloaded:"
#: modules/websearch/lib/websearch_templates.py:2054
msgid "People who viewed this page also viewed:"
msgstr "People who viewed this page also viewed:"
#: modules/websearch/lib/websearch_templates.py:2101
#, python-format
msgid ""
"<strong>Results overview:</strong> Found <strong>%s</strong> records in %.2f "
"seconds."
msgstr ""
"<strong>Результат:</strong> Знайдено <strong>%s</strong> записів за %.2f "
"секунд."
#: modules/websearch/lib/websearch_templates.py:2137
msgid ""
"Boolean query returned no hits. Please combine your search terms differently."
msgstr ""
"Результатів для умовного запиту не знайдено. Виберіть іншу комбінацію "
"термінів."
#: modules/websearch/lib/websearch_templates.py:2177
msgid "See also: similar author names"
msgstr "Див. також: подібні прізвища авторів"
#: modules/websearch/web/admin/websearchadmin.py:1049
#: modules/websearch/web/index.py:53 modules/websearch/web/index.py:121
#: modules/webstyle/lib/webstyle_templates.py:492
msgid "Internal Error"
msgstr "Внутрішня помилка"
#: modules/websearch/web/index.py:65
#, fuzzy, python-format
msgid "Collection %s Not Found"
msgstr "Розділ %s не існує"
#: modules/websearch/web/index.py:66
#, python-format
msgid ""
"<p>Sorry, collection <strong>%s</strong> does not seem to exist. <p>You may "
"want to start browsing from <a href=\"%s\">%s</a>."
msgstr ""
"<p>Вибачте, розділ <strong>%s</strong> не існує. <p>Спробуйте почати ще раз "
"з <a href=\"%s\">%s</a>."
#: modules/websession/lib/webaccount.py:90
#, python-format
msgid ""
"You are logged in as guest. You may want to <A href=\"../youraccount.py/"
"login?ln=%s\">login</A> as a regular user"
msgstr ""
#: modules/websession/lib/webaccount.py:91
#, python-format
msgid ""
"The <strong class=\"headline\">guest</strong> users need to <A href=\"../"
"youraccount.py/login?ln=%s\">register</A> first"
msgstr ""
#: modules/websession/lib/webaccount.py:92
msgid "No queries found"
msgstr ""
#: modules/websession/lib/websession_templates.py:45
msgid ""
"If you have lost password for your CERN Document Server internal account, "
"then please enter your email address below and the lost password will be "
"emailed to you."
msgstr ""
#: modules/websession/lib/websession_templates.py:47
msgid ""
"Note that if you have been using an external login system (such as CERN "
"NICE), then we cannot do anything and you have to ask there."
msgstr ""
#: modules/websession/lib/websession_templates.py:48
#, python-format
msgid ""
"Alternatively, you can ask %s to change your login system from external to "
"internal."
msgstr ""
#: modules/websession/lib/websession_templates.py:140
msgid ""
"If you want to change your email address or password, please set new values "
"in the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:141
msgid "New email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:142
#: modules/websession/lib/websession_templates.py:662
#, fuzzy
msgid "mandatory"
msgstr "будь-який день"
#: modules/websession/lib/websession_templates.py:143
#: modules/websession/lib/websession_templates.py:664
msgid "Example"
msgstr ""
#: modules/websession/lib/websession_templates.py:144
msgid "New password"
msgstr ""
#: modules/websession/lib/websession_templates.py:145
#: modules/websession/lib/websession_templates.py:663
msgid "optional"
msgstr ""
#: modules/websession/lib/websession_templates.py:146
#: modules/websession/lib/websession_templates.py:665
msgid "Note"
msgstr ""
#: modules/websession/lib/websession_templates.py:147
#: modules/websession/lib/websession_templates.py:666
msgid "The password phrase may contain punctuation, spaces, etc."
msgstr ""
#: modules/websession/lib/websession_templates.py:148
msgid "Retype password"
msgstr ""
#: modules/websession/lib/websession_templates.py:149
msgid "Set new values"
msgstr ""
#: modules/websession/lib/websession_templates.py:183
msgid "Edit login method"
msgstr ""
#: modules/websession/lib/websession_templates.py:184
msgid ""
"Please select which login method you would like to use to authenticate "
"yourself"
msgstr ""
#: modules/websession/lib/websession_templates.py:185
#: modules/websession/lib/websession_templates.py:197
#, fuzzy
msgid "Select method"
msgstr "кошики"
#: modules/websession/lib/websession_templates.py:233
#: modules/websession/lib/websession_templates.py:660
msgid "Email address"
msgstr ""
#: modules/websession/lib/websession_templates.py:234
msgid "Send lost password"
msgstr ""
#: modules/websession/lib/websession_templates.py:260
msgid ""
"The CDS Search offers you a possibility to personalize the interface, to set "
"up your own personal library of documents, or to set up an automatic alert "
"query that would run periodically and would notify you of search results by "
"email."
msgstr ""
#: modules/websession/lib/websession_templates.py:269
#: modules/websession/web/youraccount.py:56
#, fuzzy
msgid "Your Settings"
msgstr "кошики"
#: modules/websession/lib/websession_templates.py:270
msgid ""
"Set or change your account Email address or password. Specify your "
"preferences about the way the interface looks like."
msgstr ""
#: modules/websession/lib/websession_templates.py:280
#: modules/websession/lib/websession_templates.py:412
#, fuzzy
msgid "Your Searches"
msgstr "Пошук"
#: modules/websession/lib/websession_templates.py:281
msgid "View all the searches you performed during the last 30 days."
msgstr ""
#: modules/websession/lib/websession_templates.py:283
msgid ""
"With baskets you can define specific collections of items, store interesting "
"records you want to access later or share with others."
msgstr ""
#: modules/websession/lib/websession_templates.py:291
#, fuzzy
msgid "Your Alerts"
msgstr "кошики"
#: modules/websession/lib/websession_templates.py:292
msgid ""
"Subscribe to a search which will be run periodically by our service. The "
"result can be sent to you via Email or stored in one of your baskets."
msgstr ""
#: modules/websession/lib/websession_templates.py:301
#, fuzzy
msgid "Your Loans"
msgstr "підтвердження"
#: modules/websession/lib/websession_templates.py:302
msgid ""
"Check out book you have on load, submit borrowing requests, etc. Requires "
"CERN ID."
msgstr ""
#: modules/websession/lib/websession_templates.py:325
#, python-format
msgid ""
"You are logged in as a guest user, so your %s will disappear at the end of "
"the current session. If you wish you can\n"
" <a href=\"../youraccount.py/login?ln=%s\">login or register "
"here</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:349
#, python-format
msgid ""
"You are logged in as %s. You may want to a) <A href=\"../youraccount.py/"
"logout?ln=%s\">logout</A>; b) edit your <A href=\"../youraccount.py/edit?ln=%"
"s\">account settings</a>."
msgstr ""
#: modules/websession/lib/websession_templates.py:411
#, fuzzy
msgid "Your Alert Searches"
msgstr "Пошук"
#: modules/websession/lib/websession_templates.py:413
#, fuzzy
msgid "Your Submissions"
msgstr "додане"
#: modules/websession/lib/websession_templates.py:414
#, python-format
msgid ""
"You can consult the list of %(your_submissions)s and inquire about their "
"status."
msgstr ""
#: modules/websession/lib/websession_templates.py:419
#, fuzzy
msgid "your submissions"
msgstr "додане"
#: modules/websession/lib/websession_templates.py:422
#: modules/websubmit/web/yourapprovals.py:87
#, fuzzy
msgid "Your Approvals"
msgstr "підтвердження"
#: modules/websession/lib/websession_templates.py:423
#, python-format
msgid ""
"You can consult the list of %(your_approvals)s with the documents you "
"approved or refereed."
msgstr ""
#: modules/websession/lib/websession_templates.py:428
#, fuzzy
msgid "your approvals"
msgstr "підтвердження"
#: modules/websession/lib/websession_templates.py:431
#: modules/websession/web/youraccount.py:254
msgid "Your Administrative Activities"
msgstr ""
#: modules/websession/lib/websession_templates.py:458
msgid "Try again"
msgstr ""
#: modules/websession/lib/websession_templates.py:477
#, python-format
msgid "Okay, password has been emailed to %s"
msgstr ""
#: modules/websession/lib/websession_templates.py:492
#, fuzzy
msgid "Deleting your account"
msgstr "обліковий запис"
#: modules/websession/lib/websession_templates.py:508
#, python-format
msgid ""
"You are no longer recognized. If you wish you can <A href=\"./login?ln=%s"
"\">login here</A>."
msgstr ""
#: modules/websession/lib/websession_templates.py:536
msgid "If you already have an account, please login using the form below."
msgstr ""
#: modules/websession/lib/websession_templates.py:540
#, python-format
msgid ""
"If you don't own an account yet, please <a href=\"../youraccount.py/register?"
"ln=%s\">register</a> an internal account."
msgstr ""
#: modules/websession/lib/websession_templates.py:542
#, python-format
msgid ""
"It is not possible to create an account yourself. Contact %s if you want an "
"account."
msgstr ""
#: modules/websession/lib/websession_templates.py:564
#, fuzzy
msgid "Login via:"
msgstr "увійти"
#: modules/websession/lib/websession_templates.py:590
#, fuzzy
msgid "Username"
msgstr "повідомлення"
#: modules/websession/lib/websession_templates.py:591
#: modules/websession/lib/websession_templates.py:661
msgid "Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:592
#: modules/websession/lib/websession_templates.py:770
#: modules/websession/web/youraccount.py:311
#: modules/websession/web/youraccount.py:343
msgid "login"
msgstr "увійти"
#: modules/websession/lib/websession_templates.py:597
#: modules/websession/web/youraccount.py:137
msgid "Lost your password?"
msgstr ""
#: modules/websession/lib/websession_templates.py:626
msgid "Please enter your email address and desired password:"
msgstr ""
#: modules/websession/lib/websession_templates.py:628
msgid ""
"The account will not be possible to use before it has been verified and "
"activated."
msgstr ""
#: modules/websession/lib/websession_templates.py:667
msgid "Retype Password"
msgstr ""
#: modules/websession/lib/websession_templates.py:668
#: modules/websession/web/youraccount.py:404
msgid "register"
msgstr ""
#: modules/websession/lib/websession_templates.py:669
#, python-format
msgid ""
"Please do not use valuable passwords such as your Unix, AFS or NICE "
"passwords with this service. Your email address will stay strictly "
"confidential and will not be disclosed to any third party. It will be used "
"to identify you for personal services of %s. For example, you may set up an "
"automatic alert search that will look for new preprints and will notify you "
"daily of new arrivals by email."
msgstr ""
#: modules/websession/lib/websession_templates.py:698
#, python-format
msgid ""
"You seem to be the guest user. You have to <a href=\"../youraccount.py/"
"login?ln=%s\">login</a> first."
msgstr ""
#: modules/websession/lib/websession_templates.py:702
msgid "You are not authorized to access administrative functions."
msgstr ""
#: modules/websession/lib/websession_templates.py:705
#, fuzzy, python-format
msgid "You seem to be <em>%s</em>."
msgstr "Термін для пошуку <em>%s</em>"
#: modules/websession/lib/websession_templates.py:706
msgid "Here are some interesting web admin links for you:"
msgstr ""
#: modules/websession/lib/websession_templates.py:712
msgid "Configure BibFormat"
msgstr ""
#: modules/websession/lib/websession_templates.py:714
msgid "Configure BibHarvest"
msgstr ""
#: modules/websession/lib/websession_templates.py:716
msgid "Configure BibIndex"
msgstr ""
#: modules/websession/lib/websession_templates.py:718
msgid "Configure BibRank"
msgstr ""
#: modules/websession/lib/websession_templates.py:720
msgid "Configure WebAccess"
msgstr ""
#: modules/websession/lib/websession_templates.py:722
#, fuzzy
msgid "Configure WebComment"
msgstr "Пошук"
#: modules/websession/lib/websession_templates.py:724
#, fuzzy
msgid "Configure WebSearch"
msgstr "Пошук"
#: modules/websession/lib/websession_templates.py:726
msgid "Configure WebSubmit"
msgstr ""
#: modules/websession/lib/websession_templates.py:727
#, python-format
msgid "For more admin-level activities, see the complete %(admin_area)s"
msgstr ""
#: modules/websession/lib/websession_templates.py:766
msgid "guest"
msgstr "гість"
#: modules/websession/lib/websession_templates.py:767
msgid "session"
msgstr "сеанс"
#: modules/websession/lib/websession_templates.py:768
#: modules/websession/lib/websession_templates.py:782
msgid "alerts"
msgstr "повідомлення"
#: modules/websession/lib/websession_templates.py:769
#: modules/websession/lib/websession_templates.py:784
msgid "baskets"
msgstr "кошики"
#: modules/websession/lib/websession_templates.py:781
msgid "account"
msgstr "обліковий запис"
#: modules/websession/lib/websession_templates.py:783
msgid "messages"
msgstr ""
#: modules/websession/lib/websession_templates.py:790
msgid "submissions"
msgstr "додане"
#: modules/websession/lib/websession_templates.py:796
msgid "approvals"
msgstr "підтвердження"
#: modules/websession/lib/websession_templates.py:802
msgid "administration"
msgstr "адміністрування"
#: modules/websession/lib/websession_templates.py:807
msgid "logout"
msgstr "вийти"
#: modules/websession/lib/webuser.py:161
#, python-format
msgid "user #%i"
msgstr ""
#: modules/websession/web/youraccount.py:75
#: modules/websession/web/youraccount.py:97
msgid "Settings edited"
msgstr ""
#: modules/websession/web/youraccount.py:77
#: modules/websession/web/youraccount.py:96
#, fuzzy
msgid "Show account"
msgstr "обліковий запис"
#: modules/websession/web/youraccount.py:81
msgid "Login method successfully selected."
msgstr ""
#: modules/websession/web/youraccount.py:92
msgid "Password successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:94
msgid "Settings successfully edited."
msgstr ""
#: modules/websession/web/youraccount.py:99
msgid "The email address is already in use, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:101
#: modules/websession/web/youraccount.py:106
#: modules/websession/web/youraccount.py:111
#: modules/websession/web/youraccount.py:116
msgid "Edit settings"
msgstr ""
#: modules/websession/web/youraccount.py:102
#: modules/websession/web/youraccount.py:107
#: modules/websession/web/youraccount.py:112
#: modules/websession/web/youraccount.py:117
msgid "Editing settings failed"
msgstr ""
#: modules/websession/web/youraccount.py:104
msgid "The email address is not valid, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:109
msgid "The passwords do not match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:114
msgid "Could not update settings."
msgstr ""
#: modules/websession/web/youraccount.py:202
msgid "The entered e-mail address doesn't exist in the database"
msgstr ""
#: modules/websession/web/youraccount.py:214
msgid "Credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:215
msgid "Here are your user credentials for"
msgstr ""
#: modules/websession/web/youraccount.py:216
#, fuzzy
msgid "username"
msgstr "повідомлення"
#: modules/websession/web/youraccount.py:216
msgid "password"
msgstr ""
#: modules/websession/web/youraccount.py:217
msgid "You can login at"
msgstr ""
#: modules/websession/web/youraccount.py:227
msgid ""
"The entered email address is incorrect, please check that it is written "
"correctly (e.g. johndoe@example.com)."
msgstr ""
#: modules/websession/web/youraccount.py:228
msgid "Incorrect email address"
msgstr ""
#: modules/websession/web/youraccount.py:237
msgid "Lost password sent"
msgstr ""
#: modules/websession/web/youraccount.py:272
#, fuzzy
msgid "Delete Account"
msgstr "обліковий запис"
#: modules/websession/web/youraccount.py:291
#, fuzzy
msgid "Logout"
msgstr "вийти"
#: modules/websession/web/youraccount.py:364
msgid "Register"
msgstr ""
#: modules/websession/web/youraccount.py:381
msgid "Your account has been successfully created."
msgstr ""
#: modules/websession/web/youraccount.py:382
msgid "Account created"
msgstr ""
#: modules/websession/web/youraccount.py:384
msgid ""
" An email has been sent to the given address with the account information."
msgstr ""
#: modules/websession/web/youraccount.py:386
msgid ""
" A second email will be sent when the account has been activated and can be "
"used."
msgstr ""
#: modules/websession/web/youraccount.py:388
#, python-format
msgid " You can now access your <a href=\"%s\">account</a>."
msgstr ""
#: modules/websession/web/youraccount.py:391
msgid "The user already exists in the database, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:393
#: modules/websession/web/youraccount.py:397
#: modules/websession/web/youraccount.py:401
msgid "Register failure"
msgstr ""
#: modules/websession/web/youraccount.py:395
msgid "Both passwords must match, please try again."
msgstr ""
#: modules/websession/web/youraccount.py:399
msgid "The email address given is not valid, please try again."
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:490
#: modules/webstyle/lib/webstyle_templates.py:524
#, python-format
msgid "Error: %s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:494
#, fuzzy
msgid "Browser"
msgstr "Переглянути"
#: modules/webstyle/lib/webstyle_templates.py:515
#, python-format
msgid "System Error: %s %s\n"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:526
msgid "Error"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:528
#, python-format
msgid ""
"Traceback: \n"
"%s"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:573
msgid "Time"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:574
msgid "Client"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:575
msgid "Please send an error report to the Administrator"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:576
msgid "Send error report"
msgstr ""
#: modules/webstyle/lib/webstyle_templates.py:579
#, python-format
msgid ""
"Please contact <a href=\"mailto:%s\">%s</a> quoting the following "
"information:"
msgstr ""
"Зверніться на адресу <a href=\"mailto:%s\">%s</a> та вкажіть наступну "
"інформацію:"
#: modules/websubmit/lib/websubmit_engine.py:75
#: modules/websubmit/lib/websubmit_engine.py:483
msgid ""
"Sorry, you must log in to perform this action. Please use the top right menu "
"to do so."
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:80
#: modules/websubmit/lib/websubmit_engine.py:487
msgid "invalid parameter"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:85
#: modules/websubmit/lib/websubmit_engine.py:492
msgid "cannot find submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:91
msgid "unknown document type"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:97
#: modules/websubmit/lib/websubmit_engine.py:611
msgid "unknown action"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:104
msgid "can't figure number of pages"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:130
#: modules/websubmit/lib/websubmit_engine.py:191
#: modules/websubmit/lib/websubmit_engine.py:505
msgid "can't create submission directory"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:605
msgid "unknown type of document"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:618
#, fuzzy
msgid "this action does not apply on this type of document"
msgstr "Цей розділ поки що не містить записів"
#: modules/websubmit/lib/websubmit_engine.py:899
#, python-format
msgid "Cannot find document %s"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1065
#, fuzzy
msgid "Your chosen action is not supported by the document"
msgstr "Цей розділ поки що не містить записів"
#: modules/websubmit/lib/websubmit_engine.py:1120
msgid "error"
msgstr ""
#: modules/websubmit/lib/websubmit_engine.py:1131
msgid "warning"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:74
msgid "Document types available for submission"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:75
msgid "Please select the type of document you want to submit"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:91
msgid "No document types yet..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:230
msgid "please log in first.\\nUse the top right menu to log in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:273
msgid "please select a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:311
msgid "Notice"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:312
msgid ""
"Select a category and then click the button to perform the action you chose."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:333
msgid ""
"To continue an interrupted submission, enter your access number directly in "
"the input box."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:335
msgid "go"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:460
#: modules/websubmit/lib/websubmit_templates.py:895
msgid "SUMMARY"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:497
msgid "previous page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:503
#, fuzzy
msgid "Submission no(1)"
msgstr "додане"
#: modules/websubmit/lib/websubmit_templates.py:517
msgid "next page"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:532
#: modules/websubmit/lib/websubmit_templates.py:934
msgid "Are you sure you want to quit this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:533
#: modules/websubmit/lib/websubmit_templates.py:941
msgid "back to main menu"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:536
msgid ""
"(1) you should take note of this number at the beginning of the submission, "
"it will allow you to get your information back in case your browser crashes "
"before the end of the submission."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:537
msgid "(2) mandatory fields appear in red in the 'Summary' window."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:677
#, python-format
msgid ""
"The field `%s` is Mandatory.\\n Please make a choice in the 'Select:' box"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:691
msgid "Please press a button."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:699
#, python-format
msgid "The field `%s` is Mandatory. Please fill it in."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:775
#, python-format
msgid "The field '%(field)s' is mandatory.\\nGoing back to page %(page)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:886
msgid "finished!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:894
msgid "end of action"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:918
#, fuzzy
msgid "Submission no"
msgstr "додане"
#: modules/websubmit/lib/websubmit_templates.py:984
#, python-format
msgid ""
"Here is the %(action)s function list for %(doctype)s documents at level %"
"(step)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:989
#, fuzzy
msgid "Function"
msgstr "сеанс"
#: modules/websubmit/lib/websubmit_templates.py:990
#, fuzzy
msgid "Score"
msgstr "далі"
#: modules/websubmit/lib/websubmit_templates.py:991
msgid "Running Function"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:997
#, python-format
msgid "function %s does not exist..."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1036
msgid "You now have to"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1041
#, fuzzy
msgid "or"
msgstr "далі"
#: modules/websubmit/lib/websubmit_templates.py:1068
#, python-format
msgid "record #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1070
#, python-format
msgid " document #%s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1072
#, fuzzy, python-format
msgid " version #%s"
msgstr "сеанс"
#: modules/websubmit/lib/websubmit_templates.py:1101
msgid "file(s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1149
msgid "see"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1163
#, fuzzy
msgid "version"
msgstr "сеанс"
#: modules/websubmit/lib/websubmit_templates.py:1335
#, fuzzy
msgid "For"
msgstr "далі"
#: modules/websubmit/lib/websubmit_templates.py:1336
msgid "all types of document"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1389
msgid "Status"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1390
msgid "id"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1391
msgid "reference"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1393
msgid "first access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1394
msgid "last access"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1404
msgid "Are you sure you want to delete this submission?"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1405
#, python-format
msgid "delete submission %(id)s in %(docname)s"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1421
msgid "reference not yet given"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1492
msgid "Refereed Documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1502
msgid "You are general referee"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1507
#, python-format
msgid "You are referee for category: %(name)s (%(id)s)"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1546
msgid "List of refereed types of documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1547
msgid ""
"Select one of the following types of documents to check the documents status:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1605
msgid "List of refereed categories"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1606
msgid "Please choose a category"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1625
#: modules/websubmit/lib/websubmit_templates.py:1666
#, fuzzy
msgid "pending"
msgstr "Оголошення"
#: modules/websubmit/lib/websubmit_templates.py:1631
#: modules/websubmit/lib/websubmit_templates.py:1669
#, fuzzy
msgid "approved"
msgstr "підтвердження"
#: modules/websubmit/lib/websubmit_templates.py:1637
#: modules/websubmit/lib/websubmit_templates.py:1671
#: modules/websubmit/lib/websubmit_templates.py:1672
#, fuzzy
msgid "rejected"
msgstr "обмежено"
#: modules/websubmit/lib/websubmit_templates.py:1665
msgid "Key"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1668
#, fuzzy
msgid "waiting for approval"
msgstr "підтвердження"
#: modules/websubmit/lib/websubmit_templates.py:1670
#: modules/websubmit/lib/websubmit_templates.py:1673
#, fuzzy
msgid "already approved"
msgstr "підтвердження"
#: modules/websubmit/lib/websubmit_templates.py:1674
msgid "some documents are pending"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1729
msgid "List of refereed documents"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1730
msgid "Click on a report number to have more information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1731
#, fuzzy
msgid "Report Number"
msgstr "вересень"
#: modules/websubmit/lib/websubmit_templates.py:1732
#, fuzzy
msgid "Pending"
msgstr "Оголошення"
#: modules/websubmit/lib/websubmit_templates.py:1733
#, fuzzy
msgid "Approved"
msgstr "підтвердження"
#: modules/websubmit/lib/websubmit_templates.py:1734
#, fuzzy
msgid "Rejected"
msgstr "обмежено"
#: modules/websubmit/lib/websubmit_templates.py:1854
msgid "Your request has been sent to the referee!"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1874
msgid "Author"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1882
msgid "More information"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1883
msgid "click here"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1889
msgid ""
"This Document is still <strong class=\"headline\">waiting for approval</"
"strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1890
#: modules/websubmit/lib/websubmit_templates.py:1909
#: modules/websubmit/lib/websubmit_templates.py:1917
#, python-format
msgid ""
"It has first been sent to approval on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1892
#: modules/websubmit/lib/websubmit_templates.py:1894
#: modules/websubmit/lib/websubmit_templates.py:1911
#: modules/websubmit/lib/websubmit_templates.py:1913
#: modules/websubmit/lib/websubmit_templates.py:1919
#: modules/websubmit/lib/websubmit_templates.py:1921
#, python-format
msgid ""
"Last approval e-mail was sent on: <strong class=\"headline\">%(date)s</"
"strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1895
msgid ""
"You can send an approval request e-mail again by clicking the following "
"button:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1897
#: modules/websubmit/web/publiline.py:183
msgid "Send Again"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1898
msgid "WARNING! An e-mail will be send to your referee if you confirm."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1901
msgid ""
"As a referee for this document, you may click this button to approve or "
"reject it:"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1903
msgid "Approve/Reject"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1907
msgid "This Document has been <strong class=\"headline\">approved</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1908
#, python-format
msgid "Its approved reference is: <strong class=\"headline\">%(rn)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1914
#, python-format
msgid "It has been approved on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1916
msgid "This Document has been <strong class=\"headline\">rejected</strong>."
msgstr ""
#: modules/websubmit/lib/websubmit_templates.py:1922
#, python-format
msgid "It has been rejected on: <strong class=\"headline\">%(date)s</strong>"
msgstr ""
#: modules/websubmit/web/getfile.py:61
msgid "Parameter docid missing"
msgstr ""
#: modules/websubmit/web/getfile.py:66
msgid "can't find file..."
msgstr ""
#: modules/websubmit/web/getfile.py:86
msgid "Access to Fulltext"
msgstr ""
#: modules/websubmit/web/publiline.py:179
msgid "This document has never been requested for approval!"
msgstr ""
#: modules/websubmit/web/yoursubmissions.py:65
msgid ""
"You first have to login before using this feature. Use the left menu to log "
"in."
msgstr ""
#: modules/websubmit/web/admin/websubmitadmin.py:147
#: modules/websubmit/web/admin/websubmitadmin.py:199
#: modules/websubmit/web/admin/websubmitadmin.py:264
#, python-format
msgid "%s"
msgstr ""
#~ msgid "ENGLISH TRANSLATION UNDER WAY"
#~ msgstr "ПЕРЕКЛАД ГОТУЄТЬСЯ"
#~ msgid ""
#~ "At the moment the English version of this page isn't available yet. "
#~ "Please use the version presented below. Thanks for your understanding."
#~ msgstr ""
#~ "Переклад цієї сторінки не закінчено. Скористайтесь англомовною версією. "
#~ "Дякуємо за розуміння."
#, fuzzy
#~ msgid "The basket has not been deleted: %s"
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "CREATE NEW"
#~ msgstr "ДОДАТИ ДО КОШИКА"
#, fuzzy
#~ msgid "The <I>private</I> basket <B>%s</B> has been created."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The basket has not been created: specify a basket name."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The basket has not been renamed: %s"
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The basket has not been renamed: specify a basket name."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The basket has not been made public: %s"
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The basket has not been made private: %s"
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The selected items have been removed."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The items have not been removed: %s"
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The selected items have been copied/moved."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The items have not been re-ordered: %s"
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "The selected basket has been deleted."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "No baskets have been defined."
#~ msgstr "Запис видалено"
#, fuzzy
#~ msgid "Select an existing basket"
#~ msgstr "кошики"
#, fuzzy
#~ msgid "basket name"
#~ msgstr "кошики"
#, fuzzy
#~ msgid "Move"
#~ msgstr "далі"
#, fuzzy
#~ msgid "CREATE NEW BASKET"
#~ msgstr "ДОДАТИ ДО КОШИКА"
#, fuzzy
#~ msgid "Until"
#~ msgstr "до:"

Event Timeline