View | Details | Raw Unified | Return to bug 39239
Collapse All | Expand All

(-)a/management/univention-directory-reports/conffiles/etc/univention/directory/reports/config.ini (-1 / +1 lines)
 Lines 8-14   footer=/etc/univention/directory/reports/footer.tex Link Here 
8
8
9
# default report name
9
# default report name
10
@!@
10
@!@
11
print 'report=%s' % configRegistry.get('directory/reports/default', 'Standard Report')
11
print 'report=%s' % configRegistry.get('directory/reports/default', 'PDF Document')
12
@!@
12
@!@
13
13
14
[reports]
14
[reports]
(-)a/management/univention-directory-reports/conffiles/etc/univention/directory/reports/default/de_DE/footer.rml (+2 lines)
Line 0    Link Here 
1
</story>
2
</document>
(-)a/management/univention-directory-reports/conffiles/etc/univention/directory/reports/default/de_DE/header.rml (+50 lines)
Line 0    Link Here 
1
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
2
<!DOCTYPE document SYSTEM "../rml_1_0.dtd">
3
<document filename="univention-directory-report.pdf">
4
	<template author="Univention Corporate Server" title="Univention Directory Report" showBoundary="0"
5
		pageSize="(21cm, 29.7cm)" leftMargin="2.5cm" rightMargin="2.5cm" topMargin="2.5cm" bottomMargin="2.5cm">
6
   <pageTemplate id="main">
7
     <pageGraphics>
8
         <image file="@%@directory/reports/logo@%@" y="27.5cm" x="13.5cm" width="5cm"/>
9
     </pageGraphics>
10
     <frame id="first" x1="2.5cm" y1="2.5cm" width="16cm" height="24.5cm"/>
11
   </pageTemplate>
12
   <pageTemplate id="regularpages">
13
     <pageGraphics>
14
         <image file="@%@directory/reports/logo@%@" y="27.5cm" x="13.5cm" width="5cm"/>
15
         <lines>2.5cm 2.5cm 18.5cm 2.5cm</lines>
16
         <drawString x="18cm" y="2cm"><pageNumber/></drawString>
17
     </pageGraphics>
18
     <setFont name="Times-Roman" size="9"/>
19
     <frame id="first" x1="2.5cm" y1="2.5cm" width="16cm" height="24.5cm"/>
20
   </pageTemplate>
21
</template>
22
<stylesheet>
23
  <paraStyle name="content" fontName="Helvetica" fontSize="9" textColor="black"/>
24
   <blockTableStyle id="mainTableOuter">
25
       <blockFont name="Times-Roman" size="9"/>
26
       <blockTextColor colorName="black"/>
27
       <blockLeftPadding length="0"/>
28
       <blockValign value="TOP"/>
29
       <blockAlignment value="LEFT"/>
30
<!--       <lineStyle kind="GRID" colorName="black"/>-->
31
  </blockTableStyle>
32
   <blockTableStyle id="mainTable">
33
       <blockFont name="Times-Roman" size="9"/>
34
       <blockTextColor colorName="black"/>
35
       <blockValign value="TOP"/>
36
       <blockLeftPadding length="0"/>
37
       <blockBottomPadding length="0"/>
38
       <blockTopPadding length="0"/>
39
       <blockAlignment value="LEFT"/>
40
<!--       <lineStyle kind="GRID" colorName="black"/>-->
41
       <blockSpan start="0,0" stop="1,0"/>
42
  </blockTableStyle>
43
</stylesheet>
44
<story>
45
     <spacer length="1cm"/>
46
     <title>Auswertung der Verzeichnisdienstobjekte</title>
47
     <spacer length="3cm"/>
48
     <title>Erstellt am <@date format="%A %d. %B %Y"@></title>
49
<setNextTemplate name="regularpages"/>
50
<nextFrame/>
(-)a/management/univention-directory-reports/conffiles/etc/univention/directory/reports/default/en_US/footer.rml (+2 lines)
Line 0    Link Here 
1
</story>
2
</document>
(-)a/management/univention-directory-reports/conffiles/etc/univention/directory/reports/default/en_US/header.rml (+50 lines)
Line 0    Link Here 
1
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
2
<!DOCTYPE document SYSTEM "../rml_1_0.dtd">
3
<document filename="univention-directory-report.pdf">
4
	<template author="Univention Corporate Server" title="Univention Directory Report" showBoundary="0"
5
		pageSize="(21cm, 29.7cm)" leftMargin="2.5cm" rightMargin="2.5cm" topMargin="2.5cm" bottomMargin="2.5cm">
6
   <pageTemplate id="main">
7
     <pageGraphics>
8
         <image file="@%@directory/reports/logo@%@" y="27.5cm" x="13.5cm" width="5cm"/>
9
     </pageGraphics>
10
     <frame id="first" x1="2.5cm" y1="2.5cm" width="16cm" height="24.5cm"/>
11
   </pageTemplate>
12
   <pageTemplate id="regularpages">
13
     <pageGraphics>
14
         <image file="@%@directory/reports/logo@%@" y="27.5cm" x="13.5cm" width="5cm"/>
15
         <lines>2.5cm 2.5cm 18.5cm 2.5cm</lines>
16
         <drawString x="18cm" y="2cm"><pageNumber/></drawString>
17
     </pageGraphics>
18
     <setFont name="Times-Roman" size="9"/>
19
     <frame id="first" x1="2.5cm" y1="2.5cm" width="16cm" height="24.5cm"/>
20
   </pageTemplate>
21
</template>
22
<stylesheet>
23
  <paraStyle name="content" fontName="Helvetica" fontSize="9" textColor="black"/>
24
   <blockTableStyle id="mainTableOuter">
25
       <blockFont name="Times-Roman" size="9"/>
26
       <blockTextColor colorName="black"/>
27
       <blockLeftPadding length="0"/>
28
       <blockValign value="TOP"/>
29
       <blockAlignment value="LEFT"/>
30
<!--       <lineStyle kind="GRID" colorName="black"/>-->
31
  </blockTableStyle>
32
   <blockTableStyle id="mainTable">
33
       <blockFont name="Times-Roman" size="9"/>
34
       <blockTextColor colorName="black"/>
35
       <blockValign value="TOP"/>
36
       <blockLeftPadding length="0"/>
37
       <blockBottomPadding length="0"/>
38
       <blockTopPadding length="0"/>
39
       <blockAlignment value="LEFT"/>
40
<!--       <lineStyle kind="GRID" colorName="black"/>-->
41
       <blockSpan start="0,0" stop="1,0"/>
42
  </blockTableStyle>
43
</stylesheet>
44
<story>
45
     <spacer length="1cm"/>
46
     <title>Report of directory service objects</title>
47
     <spacer length="3cm"/>
48
     <title>Created on <@date@></title>
49
<setNextTemplate name="regularpages"/>
50
<nextFrame/>
(-)a/management/univention-directory-reports/debian/changelog (+6 lines)
 Lines 1-3    Link Here 
1
univention-directory-reports (9.0.1-1) unstable; urgency=medium
2
3
  * Bug #39239: remove dependency to latex
4
5
 -- Florian Best <best@univention.de>  Wed, 14 Jun 2017 14:09:00 +0200
6
1
univention-directory-reports (9.0.0-1) unstable; urgency=medium
7
univention-directory-reports (9.0.0-1) unstable; urgency=medium
2
8
3
  * Bug #41963: UCS-4.2 version bump
9
  * Bug #41963: UCS-4.2 version bump
(-)a/management/univention-directory-reports/debian/control (-6 / +16 lines)
 Lines 15-28   Architecture: all Link Here 
15
Depends: ${misc:Depends},
15
Depends: ${misc:Depends},
16
 python-univention-directory-reports,
16
 python-univention-directory-reports,
17
 shell-univention-lib,
17
 shell-univention-lib,
18
 texlive,
18
 python-univention-lib (>= 1.0.25-1),
19
 texlive-latex-recommended,
20
 texlive-latex-extra,
21
 texlive-lang-german,
22
 python-univention-lib (>= 1.0.25-1)
23
Description: Creates reports for UCS Directory Manager objects
19
Description: Creates reports for UCS Directory Manager objects
24
 UCS Report Generator creates reports in PDF format using
20
 UCS Report Generator creates reports in PDF format using
25
 LaTeX template files that contain a special template syntax to
21
 template files that contain a special template syntax to
26
 describe LDAP attributes and objects that should replace the patterns.
22
 describe LDAP attributes and objects that should replace the patterns.
27
23
28
Package: python-univention-directory-reports
24
Package: python-univention-directory-reports
 Lines 30-37   Architecture: all Link Here 
30
Depends: ${misc:Depends}, ${python:Depends},
26
Depends: ${misc:Depends}, ${python:Depends},
31
 python-univention-directory-manager,
27
 python-univention-directory-manager,
32
 univention-config,
28
 univention-config,
29
 python-trml2pdf,
33
Provides: ${python:Provides}
30
Provides: ${python:Provides}
34
Description: Creates reports for UCS Directory manager objects
31
Description: Creates reports for UCS Directory manager objects
35
 UCS Report Generator creates reports in PDF format using
32
 UCS Report Generator creates reports in PDF format using
33
 RML template files that contain a special template syntax to
34
 describe LDAP attributes and objects that should replace the patterns.
35
36
Package: univention-directory-reports-latex
37
Architecture: all
38
Depends: univention-directory-reports,
39
 univention-config,
40
 texlive,
41
 texlive-latex-recommended,
42
 texlive-latex-extra,
43
 texlive-lang-german,
44
Description: Creates reports for UCS Directory manager objects
45
 UCS Report Generator creates reports in PDF format using
36
 LaTeX template files that contain a special template syntax to
46
 LaTeX template files that contain a special template syntax to
37
 describe LDAP attributes and objects that should replace the patterns.
47
 describe LDAP attributes and objects that should replace the patterns.
(-)a/management/univention-directory-reports/debian/dirs (-4 lines)
 Lines 1-4    Link Here 
1
usr/share/univention-directory-reports
2
etc/univention/directory/reports/default/de_DE
3
etc/univention/directory/reports/default/en_US
4
usr/bin
(-)a/management/univention-directory-reports/debian/rules (-1 / +5 lines)
 Lines 30-36    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
TEMPLATE_FILES=$(shell find templates -name '*.tex' -o -name '*.csv' | sed 's/^templates\///')
33
TEMPLATE_FILES=$(shell find templates -name '*.rml' -o -name '*.csv' | sed 's/^templates\///')
34
LATEX_TEMPLATE_FILES=$(shell find templates -name '*.tex' | sed 's/^templates\///')
34
35
35
PO_FILES := $(shell find modules -name '*.po')
36
PO_FILES := $(shell find modules -name '*.po')
36
MO_FILES := $(PO_FILES:%.po=%.mo)
37
MO_FILES := $(PO_FILES:%.po=%.mo)
 Lines 52-57   override_dh_auto_install: Link Here 
