UCS3.1: Migration von Dojo 1.8 auf 2.0

german
integration

#1

Hallo,

ich bin grad dabei unser Asterisk4UCS Modul für das AppCenter flott zu machen.
Leider bin ich bei der Migration von Dojo auf ein Problem gestoßen, dass ich so nicht lösen kann.

Ich bekomme folgende Fehlermeldung:

Uncaught TypeError: Object [object Object] has no method 'appendChild' 	dojo.js:2
_1a86.buildRendering 										dojo.js:2
_11cd 	 												dojo.js:2
_abc.buildRendering 	 										dojo.js:2
_13a4.create 	 											dojo.js:2
_13a4.postscript 	 										dojo.js:2
a 	 													dojo.js:2
_11e4 	 												dojo.js:2
a 	 													dojo.js:2
(anonymous function) 									 asteriskUser.js:41
_c6 	 													dojo.js:2
_36 	 													dojo.js:2
_36 	 													dojo.js:2
_7b 	 													dojo.js:2
_37 	 													dojo.js:2
_7b 	 													dojo.js:2
_ee 	 													dojo.js:2
req.injectUrl._108											dojo.js:2

Ich kann so mit dieser Fehlermeldung leider nicht anfangen. Zu erst hatte ich die Vermutung, dass es an der Funktion addChild
leider war das nicht der Fall.

Folgend der SourceCode um den es geht:

