def update_params(self, d): super(StompWidget, self).update_params(d) d.topics = [] d.onmessageframe = defaultdict(str) # {topic: 'js callbacks'} for callback in self.callbacks: if len(moksha.livewidgets[callback]): cbs = '' if callback == 'onmessageframe': for topic in moksha.livewidgets[callback]: d.topics.append(topic) for cb in moksha.livewidgets[callback][topic]: d.onmessageframe[topic] += '%s;' % str(cb) else: for cb in moksha.livewidgets[callback]: if isinstance(cb, (js_callback, js_function)): cbs += '$(%s);' % str(cb) else: cbs += str(cb) if cbs: d[callback] = cbs if d.notify: moksha_notify.register_resources() d.onopen = js_callback( 'function() { $.jGrowl("Moksha live socket connected") }') d.onerror = js_callback( 'function(error) { $.jGrowl("Moksha Live Socket Error: " + error) }' ) d.onerrorframe = js_callback( 'function(f) { $.jGrowl("Error frame received from Moksha Socket: " + f) }' ) d.onclose = js_callback( 'function(c) { $.jGrowl("Moksha Socket Closed") }')
def update_params(self, d): super(StompWidget, self).update_params(d) d.topics = [] d.onmessageframe = defaultdict(str) # {topic: 'js callbacks'} for callback in self.callbacks: if len(moksha.livewidgets[callback]): cbs = '' if callback == 'onmessageframe': for topic in moksha.livewidgets[callback]: d.topics.append(topic) for cb in moksha.livewidgets[callback][topic]: d.onmessageframe[topic] += '%s;' % str(cb) else: for cb in moksha.livewidgets[callback]: if isinstance(cb, (js_callback, js_function)): cbs += '$(%s);' % str(cb) else: cbs += str(cb) if cbs: d[callback] = cbs if d.notify: moksha_notify.register_resources() d.onopen = js_callback('function() { $.jGrowl("Moksha live socket connected") }') d.onerror = js_callback('function(error) { $.jGrowl("Moksha Live Socket Error: " + error) }') d.onerrorframe = js_callback('function(f) { $.jGrowl("Error frame received from Moksha Socket: " + f) }') d.onclose = js_callback('function(c) { $.jGrowl("Moksha Socket Closed") }')
class OrbitedWidget(Widget): params = { 'onopen': 'A javascript callback for when the connection opens', 'onread': 'A javascript callback for when new data is read', 'onclose': 'A javascript callback for when the connection closes', } onopen = onread = onclose = js_callback('function(){}') javascript = [orbited_js] template = """ <script type="text/javascript"> Orbited.settings.port = %(port)s Orbited.settings.hostname = '%(host)s' document.domain = document.domain TCPSocket = Orbited.TCPSocket connect = function() { conn = new TCPSocket() conn.onread = ${onread} conn.onopen = ${onopen} conn.onclose = ${onclose} conn.open('%(host)s', %(port)s) } $(document).ready(function() { connect() }) </script> """ % { 'port': orbited_port, 'host': orbited_host }
def get_all(self): ''' List all fax ''' grid = MyJqGrid( id='grid', url='fetch', caption=u"Télécopies", sortname='created', sortorder='desc', colNames = [u'Action', u'Type', u'Destinataire(s)', u'Origine', u'Fichier', u'Commentaires', u'Date', u'Télécharg.' ], colModel = [ { 'width': 60, 'align': 'center', 'sortable': False }, { 'name': 'type', 'width': 60 }, { 'name': 'dest', 'width': 100 }, { 'name': 'src', 'width': 100 }, { 'name': 'filename', 'width': 100 }, { 'name': 'comment', 'width': 280 }, { 'name': 'created', 'width': 120 }, { 'width': 60, 'align': 'center', 'sortable': False }, ], navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u"Liste des télécopies", debug='')
def update_params(self, d): super(AsynchronousJQPlotWidget, self).update_params(d) if not d.get('id'): d['id'] = 'asynch_jqplot_%s' % str(int(random() * 999)) if not d.get('src_url'): raise ValueError, "AsynchronousJQPlotWidget must have a data url" src_url = d.get('src_url') url_kw = d.get('url_kw') if not url_kw: url_kw = {} data = d.get('data') if not data: data = [[[0,0]]] options = d.get('options') if not options: options = {} interval = d.get('interval') if not interval: interval = -1 callback = js_callback('function (json){%s}' % self.callback_reset % d.id) ajres = '$.getJSON(\'%s\', %s, %s)' % (src_url, url_kw, callback) self.add_call( js_function('%s ='%d.id)( js_function('$.jqplot')( "%s" % d.id, data, options))) if interval > 0 : self.add_call(js_function('setInterval')(ajres, interval))
def get_all(self): ''' List all ''' grid = MyJqGrid( id='grid', url='fetch', caption=u'Services', colNames = [u'Action', u'Prénom', u'Nom', u'Société', u'Téléphone(s)', u'@ email', u'Privé'], colModel = [ { 'width': 80, 'align': 'center', 'sortable': False, 'search': False }, { 'name': 'firstname', 'width': 80 }, { 'name': 'lastname', 'width': 80 }, { 'name': 'company', 'width': 120 }, { 'name': 'phones', 'width': 160, 'search': False, 'sortable': False }, { 'name': 'email', 'width': 160 }, { 'name': 'private', 'width': 40, 'search': False }, ], sortname = 'lastname', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), }, search_options = { 'caption': "Rechercher...", 'Find': "Chercher", 'Reset': "RAZ", 'sopt': ['cn', 'nc'], 'odata' : ['equal', 'not equal', 'less', 'less or equal','greater','greater or equal', 'begins with','does not begin with','is in','is not in','ends with','does not end with','contient','ne contient pas'], 'groupOps': [ {'op': "AND", 'text': "all"}, {'op': "OR", 'text': "any"} ], 'matchText': " match", 'rulesText': " rules" }, ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u'Annuaire téléphonique', debug='')
def get_all(self): """ List all applications """ grid = MyJqGrid( id="grid", url="fetch", caption="Applications (SVI)", sortname="name", sortorder="asc", colNames=[u"Action", u"Application", u"Extension", u"Numéro", u"Active", u"Scenario"], colModel=[ {"width": 60, "align": "center", "sortable": False}, {"name": "name", "width": 120}, {"name": "exten", "width": 40}, {"name": "dnis", "width": 40}, {"name": "active", "width": 280}, {"display": u"Scénario", "width": 60, "sortable": False}, ], navbuttons_options={ "view": False, "edit": False, "add": True, "del": False, "search": False, "refresh": True, "addfunc": js_callback("add"), }, ) tmpl_context.grid = grid tmpl_context.form = None return dict(title=u"Liste des applications", debug="")
class MokshaLiveFeedTree(Dynatree): title = 'Moksha Live Feed Tree' rootVisible = True persist = True fx = {'height': 'toggle', 'duration': 200} initAjax = { 'url': '/apps/feeds/init_tree', 'data': {'key': 'root'} } onActivate = js_callback("function(dtnode) { moksha.send_message('moksha.feeds', {action: 'get_feed', 'key': dtnode.data.key, topic: moksha_feed_topic}); }") #def __init__(self, *args, **kw): # Dynatree.__init__(self, *args, **kw) # self.template += """ # <script> # var moksha_feed_topic = "${topic}"; # </script> # """ # #LiveWidget.__init__(self, *args, **kw) def update_params(self, d): # the unique queue to use over our stomp TCPSocket d['topic'] = str(uuid4()) Dynatree.update_params(self, d)
def get_all(self): ''' List all users ''' if not in_group('admin'): redirect( str(request.identity['user'].user_id) + '/edit') grid = MyJqGrid( id='grid', url='fetch', caption=u'Utilisateurs', colNames = [u'Action', u'Compte', u'Nom', u'email', u'Poste', u'Groupes'], colModel = [ { 'sortable': False, 'search': False, 'width': 80, 'align': 'center' }, { 'name': 'user_name', 'width': 80 }, { 'name': 'display_name', 'width': 120 }, { 'name': 'email_address', 'width': 180 }, { 'name': 'phone', 'width': 60, 'sortable': False, 'search': False }, { 'name': 'groups', 'width': 160, 'sortable': False, 'search': False } ], sortname = 'user_name', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None tmpl_context.count = u'Total : %d utilisateurs' % DBSession.query(User).count() return dict( title=u'Liste des utilisateurs', debug='')
def when_ready(func): """ Takes a js_function and returns a js_callback that will run when the document is ready. >>> from tw.api import js_function >>> print when_ready(js_function('jQuery')('foo').bar({'biz': 'baz'})) $(document).ready(function(){jQuery("foo").bar({"biz": "baz"})}); """ return js_callback('$(document).ready(function(){' + str(func) + '});')
def when_ready(func): """ Takes a js_function and returns a js_callback that will run when the document is ready. >>> from tw.api import js_function >>> print when_ready(js_function('jQuery')('foo').bar({'biz': 'baz'})) $(document).ready(function(){jQuery("foo").bar({"biz": "baz"})}); """ return js_callback("$(document).ready(function(){" + str(func) + "});")
def get_all(self): ''' List all phones ''' if Globals.manager is None: flash(u'Vérifier la connexion Asterisk', 'error') else: # Refresh Asterisk peers Globals.manager.sippeers() Globals.manager.send_action({'Action': 'DeviceStateList'}) grid = MyJqGrid( id='grid', url='fetch', caption=u'Téléphones', sortname='exten', colNames = [u'Action', u'Modèle', u'Poste', u'Numéro direct', u'Utilisateur', u'Service'], colModel = [ { 'width': 80, 'align': 'center', 'search': False, 'sortable': False }, { 'name': 'ua', 'width': 140, 'search': False, 'sortable': False }, { 'name': 'exten', 'width': 60 }, { 'name': 'dnis', 'width': 60 }, { 'name': 'user_id', 'width': 120, 'search': False }, { 'name': 'department_id', 'width': 120, 'search': False }, ], postData = {'unavailable_only': js_callback('''\ function() { return $('#unavailable_only').attr('checked');}\ ''')}, # Don't display deleted campaigns by default navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), }, subGrid = True, subGridUrl = 'fetch_detail', subGridModel = [{ 'name': [u'Compte SIP', u'Secret SIP', u'Adresse IP', u'Adresse MAC'], 'width': [100, 100, 100, 100] }], ) tmpl_context.grid = grid # tmpl_context.form = None # tmpl_context.count = u'Total : %d téléphones' % DBSession.query(Phone).count() return dict( title=u'Liste des téléphones', debug='')
def update_params(self, d): super(MokshaContainer, self).update_params(d) if isinstance(d.content, Widget): d.widget_name = d.content.__class__.__name__ content_args = getattr(d, 'content_args', {}) if isinstance(d.content, LiveWidget): topics = d.content.get_topics() # FIXME: also unregister the moksha callback functions. Handle # cases where multiple widgets are listening to the same topics d.onClose = js_callback("function(o){%s $(o).remove();}" % unsubscribe_topics(topics)) d.onIconize = d.onCollapse = js_callback( "function(o){%s}" % unsubscribe_topics(topics)) d.onRestore = js_callback("function(o){%s}" % subscribe_topics(topics)) d.content = d.content.display(**content_args) for option in self.options: d[option] = d.get(option, True) and option or '' d.buttons = '' for button in self.button_options: if d.get(button, True): d.buttons += '%s,' % button[:1] d.buttons = d.buttons[:-1] d.id = str(uuid.uuid4()) self.add_call( jQuery('#%s' % d.id).buildContainers({ 'elementsPath': '/toscawidgets/resources/moksha.widgets.container.container/static/css/elements/', 'onClose': d.onClose, 'onResize': d.onResize, 'onCollapse': d.onCollapse, 'onIconize': d.onIconize, 'onDrag': d.onDrag, 'onRestore': d.onRestore, }))
def update_params(self, d): super(MokshaContainer, self).update_params(d) if isinstance(d.content, Widget): d.widget_name = d.content.__class__.__name__ content_args = getattr(d, 'content_args', {}) if isinstance(d.content, LiveWidget): topics = d.content.get_topics() # FIXME: also unregister the moksha callback functions. Handle # cases where multiple widgets are listening to the same topics d.onClose = js_callback("function(o){%s $(o).remove();}" % unsubscribe_topics(topics)) d.onIconize = d.onCollapse = js_callback("function(o){%s}" % unsubscribe_topics(topics)) d.onRestore = js_callback("function(o){%s}" % subscribe_topics(topics)) d.content = d.content.display(**content_args) for option in self.options: d[option] = d.get(option, True) and option or '' d.buttons = '' for button in self.button_options: if d.get(button, True): d.buttons += '%s,' % button[:1] d.buttons = d.buttons[:-1] d.id = str(uuid.uuid4()) self.add_call(jQuery('#%s' % d.id).buildContainers({ 'elementsPath': '/toscawidgets/resources/moksha.widgets.container.container/static/css/elements/', 'onClose': d.onClose, 'onResize': d.onResize, 'onCollapse': d.onCollapse, 'onIconize': d.onIconize, 'onDrag': d.onDrag, 'onRestore': d.onRestore, }))
class MokshaAjaxFeedTree(Dynatree): title = 'Moksha Ajax Feed Tree' rootVisible = True persist = True initAjax = { 'url': '/apps/feeds/init_tree', 'data': {'key': 'root'} } onActivate = js_callback(""" function(dtnode) { $('#TopPane').load('/apps/feeds/get_entries?key=' + dtnode.data.key.replace(/ /, '')); } """.replace('\n', ''))
def update_params(self, d): super(AutoCompleteField, self).update_params(d) if not getattr(d,"id",None): raise ValueError, "AutocompleteField is supposed to have id" if (self.fetchJSON): json_callback = js_callback('function(data) {$("#%s").autocomplete(data["data"]);}' % d.id) call = js_function('$.getJSON')(self.completionURL, json_callback) self.add_call(call) else: self.add_call( jQuery('#%s' % d.id).autocomplete(self.completionURL,dict(minChars=self.minChars,selectFirst=self.selectFirst,cacheLength=self.cacheLength,extraFields=self.extraFields)) )
class MokshaLiveFeedEntriesTree(Dynatree): rootVisible = False persist = True onActivate = js_callback(""" function(dtnode) { moksha.send_message('moksha.feeds', { 'action': 'get_entry', 'key': dtnode.data.key, topic: moksha_feed_topic }); /* Unsubscribe from current feed, subscribe to new one */ } """.replace('\n', ''))
def update_params(self, d): super(TextField, self).update_params(d) if not getattr(d, "id", None): raise ValueError, "Slider must have id" container = '%s_container' % d.id self.add_call(js_callback('$("#%s").slider({ \ min: %d, max: %d, step: 1, range: false, \ value: $("#%s").val(), \ slide: function (event, ui) { \ jQuery("#%s").val(ui.value);\ } \ })' % (container, self.min, self.max, d.id, d.id))) jQuery = js_function('jQuery') input = jQuery("#%s" % d.id) self.add_call(input.css("display", "none"))
def update_params(self, d): super(TextField, self).update_params(d) if not getattr(d, "id", None): raise ValueError, "Slider must have id" container = '%s_container' % d.id self.add_call( js_callback('$("#%s").slider({ \ min: %d, max: %d, step: 1, range: false, \ value: $("#%s").val(), \ slide: function (event, ui) { \ jQuery("#%s").val(ui.value);\ } \ })' % (container, self.min, self.max, d.id, d.id))) jQuery = js_function('jQuery') input = jQuery("#%s" % d.id) self.add_call(input.css("display", "none"))
def get_all(self): ''' List all groups ''' grid = MyJqGrid( id='grid', url='fetch', caption=u'Profils', colNames = [u'Action', u'Nom', u'Description', u'Utilisateurs'], colModel = [ { 'sortable': False, 'search': False, 'width': 80, 'align': 'center' }, { 'name': 'group_name', 'width': 80 }, { 'name': 'display_name', 'width': 160 }, { 'name': 'users', 'sortable': False, 'search': False, 'width': 160 } ], sortname = 'group_name', navbuttons_options = {'view': False, 'edit': False, 'add': False, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u'Liste des groupes', debug='', values=None)
def get_all(self): ''' List all holidays ''' grid = MyJqGrid( id='grid', url='fetch', caption=u'Jours fériés', colNames = [u'Action', u'Nom', u'Date'], colModel = [ { 'width': 80, 'align': 'center', 'sortable': False, 'search': False }, { 'name': 'name', 'width': 80 }, { 'name': 'date', 'width': 60 }, ], sortname = 'date', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': False, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u'Liste des jours fériés', debug='')
def get_all(self): ''' List all departments ''' grid = MyJqGrid( id='grid', url='fetch', caption=u'Services', colNames = [u'Action', u'Nom court', u'Nom complet', u'Téléphones',], colModel = [ { 'width': 80, 'align': 'center', 'sortable': False, 'search': False }, { 'display': u'Nom court', 'name': 'name', 'width': 80 }, { 'display': u'Nom complet', 'name': 'comment', 'width': 160 }, { 'display': u'Téléphones', 'width': 500, 'sortable': False, 'search': False } ], sortname = 'name', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u'Liste des services', debug='')
def get_all(self): ''' List all queues ''' grid = MyJqGrid( id='grid', url='fetch', caption=u'Groupes ACD', colNames = [u'Action', u'Nom', u'Priorité', u'Description'], colModel = [ { 'width': 80, 'align': 'center', 'sortable': False, 'search': False }, { 'display': u'Nom', 'name': 'name', 'width': 80 }, { 'display': u'Priorité', 'name': 'priority', 'width': 60 }, { 'display': u'Description', 'name': 'comment', 'width': 160 }, ], sortname = 'name', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': False, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u'Liste des groupes d\'appels', debug='')
def get_all(self): ''' List call forwards ''' grid = MyJqGrid( id='grid', url='fetch', caption = u'Renvois', sortname='id', sortorder='asc', colNames = [u'Action', u'Extension', u'Renvoi', u'Vers' ], colModel = [ { 'width': 60, 'align': 'center', 'sortable': False }, { 'name': 'exten', 'width': 60 }, { 'name': 'type', 'width': 60 }, { 'name': 'to', 'width': 100 }, ], navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': False, 'refresh': True, 'addfunc': js_callback('add')}, ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u"Renvois", debug='', values='')
def get_all(self): ''' List all shortcuts ''' grid = MyJqGrid( id='grid', url='fetch', caption=u'Numéros raccourcis', colNames = [u'Action', u'Description', u'Raccourci', u'Numéro réel'], colModel = [ { 'width': 80, 'align': 'center', 'sortable': False, 'search': False }, { 'name': 'comment', 'width': 160 }, { 'name': 'exten', 'width': 80 }, { 'name': 'number', 'width': 80 }, ], sortname = 'exten', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': False, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u'Liste des raccourcis', debug='')
def get_all(self): ''' List all moh ''' grid = MyJqGrid( id='grid', url='fetch', caption=u"Sons et musiques d\'attente", sortname='name', sortorder='asc', colNames = [u'Action', u'Type', u'Langue', u'Nom', u'Commentaires', u'\u00C9coute' ], colModel = [ { 'width': 60, 'align': 'center', 'sortable': False }, { 'name': 'type', 'width': 60 }, { 'name': 'language', 'width': 60 }, { 'name': 'name', 'width': 60 }, { 'name': 'comment', 'width': 280 }, { 'width': 60, 'align': 'center', 'sortable': False }, ], navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': True, 'refresh': True, 'addfunc': js_callback('add'), } ) tmpl_context.grid = grid tmpl_context.form = None return dict( title=u"Liste des sons & musiques d'attente", debug='')
def test_attr_mixed_in_chain_call(self): proto = js_function('$') iframe = js_callback('window.frames.my_iframe') call = proto('my_component').ajax.load_in(iframe) expected = '$("my_component").ajax.load_in(window.frames.my_iframe)' self.failUnlessEqual(str(call), expected)
re_pro = re.compile(r'CLIPRO') grid = MyJqGrid( id='grid', url='fetch', caption=u'Campagnes', colNames = [u'Action', u'Nom', u'Active', u'Type', u'Statistiques'], colModel = [ { 'width': 80, 'align': 'center', 'sortable': False, 'search': False }, { 'name': 'name', 'width': 80 }, { 'name': 'active', 'width': 160 }, { 'name': 'type', 'width': 100, }, { 'name': 'stats', 'width': 100, 'sortable': False, 'search': False }, ], sortname = 'name', navbuttons_options = {'view': False, 'edit': False, 'add': True, 'del': False, 'search': False, 'refresh': True, 'addfunc': js_callback('add'), } ) cmp_types = ((-1, ' - - - '), (0, u'Commerciale'), (1, u'Récurrente'), (2, u'\u00C9vénementielle')) def percent(n, t): if t==0: return '-' r = 100*n/t return u'%d %%' % r def stats_compute(cmp_id): p = DBSession.query(Campaign).get(cmp_id)
class MokshaContainer(Widget): template = 'mako:moksha.widgets.container.templates.container' javascript = [container_js] css = [container_css] options = ['draggable', 'resizable'] button_options = ['iconize', 'minimize', 'close'] params = [ 'buttons', 'skin', 'height', 'width', 'left', 'top', 'id', 'title', 'icon', 'content', 'widget_name', 'view_source', 'dock', 'onResize', 'onClose', 'onCollapse', 'onIconize', 'onDrag', 'onRestore' ] + options[:] draggable = droppable = True resizable = False iconize = minimize = close = True hidden = True # hide from the moksha menu content = '' # either text, or a Widget instance widget_name = None title = 'Moksha Container' skin = 'default' # default, black, white, stiky, alert view_source = True dock = 'moksha_dock' icon = 'gears.png' # Pixel tweaking width = 450 height = 500 left = 170 top = 125 # Javascript callbacks onResize = js_callback("function(o){}") onClose = js_callback("function(o){}") onCollapse = js_callback("function(o){}") onIconize = js_callback("function(o){}") onDrag = js_callback("function(o){}") onRestore = js_callback("function(o){}") def update_params(self, d): super(MokshaContainer, self).update_params(d) if isinstance(d.content, Widget): d.widget_name = d.content.__class__.__name__ content_args = getattr(d, 'content_args', {}) if isinstance(d.content, LiveWidget): topics = d.content.get_topics() # FIXME: also unregister the moksha callback functions. Handle # cases where multiple widgets are listening to the same topics d.onClose = js_callback("function(o){%s $(o).remove();}" % unsubscribe_topics(topics)) d.onIconize = d.onCollapse = js_callback( "function(o){%s}" % unsubscribe_topics(topics)) d.onRestore = js_callback("function(o){%s}" % subscribe_topics(topics)) d.content = d.content.display(**content_args) for option in self.options: d[option] = d.get(option, True) and option or '' d.buttons = '' for button in self.button_options: if d.get(button, True): d.buttons += '%s,' % button[:1] d.buttons = d.buttons[:-1] d.id = str(uuid.uuid4()) self.add_call( jQuery('#%s' % d.id).buildContainers({ 'elementsPath': '/toscawidgets/resources/moksha.widgets.container.container/static/css/elements/', 'onClose': d.onClose, 'onResize': d.onResize, 'onCollapse': d.onCollapse, 'onIconize': d.onIconize, 'onDrag': d.onDrag, 'onRestore': d.onRestore, }))
def do_stat(self, period, begin, end, stat, queues='', members=''): tmpl_context.flot_labels_rotated = 'false' # Rotate plot labels ? if stat=='global': row_list = (10, 25) caption = flot_label = u'Appels reçus par groupe' sortname = 'name' sortorder = 'asc' colnames = [u'Groupe d\'appels', u'Nombre d\'appels reçus'] colmodel = [ { 'name': 'name', 'width': 60, 'sortable': True}, { 'name': 'count', 'width': 60, 'align': 'right', 'sortable': True}, ] tmpl_context.flot_series = '"0,1"' # List of series to plot title = u'Statistiques globales' elif stat=='queues': row_list = (10, 25) caption = flot_label = u'Appels par groupe' sortname = 'name' sortorder = 'asc' colnames = [u'Groupe d\'appels', u'Appels reçus', u'Traités', u'%', u'Abandons', u'%', u'Dissuasions', u'%', u'Fermé', u'%'] colmodel = [ { 'name': 'name', 'width': 60, 'sortable': True}, { 'name': 'incoming', 'width': 40, 'align': 'right', 'sortable': True}, { 'name': 'connect', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'abandon', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'dissuasion', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'closed', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, ] tmpl_context.flot_series = '"0,1,3,5,7"' # List of series to plot title = u'Statistiques par groupes d\'appels' elif stat in ('sla','abandon'): row_list = (30,120) caption = flot_label = u'Niveau de service' sortname = 'wait' sortorder = 'asc' colnames = [u'Attente', u'Appels', u'%', u'Cumul (%)'] colmodel = [ { 'name': 'wait', 'width': 60, 'sortable': False}, { 'name': 'count', 'width': 40, 'align': 'right', 'sortable': False}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'width': 20, 'align': 'right', 'sortable': False}, ] tmpl_context.flot_series = '"0,"' # List of series to plot if stat=='sla': title = u'Niveau de service' else: title = u'Abandons' elif stat=='daily': row_list = (30,120) caption = flot_label = u'Niveau de service' sortname = 'wait' sortorder = 'asc' colnames = [u'Jour de la semaine', u'Appels', u'%'] colmodel = [ { 'name': 'dow', 'width': 60, 'sortable': True}, { 'name': 'count', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, ] tmpl_context.flot_series = '"0,"' # List of series to plot title = u'Distribution quotidienne' elif stat=='hourly': row_list = (48,) caption = flot_label = u'Distribution horaire' sortname = 'hour' sortorder = 'asc' colnames = [u'Heure', u'Entrant', u'%', u'Fermé', u'%', u'Dissuasion', u'%', u'Abandons', u'%', u'Traités', u'%'] colmodel = [ { 'name': 'hour', 'width': 60, 'sortable': True}, { 'name': 'incoming', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'closed', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'dissuasion', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'abandon', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, { 'name': 'connect', 'width': 40, 'align': 'right', 'sortable': True}, { 'width': 20, 'align': 'right', 'sortable': False}, ] tmpl_context.flot_series = '"0,2,4,6"' # List of series to plot title = u'Distribution horaire' tmpl_context.flot_labels_rotated = 'true' # Rotate plot labels ? elif stat=='members': row_list = (50, 100, 150) caption = flot_label = u'Agents' sortname = 'member' sortorder = 'asc' colnames = [u'Agent', u'Services', u'Durée', u'Pauses', u'Durée', u'Appels reçus', u'Durée', u'Moyenne', u'Appels émis', u'Durée', u'Moyenne' ] colmodel = [ {'name': 'member', 'width': 60, 'sortable': True}, {'name': 'service_num', 'width': 40, 'align': 'right', 'sortable': True}, {'name': 'service', 'width': 40, 'align': 'right', 'sortable': True}, {'name': 'pause_num', 'width': 40, 'align': 'right', 'sortable': True}, {'name': 'pause', 'width': 20, 'align': 'right', 'sortable': True}, {'name': 'calls_in', 'width': 40, 'align': 'right', 'sortable': True}, {'name': 'ci_dur', 'width': 20, 'align': 'right', 'sortable': True}, {'name': 'ci_avg', 'width': 20, 'align': 'right', 'sortable': True}, {'name': 'calls_out', 'width': 40, 'align': 'right', 'sortable': True}, {'name': 'co_dur', 'width': 20, 'align': 'right', 'sortable': True}, {'name': 'co_avg', 'width': 20, 'align': 'right', 'sortable': True}, ] tmpl_context.flot_series = '"0,2,4,7"' # List of series to plot title = u'Distribution par agent' tmpl_context.flot_labels_rotated = 'true' # Rotate plot labels ? # Hidden form for CSV export tmpl_context.form = Form( name = 'stats_form', submit_text = None, # hover_help = True, fields = [ HiddenField(name='period',default=period), HiddenField(name='begin',default=begin), HiddenField(name='end',default=end), HiddenField(name='queues',default=';'.join(queues)), HiddenField(name='members',default=';'.join(members)), HiddenField(name='stat',default=stat), ] ) # Data grid tmpl_context.data_grid = MyJqGrid( id='data_grid', url='fetch', caption=caption, sortname=sortname, sortorder=sortorder, colNames = colnames, colModel = colmodel, navbuttons_options = {'view': False, 'edit': False, 'add': False, 'del': False, 'search': False, 'refresh': True, }, loadComplete = js_callback('load_complete'), rowNum = row_list[0], rowList = row_list, postData = {'period': period, 'begin': begin, 'end': end, 'queues': queues, 'members': members, 'stat': stat}, ) # Plot: data are gathered from the grid, through javscript, cf. cc_stats.html tmpl_context.data_flot = FlotWidget( data = [ { 'data': [], 'label': u'' }, ], options = { 'grid': { 'backgroundColor': '#fffaff', 'clickable': True, 'hoverable': True}, 'xaxis': { 'ticks': []} }, height = '300px', width = '600px', label = flot_label, id='data_flot' ) log.debug(''' period=%s, begin=%s, end=%s queues=%s members=%s stat=%s ''' % (period, begin, end, queues, members, stat)) return dict( title=title , debug='', values='')
def test_can_chain_calls(self): jQuery = js_function('jQuery') cb = js_callback('make_async') call = jQuery('a .async').click(cb).foo().bar() expected = 'jQuery("a .async").click(make_async).foo().bar()' self.failUnlessEqual(str(call), expected)
class StompWidget(Widget): callbacks = [ 'onopen', 'onerror', 'onerrorframe', 'onclose', 'onconnectedframe', 'onmessageframe' ] javascript = [jquery_json_js] params = callbacks[:] + [ 'topics', 'notify', 'orbited_host', 'orbited_port', 'orbited_url', 'orbited_js', 'stomp_host', 'stomp_port', 'stomp_user', 'stomp_pass' ] onopen = js_callback('function(){}') onerror = js_callback('function(error){}') onclose = js_callback('function(c){}') onerrorframe = js_callback('function(f){}') onmessageframe = '' onconnectedframe = '' # Popup notification bubbles on socket state changes notify = False engine_name = 'mako' template = u""" <script type="text/javascript"> if (typeof TCPSocket == 'undefined') { moksha_callbacks = new Object(); moksha_socket_busy = false; } ## Register our topic callbacks % for topic in topics: var topic = "${topic}"; if (!moksha_callbacks[topic]) { moksha_callbacks[topic] = []; } moksha_callbacks[topic].push(function(json, frame) { ${onmessageframe[topic]} }); % endfor if (typeof TCPSocket == 'undefined') { document.domain = document.domain; moksha_socket_busy = true; $.getScript("${orbited_url}/static/Orbited.js", function(){ Orbited.settings.port = ${orbited_port}; Orbited.settings.hostname = '${orbited_host}'; Orbited.settings.streaming = true; TCPSocket = Orbited.TCPSocket; $.getScript("${orbited_url}/static/protocols/stomp/stomp.js", function(){ ## Create a new TCPSocket & Stomp client stomp = new STOMPClient(); stomp.onopen = ${onopen}; stomp.onclose = ${onclose}; stomp.onerror = ${onerror}; stomp.onerrorframe = ${onerrorframe}; stomp.onconnectedframe = function(){ moksha_socket_busy = false; $('body').triggerHandler('moksha.socket_ready'); ${onconnectedframe} }; stomp.onmessageframe = function(f){ var dest = f.headers.destination; var json = null; try { var json = $.parseJSON(f.body); } catch(err) { moksha.error("Unable to decode JSON message body"); moksha.error(msg); } if (moksha_callbacks[dest]) { for (var i=0; i < moksha_callbacks[dest].length; i++) { moksha_callbacks[dest][i](json, f); } } }; stomp.connect('${stomp_host}', ${stomp_port}, '${stomp_user}', '${stomp_pass}'); }); }); } else { ## Utilize the existing stomp connection if (moksha_socket_busy) { $('body').bind('moksha.socket_ready', function() { ${onconnectedframe} }); } else { ${onconnectedframe} } } window.onbeforeunload = function() { if (typeof stomp != 'undefined') { stomp.reset(); } } if (typeof moksha == 'undefined') { moksha = { /* Send a STOMP message to a given topic */ send_message: function(topic, body) { stomp.send($.toJSON(body), topic) } } } % if notify: $.jGrowl.defaults.position = 'bottom-right'; % endif </script> """ hidden = True def __init__(self, *args, **kw): self.notify = asbool(config.get('moksha.socket.notify', False)) self.orbited_host = config.get('orbited_host', 'localhost') self.orbited_port = config.get('orbited_port', 9000) self.orbited_scheme = config.get('orbited_scheme', 'http') self.orbited_url = '%s://%s:%s' % ( self.orbited_scheme, self.orbited_host, self.orbited_port) self.orbited_js = JSLink(link=self.orbited_url + '/static/Orbited.js') self.stomp_host = config.get('stomp_host', 'localhost') self.stomp_port = config.get('stomp_port', 61613) self.stomp_user = config.get('stomp_user', 'guest') self.stomp_pass = config.get('stomp_pass', 'guest') super(StompWidget, self).__init__(*args, **kw) def update_params(self, d): super(StompWidget, self).update_params(d) d.topics = [] d.onmessageframe = defaultdict(str) # {topic: 'js callbacks'} for callback in self.callbacks: if len(moksha.livewidgets[callback]): cbs = '' if callback == 'onmessageframe': for topic in moksha.livewidgets[callback]: d.topics.append(topic) for cb in moksha.livewidgets[callback][topic]: d.onmessageframe[topic] += '%s;' % str(cb) else: for cb in moksha.livewidgets[callback]: if isinstance(cb, (js_callback, js_function)): cbs += '$(%s);' % str(cb) else: cbs += str(cb) if cbs: d[callback] = cbs if d.notify: moksha_notify.register_resources() d.onopen = js_callback( 'function() { $.jGrowl("Moksha live socket connected") }') d.onerror = js_callback( 'function(error) { $.jGrowl("Moksha Live Socket Error: " + error) }' ) d.onerrorframe = js_callback( 'function(f) { $.jGrowl("Error frame received from Moksha Socket: " + f) }' ) d.onclose = js_callback( 'function(c) { $.jGrowl("Moksha Socket Closed") }')
{'display':'Pressure', 'name':'prep_pressure', 'width':10, 'align':'center'}, {'display':'Press Dwell', 'name':'prep_press_dwell', 'width':10, 'align':'center'}, {'display':'Press Method', 'name':'prep_press_method', 'width':10, 'align':'center'}, {'display':'Heat Treatment', 'name':'heat_treatment', 'width':10, 'align':'center'}, {'display':'Case', 'name':'location_case', 'width':10, 'align':'center'}, {'display':'Tray', 'name':'location_tray', 'width':10, 'align':'center'}, ] searchitems = [ {'display':'ID', 'name':'sample_id', 'isdefault':True}, {'display':'Material Type', 'name':'material_type'}, {'display':'Source', 'name':'source'} ] from tw.api import js_callback buttons=[ {'name':'Add', 'bclass':'add', 'onpress': js_callback('add_record')}, {'name':'Delete', 'bclass':'delete', 'onpress': js_callback('delete_record')}, {'separator':True} ] colModel = [ {'display':'ID', 'name':'id', 'width':20, 'align':'center'}, {'display':'Title', 'name':'title', 'width':80, 'align':'left'}, {'display':'Description', 'name':'description', 'width':100, 'align':'left'}, {'display':'Year', 'name':'year', 'width':40, 'align':'center'}, {'display':'Genera', 'name':'genera', 'width':40, 'align':'center'} ] searchitems = [ {'display':'Title', 'name':'title', 'isdefault':True}, {'display':'Year', 'name':'year'}, {'display':'Genre', 'name':'genera'}
def crm(self, cust_id, out_id=None, result=None, message=None, begin=None, duration=None, alarm_type=None, alarm_dest=None, comment=None, next=None, prev=None): ''' CRM page ''' cust_id = int(cust_id) c = DBSession.query(Customer).get(cust_id) if next: cc = DBSession.query(Customer). \ filter(Customer.cmp_id==c.cmp_id). \ filter(Customer.active==True). \ filter(func.lower(Customer.lastname)>c.lastname.lower()). \ order_by(func.lower(Customer.lastname)). \ first() if cc: c = cc cust_id = cc.cust_id elif prev: cc = DBSession.query(Customer). \ filter(Customer.cmp_id==c.cmp_id). \ filter(Customer.active==True). \ filter(func.lower(Customer.lastname)<c.lastname.lower()). \ order_by(desc(func.lower(Customer.lastname))). \ first() if cc: c = cc cust_id = cc.cust_id if not c.active: # Return to list of customers redirect('/cc_outcall/list', params={ 'cmp_id': c.campaign.cmp_id, 'cmp_name': c.campaign.name}) phone1 = c.phone1 phone2 = c.phone2 phone3 = c.phone3 phone4 = c.phone4 phone5 = c.phone5 ph1_click = '''onclick="originate('%s',%d)"''' % (c.phone1, cust_id) ph2_click = '''onclick="originate('%s',%d)"''' % (c.phone2, cust_id) ph3_click = '''onclick="originate('%s',%d)"''' % (c.phone3, cust_id) ph4_click = '''onclick="originate('%s',%d)"''' % (c.phone4, cust_id) ph5_click = '''onclick="originate('%s',%d)"''' % (c.phone5, cust_id) email_href = 'href=mailto:%s' % c.email if config.get('crm_url') != '': crm_url = config.get('crm_url') % c.code crm_click = '''onclick="crm('%s')"''' % crm_url else: crm_click = '''onclick="alert('CRM URL not configured!')"''' cal = {} back_list = \ '''onclick="postdata('list',{cmp_id:%d,cmp_name:'%s'})"''' % ( c.campaign.cmp_id, c.campaign.name) next_cust = \ '''onclick="postdata('crm',{cust_id:%d,next:true})"''' % cust_id prev_cust = \ '''onclick="postdata('crm',{cust_id:%d,prev:true})"''' % cust_id title = u'%s : %s' % (c.campaign.name, capwords(c.display_name)) tmpl_context.grid = MyJqGrid( id='grid', url='outcall_fetch', caption=u'Appels', colNames = [u'Date', u'Numéro', u'Résultat', u'Commentaire'], colModel = [ { 'name': 'created', 'width': 80 }, { 'name': 'dst', 'width': 40, 'sortable': False }, { 'name': 'result', 'width': 160, 'sortable': False }, { 'name': 'comment', 'width': 160, 'sortable': False }, ], postData = {'cust_id': cust_id}, sortname = 'created', navbuttons_options = {'view': False, 'edit': False, 'add': False, 'del': False, 'search': False, 'refresh': True, }, loadComplete = js_callback('load_complete'), ) tmpl_context.form = crm_form values = {'cust_id': cust_id, 'out_id': out_id, 'result': result, 'begin': begin, 'duration': duration, 'message': message, 'comment': comment} return dict(title=title, campaign=c.campaign.name, code=c.code, name=capwords(c.display_name), phone1=phone1, phone2=phone2, phone3=phone3, phone4=phone4, phone5=phone5, email=c.email, ph1_click=ph1_click, ph2_click=ph2_click, ph3_click=ph3_click, ph4_click=ph4_click, ph5_click=ph5_click, email_href=email_href, crm_click=crm_click, cal_click=cal, back_list=back_list, next_cust=next_cust, prev_cust=prev_cust, values=values)
def index(self, selected=None, daily=None): if not in_any_group('admin','STATS'): flash(u'Accès interdit !', 'error') redirect('/') if daily: log.info('stats_type <- %s' % daily) self.stats_type = daily (m,d,y) = daily.split('/') title = u'Statistiques quotidiennes de %s %s' % (month_name[int(m)-1], y) flot_label = u'Appels quotidiens (%s %s)' % (month_name[int(m)-1], y) last_day = monthrange(int(y),int(m))[1] row_list = [last_day, 15, 10, 5] else: self.stats_type = None title = u'Statistiques mensuelles' flot_label = u'Appels mensuels' row_list = [12, 18, 24, 30, 36, 48, 60, 120] # Data grid tmpl_context.data_grid = MyJqGrid( id='data_grid', url='/stats/fetch', caption=u"Valeurs", sortname='name', sortorder='desc', colNames = [u'Jour' if daily else u'Mois', u'Appels', u'Durée'], colModel = [ { 'name': 'date', 'width': 60, 'sortable': True}, { 'name': 'calls', 'width': 40, 'align': 'right', 'sortable': True}, { 'name': 'billsec', 'width': 40, 'align': 'right', 'sortable': True} ], navbuttons_options = {'view': False, 'edit': False, 'add': False, 'del': False, 'search': False, 'refresh': True, }, loadComplete = js_callback('load_complete'), rowNum = row_list[0], rowList = row_list, ) # Hidden form for daily stats tmpl_context.form = Form( name = 'stats_form', submit_text = None, hover_help = True, fields = [ HiddenField(name='daily',default=self.stats_type), ] ) log.info('stats_type -> %s' % self.stats_type) # Plot: data are gathered from the grid, through javscript, cf. stats.html tmpl_context.data_flot = FlotWidget( data = [ { 'data': [], 'label': u'Appels mensuels' }, ], options = { 'grid': { 'backgroundColor': '#fffaff', 'clickable': True, 'hoverable': True}, 'xaxis': { 'ticks': []} }, height = '300px', width = '600px', label = flot_label, id='data_flot' ) # Hourly grid tmpl_context.hourly_grid = MyJqGrid( id='hourly_grid', url='/stats/fetch_hourly', caption=u'Valeurs horaires', sortname='name', sortorder='desc', colNames = [u'Tranche horaire', u'Appels', u'Durée'], colModel = [ { 'name': 'date', 'width': 60, 'sortable': False}, { 'name': 'calls', 'width': 40, 'align': 'right', 'sortable': False}, { 'name': 'billsec', 'width': 40, 'align': 'right', 'sortable': False} ], navbuttons_options = {'view': False, 'edit': False, 'add': False, 'del': False, 'search': False, 'refresh': True, }, loadComplete = js_callback('load_hourly_complete'), rowNum = 24, rowList = [12,24], ) # Plot: data are gathered from the grid, through javscript, cf. stats.html tmpl_context.hourly_flot = FlotWidget( data = [ { 'data': [], 'label': u'Distribution horaire' }, ], options = { 'grid': { 'backgroundColor': '#fffaff', 'clickable': True, 'hoverable': True}, 'xaxis': { 'ticks': []} }, height = '300px', width = '600px', label = flot_label, id='hourly_flot' ) # Inject javascript for tabs from tw.jquery.ui import ui_tabs_js ui_tabs_js.inject() return dict( title=title, debug=False, values={})
return a # New phone page contains 2 forms, displayed in two tabs: # the first form (ip_form) "discovers" the phone ip_form = AjaxForm( id = 'ip_form', fields = [ TextField('ip', label_text=u'Adresse IP'), # help_text=u'ex. 192.168.123.234'), TextField('mac', label_text=u'Adresse matérielle (MAC)'), # help_text=u'ex. 01:23:45:68:89:ab'), TextField('pwd', label_text=u'Mot de passe', default='admin'), ], # hover_help = True, beforeSubmit = js_callback('wait'), success = js_callback('phone_ok'), action = 'check_phone', dataType = 'JSON', target = None, clearForm = False, resetForm = False, timeout = '60000', submit_text = u'Rechercher...' ) # The second form for related data class New_phone_form(AjaxForm): ''' New phone form ''' fields = [
class MokshaAjaxFeedEntriesTree(Dynatree): rootVisible = False persist = True onActivate = js_callback("""function(dtnode) { $('#BottomPane').load('/apps/feeds/get_entry?key=' + dtnode.data.key); }""")