52
	@for i in $(TEMPLATE_FILES); do\
53
	@for i in $(TEMPLATE_FILES); do\
53
		install -m 644 templates/$$i debian/univention-directory-reports/etc/univention/directory/reports/default/$$i;\
54
		install -m 644 templates/$$i debian/univention-directory-reports/etc/univention/directory/reports/default/$$i;\
54
	done
55
	done
56
	@for i in $(LATEX_TEMPLATE_FILES); do\
57
		install -m 644 templates/$$i debian/univention-directory-reports-latex/etc/univention/directory/reports/default/$$i;\
58
	done
55
	@for i in $(MO_FILES); do\
59
	@for i in $(MO_FILES); do\
56
		lang=`basename $$i .mo`;\
60
		lang=`basename $$i .mo`;\
57
		domain=`dirname $$i | sed 's,^modules/,,;s,/,-,g'`;\
61
		domain=`dirname $$i | sed 's,^modules/,,;s,/,-,g'`;\
(-)a/management/univention-directory-reports/debian/univention-directory-reports-latex.dirs (+2 lines)
Line 0    Link Here 
1
etc/univention/directory/reports/default/de_DE
2
etc/univention/directory/reports/default/en_US
(-)a/management/univention-directory-reports/debian/univention-directory-reports-latex.postinst (+44 lines)
Line 0    Link Here 
1
#!/bin/bash
2
#
3
# Univention Reports LaTex
4
#  postinst file for the debian package
5
#
6
# Copyright 2017 Univention GmbH
7
#
8
# http://www.univention.de/
9
#
10
# All rights reserved.
11
#
12
# The source code of this program is made available
13
# under the terms of the GNU Affero General Public License version 3
14
# (GNU AGPL V3) as published by the Free Software Foundation.
15
#
16
# Binary versions of this program provided by Univention to you as
17
# well as other copyrighted, protected or trademarked materials like
18
# Logos, graphics, fonts, specific documentations and configurations,
19
# cryptographic keys etc. are subject to a license agreement between
20
# you and Univention and not subject to the GNU AGPL V3.
21
#
22
# In the case you use this program under the terms of the GNU AGPL V3,
23
# the program is provided in the hope that it will be useful,
24
# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
# GNU Affero General Public License for more details.
27
#
28
# You should have received a copy of the GNU Affero General Public
29
# License with the Debian GNU/Linux or Univention distribution in file
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
32
33
. /usr/share/univention-lib/all.sh
34
35
#DEBHELPER#
36
37
eval "$(univention-config-registry shell)"
38
39
univention-config-registry set \
40
	directory/reports/templates/pdf/user2?'users/user "PDF Latex Document" /etc/univention/directory/reports/default users.tex' \
41
	directory/reports/templates/pdf/group2?'groups/group "PDF Latex Document" /etc/univention/directory/reports/default groups.tex' \
42
	directory/reports/templates/pdf/computer2?'computers/computer "PDF Latex Document" /etc/univention/directory/reports/default computers.tex' \
43
44
exit 0
(-)a/management/univention-directory-reports/debian/univention-directory-reports-latex.univention-config-registry (+13 lines)
Line 0    Link Here 
1
Type: file
2
File: etc/univention/directory/reports/default/en_US/header.tex
3
Variables: directory/reports/logo
4
5
Type: file
6
File: etc/univention/directory/reports/default/en_US/footer.tex
7
8
Type: file
9
File: etc/univention/directory/reports/default/de_DE/header.tex
10
Variables: directory/reports/logo
11
12
Type: file
13
File: etc/univention/directory/reports/default/de_DE/footer.tex
(-)a/management/univention-directory-reports/debian/univention-directory-reports.dirs (+4 lines)
Line 0    Link Here 
1
usr/share/univention-directory-reports
2
etc/univention/directory/reports/default/de_DE
3
etc/univention/directory/reports/default/en_US
4
usr/bin
(-)a/management/univention-directory-reports/debian/univention-directory-reports.postinst (-44 / +8 lines)
 Lines 38-89   create_logfile /var/log/univention/directory-reports.log "root:adm" 640 Link Here 
38
38
39
eval "$(univention-config-registry shell)"
39
eval "$(univention-config-registry shell)"
40
40
41
# remove old variables
41
if dpkg --compare-versions "$2" lt-nl 9.0.1-1; then
42
if [ -n "$directory_reports_templates_default1" ]; then
42
	univention-config-registry unset directory/reports/templates/pdf/user1 directory/reports/templates/pdf/group1 directory/reports/templates/pdf/computer1
43
	univention-config-registry unset directory/reports/templates/default1
44
fi
45
if [ -n "$directory_reports_templates_default2" ]; then
46
	univention-config-registry unset directory/reports/templates/default2
47
fi
48
49
# migration from older package version
50
if dpkg --compare-versions "$2" lt-nl 3.0.1-1; then
51
	# unset old UCR variables if they have not been changed in the meanwhile
52
	echo 'directory/reports/templates/csv/computer1 computers/computer "Standard CSV Report" /etc/univention/directory/reports/default/computers.csv
53
	directory/reports/templates/csv/group1 groups/group "Standard CSV Report" /etc/univention/directory/reports/default/groups.csv
54
	directory/reports/templates/csv/user1 users/user "Standard CSV Report" /etc/univention/directory/reports/default/users.csv
55
	directory/reports/templates/pdf/computer1 computers/computer "Standard Report" /etc/univention/directory/reports/default/computers.tex
56
	directory/reports/templates/pdf/group1 groups/group "Standard Report" /etc/univention/directory/reports/default/groups.tex
57
	directory/reports/templates/pdf/user1 users/user "Standard Report" /etc/univention/directory/reports/default/users.tex' \
58
	| (
59
		keyList=()
60
		while read key val; do
61
			[ "$(univention-config-registry get "$key")" = "$val" ] && keyList+=("$key")
62
		done
63
64
		# unset all keys at once
65
		[ "${#keyList[@]}" -gt 0 ] && univention-config-registry unset "${keyList[@]}"
66
	)
67
68
	# for compatibility reasons, try to set a link to the header.tex and footer.tex 
69
	# files, so that old reports do not break .. only do this in case the original 
70
	# template has not been modified
71
	tmpPath=/etc/univention/directory/reports
72
	for ifile in header.tex footer.tex; do
73
		if [ ! -e /etc/univention/templates/files/$tmpPath/$ifile ]; then
74
			rm -f $tmpPath/$ifile 
75
			ln -s $tmpPath/default/de_DE/$ifile $tmpPath/$ifile
76
		fi
77
	done
78
fi
43
fi
79
44
80
# set default values for UCR variables
81
univention-config-registry set directory/reports/logo?/usr/share/univention-directory-reports/univention_logo.png \
45
univention-config-registry set directory/reports/logo?/usr/share/univention-directory-reports/univention_logo.png \
82
	directory/reports/templates/pdf/user1?'users/user "Standard Report" /etc/univention/directory/reports/default users.tex' \
46
	directory/reports/templates/pdf/user1?'users/user "PDF Document" /etc/univention/directory/reports/default users.rml' \
83
	directory/reports/templates/pdf/group1?'groups/group "Standard Report" /etc/univention/directory/reports/default groups.tex' \
47
	directory/reports/templates/pdf/group1?'groups/group "PDF Document" /etc/univention/directory/reports/default groups.rml' \
84
	directory/reports/templates/pdf/computer1?'computers/computer "Standard Report" /etc/univention/directory/reports/default computers.tex' \
48
	directory/reports/templates/pdf/computer1?'computers/computer "PDF Document" /etc/univention/directory/reports/default computers.rml' \
85
	directory/reports/templates/csv/user1?'users/user "Standard CSV Report" /etc/univention/directory/reports/default users.csv' \
49
	directory/reports/templates/csv/user1?'users/user "CSV Report" /etc/univention/directory/reports/default users.csv' \
86
	directory/reports/templates/csv/group1?'groups/group "Standard CSV Report" /etc/univention/directory/reports/default groups.csv' \
50
	directory/reports/templates/csv/group1?'groups/group "CSV Report" /etc/univention/directory/reports/default groups.csv' \
87
	directory/reports/templates/csv/computer1?'computers/computer "Standard CSV Report" /etc/univention/directory/reports/default computers.csv'
51
	directory/reports/templates/csv/computer1?'computers/computer "CSV Report" /etc/univention/directory/reports/default computers.csv'
88
52
89
exit 0
53
exit 0
(-)a/management/univention-directory-reports/debian/univention-directory-reports.univention-config-registry (-4 / +4 lines)
 Lines 4-21   Variables: directory/reports/templates/.* Link Here 
4
Variables: directory/reports/default
4
Variables: directory/reports/default
5
5
6
Type: file
6
Type: file
7
File: etc/univention/directory/reports/default/en_US/header.tex
7
File: etc/univention/directory/reports/default/en_US/header.rml
8
Variables: directory/reports/logo
8
Variables: directory/reports/logo
9
9
10
Type: file
10
Type: file
11
File: etc/univention/directory/reports/default/en_US/footer.tex
11
File: etc/univention/directory/reports/default/en_US/footer.rml
12
12
13
Type: file
13
Type: file
14
File: etc/univention/directory/reports/default/de_DE/header.tex
14
File: etc/univention/directory/reports/default/de_DE/header.rml
15
Variables: directory/reports/logo
15
Variables: directory/reports/logo
16
16
17
Type: file
17
Type: file
18
File: etc/univention/directory/reports/default/de_DE/footer.tex
18
File: etc/univention/directory/reports/default/de_DE/footer.rml
19
19
20
Type: file
20
Type: file
21
File: etc/logrotate.d/univention-directory-reports
21
File: etc/logrotate.d/univention-directory-reports
(-)a/management/univention-directory-reports/man/univention-directory-reports.1 (-4 / +1 lines)
 Lines 15-21   This manual page documents briefly the Link Here 
15
.B univention\-directory\-reports
15
.B univention\-directory\-reports
16
command.
16
command.
17
It is a tool to generate a report over UDM objects stored in the LDAP tree.
17
It is a tool to generate a report over UDM objects stored in the LDAP tree.
18
Currently supported output formats include Comma Separated Values (CSV) and PDF generated through LaTeX.
18
Currently supported output formats include Comma Separated Values (CSV) and PDF generated through RML or LaTeX.
19
19
20
.SH OPTIONS
20
.SH OPTIONS
21
A summary of options is included below.
21
A summary of options is included below.
 Lines 52-60   Use \fB-l\fP to list the available reports. Link Here 