[code]/*
Copyright © 2012 DECOIT GmbH asterisk4ucs@decoit.de

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

//dojo.provide(“umc.modules.asteriskUser”);

//dojo.require(“umc.widgets.Module”);
//dojo.require(“umc.widgets.ContainerWidget”);
//dojo.require(“umc.widgets.Page”);
//dojo.require(“umc.widgets.Form”);
//dojo.require(“umc.widgets.Grid”);

//dojo.declare(“umc.modules.asteriskUser”, [ umc.widgets.Module ], {
define([
“dojo”,
“dojo/_base/declare”,
“dojo/_base/lang”,
"dojo/base/array",
“umc/widgets/Module”,
“umc/widgets/ContainerWidget”,
“umc/widgets/Page”,
“umc/widgets/Form”,
“umc/widgets/Grid”,
“umc/widgets/TabContainer”,
“umc/widgets/ExpandingTitlePane”
],
function(declare,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,
){
return declare(“umc.modules.asteriskUser”,[ Module ],{
_buttons: null,
_mailboxHint: null,
_mailboxForm: null,
_grid: null,
_forms: [],

	buildRendering: function () {
		this.inherited(arguments);

		this._buttons = [{
			name: 'submit',
			label: "Speichern",
			callback: lang.hitch(this, function () {
				this.save();
			}),
		}];

		this._forms = [];

		var tabContainer = new umc.widgets.TabContainer({
			nested: true
		});

		

		tabContainer.addChild(this.renderPhones());

		tabContainer.addChild(this.renderMailbox());

		tabContainer.addChild(this.renderForwarding());
		this.addChild(tabContainer);

		this.startup();
		this.load();
	},
	renderMailbox: function () {
		var page = new umc.widgets.Page({
			title: "Anrufbeantworter",
			headerText: "Anrufbeantwortereinstellungen",
			footerButtons: this._buttons,
			closable: false,
		});

		var container = new umc.widgets.ContainerWidget({
			scrollable: true,
		});
		page.addChild(container);

		var noMailboxHint = new umc.widgets.Text({
			content: "Leider hat Ihnen der Administrator keinen " +
				"Anrufbeantworter zugewiesen.",
			region: "top",
		});
		container.addChild(noMailboxHint);
		this._mailboxHint = noMailboxHint;

		var widgets = [{
			type: 'TextBox',
			name: 'mailbox/password',
			label: "PIN-Nummer zum Abrufen",
		}, {
			type: 'ComboBox',
			name: 'mailbox/email',
			label: "Per eMail benachrichtigen?",
			staticValues: [
				{ id: '0', label: "Nein" },
				{ id: '1', label: "Ja, gerne!" },
			],
		}, {
			type: 'ComboBox',
			name: 'mailbox/timeout',
			label: "Mailbox antwortet nach",
			staticValues: [
				{ id:   '5', label: "5 Sekunden" },
				{ id:  '10', label: "10 Sekunden" },
				{ id:  '20', label: "20 Sekunden" },
				{ id:  '30', label: "30 Sekunden" },
				{ id:  '45', label: "45 Sekunden" },
				{ id:  '60', label: "einer Minute" },
				{ id: '120', label: "zwei Minuten" },
				{ id: '180', label: "π Minuten" },
			],
		}];

		var layout = [
			'mailbox/password',
			'mailbox/email',
			'mailbox/timeout'
		];

		var form = new umc.widgets.Form({
			widgets: widgets,
			layout: layout,
			scrollable: true,
		});
		container.addChild(form);
		this._forms.push(form);
		this._mailboxForm = form;

		this._mailboxForm.domNode.style.display = 'none';
		this._mailboxHint.domNode.style.display = 'block';

		return page;
	},
	renderPhones: function () {
		var page = new umc.widgets.Page({
			title: "Telefone",
			headerText: "Telefoneinstellungen",
			footerButtons: this._buttons,
			closable: false,
		});

		var container = new umc.widgets.ExpandingTitlePane({
			title: "Klingelreihenfolge",
		});
		page.addChild(container);

		this._grid = new umc.widgets.Grid({
			moduleStore: umc.store.getModuleStore("dn",
				"asteriskUser/phones"),
			query: {
				filter:'*',
			},
			columns: [{
				name: 'position',
				label: "Position",
				editable: false,
				hidden: true,
			}, {
				name: 'name',
				label: "Telefon",
				editable: false,
			}],
			actions: [{
				name: 'earlier',
				label: "Früher",
				isStandardAction: true,
				canExecute: lang.hitch(this, function (values) {
					return values.position > 0;
				}),
				callback: lang.hitch(this, function (id) {
					this._grid.filter({
						dn: id,
						position: -1,
					});
				}),
			}, {
				name: 'later',
				label: "Später",
				isStandardAction: true,
				canExecute: lang.hitch(this, function (values) {
					return (values.position + 1 <
						this._grid._grid.rowCount);
				}),
				callback: lang.hitch(this, function (id) {
					this._grid.filter({
						dn: id,
						position: 1,
					});
				}),
			}],
		});
		container.addChild(this._grid);
		foo = this._grid;

		this._grid._grid.canSort = function (index) {
			return false;
		};

		var widgets = [{
			type: 'ComboBox',
			name: 'phones/interval',
			label: "Klingelintervall",
			staticValues: [
				{ id:   '2', label:  "2 Sekunden" },
				{ id:   '4', label:  "4 Sekunden" },
				{ id:   '6', label:  "6 Sekunden" },
				{ id:   '8', label:  "8 Sekunden" },
				{ id:  '10', label: "10 Sekunden" },
			],
		}];

		var layout = [
			'phones/interval',
		];

		var form = new umc.widgets.Form({
			region: 'top',
			widgets: widgets,
			layout: layout,
			scrollable: true,
		});
		page.addChild(form);
		this._forms.push(form);

		page.startup();
		return page;
	},
	renderForwarding: function () {
		var page = new umc.widgets.Page({
			title: "Weiterleitung",
			headerText: "Weiterleitungseinstellungen",
			footerButtons: this._buttons,
			closable: false,
		});

		var container = new umc.widgets.ContainerWidget({
			scrollable: true,
		});
		page.addChild(container);

		var widgets = [{
			type: 'TextBox',
			name: 'forwarding/number',
			label: "Weiterleitungsziel",
		}];

		var layout = [
			'forwarding/number'
		];

		var form = new umc.widgets.Form({
			widgets: widgets,
			layout: layout,
			scrollable: true,
		});
		container.addChild(form);
		this._forms.push(form);

		return page;
	},
	setValues: function (values) {
		array.forEach(this._forms, function (form) {
			form.setFormValues(values);
		}, this);

		// disable the mailbox form if needed
		if (values.mailbox) {
			this._mailboxForm.domNode.style.display = 'block';
			this._mailboxHint.domNode.style.display = 'none';
		} else {
			this._mailboxForm.domNode.style.display = 'none';
			this._mailboxHint.domNode.style.display = 'block';
		}
	},
	getValues: function () {
		var values = {};
		array.forEach(this._forms, function (form) {
			lang.mixin(values, form.gatherFormValues());
		}, this);
		return values;
	},
	load: function () {
		this.umcpCommand('asteriskUser/load').then(
			lang.hitch(this, function (data) {
				this.setValues(data.result);
			}),
			lang.hitch(this, function () {
				// hm...
			})
		);
	},
	save: function () {
		var data = this.getValues();
		this.umcpCommand('asteriskUser/save', data);
	},
});

});
[/code]

Hat vllt. einer noch eine Idee für mich?

Vielen Danke für die Hilfe schon mal!

Gruß,
Marcel


#2

Hallo!

Ich habe die Wiki-Seite zur Portierung von UMC-Modulen noch etwas aktualisiert (sie ist noch nicht ganz fertig und Anregungen sind gerne willkommen), sie gibt sicherlich einige Hilfestellungen: wiki.univention.de/Dojo_1.8_migration

Zum Debuggen am besten die URL my-ucs-server/univention-managem … sole/debug benutzen. So wird eine nicht komprimierte JavaScript-Datei eingebunden und Tracebacks können sinnvoll verfolgt werden. Intern benutzen wir zur Entwicklung gerne Chromium, da seine Entwicklerwerkzeuge und insb. der Debugger gut und performant funktionieren. Damit lässt sich dann auch im Traceback sagen wo genau der Fehler entstand.

Ein Problem kann sein, dass this.startup() in buildRendering() aufgerufen wird. Das ist nicht notwendig, da startup() automatisch aufgerufen wird sobald das Modul in den überliegenden Container hinzugefügt wird.

Es kann übrigens statt umc/widgets/Module auch direkt umc/widgets/TabbedModule genommen werden, dann ist das Modul-Widget direkt schon ein TabContainer.

In der Funktion define() scheint noch die Referenz für die Übersetzungsfunktion _() zu fehlen: “umc/i18n!..”

Ich hoffe das hilft bei der Fehlersuche weiter!

Mit besten Grüßen
Alexander Kläser


#3

Hallo,
danke für die Hilfe, es hatte weitergeholfen. :slight_smile:

ich hab “schon” wieder ein Problem, welches sich mir nicht erschließt.

Ich nutze folgende Funktion in meiner JS-Datei:

this._grid = new umc.widgets.Grid({ moduleStore: umc.store.getModuleStore("dn", "asteriskUser/phones"), query: { filter:'*', },...

Die Funktion “getModuleStore” wird mir aber als Fehler “is not a function” angezeigt. Aus eurem SVN konnte ich
herrausfinden, dass ich unter define “umc/store” einbinden sollte und die Funktion auf

moduleStore: store("dn","/phones"),...

ändern muss. Leider führen die Änderungen dazu, dass mir das Modul/App nicht mehr in der management console angezeigt wird.
Hast Du vllt. eine Ahnung woran das liegen könnte?

Den ganzen Quellcode kann man unter https://github.com/decoit/asterisk4ucs/blob/master/asterisk4ucs-umc-user/umc/js/ finden.
Den wollt ich jetzt nicht schon wieder hier Posten :wink:

Gruß,
Marcel


#4

Hi!

Ja, jshint / jslint hilft hier weiter, hier meine Ausgabe:

### jshint asteriskUser.js.orig ###
Trailing whitespace. (asteriskUser.js.orig:40:3)
> ],

Extra comma. (asteriskUser.js.orig:57:15)
> }),

Extra comma. (asteriskUser.js.orig:83:28)
> closable: false,

Extra comma. (asteriskUser.js.orig:87:29)
> scrollable: true,

Extra comma. (asteriskUser.js.orig:94:26)
> region: "top",

Extra comma. (asteriskUser.js.orig:102:44)
> label: "PIN-Nummer zum Abrufen",

Extra comma. (asteriskUser.js.orig:109:48)
> { id: '1', label: "Ja, gerne!" },

Extra comma. (asteriskUser.js.orig:110:14)
> ],

Extra comma. (asteriskUser.js.orig:123:49)
> { id: '180', label: "π Minuten" },

Extra comma. (asteriskUser.js.orig:124:14)
> ],

Extra comma. (asteriskUser.js.orig:136:29)
> scrollable: true,

Extra comma. (asteriskUser.js.orig:152:28)
> closable: false,

Extra comma. (asteriskUser.js.orig:156:40)
> title: "Klingelreihenfolge",

Extra comma. (asteriskUser.js.orig:164:26)
> filter:'*',

Extra comma. (asteriskUser.js.orig:170:28)
> hidden: true,

Extra comma. (asteriskUser.js.orig:174:31)
> editable: false,

Extra comma. (asteriskUser.js.orig:186:34)
> position: -1,

Extra comma. (asteriskUser.js.orig:188:18)
> }),

Extra comma. (asteriskUser.js.orig:200:33)
> position: 1,

Extra comma. (asteriskUser.js.orig:202:18)
> }),

Extra comma. (asteriskUser.js.orig:203:15)
> }],

Extra comma. (asteriskUser.js.orig:221:51)
> { id:  '10', label: "10 Sekunden" },

Extra comma. (asteriskUser.js.orig:222:14)
> ],

Extra comma. (asteriskUser.js.orig:226:30)
> 'phones/interval',

Extra comma. (asteriskUser.js.orig:233:29)
> scrollable: true,

Extra comma. (asteriskUser.js.orig:246:28)
> closable: false,

Extra comma. (asteriskUser.js.orig:250:29)
> scrollable: true,

Extra comma. (asteriskUser.js.orig:257:40)
> label: "Weiterleitungsziel",

Extra comma. (asteriskUser.js.orig:267:29)
> scrollable: true,

Extra comma. (asteriskUser.js.orig:308:8)
> },

'define' is not defined. (asteriskUser.js.orig:27:1)
> define([

'umc' is not defined. (asteriskUser.js.orig:62:33)
> var tabContainer = new umc.widgets.TabContainer({

'umc' is not defined. (asteriskUser.js.orig:79:25)
> var page = new umc.widgets.Page({

'umc' is not defined. (asteriskUser.js.orig:86:30)
> var container = new umc.widgets.ContainerWidget({

'umc' is not defined. (asteriskUser.js.orig:91:34)
> var noMailboxHint = new umc.widgets.Text({

'umc' is not defined. (asteriskUser.js.orig:133:25)
> var form = new umc.widgets.Form({

'umc' is not defined. (asteriskUser.js.orig:148:25)
> var page = new umc.widgets.Page({

'umc' is not defined. (asteriskUser.js.orig:155:30)
> var container = new umc.widgets.ExpandingTitlePane({

'umc' is not defined. (asteriskUser.js.orig:160:27)
> this._grid = new umc.widgets.Grid({

'foo' is not defined. (asteriskUser.js.orig:206:10)
> foo = this._grid;

'umc' is not defined. (asteriskUser.js.orig:229:25)
> var form = new umc.widgets.Form({

'umc' is not defined. (asteriskUser.js.orig:242:25)
> var page = new umc.widgets.Page({

'umc' is not defined. (asteriskUser.js.orig:249:30)
> var container = new umc.widgets.ContainerWidget({

'umc' is not defined. (asteriskUser.js.orig:264:25)
> var form = new umc.widgets.Form({

'ContainerWidget' is defined but never used. (asteriskUser.js.orig:41:57)
> function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){

'Page' is defined but never used. (asteriskUser.js.orig:41:62)
> function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){

'Form' is defined but never used. (asteriskUser.js.orig:41:67)
> function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){

'Grid' is defined but never used. (asteriskUser.js.orig:41:72)
> function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){

'TabContainer' is defined but never used. (asteriskUser.js.orig:41:85)
> function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){

'ExpandingTitlePane' is defined but never used. (asteriskUser.js.orig:41:104)
> function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){

Too many errors. (13% scanned). (asteriskUser.js.orig:41:104)
> 

Wichtig, am Ende einer Liste darf (nicht wie in Python) kein Komma mehr folgen! Das sind Syntaxfehler, dadurch kann die Datei nicht mehr geladen werden und wird nicht angezeigt (in UMC). Auf der JS-Fehler-Konsole (Chromium oder Firebug) werden Syntaxfehler auch angezeigt (kann sein, dass dies durch die AMD-Technik auch verschluckt wird, habe ich auch schon beobachtet). Ansonsten sollten alle Referenzen wie bspw. umc.. entfernt werden, da die entsprechenden Klassen ja in dem Scope der Modul-Callback-Funktion zur Verfügung stehen (d.h. umc.widgets.Form → Form, umc.widgets.Grid → Grid etc.).

Alle Labels können entsprechend angepasst werden, dass sie auf Englisch und Deutsch verfügbar sind. Dazu müssen sie nur entsprechend angepasst werden, bspw.:

+++ asteriskUser.js     2012-12-05 13:32:24.797585987 +0100
@@ -51,7 +51,7 @@
 
          this._buttons = [{
             name: 'submit',
-            label: "Speichern",
+            label: _("Save"),
             callback: lang.hitch(this, function () {
                this.save();
             }),

In dem Modul wird dann automatisch eine de.po-Datei erzeugt, in der dann nur die Übersetzungen eingetragen werden. Es reicht dh-umc-module-build oder dpkg-buildpackage aufzurufen, dann werden die .po-Dateien aktualisiert.

Das waren die Dinge, die mir direkt aufgefallen sind. Einfach mit jshint durchchecken (wie im Wiki beschrieben), das hilft immer sehr weiter.

Viele Grüße
Alexander Kläser


#5

Hey,

Danke die Tipps waren Gold wert! :slight_smile:

Die Anpassungen der Labels werde ich erstmal noch verschieben, bis das Modul dann auch funktioniert.

Ein Fehler wirft mir jslint nun noch aus der sich mir nicht ergibt.

[code]‘define’ is not defined. (asterisk4ucs-umc-user/umc/js/asteriskUser.js:27:1)

define([
[/code]

Vor der Zeile wird nach meinem Verständnis allerdings nichts mehr definiert!

Der aktuellen Code ist wieder auf GitHub zu finden.

Gruß,
Marcel


#6

Hi!

Super :slight_smile: !

Der jslint-Fehler ist OK, define ist ja auch nicht definiert. Dazu kann am Anfang der JS-Datei die folgende Zeile eingefügt werden (siehe auch auf der jshint-Webseite):

/*global define require*/