52
\fB-l\fP, \fB--list\fP
52
\fB-l\fP, \fB--list\fP
53
List names of available modules and reports.
53
List names of available modules and reports.
54
.TP
54
.TP
55
\fB\-n\fP, \fB\-\-no\-cleanup\fP
56
Do not remove the temporary LaTeX files (for debugging).
57
.TP
58
\fB\-c\fP \fICONFIG\fP, \fB\-\-config=\fP\fICONFIG\fP
55
\fB\-c\fP \fICONFIG\fP, \fB\-\-config=\fP\fICONFIG\fP
59
Location of an alternative configuration file.
56
Location of an alternative configuration file.
60
.TP
57
.TP
(-)a/management/univention-directory-reports/modules/univention/directory/reports/__init__.py (-3 / +8 lines)
 Lines 30-35    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from document import *
33
34
from admin import *
34
from univention.directory.reports.error import ReportError
35
from config import *
35
from univention.directory.reports.report import Report
36
from univention.directory.reports.document import Document
37
from univention.directory.reports.admin import connect, get_object, cache_object, connected, identify, set_format
38
from univention.directory.reports.config import Config
39
40
__all__ = ['Report', 'ReportError', 'Document', 'connect', 'get_object', 'cache_object', 'connected', 'identify', 'set_format', 'Config']
(-)a/management/univention-directory-reports/modules/univention/directory/reports/admin.py (-8 / +19 lines)
 Lines 30-47    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
import cgi
34
33
import univention.admin.uldap as ua_ldap
35
import univention.admin.uldap as ua_ldap
34
import univention.admin.objects as ua_objects
36
import univention.admin.objects as ua_objects
35
import univention.admin.modules as ua_modules
37
import univention.admin.modules as ua_modules
36
import univention.admin.mapping as ua_mapping
38
import univention.admin.mapping as ua_mapping
37
import univention.admin.syntax as ua_syntax
38
import univention.admin.config as ua_config
39
import univention.admin.config as ua_config
39
import univention.admin.uexceptions as ua_exceptions
40
import univention.admin.uexceptions as ua_exceptions
40
from univention.config_registry import ConfigRegistry
41
from univention.config_registry import ConfigRegistry
41
42
42
import univention.debug as ud
43
import univention.debug as ud
43
44
44
from filter import filter_get
45
from univention.directory.reports.filter import filter_get
45
46
46
__all__ = ['connect', 'get_object', 'cache_object', 'connected', 'identify', 'set_format']
47
__all__ = ['connect', 'get_object', 'cache_object', 'connected', 'identify', 'set_format']
47
48
 Lines 85-91   def texClean(str): Link Here 
85
86
86
class AdminConnection(object):
87
class AdminConnection(object):
87
88
88
	def __init__(self, userdn=None, password=None, host='localhost', base=None, start_tls=2, access=None, format=True):
89
	def __init__(self, userdn=None, password=None, host='localhost', base=None, start_tls=2, access=None, format=None):
89
		self._cached = {}
90
		self._cached = {}
90
		self._modules = {}
91
		self._modules = {}
91
		self._policies = {}
92
		self._policies = {}
 Lines 163-169   def get_object_real(self, module, dn): Link Here 
163
			except:
164
			except:
164
				pass
165
				pass
165
		for key, value in new.items():
166
		for key, value in new.items():
166
			if self._format:
167
			from univention.directory.reports.document import Document
168
			if self._format in (Document.TYPE_LATEX, Document.TYPE_RML):
167
				i, j = self.format_property(new.descriptions, key, value)
169
				i, j = self.format_property(new.descriptions, key, value)
168
				new.info[i] = j
170
				new.info[i] = j
169
			else:
171
			else:
 Lines 215-232   def format_property_real(self, props, key, value): Link Here 
215
				for v in value:
217
				for v in value:
216
					if isinstance(v, (list, tuple)):
218
					if isinstance(v, (list, tuple)):
217
						for i in v:
219
						for i in v:
218
							result.append(texClean(str(i)))
220
							result.append(self.escape(str(i)))
219
					else:
221
					else:
220
						result.append(texClean(str(v)))
222
						result.append(self.escape(str(v)))
221
				value = result
223
				value = result
222
			elif value:
224
			elif value:
223
				value = texClean(value)
225
				value = self.escape(value)
224
			filter = filter_get(prop.syntax)
226
			filter = filter_get(prop.syntax)
225
			if filter:
227
			if filter:
226
				return filter(prop, key, value)
228
				return filter(prop, key, value)
227
229
228
		return (key, value)
230
		return (key, value)
229
231
232
	def escape(self, value):
233
		from univention.directory.reports.document import Document
234
		if self._format == Document.TYPE_LATEX:
235
			return texClean(value)
236
		elif self._format == Document.TYPE_RML:
237
			return cgi.escape(value, quote=True)
238
		return value
239
230
	def _get_policies(self, obj):
240
	def _get_policies(self, obj):
231
		dict = {}
241
		dict = {}
232
		policies = self._access.getPolicies(obj.dn)
242
		policies = self._access.getPolicies(obj.dn)
 Lines 239-245   def _get_policies(self, obj): Link Here 
239
				dict[attr_name] = value_dict['value']
249
				dict[attr_name] = value_dict['value']
240
250
241
			for key, value in ua_mapping.mapDict(module.mapping, dict).items():
251
			for key, value in ua_mapping.mapDict(module.mapping, dict).items():
242
				if self._format:
252
				from univention.directory.reports.document import Document
253
				if self._format in (Document.TYPE_LATEX, Document.TYPE_RML):
243
					i, j = self.format_property(module.property_descriptions, key, value)
254
					i, j = self.format_property(module.property_descriptions, key, value)
244
					obj.info[i] = j
255
					obj.info[i] = j
245
				else:
256
				else:
(-)a/management/univention-directory-reports/modules/univention/directory/reports/config.py (-4 / +4 lines)
 Lines 115-131   def _guess_path(self, directory, fileName, alternativePath=''): Link Here 
115
				return path
115
				return path
116
		return None
116
		return None
117
117
118
	def get_header(self, module, name=None):
118
	def get_header(self, module, name=None, suffix='.tex'):
119
		report = self._get_report_entry(module, name)
119
		report = self._get_report_entry(module, name)
120
		if not report:
120
		if not report:
121
			return None
121
			return None
122
		return self._guess_path(report[1], 'header.tex', self._oldHeader)
122
		return self._guess_path(report[1], 'header%s' % (suffix,), self._oldHeader)
123
123
124
	def get_footer(self, module, name=None):
124
	def get_footer(self, module, name=None, suffix='.tex'):
125
		report = self._get_report_entry(module, name)
125
		report = self._get_report_entry(module, name)
126
		if not report:
126
		if not report:
127
			return None
127
			return None
128
		return self._guess_path(report[1], 'footer.tex', self._oldFooter)
128
		return self._guess_path(report[1], 'footer%s' % (suffix,), self._oldFooter)
129
129
130
	def get_report_names(self, module):
130
	def get_report_names(self, module):
131
		reports = self._reports.get(module, [])
131
		reports = self._reports.get(module, [])
(-)a/management/univention-directory-reports/modules/univention/directory/reports/document.py (-22 / +52 lines)
 Lines 1-7    Link Here 
1
# -*- coding: utf-8 -*-
1
# -*- coding: utf-8 -*-
2
#
2
#
3
# Univention Directory Reports
3
# Univention Directory Reports
4
#  	creates a report document
4
#  creates a report document
5
#
5
#
6
# Copyright 2007-2017 Univention GmbH
6
# Copyright 2007-2017 Univention GmbH
7
#
7
#
 Lines 37-65    Link Here 
37
import tempfile
37
import tempfile
38
import subprocess
38
import subprocess
39
39
40
from parser import Parser
40
from univention.directory.reports.error import ReportError
41
from output import Output
41
from univention.directory.reports.parser import Parser
42
from interpreter import Interpreter
42
from univention.directory.reports.output import Output
43
import admin
43
from univention.directory.reports.interpreter import Interpreter
44
from univention.directory.reports import admin
45
46
import trml2pdf
47
48
from univention.lib.i18n import Translation
49
_ = Translation('univention-directory-reports').translate
44
50
45
51
46
class Document(object):
52
class Document(object):
47
	(TYPE_LATEX, TYPE_CSV, TYPE_UNKNOWN) = range(3)
53
	(TYPE_LATEX, TYPE_CSV, TYPE_RML, TYPE_UNKNOWN) = range(4)
54
55
	@classmethod
56
	def get_type(cls, template):
57
		if template.endswith('.tex'):
58
			return cls.TYPE_LATEX
59
		elif template.endswith('.csv'):
60
			return cls.TYPE_CSV
61
		elif template.endswith('.rml'):
62
			return cls.TYPE_RML
63
		return cls.TYPE_UNKNOWN
48
64
49
	def __init__(self, template, header=None, footer=None):
65
	def __init__(self, template, header=None, footer=None):
50
		self._template = template
66
		self._template = template
51
		self._header = header
67
		self._header = header
52
		self._footer = footer
68
		self._footer = footer
53
		if self._template.endswith('.tex'):
69
		self._type = self.get_type(self._template)
54
			self._type = Document.TYPE_LATEX
55
		elif self._template.endswith('.csv'):
56
			self._type = Document.TYPE_CSV
57
		else:
58
			self._type = Document.TYPE_UNKNOWN
59
		self.__check_files()
70
		self.__check_files()
60
71
61
	def __check_files(self):
72
	def __check_files(self):
62
		if self._type == Document.TYPE_LATEX:
73
		if self._type in (Document.TYPE_LATEX, Document.TYPE_RML):
63
			files = (self._header, self._footer, self._template)
74
			files = (self._header, self._footer, self._template)
64
		elif self._type == Document.TYPE_CSV:
75
		elif self._type == Document.TYPE_CSV:
65
			files = (self._template, )
76
			files = (self._template, )
 Lines 67-73   def __check_files(self): Link Here 
67
			files = tuple()
78
			files = tuple()
68
		for filename in files:
79
		for filename in files:
69
			if not os.path.isfile(filename):
80
			if not os.path.isfile(filename):
70
				raise NameError("error: required file '%s' does not exist or is not readable" % filename)
81
				raise ReportError(_("Configuration error: File %r could not be opened.") % (filename,))
71
82
72
	def __create_tempfile(self):
83
	def __create_tempfile(self):
73
		if self._type == Document.TYPE_LATEX:
84
		if self._type == Document.TYPE_LATEX:
 Lines 82-96   def __create_tempfile(self): Link Here 
82
93
83
		return filename
94
		return filename
84
95
85
	def __append_file(self, fd, filename):
96
	def __append_file(self, fd, filename, obj=None):
86
		tmpfd = open(filename, 'r')
97
		parser = Parser(filename=filename)
87
		fd.write(tmpfd.read())
98
		parser.tokenize()
88
		tmpfd.close()
99
		tks = copy.deepcopy(parser._tokens)
100
		interpret = Interpreter(obj, tks)
101
		interpret.run()
102
		output = Output(tks, fd=fd)
103
		output.write()
89
104
90
	def create_source(self, objects=[]):
105
	def create_source(self, objects=[]):
91
		"""Create report from objects (list of DNs)."""
106
		"""Create report from objects (list of DNs)."""
92
		tmpfile = self.__create_tempfile()
107
		tmpfile = self.__create_tempfile()
93
		admin.set_format(self._type == Document.TYPE_LATEX)
108
		admin.set_format(self._type)
94
		parser = Parser(filename=self._template)
109
		parser = Parser(filename=self._template)
95
		parser.tokenize()
110
		parser.tokenize()
96
		tokens = parser._tokens
111
		tokens = parser._tokens
 Lines 106-112   def create_source(self, objects=[]): Link Here 
106
			else:
121
			else:
107
				obj = admin.cache_object(dn)
122
				obj = admin.cache_object(dn)
108
			if obj is None:
123
			if obj is None:
109
				print >>sys.stderr, "warning: dn '%s' not found, skipped." % dn
124
				print >> sys.stderr, "warning: dn '%s' not found, skipped." % dn
110
				continue
125
				continue
111
			tks = copy.deepcopy(tokens)
126
			tks = copy.deepcopy(tokens)
112
			interpret = Interpreter(obj, tks)
127
			interpret = Interpreter(obj, tks)
 Lines 130-136   def create_pdf(self, latex_file): Link Here 
130
			if not subprocess.call(cmd, stdout=devnull, stderr=devnull, env=env_vars):
145
			if not subprocess.call(cmd, stdout=devnull, stderr=devnull, env=env_vars):
131
				if not subprocess.call(cmd, stdout=devnull, stderr=devnull, env=env_vars):
146
				if not subprocess.call(cmd, stdout=devnull, stderr=devnull, env=env_vars):
132
					return '%s.pdf' % latex_file.rsplit('.', 1)[0]
147
					return '%s.pdf' % latex_file.rsplit('.', 1)[0]
133
			print >>sys.stderr, "error: failed to create PDF file"
148
			raise ReportError(_('Failed creating PDF file.'))
134
			return None
135
		finally:
149
		finally:
136
			devnull.close()
150
			devnull.close()
151
			basefile = latex_file.rsplit('.', 1)[0]  # strip suffix
152
			for file_ in [latex_file] + ['%s.%s' % (basefile, suffix) for suffix in ('aux', 'log')]:
153
				try:
154
					os.unlink(file_)
155
				except EnvironmentError:
156
					pass
157
158
	def create_rml_pdf(self, rml_file):
159
		output = '%s.pdf' % (os.path.splitext(rml_file)[0],)
160
		with open(rml_file, 'rb') as fd:
161
			outputfile = trml2pdf.parseString(fd.read(), output)
162
		try:
163
			os.unlink(rml_file)
164
		except EnvironmentError:
165
			pass
166
		return outputfile
(-)a/management/univention-directory-reports/modules/univention/directory/reports/error.py (+34 lines)
Line 0    Link Here 
1
# -*- coding: utf-8 -*-
2
#
3
# Univention Directory Reports
4
#
5
# Copyright 2017 Univention GmbH
6
#
7
# http://www.univention.de/
8
#
9
# All rights reserved.
10
#
11
# The source code of this program is made available
12
# under the terms of the GNU Affero General Public License version 3
13
# (GNU AGPL V3) as published by the Free Software Foundation.
14
#
15
# Binary versions of this program provided by Univention to you as
16
# well as other copyrighted, protected or trademarked materials like
17
# Logos, graphics, fonts, specific documentations and configurations,
18
# cryptographic keys etc. are subject to a license agreement between
19
# you and Univention and not subject to the GNU AGPL V3.
20
#
21
# In the case you use this program under the terms of the GNU AGPL V3,
22
# the program is provided in the hope that it will be useful,
23
# but WITHOUT ANY WARRANTY; without even the implied warranty of
24
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
# GNU Affero General Public License for more details.
26
#
27
# You should have received a copy of the GNU Affero General Public
28
# License with the Debian GNU/Linux or Univention distribution in file
29
# /usr/share/common-licenses/AGPL-3; if not, see
30
# <http://www.gnu.org/licenses/>.
31
32
33
class ReportError(Exception):
34
	pass
(-)a/management/univention-directory-reports/modules/univention/directory/reports/filter.py (-3 / +5 lines)
 Lines 77-85   def _email_address(prop, key, value): Link Here 
77
77
78
def _samba_group_type(prop, key, value):
78
def _samba_group_type(prop, key, value):
79
	# need to call str() directly in order to force a correct translation
79
	# need to call str() directly in order to force a correct translation
80
	types = {'2': str(_('Domain Group')),
80
	types = {
81
			  '3': str(_('Local Group')),
81
		'2': str(_('Domain Group')),
82
			  '5': str(_('Well-Known Group'))}
82
		'3': str(_('Local Group')),
83
		'5': str(_('Well-Known Group'))
84
	}
83
	if value in types.keys():
85
	if value in types.keys():
84
		value = types[value]
86
		value = types[value]
85
	return (key, value)
87
	return (key, value)