Damit weiß jslint, dass define und require zwar nicht definiert sind, aber ignoriert werden können.

Ansonsten sieht der Code auf den ersten Blick gut aus. Funktioniert das Modul wie erwartet?

Die folgende (unkritische) Dinge sind mir aufgefallen, die noch angepasst werden könnten. Statt noMailBoxHint kann die Funktion addNote(…) für die Page benutzt werden, dadurch wird ein entsprechend gestylter Hinweis-Text am Anfang der Page eingeblendet (das wird bspw. in /usr/share/univention-management-console-frontend/js/umc/modules/setup/CertificatePage.js verwendet). Hier noch ein paar mögliche Kosmetikvorschläge:

--- asteriskUser.js.orig	2012-12-05 19:00:51.818035649 +0100
+++ asteriskUser.js	2012-12-05 19:46:50.454098594 +0100
@@ -28,18 +28,17 @@
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/_base/array",
-   "umc/widgets/Module",
+   "umc/widgets/TabbedModule",
    "umc/widgets/ContainerWidget",
    "umc/widgets/Page",
    "umc/widgets/Form",
    "umc/widgets/Grid",
-   "umc/widgets/TabContainer",
    "umc/widgets/ExpandingTitlePane",
    "umc/store",
-   "umc/i18n!umc/modules/umc"
+   "umc/i18n!umc/modules/asteriskUser"
 ],