(-)a/management/univention-directory-reports/modules/univention/directory/reports/interpreter.py (-8 / +9 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
import univention.admin.modules as ua_modules
33
import re
34
import copy
35
import fnmatch
36
import datetime
37
34
import univention.admin.objects as ua_objects
38
import univention.admin.objects as ua_objects
35
import univention.admin.uldap as ua_ldap
36
39
37
from tokens import QueryToken, ResolveToken, TextToken, AttributeToken, PolicyToken
40
from univention.directory.reports.tokens import QueryToken, ResolveToken, TextToken, AttributeToken, PolicyToken, DateToken
38
import admin
41
from univention.directory.reports import admin
39
42
40
import univention.admin.localization
43
import univention.admin.localization
41
translation = univention.admin.localization.translation('univention-directory-reports')
44
translation = univention.admin.localization.translation('univention-directory-reports')
42
_ = translation.translate
45
_ = translation.translate
43
46
44
import copy
45
import fnmatch
46
import re
47
48
47
49
class Interpreter(object):
48
class Interpreter(object):
50
49
 Lines 101-106   def run(self, tokens=[], base_objects=[]): Link Here 
101
						token.value = token.attrs['prepend'] + token.value
100
						token.value = token.attrs['prepend'] + token.value
102
			elif isinstance(token, PolicyToken):
101
			elif isinstance(token, PolicyToken):
103
				self.policy(token, base_objects[0])
102
				self.policy(token, base_objects[0])
103
			elif isinstance(token, DateToken):
104
				token.value = datetime.datetime.today().strftime(token.attrs.get('format', "%A %B %d, %Y"))
104
105
105
	def resolve(self, token, base):
106
	def resolve(self, token, base):
106
		if 'module' in token.attrs:
107
		if 'module' in token.attrs:
(-)a/management/univention-directory-reports/modules/univention/directory/reports/output.py (-2 / +2 lines)
 Lines 33-39    Link Here 
33
import codecs
33
import codecs
34
import os
34
import os
35
35
36
from tokens import TextToken, ResolveToken, QueryToken, AttributeToken, PolicyToken
36
from tokens import TextToken, ResolveToken, QueryToken, AttributeToken, PolicyToken, DateToken
37
37
38
38
39
class Output(object):
39
class Output(object):
 Lines 69-73   def write(self, tokens=[]): Link Here 
69
			elif isinstance(token, (ResolveToken, QueryToken)):
69
			elif isinstance(token, (ResolveToken, QueryToken)):
70
				if len(token):
70
				if len(token):
71
					self.write(token)
71
					self.write(token)
72
			elif isinstance(token, (AttributeToken, PolicyToken)):
72
			elif isinstance(token, (DateToken, AttributeToken, PolicyToken)):
73
				self._fd.write(token.value)
73
				self._fd.write(token.value)
(-)a/management/univention-directory-reports/modules/univention/directory/reports/parser.py (-2 / +4 lines)
 Lines 33-39    Link Here 
33
import re
33
import re
34
import shlex
34
import shlex
35
35
36
from tokens import Token, TextToken, AttributeToken, PolicyToken, QueryToken, HeaderToken, FooterToken, IContextToken, ResolveToken
36
from tokens import Token, TextToken, AttributeToken, PolicyToken, QueryToken, HeaderToken, FooterToken, IContextToken, ResolveToken, DateToken
37
37
38
38
39
class Parser(object):
39
class Parser(object):
 Lines 109-121   def next_token(self): Link Here 
109
			return HeaderToken(attrs, closing)
109
			return HeaderToken(attrs, closing)
110
		elif name == 'footer':
110
		elif name == 'footer':
111
			return FooterToken(attrs, closing)
111
			return FooterToken(attrs, closing)
112
		elif name == 'date':
113
			return DateToken(attrs)
112
		else:
114
		else:
113
			raise SyntaxError('Unknown tag: %s' % name)
115
			raise SyntaxError('Unknown tag: %s' % name)
114
116
115
	def tokenize(self):
117
	def tokenize(self):
116
		token = self.next_token()
118
		token = self.next_token()
117
		while token:
119
		while token:
118
			if isinstance(token, (TextToken, AttributeToken, PolicyToken)):
120
			if isinstance(token, (TextToken, AttributeToken, PolicyToken, DateToken)):
119
				if isinstance(token, TextToken):
121
				if isinstance(token, TextToken):
120
					if token.data == '\n' and len(self._context) and isinstance(self._context[-1], HeaderToken):
122
					if token.data == '\n' and len(self._context) and isinstance(self._context[-1], HeaderToken):
121
						# ignore line feed after header
123
						# ignore line feed after header
(-)a/management/univention-directory-reports/modules/univention/directory/reports/report.py (+76 lines)
Line 0    Link Here 
1
# -*- coding: utf-8 -*-
2
#
3
# Univention Directory Reports
4
#
5
# Copyright 2017 Univention GmbH
6
#
7
# http://www.univention.de/
8
#
9
# All rights reserved.
10
#
11
# The source code of this program is made available
12
# under the terms of the GNU Affero General Public License version 3
13
# (GNU AGPL V3) as published by the Free Software Foundation.
14
#
15
# Binary versions of this program provided by Univention to you as
16
# well as other copyrighted, protected or trademarked materials like
17
# Logos, graphics, fonts, specific documentations and configurations,
18
# cryptographic keys etc. are subject to a license agreement between
19
# you and Univention and not subject to the GNU AGPL V3.
20
#
21
# In the case you use this program under the terms of the GNU AGPL V3,
22
# the program is provided in the hope that it will be useful,
23
# but WITHOUT ANY WARRANTY; without even the implied warranty of
24
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
# GNU Affero General Public License for more details.
26
#
27
# You should have received a copy of the GNU Affero General Public
28
# License with the Debian GNU/Linux or Univention distribution in file
29
# /usr/share/common-licenses/AGPL-3; if not, see
30
# <http://www.gnu.org/licenses/>.
31
32
import os
33
34
from univention.directory.reports.error import ReportError
35
from univention.directory.reports.document import Document
36
from univention.directory.reports.admin import connect, clear_cache
37
from univention.directory.reports.config import Config
38
39
from univention.lib.i18n import Translation
40
_ = Translation('univention-directory-reports').translate
41
42
43
class Report(object):
44
45
	def __init__(self, lo, config=None):
46
		self.lo = lo
47
		self.config = config or Config()
48
49
	def create(self, module, report, objects):
50
		"""Create a report of objects for the specified module in the specified report type format"""
51
		connect(access=self.lo)
52
		clear_cache()
53
54
		template = self.config.get_report(module, report)
55
		if template is None:
56
			if not module:
57
				raise ReportError(_('Please specify a module.'))
58
			if module not in self.config._reports:
59
				raise ReportError(_('No report for the specified module %r exists.') % (module,))
60
			if report:
61
				raise ReportError(_('The report %r does not exists or is misconfigured.') % (report,))
62
			raise ReportError(_('No %r report exists for the module %r.') % (report, module))
63
64
		suffix = '.rml' if Document.get_type(template) == Document.TYPE_RML else '.tex'
65
		header = self.config.get_header(module, report, suffix)
66
		footer = self.config.get_footer(module, report, suffix)
67
		doc = Document(template, header=header, footer=footer)
68
69
		tmpfile = doc.create_source(objects)
70
		pdffile = tmpfile
71
		func = {Document.TYPE_RML: doc.create_rml_pdf, Document.TYPE_LATEX: doc.create_pdf}.get(doc._type)
72
		if func:
73
			pdffile = func(tmpfile)
74
		if not pdffile or not os.path.exists(pdffile):
75
			raise ReportError(_('The report could not be created.'))
76
		return pdffile
(-)a/management/univention-directory-reports/modules/univention/directory/reports/tokens.py (+7 lines)
 Lines 118-120   class PolicyToken(TemplateToken): Link Here 
118
	def __init__(self, attrs={}, value=''):
118
	def __init__(self, attrs={}, value=''):
119
		TemplateToken.__init__(self, 'policy', attrs)
119
		TemplateToken.__init__(self, 'policy', attrs)
120
		self.value = value
120
		self.value = value
121
122
123
class DateToken(TemplateToken):
124
125
	def __init__(self, attrs={}, value=''):
126
		TemplateToken.__init__(self, 'date', attrs)
127
		self.value = value
(-)a/management/univention-directory-reports/templates/de_DE/computers.rml (+11 lines)
Line 0    Link Here 
1
<!--<para><h1>Rechner-Report</h1></para>
2
<spacer length="1cm"/>
3
-->
4
<blockTable style="mainTable">
5
<tr><td><h3>Rechner <@attribute name="name"@></h3></td> </tr>
6
<tr><td><para style="content">IP-Adresse:</para></td><td><para style="content"><@attribute name="ip"@></para></td> </tr>
7
<tr><td><para style="content">MAC-Adresse:</para></td><td><para style="content"><@attribute name="mac"@></para></td></tr>
8
<tr><td><para style="content">Network:</para></td><td><para style="content"><@resolve module="networks/network" dn-attribute="network" alternative="nicht zugewiesen"@><@attribute name="name"@><@/resolve@></para></td></tr>
9
<tr><td><para style="content">Inventarnummer:</para></td><td><para style="content"><@attribute name="inventoryNumber"@></para></td></tr>
10
</blockTable>
11
<spacer length="1cm"/>
(-)a/management/univention-directory-reports/templates/de_DE/groups.rml (+42 lines)
Line 0    Link Here 
1
<para><h1>Gruppen-Report: <@attribute name="name"@></h1></para>
2
<spacer length="1cm"/>
3
4
<blockTable style="mainTable">
5
<tr><td><h3>Gruppeneinzelnachweis: <@attribute name="name"@></h3></td></tr>
6
<tr><td><para style="content">Name:</para></td><td><para style="content"><@attribute name="name"@></para></td></tr>
7
<tr><td><para style="content">Beschreibung:</para></td><td><para style="content"><@attribute name="description" default="-"@></para></td></tr>
8
<tr><td><para style="content">Gruppen ID:</para></td><td><para style="content"><@attribute name="gidNumber"@></para></td></tr>
9
<tr><td><para style="content">Relative ID:</para></td><td><para style="content"><@attribute name="sambaRID"@></para></td></tr>
10
<tr><td><para style="content">Gruppentyp:</para></td><td><para style="content"><@attribute name="sambaGroupType"@></para></td></tr>
11
<tr><td><para style="content">E-Mail-Adresse:</para></td><td><para style="content"><@attribute name="mailAddress" default="-"@></para></td></tr>
12
</blockTable>
13
14
<spacer length="0.5cm"/>
15
16
<h3>Mitglied folgender Gruppen</h3>
17
18
<@resolve module="groups/group" dn-attribute="memberOf" alternative="<para>Diese Gruppe ist in keiner anderen Gruppe Mitglied.</para>"@>
19
  <para bulletFontSize="5" bulletText="&#x25cf;"><@attribute name="name"@> (<@attribute name="description"@>)</para>
20
<@/resolve@>
21
22
23
<h3>Gruppen in dieser Gruppe</h3>
24
25
<@query module="groups/group" start="nestedGroup" next="nestedGroup" alternative="<para>Keine Gruppe ist Mitglied dieser Gruppe.</para>"@>
26
  <para bulletFontSize="5" bulletText="&#x25cf;"><@attribute name="name"@> (<@attribute name="description"@>)</para>
27
<@/query@>
28
29
<h3>Benutzer in dieser Gruppe</h3>
30
31
<@resolve module="users/user" dn-attribute="users" alternative="<para>Kein Benutzer ist Mitglied dieser Gruppe.</para>"@>
32
  <para bulletFontSize="5" bulletText="&#x25cf;"><@attribute name="username"@> (<@attribute name="lastname"@>, <@attribute name="firstname"@>)</para>
33
<@/resolve@>
34
35
<@query module="groups/group" start="nestedGroup" next="nestedGroup" alternative="<para>Keine indirekten Gruppenmitgliedschaften.</para>"@>
36
  <h2>Gruppe: <@attribute name="name"@> (<@attribute name="description"@>)</h2>
37
  <@resolve module="users/user" dn-attribute="users" alternative="<para>Keine Mitglieder in dieser Gruppe</para>"@>
38
    <para bulletFontSize="4" bulletText="&#x25cf;"><@attribute name="username"@> (<@attribute name="lastname"@>)</para>
39
  <@/resolve@>
40
<@/query@>
41
42
<nextFrame/>
(-)a/management/univention-directory-reports/templates/de_DE/users.rml (+96 lines)
Line 0    Link Here 
1
<para><h1>Benutzer-Report: <@attribute name="lastname"@><@attribute name="firstname" prepend=", "@></h1></para>
2
<spacer length="1cm"/>
3
4
<blockTable style="mainTableOuter" colWidths="7.8cm,7.8cm">
5
<tr><td>
6
7
<blockTable style="mainTable" colWidths="3.5cm,4cm">
8
<tr><td><h3>Benutzereinzelnachweis: <@attribute name="lastname"@>, <@attribute name="firstname"@></h3></td> </tr>
9
<tr><td><para style="content">Name:</para></td><td><para style="content"><@attribute name="lastname"@><@attribute name="firstname" prepend=", "@></para></td> </tr>
10
<tr><td><para style="content">Benutzer:</para></td><td><para style="content"><@attribute name="username"@></para></td></tr>
11
<tr><td><para style="content">Beschreibung:</para></td><td><para style="content"><@attribute name="description"@></para></td></tr>
12
<tr><td><para style="content">Organisation:</para></td><td><para style="content"><@attribute name="organisation"@></para></td></tr>
13
<tr><td><para style="content">Mitarbeiternummer:</para></td><td><para style="content"><@attribute name="employeeNumber"@></para></td></tr>
14
<tr><td><para style="content">Mitarbeitertyp:</para></td><td><para style="content"><@attribute name="employeeType"@></para></td></tr>
15
<tr><td><para style="content">Raumnummer:</para></td><td><para style="content"><@attribute name="roomNumber"@></para></td></tr>
16
<tr><td><para style="content">Vorgesetzter:</para></td><td><para style="content">
17
<@resolve module="users/user" dn-attribute="secretary" alternative=""@>
18
    <@attribute name="lastname"@><@attribute name="firstname" prepend=", "@>
19
<@/resolve@></para></td></tr>
20
</blockTable>
21
<spacer length="1cm"/>
22
23
24
<blockTable style="mainTable" colWidths="3.5cm,4cm">
25
<tr><td><h3>Kontakt</h3></td></tr>
26
<tr><td></td></tr>
27
<tr><td><para style="content">Telefon:</para></td><td><para style="content"><@attribute name="phone"@> </para></td></tr>
28
<tr><td><para style="content">Mobiltelefon:</para></td><td><para style="content"><@attribute name="mobileTelephoneNumber"@></para></td></tr>
29
<tr><td><para style="content">Straße:</para></td><td><para style="content"><@attribute name="street"@></para></td></tr>
30
<tr><td></td></tr>
31
</blockTable>
32
<spacer length="1cm"/>
33
34
<blockTable style="mainTable" colWidths="3.5cm,4cm">
35
<tr><td><h3>Kontoeinstellungen</h3></td></tr>
36
<tr><td><para style="content">Deaktiviert:</para></td><td><para style="content"><@attribute name="disabled" default="Nein"@> </para></td></tr>
37
<tr><td><para style="content">Gesperrt:</para></td><td><para style="content"><@attribute name="locked" default="Nein"@> </para></td></tr>
38
<tr><td><para style="content">Kontoablaufdatum:</para></td><td><para style="content"><@attribute name="userexpiry" default="Nicht gesetzt"@> </para></td></tr>
39
<tr><td><para style="content">Passwortablaufdatum:</para></td><td><para style="content"><@attribute name="passwordexpiry" default="Nicht gesetzt"@> </para></td></tr>
40
<tr><td><para style="content">Passwortänderung:</para></td><td><para style="content"><@attribute name="pwdChangeNextLogin" default="Nein"@> </para></td></tr>
41
</blockTable>
42
<spacer length="1cm"/>
43
44
</td><td>
45
46
<blockTable style="mainTable" colWidths="3.5cm,4cm">
47
<tr><td><h3>Linux/UNIX</h3></td></tr>
48
<tr><td><para style="content">Benutzer-ID:</para></td><td><para style="content"><@attribute name="uidNumber"@> </para></td></tr>
49
<tr><td><para style="content">Gruppen-ID:</para></td><td><para style="content"><@attribute name="gidNumber"@></para></td></tr>
50
<tr><td><para style="content">Login-Shell:</para></td><td><para style="content"><@attribute name="shell"@> </para></td></tr>
51
<tr><td><para style="content">Heimatverzeichnis:</para></td><td><para style="content"><@attribute name="unixhome"@> </para></td></tr>
52
<tr><td><para style="content">Freigabepfad:</para></td><td><para style="content"><@attribute name="homeSharePath"@> </para></td></tr>
53
<tr><td><para style="content">Freigabe:</para></td><td><para style="content"><@resolve module="shares/share" dn-attribute="homeShare"@>
54
    <@attribute name="printablename"@>
55
<@/resolve@></para></td></tr>
56
</blockTable>
57
58
<spacer length="1cm"/>
59
60
<blockTable style="mainTable" colWidths="3.5cm,4cm">
61
<tr><td><h3>Passwort-Richtlinie</h3></td></tr>
62
<tr><td><para style="content">Ererbt:</para></td><td><@policy module="policies/pwdhistory" inherited=""@> </td></tr>
63
<tr><td><para style="content">History Länge:</para></td><td><para style="content"><@attribute name="length"@></para></td></tr>
64
<tr><td><para style="content">Passwort Länge:</para></td><td><para style="content"><@attribute name="pwLength"@></para></td></tr>
65
<tr><td><para style="content">Ablaufintervall:</para></td><td><para style="content"><@attribute name="expiryInterval" default="-"@></para></td></tr>
66
</blockTable>
67
<spacer length="1cm"/>
68
69
<blockTable style="mainTable" colWidths="3.5cm,4cm">
70
<tr><td><h3>Mail</h3></td></tr>
71
<tr><td><para style="content">E-Mail-Adresse:</para></td><td><para style="content"><@attribute name="mailPrimaryAddress" default="Keine"@> </para></td></tr>
72
<tr><td><para style="content">weitere Adressen:</para></td><td><para style="content"><@attribute name="mailAlternativeAddress" default="Keine"@> </para></td></tr>
73
<tr><td><para style="content">Globaler SPAM-Ordner:</para></td><td><para style="content"><@attribute name="mailGlobalSpamFolder" default="-"@> </para></td></tr>
74
</blockTable>
75
<spacer length="1cm"/>
76
77
<blockTable style="mainTable" colWidths="3.5cm,4cm">
78
<tr><td><h3>Windows</h3></td></tr>
79
<tr><td><para style="content">Heimatverzeichnis:</para></td><td><para style="content"><@attribute name="sambahome"@> </para></td></tr>
80
<tr><td><para style="content">Laufwerk für Heimatverzeichnis:</para></td><td><para style="content"><@attribute name="homedrive"@> </para></td></tr>
81
<tr><td><para style="content">Profilverzeichnis:</para></td><td><para style="content"><@attribute name="profilepath"@> </para></td></tr>
82
<tr><td><para style="content">Anmeldeskript:</para></td><td><para style="content"><@attribute name="scriptpath"@> </para></td></tr>
83
<tr><td><para style="content">Relative ID:</para></td><td><para style="content"><@attribute name="sambaRID"@> </para></td></tr>
84
</blockTable>
85
86
</td></tr>
87
</blockTable>
88
89
90
<h3>Mitglied in folgenden Gruppen</h3>
91
92
<@query module="groups/group" start="groups" next="memberOf" regex="name=^[^(s\-)([a\-)(i\-)(h\-)]" alternative="<para>Der Benutzer ist in keiner weiteren Gruppen enthalten</para>"@>
93
	<para bulletFontSize="5" bulletText="&#x25cf;"><b><@attribute name="name"@></b> (<@attribute name="description"@>)</para>
94
<@/query@>
95
96
<nextFrame/>
(-)a/management/univention-directory-reports/templates/en_US/computers.rml (+12 lines)
Line 0    Link Here 
1
<!--<para><h1>Hostname report</h1></para>
2
<spacer length="1cm"/>
3
-->
4
<blockTable style="mainTable">
5
<tr><td><h3>Hostname <@attribute name="name"@></h3></td> </tr>
6
<tr><td><para style="content">IP address:</para></td><td><para style="content"><@attribute name="ip"@></para></td> </tr>
7
<tr><td><para style="content">MAC address:</para></td><td><para style="content"><@attribute name="mac"@></para></td></tr>
8
<tr><td><para style="content">Network:</para></td><td><para style="content"><@resolve module="networks/network" dn-attribute="network" alternative="nicht zugewiesen"@><@attribute name="name"@><@/resolve@></para></td></tr>
9
<tr><td><para style="content">Inventory number:</para></td><td><para style="content"><@attribute name="inventoryNumber"@></para></td></tr>
10
</blockTable>
11
<spacer length="1cm"/>
12
\ihead{Hostname report}
(-)a/management/univention-directory-reports/templates/en_US/groups.rml (+42 lines)
Line 0    Link Here 
1
<para><h1>Group report: <@attribute name="name"@></h1></para>
2
<spacer length="1cm"/>
3
4
<blockTable style="mainTable">
5
<tr><td><h3>Group record: <@attribute name="name"@></h3></td></tr>
6
<tr><td><para style="content">Name:</para></td><td><para style="content"><@attribute name="name"@></para></td></tr>
7
<tr><td><para style="content">Description:</para></td><td><para style="content"><@attribute name="description" default="-"@></para></td></tr>
8
<tr><td><para style="content">Group ID:</para></td><td><para style="content"><@attribute name="gidNumber"@></para></td></tr>
9
<tr><td><para style="content">Relative ID:</para></td><td><para style="content"><@attribute name="sambaRID"@></para></td></tr>
10
<tr><td><para style="content">Group type:</para></td><td><para style="content"><@attribute name="sambaGroupType"@></para></td></tr>
11
<tr><td><para style="content">E-Mail address:</para></td><td><para style="content"><@attribute name="mailAddress" default="-"@></para></td></tr>
12
</blockTable>
13
14
<spacer length="0.5cm"/>
15
16
<h3>Member of the following groups</h3>
17
18
<@resolve module="groups/group" dn-attribute="memberOf" alternative="<para>This group is no member of any other group.</para>"@>
19
  <para bulletFontSize="5" bulletText="&#x25cf;"><@attribute name="name"@> (<@attribute name="description"@>)</para>
20
<@/resolve@>
21
22
23
<h3>Group members of this group</h3>
24
25
<@query module="groups/group" start="nestedGroup" next="nestedGroup" alternative="<para>No group is member of this group.</para>"@>
26
  <para bulletFontSize="5" bulletText="&#x25cf;"><@attribute name="name"@> (<@attribute name="description"@>)</para>
27
<@/query@>
28
29
<h3>User members of this group</h3>
30
31
<@resolve module="users/user" dn-attribute="users" alternative="<para>No user is member of this group.</para>"@>
32
  <para bulletFontSize="5" bulletText="&#x25cf;"><@attribute name="username"@> (<@attribute name="lastname"@>, <@attribute name="firstname"@>)</para>
33
<@/resolve@>
34
35
<@query module="groups/group" start="nestedGroup" next="nestedGroup" alternative="<para>No indirect group members.</para>"@>
36
  <h2>Group: <@attribute name="name"@> (<@attribute name="description"@>)</h2>
37
  <@resolve module="users/user" dn-attribute="users" alternative="<para>No members of this group.</para>"@>
38
    <para bulletFontSize="4" bulletText="&#x25cf;"><@attribute name="username"@> (<@attribute name="lastname"@>)</para>
39
  <@/resolve@>
40
<@/query@>
41
42
<nextFrame/>
(-)a/management/univention-directory-reports/templates/en_US/users.rml (+96 lines)
Line 0    Link Here 
1
<para><h1>User report: <@attribute name="lastname"@><@attribute name="firstname" prepend=", "@></h1></para>
2
<spacer length="1cm"/>
3
4
<blockTable style="mainTableOuter" colWidths="7.8cm,7.8cm">
5
<tr><td>
6
7
<blockTable style="mainTable" colWidths="3.5cm,4cm">
8
<tr><td><h3>User record: <@attribute name="lastname"@>, <@attribute name="firstname"@></h3></td> </tr>
9
<tr><td><para style="content">Name:</para></td><td><para style="content"><@attribute name="lastname"@><@attribute name="firstname" prepend=", "@></para></td> </tr>
10
<tr><td><para style="content">User name:</para></td><td><para style="content"><@attribute name="username"@></para></td></tr>
11
<tr><td><para style="content">Description:</para></td><td><para style="content"><@attribute name="description"@></para></td></tr>
12
<tr><td><para style="content">Organisation:</para></td><td><para style="content"><@attribute name="organisation"@></para></td></tr>
13
<tr><td><para style="content">Employee number:</para></td><td><para style="content"><@attribute name="employeeNumber"@></para></td></tr>
14
<tr><td><para style="content">Employee type:</para></td><td><para style="content"><@attribute name="employeeType"@></para></td></tr>
15
<tr><td><para style="content">Room number:</para></td><td><para style="content"><@attribute name="roomNumber"@></para></td></tr>
16
<tr><td><para style="content">Superior:</para></td><td><para style="content">
17
<@resolve module="users/user" dn-attribute="secretary" alternative=""@>
18
    <@attribute name="lastname"@><@attribute name="firstname" prepend=", "@>
19
<@/resolve@></para></td></tr>
20
</blockTable>
21
<spacer length="1cm"/>
22
23
24
<blockTable style="mainTable" colWidths="3.5cm,4cm">
25
<tr><td><h3>Contact</h3></td></tr>
26
<tr><td></td></tr>
27
<tr><td><para style="content">Phone:</para></td><td><para style="content"><@attribute name="phone"@> </para></td></tr>
28
<tr><td><para style="content">Mobile phone:</para></td><td><para style="content"><@attribute name="mobileTelephoneNumber"@></para></td></tr>
29
<tr><td><para style="content">Street:</para></td><td><para style="content"><@attribute name="street"@></para></td></tr>
30
<tr><td></td></tr>
31
</blockTable>
32
<spacer length="1cm"/>
33
34
<blockTable style="mainTable" colWidths="3.5cm,4cm">
35
<tr><td><h3>Account settings</h3></td></tr>
36
<tr><td><para style="content">Disabled:</para></td><td><para style="content"><@attribute name="disabled" default="No"@> </para></td></tr>
37
<tr><td><para style="content">Locked:</para></td><td><para style="content"><@attribute name="locked" default="No"@> </para></td></tr>
38
<tr><td><para style="content">Account expiry date:</para></td><td><para style="content"><@attribute name="userexpiry" default="Not set"@> </para></td></tr>
39
<tr><td><para style="content">Password expiry date:</para></td><td><para style="content"><@attribute name="passwordexpiry" default="Not set"@> </para></td></tr>
40
<tr><td><para style="content">Change password:</para></td><td><para style="content"><@attribute name="pwdChangeNextLogin" default="No"@> </para></td></tr>
41
</blockTable>
42
<spacer length="1cm"/>
43
44
</td><td>
45
46
<blockTable style="mainTable" colWidths="3.5cm,4cm">
47
<tr><td><h3>Linux/UNIX</h3></td></tr>
48
<tr><td><para style="content">User ID:</para></td><td><para style="content"><@attribute name="uidNumber"@> </para></td></tr>
49
<tr><td><para style="content">Group ID:</para></td><td><para style="content"><@attribute name="gidNumber"@></para></td></tr>
50
<tr><td><para style="content">Login shell:</para></td><td><para style="content"><@attribute name="shell"@> </para></td></tr>
51
<tr><td><para style="content">Home directory:</para></td><td><para style="content"><@attribute name="unixhome"@> </para></td></tr>
52
<tr><td><para style="content">Share path:</para></td><td><para style="content"><@attribute name="homeSharePath"@> </para></td></tr>
53
<tr><td><para style="content">Share:</para></td><td><para style="content"><@resolve module="shares/share" dn-attribute="homeShare"@>
54
    <@attribute name="printablename"@>
55
<@/resolve@></para></td></tr>
56
</blockTable>
57
58
<spacer length="1cm"/>
59
60
<blockTable style="mainTable" colWidths="3.5cm,4cm">
61
<tr><td><h3>Password policy</h3></td></tr>
62
<tr><td><para style="content">Inherited:</para></td><td><@policy module="policies/pwdhistory" inherited=""@> </td></tr>
63
<tr><td><para style="content">History length:</para></td><td><para style="content"><@attribute name="length"@></para></td></tr>
64
<tr><td><para style="content">Password length:</para></td><td><para style="content"><@attribute name="pwLength"@></para></td></tr>
65
<tr><td><para style="content">Expiry interval:</para></td><td><para style="content"><@attribute name="expiryInterval" default="-"@></para></td></tr>
66
</blockTable>
67
<spacer length="1cm"/>
68
69
<blockTable style="mainTable" colWidths="3.5cm,4cm">
70
<tr><td><h3>Mail</h3></td></tr>
71
<tr><td><para style="content">E-mail address:</para></td><td><para style="content"><@attribute name="mailPrimaryAddress" default="None"@> </para></td></tr>
72
<tr><td><para style="content">Alternative address:</para></td><td><para style="content"><@attribute name="mailAlternativeAddress" default="None"@> </para></td></tr>
73
<tr><td><para style="content">Global SPAM folder:</para></td><td><para style="content"><@attribute name="mailGlobalSpamFolder" default="-"@> </para></td></tr>
74
</blockTable>
75
<spacer length="1cm"/>
76
77
<blockTable style="mainTable" colWidths="3.5cm,4cm">
78
<tr><td><h3>Windows</h3></td></tr>
79
<tr><td><para style="content">Home directory:</para></td><td><para style="content"><@attribute name="sambahome"@> </para></td></tr>
80
<tr><td><para style="content">Home drive:</para></td><td><para style="content"><@attribute name="homedrive"@> </para></td></tr>
81
<tr><td><para style="content">Profile path:</para></td><td><para style="content"><@attribute name="profilepath"@> </para></td></tr>
82
<tr><td><para style="content">Logon script:</para></td><td><para style="content"><@attribute name="scriptpath"@> </para></td></tr>
83
<tr><td><para style="content">Relative ID:</para></td><td><para style="content"><@attribute name="sambaRID"@> </para></td></tr>
84
</blockTable>
85
86
</td></tr>
87
</blockTable>
88
89
90
<h3>Member of the following groups</h3>
91
92
<@query module="groups/group" start="groups" next="memberOf" regex="name=^[^(s\-)([a\-)(i\-)(h\-)]" alternative="<para>The user is not member of any other group</para>"@>
93
	<para bulletFontSize="5" bulletText="&#x25cf;"><b><@attribute name="name"@></b> (<@attribute name="description"@>)</para>
94
<@/query@>
95
96
<nextFrame/>
(-)a/management/univention-directory-reports/templates/en_US/users.tex (-1 / +1 lines)
 Lines 126-132   Relative ID & <@attribute name="sambaRID"@> \\ Link Here 
126
126
127
\section*{Member of the following groups}
127
\section*{Member of the following groups}
128
128
129
<@query module="groups/group" start="groups" next="memberOf" regex="name=^[^(s\-)([a\-)(i\-)(h\-)]" header="\begin{description}" footer="\end{description}" alternative="The user is not member of any other gropu"@>
129
<@query module="groups/group" start="groups" next="memberOf" regex="name=^[^(s\-)([a\-)(i\-)(h\-)]" header="\begin{description}" footer="\end{description}" alternative="The user is not member of any other group"@>
130
  \item[<@attribute name="name"@>] (<@attribute name="description"@>)
130
  \item[<@attribute name="name"@>] (<@attribute name="description"@>)
131
<@/query@>
131
<@/query@>
132
132
(-)a/management/univention-directory-reports/univention-directory-reports (-91 / +37 lines)
 Lines 31-49    Link Here 
31
# /usr/share/common-licenses/AGPL-3; if not, see
31
# /usr/share/common-licenses/AGPL-3; if not, see
32
# <http://www.gnu.org/licenses/>.
32
# <http://www.gnu.org/licenses/>.
33
33
34
import univention.debug as ud
34
import sys
35
35
import locale
36
from optparse import OptionParser
36
from optparse import OptionParser
37
37
38
import os
38
import univention.debug as ud
39
import sys
39
import univention.admin.uldap
40
40
41
import univention.directory.reports as udr
41
from univention.directory.reports import Report, ReportError, Config
42
from univention.config_registry import ConfigRegistry
42
from univention.config_registry import ConfigRegistry
43
43
44
from univention.lib.i18n import Translation
45
_ = Translation('univention-directory-reports').translate
44
46
45
baseConfig = ConfigRegistry()
47
ucr = ConfigRegistry()
46
baseConfig.load()
48
ucr.load()
47
49
48
50
49
def dump_modules(cfg, module=None, out=sys.stdout):
51
def dump_modules(cfg, module=None, out=sys.stdout):
 Lines 53-65   def dump_modules(cfg, module=None, out=sys.stdout): Link Here 
53
	else:
55
	else:
54
		modules = [module]
56
		modules = [module]
55
	for module in modules:
57
	for module in modules:
56
		print >>out, 'Reports for module: %s' % module
58
		print >> out, 'Reports for module: %s' % module
57
		for name in cfg.get_report_names(module):
59
		for name in cfg.get_report_names(module):
58
			print >>out, ' - %s' % name
60
			print >> out, ' - %s' % name
59
61
60
62
61
def main():
63
def main():
62
	cfg = udr.Config()
64
	cfg = Config()
63
65
64
	parser = OptionParser(usage='usage: %prog -m <module> [options] dn1 dn2 ...')
66
	parser = OptionParser(usage='usage: %prog -m <module> [options] dn1 dn2 ...')
65
	parser.add_option(
67
	parser.add_option(
 Lines 80-90   def main(): Link Here 
80
		help='file containing the footer for the report')
82
		help='file containing the footer for the report')
81
	parser.add_option(
83
	parser.add_option(
82
		'-s', '--server', action='store',
84
		'-s', '--server', action='store',
83
		dest='server', default=baseConfig.get('ldap/server/name', 'localhost'),
85
		dest='server', default=ucr.get('ldap/server/name', 'localhost'),
84
		help='LDAP server [%default]')
86
		help='LDAP server [%default]')
85
	parser.add_option(
87
	parser.add_option(
86
		'-b', '--base', action='store',
88
		'-b', '--base', action='store',
87
		dest='base', default=baseConfig.get('ldap/base', ''),
89
		dest='base', default=ucr.get('ldap/base', ''),
88
		help='LDAP base [%default]')
90
		help='LDAP base [%default]')
89
	parser.add_option(
91
	parser.add_option(
90
		'-m', '--module', action='store',
92
		'-m', '--module', action='store',
 Lines 99-108   def main(): Link Here 
99
		dest='list_reports', default=False,
101
		dest='list_reports', default=False,
100
		help='List names of available reports')
102
		help='List names of available reports')
101
	parser.add_option(
103
	parser.add_option(
102
		'-n', '--no-cleanup', action='store_true',
103
		dest='no_cleanup', default=False,
104
		help='do not remove the temporary LaTeX files (for debugging)')
105
	parser.add_option(
106
		'-c', '--config', action='store',
104
		'-c', '--config', action='store',
107
		dest='config', default='/etc/univention/directory/reports/config.ini',
105
		dest='config', default='/etc/univention/directory/reports/config.ini',
108
		help='location of the configuration file [%default]')
106
		help='location of the configuration file [%default]')
 Lines 113-208   def main(): Link Here 
113
111
114
	(options, args) = parser.parse_args()
112
	(options, args) = parser.parse_args()
115
113
116
	if not options.user or not options.password:
114
	ud.init('/var/log/univention/directory-reports.log', ud.FLUSH, ud.FUNCTION)
117
		try:
118
			pwdfile = '/etc/machine.secret'
119
			options.user = baseConfig['ldap/hostdn']
120
			if baseConfig['server/role'] == 'domaincontroller_master':
121
				pwdfile = '/etc/ldap.secret'
122
				options.user = 'cn=admin,%s' % baseConfig['ldap/base']
123
			fd = open(pwdfile, 'r')
124
			options.password = fd.readline()[: -1]
125
			fd.close()
126
		except:
127
			print >>sys.stderr, "error: user and/or password not specified"
128
			parser.print_help(sys.stderr)
129
			sys.exit(1)
130
131
	ud.init('/var/log/univention/directory-reports.log', 1, 1)
132
	ud.set_level(ud.ADMIN, options.debug)
115
	ud.set_level(ud.ADMIN, options.debug)
133
116
134
	cfg = udr.Config(options.config)
117
	locale.setlocale(locale.LC_ALL, locale.getdefaultlocale())
118
119
	cfg = Config(options.config)
135
120
136
	if options.list_reports:
121
	if options.list_reports:
137
		dump_modules(cfg, options.module)
122
		dump_modules(cfg, options.module)
138
		sys.exit(0)
123
		sys.exit(0)
139
124
140
	template = cfg.get_report(options.module, options.report)
141
	if template is None:
142
		parser.print_usage(sys.stderr)
143
		if options.module is None:
144
			print >>sys.stderr, "error: module not specified (use -m)"
145
		elif options.module not in cfg._reports:
146
			print >>sys.stderr, "error: specified module '%s' does not exist" % options.module
147
			options.module = None
148
		elif options.report is not None:
149
			report_entry = cfg._get_report_entry(options.module, options.report)
150
			if report_entry is None:
151
				print >>sys.stderr, "error: specified report '%s' does not exist" % options.report
152
			else:
153
				print >>sys.stderr, "error: specified report '%s' is unavailable" % options.report
154
				name, dir, filename = report_entry
155
				if not os.path.exists(filename):
156
					print >>sys.stderr, "Template file '%s' seems to be missing." % filename
157
				else:
158
					print >>sys.stderr, "Check settings in file '%s'." % cfg._filename
159
				sys.exit(2)
160
		else:
161
			print >>sys.stderr, "error: no report found for module '%s'" % options.module
162
		dump_modules(cfg, options.module, sys.stderr)
163
		sys.exit(2)
164
165
	if not args:
125
	if not args:
166
		parser.print_usage(sys.stderr)
126
		parser.print_usage(sys.stderr)
167
		print >>sys.stderr, "error: no DNs specified on command line"
127
		print >> sys.stderr, _("Error: no DNs specified on command line")
168
		sys.exit(2)
128
		sys.exit(2)
169
129
170
	udr.admin.connect(options.user, options.password, host=options.server, base=options.base, start_tls=0)
130
	# FIXME: why is start_tls=0 used here?
131
	if options.user and options.password:
132
		lo = univention.admin.uldap.access(host=options.server, base=options.base, binddn=options.user, bindpw=options.password, start_tls=0)
133
	else:
134
		try:
135
			if ucr['server/role'] == 'domaincontroller_master':
136
				lo, po = univention.admin.uldap.getAdminConnection(start_tls=0)
137
			else:
138
				lo, po = univention.admin.uldap.getMachineConnection(start_tls=0)
139
		except IOError:
140
			print >> sys.stderr, _("Error: user and/or password not specified")
141
			parser.print_help(sys.stderr)
142
			sys.exit(1)
171
143
144
	report = Report(lo, config=cfg)
172
	try:
145
	try:
173
		if options.header is None:
146
		filename = report.create(options.module, options.report, args)
174
			options.header = cfg.get_header(options.module, options.report)
147
	except ReportError as exc:
175
		if options.footer is None:
148
		print >> sys.stderr, _("Error: The %s report could not be created: %s") % (options.report, exc)
176
			options.footer = cfg.get_footer(options.module, options.report)
177
		doc = udr.Document(template, header=options.header, footer=options.footer)
178
	except NameError as e:  # missing file
179
		print >>sys.stderr, e
180
		sys.exit(1)
149
		sys.exit(1)
181
	tmpfile = doc.create_source(args)
182
	if doc._type == udr.Document.TYPE_LATEX:
183
		type = 'PDF'
184
		outfile = doc.create_pdf(tmpfile)
185
		if options.no_cleanup:
186
			print >>sys.stderr, 'kept temporary source file at %s' % tmpfile
187
		else:
188
			basefile = tmpfile.rsplit('.', 1)[0]  # strip suffix
189
			for file in [tmpfile] + ['%s.%s' % (basefile, suffix) for suffix in ('aux', 'log')]:
190
				try:
191
					os.unlink(file)
192
				except OSError as e:
193
					pass
194
	elif doc._type == udr.Document.TYPE_CSV:
195
		type = 'CSV'
196
		outfile = tmpfile
197
	else:
198
		type = ''
199
		outfile = tmpfile
200
150
201
	if os.path.exists(outfile):
151
	print _('The %s has been created: %s') % (options.report, filename)
202
		print 'created %s file: %s' % (type, outfile)
203
	else:
204
		print >>sys.stderr, "error: report could not be created"
205
		sys.exit(1)
206
152
207
153
208
if __name__ == "__main__":
154
if __name__ == "__main__":
(-)a/management/univention-management-console-module-udm/umc/js/udm/CreateReportDialog.js (-13 / +3 lines)
 Lines 224-246   define([ Link Here 
224
224
225
			this.set('title', _('Creating the report ...'));
225
			this.set('title', _('Creating the report ...'));
226
226
227
			var request_data = {objects: this.objects, report: options.report};
227
			this.standbyDuring(this.umcpCommand('udm/reports/create', {objects: this.objects, report: options.report}, this._form)).then(lang.hitch(this, function(data) {
228
			this.standbyDuring(this.umcpCommand('udm/reports/create', request_data, this._form)).then(lang.hitch(this, function(data) {
229
				var title = '';
230
				var message = '';
231
232
				this._container.removeChild(this._form);
228
				this._container.removeChild(this._form);
233
				this._container.removeChild(waiting);
229
				this._container.removeChild(waiting);
234
				waiting.destroy();
230
				waiting.destroy();
235
231
236
				if (true === data.result.success) {
232
				var message = lang.replace('<p>{0}</p>', [_standbyDuringSuccessText(options.report, data.result.URL)]);
237
					message = lang.replace('<p>{0}</p>', [_standbyDuringSuccessText(data.result.docType, data.result.URL)]);
233
				this.set('title', _('Report has been created'));
238
					title = _('Report has been created');
239
				} else {
240
					title = _('Report creation has failed');
241
					message = _('The report could not be created. Details for the problems can be found in the log files.');
242
				}
243
				this.set('title', title);
244
				this._container.addChild(new Text({content: message}));
234
				this._container.addChild(new Text({content: message}));
245
235
246
				var btnContainer = new ContainerWidget({
236
				var btnContainer = new ContainerWidget({
(-)a/management/univention-management-console-module-udm/umc/python/udm/__init__.py (-44 / +20 lines)
 Lines 51-57    Link Here 
51
from univention.management.console.modules.decorators import simple_response, sanitize, multi_response, prevent_xsrf_check
51
from univention.management.console.modules.decorators import simple_response, sanitize, multi_response, prevent_xsrf_check
52
from univention.management.console.modules.sanitizers import (
52
from univention.management.console.modules.sanitizers import (
53
	Sanitizer, LDAPSearchSanitizer, EmailSanitizer, ChoicesSanitizer,
53
	Sanitizer, LDAPSearchSanitizer, EmailSanitizer, ChoicesSanitizer,
54
	ListSanitizer, StringSanitizer, DictSanitizer, BooleanSanitizer
54
	ListSanitizer, StringSanitizer, DictSanitizer, BooleanSanitizer,
55
	DNSanitizer
55
)
56
)
56
from univention.management.console.modules.mixins import ProgressMixin
57
from univention.management.console.modules.mixins import ProgressMixin
57
from univention.management.console.log import MODULE
58
from univention.management.console.log import MODULE
 Lines 579-640   def _thread(request): Link Here 
579
580
580
	def reports_query(self, request):
581
	def reports_query(self, request):
581
		"""Returns a list of reports for the given object type"""
582
		"""Returns a list of reports for the given object type"""
582
		self.finished(request.id, self.reports_cfg.get_report_names(request.flavor))
583
		self.finished(request.id, sorted(self.reports_cfg.get_report_names(request.flavor)))
583
584
584
	def sanitize_reports_create(self, request):
585
	def sanitize_reports_create(self, request):
585
		choices = self.reports_cfg.get_report_names(request.flavor)
586
		choices = self.reports_cfg.get_report_names(request.flavor)
586
		return dict(
587
		return dict(
587
			report=ChoicesSanitizer(choices=choices, required=True),
588
			report=ChoicesSanitizer(choices=choices, required=True),
588
			objects=ListSanitizer(StringSanitizer(minimum=1), required=True, min_elements=1)
589
			objects=ListSanitizer(DNSanitizer(minimum=1), required=True, min_elements=1)
589
		)
590
		)
590
591
591
	@sanitize_func(sanitize_reports_create)
592
	@sanitize_func(sanitize_reports_create)
592
	def reports_create(self, request):
593
	def reports_create(self, request):
593
		"""Creates a report for the given LDAP DNs and returns the file
594
		"""Creates a report for the given LDAP DNs and returns the URL to access the file"""
594
595
		requests.options = {}
596
			'report' -- name of the report
597
			'objects' -- list of LDAP DNs to include in the report
598
599
		return: report file
600
		"""
601
595
602
		@LDAP_Connection
596
		@LDAP_Connection
603
		def _thread(request, ldap_connection=None, ldap_position=None):
597
		def _thread(request, ldap_connection=None, ldap_position=None):
604
			udr.admin.connect(access=ldap_connection)
598
			report = udr.Report(ldap_connection)
605
			udr.admin.clear_cache()
606
			cfg = udr.Config()
607
			template = cfg.get_report(request.flavor, request.options['report'])
608
			doc = udr.Document(template, header=cfg.get_header(request.flavor, request.options['report']), footer=cfg.get_footer(request.flavor, request.options['report']))
609
			tmpfile = doc.create_source(request.options['objects'])
610
			if doc._type == udr.Document.TYPE_LATEX:
611
				doc_type = _('PDF document')
612
				pdffile = doc.create_pdf(tmpfile)
613
				os.unlink(tmpfile)
614
			else:
615
				doc_type = _('text file')
616
				pdffile = tmpfile
617
			try:
599
			try:
618
				os.unlink(tmpfile[: -4] + 'aux')
600
				report_file = report.create(request.flavor, request.options['report'], request.options['objects'])
619
				os.unlink(tmpfile[: -4] + 'log')
601
			except udr.ReportError as exc:
620
			except:
602
				raise UMC_Error(str(exc))
621
				pass
603
622
			if pdffile:
604
			www_data_user = pwd.getpwnam('www-data')
623
				path = '/var/www/univention-directory-reports'
605
			www_data_grp = grp.getgrnam('www-data')
624
				shutil.copy(pdffile, path)
606
			path = '/var/www/univention-directory-reports/'
625
				os.unlink(pdffile)
607
			filename = os.path.join(path, os.path.basename(report_file))
626
608
627
				www_data_user = pwd.getpwnam('www-data')
609
			shutil.move(report_file, path)
628
				www_data_grp = grp.getgrnam('www-data')
610
			os.chown(filename, www_data_user.pw_uid, www_data_grp.gr_gid)
629
				filename = os.path.join(path, os.path.basename(pdffile))
611
			os.chmod(filename, 0o644)
630
				os.chown(filename, www_data_user.pw_uid, www_data_grp.gr_gid)
612
			url = '/univention-directory-reports/%s' % os.path.basename(report_file)
631
				os.chmod(filename, 0o644)
613
			return {'URL': url}
632
				url = '/univention-directory-reports/%s' % os.path.basename(pdffile)
633
				# link = '<a target="_blank" href="%s">%s (%s)</a>' % ( url, module.name, request.options[ 'report' ] )
634
635
				return {'success': True, 'count': len(request.options['objects']), 'URL': url, 'docType': doc_type}
636
			else:
637
				return {'success': False, 'count': 0, 'URL': None, 'docType': doc_type}
638
614
639
		thread = notifier.threads.Simple('ReportsCreate', notifier.Callback(_thread, request), notifier.Callback(self.thread_finished_callback, request))
615
		thread = notifier.threads.Simple('ReportsCreate', notifier.Callback(_thread, request), notifier.Callback(self.thread_finished_callback, request))
640
		thread.run()
616
		thread.run()

Return to bug 39239