-function(declare,store,lang,array,Module,ContainerWidget,Page,Form,Grid,TabContainer,ExpandingTitlePane,_){
-   return declare("umc.modules.asteriskUser",[ Module ],{
+function(declare,store,lang,array,TabbedModule,ContainerWidget,Page,Form,Grid,ExpandingTitlePane,_){
+   return declare("umc.modules.asteriskUser",[ TabbedModule ],{
       _buttons: null,
       _mailboxHint: null,
       _mailboxForm: null,
@@ -60,18 +59,11 @@
 
          this._forms = [];
 
-         var tabContainer = new TabContainer({
-            nested: true
-         });
-
-         
-
-         tabContainer.addChild(this.renderPhones());
+         this.addChild(this.renderPhones());
 
-         tabContainer.addChild(this.renderMailbox());
+         this.addChild(this.renderMailbox());
 
-         tabContainer.addChild(this.renderForwarding());
-         this.addChild(tabContainer);
+         this.addChild(this.renderForwarding());
 
          //this.startup();
          this.load();
@@ -237,7 +229,7 @@
          page.addChild(form);
          this._forms.push(form);
 
-         page.startup();
+         //page.startup();
          return page;
       },
       renderForwarding: function () {
@@ -295,18 +287,26 @@
          return values;
       },
       load: function () {
+		 this.standby(true);
          this.umcpCommand('asteriskUser/load').then(
             lang.hitch(this, function (data) {
+			   this.standby(false);
                this.setValues(data.result);
             }),
             lang.hitch(this, function () {
                // hm...
+			   this.standby(false);
             })
          );
       },
       save: function () {
+		 this.standby(true);
          var data = this.getValues();
-         this.umcpCommand('asteriskUser/save', data);
+         this.umcpCommand('asteriskUser/save', data).then(lang.hitch(this, function() {
+			 this.standby(false);
+		 }), lang.hitch(this, function() {
+			 this.standby(false);
+		 }));
       }
    });
 });

startup() wird automatisch aufgerufen, addChild() prüft ob das Container-Widget (in diesem Fall das Modul selber) schon gestartet wurde, wenn ja wird die startup() das hinzugefügten Elementes direkt aufgerufen. Wenn nicht wird so lange gewartet bis startup() für den übergeordneten Container selber aufgerufen wird.

Hoffe jetzt klappt’s :slight_smile: .

Viele Grüße
Alexander Kläser


#7

Hey,

danke für die guten Tips.

Jslint zeigt mir nun keine “wichtigen” Fehler mehr an sondern nur “unused” Dinge.

Leider wird mir das entsprechende Modul dennoch nicht in der Management Console angezeigt und auch der Chrome
gibt keine Fehler an.

Gruß und schönen Nikolaus,
Marcel


#8

Hallo!

Ok. Bei der Installation eines Moduls wird über ein Join-Skript im LDAP (via UDM) ein sogenanntes UMC-Operation-Set erzeugt. Normalerweise gibt es einen Eintrag pro Modul mit dem Eintrag operation=mymoduleid/*. Wenn das UMC-Modul über ein Debian-Paket auf einem Master-System installiert wird, wird das Join-Skript im postinst Skript des Paketes automatisch ausgeführt, so dass die Informationen im LDAP existieren sollten. Bitte einmal überprüfen, ob dies der Fall ist:

udm settings/umc_operationset list | grep -e DN -e operation:

Taucht dort ein entsprechender Eintrag für das Modul auf (mit der korrekten ID)? Wenn nicht, bitte einmal univention-run-join-scripts ausführen.

Wenn dies alles soweit OK ist, bitte einmal nach dem Einloggen auf der JS-Konsole folgenden Befehl ausführen:

require('umc/tools').umcpCommand('get/modules/list').then(function(res) {
    res.modules.forEach(function(imod) {
        console.log(imod.id, '-', imod.name);
    });
});

Dieser fragt die Liste aller vorhandenen Module ab und gibt sie aus. Dort sollte auch das asterisk-Modul ausgegeben werden (also asteriskUser, wenn ich das richtig sehe).

Ist dies nicht der Fall, dann deutet dies darauf hin, dass die entsprechenden Rechte für das Modul dem Benutzer nicht zugewiesen wurden. Das oben erwähnte Join-Skript hängt das erstellt Operation-Set an die Default-UMC-Policy für Administratoren, damit alle Administratoren das Modul sehen können. Bitte einmal überprüfen, ob dies der Fall ist:

udm policies/umc list --filter cn=default-umc-all

Dort sollte dann das UMC-Operation-Set für das Modul eingetragen sein. Ist dies nicht der Fall, kann dies zunächst manuell durchgeführt werden über das UDM-Richtlinien-Modul (dort die Richtlinie default-umc-all auswählen und das Asterisk-Operation-Set hinzufügen). Allerdings sollte dies automatisch durch das Join-Skript bei der Installation erledigt werden. Ist dies nicht der Fall, bitte auch einmal das Join-Skript überprüfen.

Wird in der Liste aller vorhandenen Module das Modul aber mit ausgegeben, deutet dies auf einen JS-Fehler hin, der durch das AMD-System verschluckt wird. Ich könnte dann noch einmal auf den JS-Code schauen, um den Fehler zu suchen.

Hoffe das hilft weiter.

Viele Grüße und einen schönen Nikolaus zurück
o<():o)>>
Alexander Kläser


#9

Hey Danke für die guten Tipps!

Leider scheinen die Module tatsächlich installiert zu sein, denn sie werden alle angezeigt:

[code]udm settings/umc_operationset list | grep -e DN -e operation:

DN: cn=asteriskDeploy-all,cn=operations,cn=UMC,cn=univention,dc=decoit,dc=test
operation: asteriskDeploy/*
DN: cn=udm-asterisk,cn=operations,cn=UMC,cn=univention,dc=decoit,dc=test
operation: udm/* objectType=asterisk/*
DN: cn=asteriskUser-all,cn=operations,cn=UMC,cn=univention,dc=decoit,dc=test
operation: asteriskUser/*
DN: cn=asteriskMusic-all,cn=operations,cn=UMC,cn=univention,dc=decoit,dc=test
operation: asteriskMusic/*
[/code]

[code]require(‘umc/tools’).umcpCommand(‘get/modules/list’).then(function(res) {
res.modules.forEach(function(imod) {
console.log(imod.id, ‘-’, imod.name);
});
});

asteriskMusic - Asterisk4UCS Warteschlangenmusiken

asteriskUser - Telefoneinstellungen
asteriskDeploy - Asterisk4UCS Deployment

udm - Asterisk

udm - Passwort ändern
[/code]

Ich habe nun auch die anderen Module soweit angepasst. Natürlich werden diese nicht angezeigt auf der Web Management Console! :wink:

Bei AstersikDeploy gibt mir Jslint so auch keine kritischen Fehler aus nur bei AsteriskMusic kommen folgende Fehler:

[code]‘prompt’ is not defined. (asterisk4ucs-umc-music/umc/js/asteriskMusic.js:80:32)

var name = prompt(“Bitte geben Sie den Namen für die neue Musikklasse ein:”);

‘window’ is not defined. (asterisk4ucs-umc-music/umc/js/asteriskMusic.js:119:21)

window.setTimeout(lang.hitch(this, function() {

‘console’ is not defined. (asterisk4ucs-umc-music/umc/js/asteriskMusic.js:172:13)

console.log(this);
[/code]

Sind das wieder Sachen die über den global Befehl am Anfang der Datei beseitigt werden?

Danke für die gute Hilfe!

Gruß,
Marcel

EDIT: Der aktuelle Code liegt auf GitHub!


#10

Hi!

Folgender Fehler ist mir aufgefallen, die Zuweisungen der Dependencies waren nicht korrekt:

--- asterisk4ucs-master/asterisk4ucs-umc-user/umc/js/asteriskUser.js    2012-11-29 01:46:31.000000000 +0100
+++ asterisk4ucs-master.mod/asterisk4ucs-umc-user/umc/js/asteriskUser.js        2012-12-07 10:25:42.868000090 +0100
@@ -30,7 +30,7 @@
    "umc/store",
    "umc/i18n!umc/modules/asteriskUser"
 ],
-function(declare,store,lang,array,Text,TabbedModule,ContainerWidget,Page,Form,Grid,ExpandingTitlePane){
+function(declare,lang,array,TabbedModule,ContainerWidget,Page,Form,Grid,ExpandingTitlePane,Text,store,_){
    return declare("umc.modules.asteriskUser",[ TabbedModule ],{
       _buttons: null,
       _mailboxHint: null,

Danach ging es bei mir.

Viele Grüße
Alexander Kläser


#11

Hi!

Ja das war die Lösung für das User Modul! :slight_smile:

Leider werden mir die beiden anderen Module auch nach diesem Tipp nicht angezeigt.

Im Browser werden mir auch diese Beiden Fehler angezeigt:

GET http://10.10.253.116/univention-management-console/js_$20122911024349$/umc/dialog/notify.js 404 (Not Found) dojo.js.uncompressed.js:1662 GET http://10.10.253.116/univention-management-console/js_$20122911024349$/umc/dialog/alert.js 404 (Not Found) dojo.js.uncompressed.js:1662 Error dojo.js.uncompressed.js:1821 src: dojoLoader dojo.js.uncompressed.js:1824 info: ["js_$20122911024349$/umc/dialog/notify.js", Event ] dojo.js.uncompressed.js:1824 . dojo.js.uncompressed.js:1826 Error dojo.js.uncompressed.js:1821 src: dojoLoader dojo.js.uncompressed.js:1824 info: ["js_$20122911024349$/umc/dialog/alert.js", Event ] dojo.js.uncompressed.js:1824 .

Notify und Alert verwende ich in asteriskMusic und asteriskDeploy.

Kann ich sein das ich die falschen Dependencies eingebunden habe?

asteriskDeploy: https://github.com/decoit/asterisk4ucs/tree/master/asterisk4ucs-umc-deploy/umc/js
asteriskMusic: https://github.com/decoit/asterisk4ucs/tree/master/asterisk4ucs-umc-music/umc/js


#12

Super :slight_smile: !

Ja, als Dependency reicht folgendes aus:

require(["umc/dialog"], function(dialog) {
    dialog.notify('Notification');
    dialog.alert('Alert);
})

Gruß
Alexander Kläser


#13

Ja das waren die Fehler in den JS Dateien! :wink:

Nun hab ich wohl noch mit Python ein paar Probleme aber die muss ich erstmal analysieren.

Ich danke aber schon mal für die Hilfe!

Gruß,
Marcel


#14

Das freut mich zu hören :slight_smile: !

Viele Grüße
Alexander Kläser


#15

So nun hab ich doch noch ein Problem was ich nicht lösen kann.

In asteriskMusic gibt es einen Musicupload. Dieser upload funktioniert leider nicht er bricht mit folgender Fehlermeldung ab:

[code]Die Ausführung des Kommandos asteriskMusic/upload ist fehlgeschlagen:

Traceback (most recent call last):
File “/usr/lib/pymodules/python2.6/univention/management/console/modules/init.py”, line 204, in execute
func( request )
File “/usr/lib/pymodules/python2.6/univention/management/console/modules/asteriskMusic/init.py”, line 121, in upload
stem = re.sub(r".\w+$", “”, filename)
File “/usr/lib/python2.6/re.py”, line 151, in sub
return _compile(pattern, 0).sub(repl, string, count)
TypeError: expected string or buffer[/code]

Der Chrome gibt folgendes aus:

POST http://10.10.253.116/umcp/command/asteriskMusic/upload 500 (Internal Server Error) dojo.js.uncompressed.js:53812 xhr dojo.js.uncompressed.js:53812 exports.addCommonMethods.array.forEach.provider.(anonymous function) dojo.js.uncompressed.js:63693 lang.mixin.umcpCommand dojo.js.uncompressed.js:16825 declare.buildRendering.widgets.onUploaded asteriskMusic.js:130 lang.hitch dojo.js.uncompressed.js:37276 declare.postCreate dojo.js.uncompressed.js:25092 lang.hitch dojo.js.uncompressed.js:37276 target.(anonymous function).dispatcher dojo.js.uncompressed.js:65770 (anonymous function) dojo.js.uncompressed.js:38628 lang.hitch

Was ich nun schon herausgefunden habe ist, dass der filename wohl nicht übertragen wird an das phython Skript.

Es gibt in der asteriskMusic.js eine Funktion die postCreate heißt in dieser wird der filename eigentlich gesetzt. Leider konnte ich bisher nicht herrausfinden, warum genau diese Funktion nicht
funktioniert.

Hast du vllt. eine Idee was da falsch ist?

Der aktuelle code ist hier: https://github.com/decoit/asterisk4ucs/tree/master/asterisk4ucs-umc-music/umc/

Gruß,
Marcel


#16

Hallo!

Euer momentaner Code benutzt den Default-Upload, der die Daten einfach wieder zurück an den Browser sendet, so dass die Daten in JS zur Verfügung stehen. Dann ruft ihr in onUploaded ein UMCP-Befehl noch einmal auf, so dass alle Daten noch ein zweites Mal an den Server gesendet werden. Günstiger wäre es, die Daten nur einmal an den Server zu senden. Die Python-Backend-Funktion erhält dann den Pfad einer temporären Datei, die weiter verarbeitet werden kann. Das ist günstiger. Beispiele für Upload-Funktionalitäten finden sich im UDM-UMC-Modul (die Funktion license_import()) sowie im USC@school-Materialverteilungsmodul (die Funktion upload). Die Funktion license_import() ist insofern etwas komplexer, da sie mit Uploads und auch normalen Requests zurecht kommt.

Zu dem Traceback kann ich nichts genaues sagen. Wie sehen denn die Options aus, die der Funktion übergeben werden? Bspw. über die folgende Zeile im Logfile ausgeben lassen:

from univention.management.console.log import MODULE
...
def upload(...)
    MODULE.error('### request.options: %s' % request.options)
    ...

Die Ausgabe wird dann in /var/log/univention/management-console-module-…log geloggt.

Hoffe das hilft weiter.

Viele Grüße
Alexander Kläser


#17

Da liegt das Problem die Options enthalten alles bis auf den ‘filename’ dieser wird mir ‘None’ angegeben. Das ist auch das Problem
und das was der Traceback aussagt. Der Name des Files ist nicht gesetzt. Das es jetzt zweimal zum Server geschickt wird ist
vllt. unglücklich aber nicht das eigentliche Problem zu mal es in der “alten” Version wunderbar Funktioniert hatte. Das werde ich
aber dann auch mal Anpassen. Im Moment liegt mir erstmal was daran, dass so anzupassen, damit es unter UCS 3.1 zuverlässig
Funktioniert!

Upload Options: {'moh': 'cn=cool,cn=Testserver,cn=asterisk,dc=decoit,dc=test', 'data': '//uQRAAAAq ... gICAgICAgICAgICAgIBE=', 'filename': None}

EDIT:
Muss mich korrigieren das mit dem zweimal Senden hatte den Hintergrund, dass wir die Datei noch konvertieren und im konvertierten
Zustand wieder zurück senden.

Gruß

Marcel


#18

Moin,
Um mich mal abzulenken habe ich nun ein anderes Modul angepasst das asteriskDeploy.

Leider traf ich da auch auf Probleme. Im Prinzip ist es so das gleiche wie in asteriskMusic. Der Name des Server ist in Python nicht da:

MODULE      ( ERROR   ) : ### request: REQUEST/135773063481925-48/27/application/json: COMMAND asteriskDeploy/create {"options": {"server": ""}}

Allerdings ist mir diesmal aufgefallen, dass im JavaSkript auch ein Fehler auftaucht:

declare._startAction asteriskDeploy.js:137

Das lässt mich nun vermuten das der umcpCommand nicht funktioniert was dann, soweit ich das bisher Verstanden habe, auch erklären könnte warum der Name bzw. die Auswahl der
ComboBox nicht übertragen wird.

Die entsprechende Codestelle wäre:

[code]_startAction: function (action, args) {

		this._form.getWidget("server")._setDisabledAttr(true);
//		this._form.getWidget("copyid")._setDisabledAttr(true);
		this._form.getWidget("create")._setDisabledAttr(true);
		this._form.getWidget("deploy")._setDisabledAttr(true);
		
		var call = tools.umcpCommand(action, args);
		call.then(lang.hitch(this, function (data) {
			this._stopAction();
			dialog.notify("Befehl ausgeführt; Siehe Logdatei im unteren Teil des Fensters");
		}), lang.hitch(this, function (data) {
			this._stopAction();
			dialog.notify(this._form.getWidget("server").get("value"));
		}));
	},[/code]

Erkennst du den Fehler an der Stelle? Ich habe schon in euren Sourcen mal nachgeforscht aber leider nicht wirklich was gefunden.

Der Aktuelle Code ist wieder auf Github zu finden: https://github.com/decoit/asterisk4ucs/blob/master
Direkter Link zu asteriskDeploy: https://github.com/decoit/asterisk4ucs/blob/master/asterisk4ucs-umc-deploy/umc/js/asteriskDeploy.js

Gruß,
Marcel


#19

Hi,

so nach langem und zähem Debugging habe ich es geschafft die Module anzupassen und zum laufen zu bringen.

Danke nochmal für die Hilfe :wink:

Gruß,
Marcel


#20

Moin!

Gerne geschehen. Das ist schön zu hören! Die zuletzt gestellten Fragen haben sich ebenfalls erledigt?

Viele Grüße aus Bremen
Alexander Kläser