Esempio n. 1
0
    def _test_compare(self):
        '''Test early exiting of compare statements.'''
 
        # Clear expression cache
        ExpressionParser.clear_cache()

        transaction = Transaction.get(create=True)

        sobject = Search.get_by_search_key(self.search_key)
        tasks = Search.eval("@SOBJECT(sthpw/task)", sobject)
        new_status = 'complete'
        for task in tasks:
            task.set_value("status", new_status)
            task.commit()

        transaction.commit()
        
        time.sleep(3)

        cmd = DynamicUpdateCmd(last_timestamp=self.last_timestamp, updates=self.updates)
        Command.execute_cmd(cmd)
        self.last_timestamp = cmd.get_info("timestamp")
        updates = cmd.get_info("updates")
 
        self.assertEquals(updates["001"], 0)
        self.assertEquals(updates["002"], new_status)
        self.assertEquals(updates.get("003"), None)
        self.assertEquals(updates["004"], True)
        self.assertEquals(updates.get("005"), None)
        self.assertEquals(updates["006"], 0)
    def init(my):

        list_item_table = ''
        my.full_item_list = []
        if my.kwargs.has_key( 'list_item_table' ):
            list_item_table = my.kwargs.get( 'list_item_table' )
            expr = '@SOBJECT(MMS/%s)' % list_item_table
            parser = ExpressionParser()
            my.full_item_list = parser.eval(expr)

        my.el_name = ''
        if my.kwargs.has_key( 'element_name' ):
            my.el_name = my.kwargs.get( 'element_name' )

        my.input_el_name = ''
        if my.kwargs.has_key( 'input_element_to_find' ):
            my.input_el_name = my.kwargs.get( 'input_element_to_find' )

        my.col_to_match = ''
        if my.kwargs.has_key( 'column_to_match_value' ):
            my.col_to_match = my.kwargs.get( 'column_to_match_value' )

        my.col_for_label = ''
        if my.kwargs.has_key( 'column_for_label' ):
            my.col_for_label = my.kwargs.get( 'column_for_label' )

        my.select_element = HtmlElement('select')
Esempio n. 3
0
    def get_group_bottom_wdg(self, sobjects):

        expression = self.get_option("group_bottom")
        if not expression:
            return None

        # parse the expression
        self.vars = self.get_vars()

        parser = ExpressionParser()
        raw_result = parser.eval(expression, sobjects=sobjects, vars=self.vars)

        format_str = self.kwargs.get("display_format")
        if format_str:
            from tactic.ui.widget import FormatValueWdg
            format_wdg = FormatValueWdg(format=format_str, value=raw_result)
            result = format_wdg
        else:
            result = str(raw_result)

        div = DivWdg()
        div.add(result)
        div.add_style("text-align: right")
        #div.add_class( "spt_%s_expr_bottom" % (self.get_name()) )

        # add a listener
        #for sobject in sobjects:
        #    if sobject.is_insert():
        #        continue
        #
        #    if self.enable_eval_listener:
        #        self.add_js_expression(div, sobject, expression)

        return div, raw_result
Esempio n. 4
0
    def init(my):

        list_item_table = ''
        my.full_item_list = []
        if my.kwargs.has_key( 'list_item_table' ):
            list_item_table = my.kwargs.get( 'list_item_table' )
            expr = '@SOBJECT(MMS/%s)' % list_item_table
            parser = ExpressionParser()
            my.full_item_list = parser.eval(expr)

        my.el_name = ''
        if my.kwargs.has_key( 'element_name' ):
            my.el_name = my.kwargs.get( 'element_name' )

        my.input_el_name = ''
        if my.kwargs.has_key( 'input_element_to_find' ):
            my.input_el_name = my.kwargs.get( 'input_element_to_find' )

        my.col_to_match = ''
        if my.kwargs.has_key( 'column_to_match_value' ):
            my.col_to_match = my.kwargs.get( 'column_to_match_value' )

        my.col_for_label = ''
        if my.kwargs.has_key( 'column_for_label' ):
            my.col_for_label = my.kwargs.get( 'column_for_label' )

        my.select_element = HtmlElement('select')
Esempio n. 5
0
    def _test_status_change(self):
        '''Test a change to a single task.'''
        
        # Clear expression cache
        ExpressionParser.clear_cache()
        
        transaction = Transaction.get(create=True)
        task = Search.get_by_search_key(self.task_sk) 
        new_status = 'pending'
        task.set_value("status", new_status)
        task.commit()
        transaction.commit()
        
        time.sleep(3)

        cmd = DynamicUpdateCmd(last_timestamp=self.last_timestamp, updates=self.updates)
        Command.execute_cmd(cmd)
        self.last_timestamp = cmd.get_info("timestamp")
        updates = cmd.get_info("updates")
        
        sobject = Search.get_by_search_key(self.search_key)
        num_tasks = Search.eval("@COUNT(@SOBJECT(sthpw/task))", sobject)
        self.assertEquals(updates["001"], num_tasks)
        self.assertEquals(updates["002"], new_status)
        self.assertEquals(updates["003"], "Loading ...")
        self.assertEquals(updates["004"], True)
        self.assertEquals(updates["005"], "Loading ...")
        self.assertEquals(updates["006"], num_tasks)
Esempio n. 6
0
    def get_group_bottom_wdg(my, sobjects):

        expression = my.get_option("group_bottom")
        if not expression:
            return None

        # parse the expression
        my.vars = my.get_vars()

        parser = ExpressionParser()
        result = parser.eval(expression, sobjects=sobjects, vars=my.vars)

        format_str = my.kwargs.get("display_format")
        if format_str:
            from tactic.ui.widget import FormatValueWdg

            format_wdg = FormatValueWdg(format=format_str, value=result)
            result = format_wdg
        else:
            result = str(result)

        div = DivWdg()
        div.add(result)
        div.add_style("text-align: right")
        # div.add_class( "spt_%s_expr_bottom" % (my.get_name()) )

        # add a listener
        # for sobject in sobjects:
        #    if sobject.is_insert():
        #        continue
        #
        #    if my.enable_eval_listener:
        #        my.add_js_expression(div, sobject, expression)

        return div
Esempio n. 7
0
    def get_mail_users(my, column):
        # mail groups
        recipients = set()

        expr = my.notification.get_value(column, no_exception=True)
        if expr:
            sudo = Sudo()
            # Introduce an environment that can be reflected
            env = {
                'sobject': my.sobject
            }

            #if expr.startswith("@"):
            #    logins = Search.eval(expr, list=True, env_sobjects=env)
            #else:
            parts = expr.split("\n")

            # go through each login and evaluate each
            logins = []
            for part in parts:
                if part.startswith("@") or part.startswith("{"):
                    results = Search.eval(part, list=True, env_sobjects=env)
                    # clear the container after each expression eval
                    ExpressionParser.clear_cache()
                    # these can just be login names, get the actual Logins
                    if results:
                        if isinstance(results[0], basestring):
                            login_sobjs = Search.eval("@SOBJECT(sthpw/login['login','in','%s'])" %'|'.join(results),  list=True)
                        
                            login_list = SObject.get_values(login_sobjs, 'login')
                            
                            for result in results:
                                # the original result could be an email address already
                                if result not in login_list:
                                    logins.append(result)
                                
                            if login_sobjs:
                                logins.extend( login_sobjs )
                        else:
                            logins.extend(results)

                elif part.find("@") != -1:
                    # this is just an email address
                    logins.append( part )
                elif part:
                    # this is a group
                    group = LoginGroup.get_by_code(part)
                    if group:
                        logins.extend( group.get_logins() )

            del sudo
        else:
            notification_id = my.notification.get_id()
            logins = GroupNotification.get_logins_by_id(notification_id)

        for login in logins:
            recipients.add(login) 

        return recipients
Esempio n. 8
0
    def cache(self):

        # get the value from cache
        from pyasm.biz import ExpressionParser
        parser = ExpressionParser()
        logins = parser.eval("@SOBJECT(sthpw/login)")

        self.attrs[self.key] = logins
Esempio n. 9
0
    def cache(my):

        # get the value from cache
        from pyasm.biz import ExpressionParser
        parser = ExpressionParser()
        logins = parser.eval("@SOBJECT(sthpw/login)")

        my.attrs[my.key] = logins
Esempio n. 10
0
    def get_item_div(self, sobject):
        ''' get the item div the sobject'''
        top = DivWdg()
        top.add_style("padding: 3px 2px")
        top.add_class("spt_drop_item")
        top.add_class("SPT_DROP_ITEM")


        item_div = DivWdg()
        top.add(item_div, "item_div")
        item_div.add_style("text-overflow: ellipsis")
        item_div.add_style("white-space: nowrap")
        item_div.add_style("width: 80%")
        item_div.add_attr('title','Click to remove')
        item_div.add_style("display", "inline-block")
        item_div.add_style("vertical-align", "top")
        item_div.add_style("overflow", "hidden")


        icon_div = DivWdg()
        top.add(icon_div)
        icon = IconWdg(icon="BS_REMOVE")
        icon_div.add(icon)
        icon_div.add_behavior( {
            'type': 'click_up',
            #'cbjs_action': '''spt.dg_table_action.sobject_drop_remove(evt,bvr)'''
            'cbjs_action': '''spt.drop.sobject_drop_remove(evt,bvr)'''
        } )
        icon.add_style("opacity: 0.3")
        icon_div.add_class("hand")
        icon_div.add_style("display", "inline-block")
        icon_div.add_style("vertical-align", "top")
        #icon_div.add_border()


        #self.menu.set_over(item_div, event="mousein")
        #self.menu.set_out(top, event="mouseleave")


        # set this as the place for the display value to go
        item_div.add_class("spt_drop_display_value")

        add_icon = True
        ExpressionParser.clear_cache()
        if sobject:
            if add_icon:
                self._add_icon(sobject, item_div)

            if self.display_expr:
                display_value = Search.eval(self.display_expr, sobjects = sobject, single=True)
            else:
                display_value = sobject.get_display_value()
            if isinstance(display_value, list):
                display_value = display_value[0]
            item_div.add( display_value )
            self.values.append( SearchKey.get_by_sobject(sobject) )
        return top
Esempio n. 11
0
    def get_message(my):
        search_type_obj = my.sobject.get_search_type_obj()
        title = search_type_obj.get_title()
        subject = my.get_subject()
        notification_message = my.notification.get_value("message")
        if notification_message:
            # parse it through the expression
            sudo = Sudo()
            parser = ExpressionParser()
            snapshot = my.input.get('snapshot')
            env_sobjects = {}

            # turn prev_data and update_data from input into sobjects
            prev_data = SearchType.create("sthpw/virtual")
            id_col = prev_data.get_id_col()

            if id_col:
                del prev_data.data[id_col]

            prev_dict = my.input.get("prev_data")
            if prev_dict:
                for name, value in prev_dict.items():
                    if value != None:
                        prev_data.set_value(name, value)


            update_data = SearchType.create("sthpw/virtual")
            id_col = update_data.get_id_col()

            if id_col:
                del update_data.data[id_col]

            update_dict = my.input.get("update_data")
            if update_dict:
                for name, value in update_dict.items():
                    if value != None:
                        update_data.set_value(name, value)



            if snapshot:

                env_sobjects = {
                'snapshot': snapshot
            }


            env_sobjects['prev_data'] = prev_data
            env_sobjects['update_data'] = update_data

            notification_message  = parser.eval(notification_message, my.sobject, env_sobjects=env_sobjects, mode='string')
            del sudo
            return notification_message

        message = "%s %s" % (title, my.sobject.get_name())
        message = '%s\n\nReport from transaction:\n%s\n' % (message, subject)
        return message
Esempio n. 12
0
    def get_item_div(my, sobject):
        ''' get the item div the sobject'''
        top = DivWdg()
        top.add_style("padding: 3px 2px")
        top.add_class("spt_drop_item")
        top.add_class("SPT_DROP_ITEM")

        item_div = DivWdg()
        top.add(item_div, "item_div")
        item_div.add_style("text-overflow: ellipsis")
        item_div.add_style("white-space: nowrap")
        item_div.add_style("width: 80%")
        item_div.add_attr('title', 'Click to remove')
        item_div.add_style("display", "inline-block")
        item_div.add_style("vertical-align", "top")
        item_div.add_style("overflow", "hidden")

        icon_div = DivWdg()
        top.add(icon_div)
        icon = IconWdg(icon="BS_REMOVE")
        icon_div.add(icon)
        icon_div.add_behavior({
            'type':
            'click_up',
            #'cbjs_action': '''spt.dg_table_action.sobject_drop_remove(evt,bvr)'''
            'cbjs_action':
            '''spt.drop.sobject_drop_remove(evt,bvr)'''
        })
        icon.add_style("opacity: 0.3")
        icon_div.add_class("hand")
        icon_div.add_style("display", "inline-block")
        icon_div.add_style("vertical-align", "top")
        #icon_div.add_border()

        #my.menu.set_over(item_div, event="mousein")
        #my.menu.set_out(top, event="mouseleave")

        # set this as the place for the display value to go
        item_div.add_class("spt_drop_display_value")

        add_icon = True
        ExpressionParser.clear_cache()
        if sobject:
            if add_icon:
                my._add_icon(sobject, item_div)

            if my.display_expr:
                display_value = Search.eval(my.display_expr,
                                            sobjects=sobject,
                                            single=True)
            else:
                display_value = sobject.get_display_value()
            if isinstance(display_value, list):
                display_value = display_value[0]
            item_div.add(display_value)
            my.values.append(SearchKey.get_by_sobject(sobject))
        return top
Esempio n. 13
0
    def get_message(my):
        search_type_obj = my.sobject.get_search_type_obj()
        title = search_type_obj.get_title()
        subject = my.get_subject()
        notification_message = my.notification.get_value("message")
        if notification_message:
            # parse it through the expression
            sudo = Sudo()
            parser = ExpressionParser()
            snapshot = my.input.get('snapshot')
            env_sobjects = {}

            # turn prev_data and update_data from input into sobjects
            prev_data = SearchType.create("sthpw/virtual")
            id_col = prev_data.get_id_col()

            if id_col:
                del prev_data.data[id_col]

            prev_dict = my.input.get("prev_data")
            if prev_dict:
                for name, value in prev_dict.items():
                    if value != None:
                        prev_data.set_value(name, value)

            update_data = SearchType.create("sthpw/virtual")
            id_col = update_data.get_id_col()

            if id_col:
                del update_data.data[id_col]

            update_dict = my.input.get("update_data")
            if update_dict:
                for name, value in update_dict.items():
                    if value != None:
                        update_data.set_value(name, value)

            if snapshot:

                env_sobjects = {'snapshot': snapshot}

            env_sobjects['prev_data'] = prev_data
            env_sobjects['update_data'] = update_data

            notification_message = parser.eval(notification_message,
                                               my.sobject,
                                               env_sobjects=env_sobjects,
                                               mode='string')
            del sudo
            return notification_message

        message = "%s %s" % (title, my.sobject.get_name())
        message = '%s\n\nReport from transaction:\n%s\n' % (message, subject)
        return message
Esempio n. 14
0
 def get_subject(my):
     subject = my.notification.get_value("subject",no_exception=True)
     if subject:
         # parse it through the expression
         sudo = Sudo()
         parser = ExpressionParser()
         subject  = parser.eval(subject, my.sobject, mode='string')
         del sudo
     else:
         subject = '%s - %s' %(my.sobject.get_update_description(), my.command.get_description())
     return subject
Esempio n. 15
0
 def get_subject(self):
     subject = self.notification.get_value("subject",no_exception=True)
     if subject:
         # parse it through the expression
         sudo = Sudo()
         parser = ExpressionParser()
         subject  = parser.eval(subject, self.sobject, mode='string')
         del sudo
     else:
         subject = '%s - %s' %(self.sobject.get_update_description(), self.command.get_description())
     return subject
Esempio n. 16
0
    def get_display(my):
        filter_data = FilterData.get_from_cgi()
        values = filter_data.get_values("custom", "year")

        year = 0
        for value in values:
            if value:
                try:
                    year = int(value)
                except:
                    pass
        if not year:
            date = Date()
            year = int(date.get_year())

        sobject = my.get_current_sobject()
        id = sobject.get_id()

        column = my.get_option("column")
        month = int( my.get_option('month') )

        end_year = year
        end_month = month + 1
        if end_month > 12:
            end_month = 1
            end_year += 1



        search_type = 'MMS/personal_time_log'

        if year:

            search = Search(search_type)
            search.add_filter('login_id', id)
            search.add_filter('work_performed_date', '%s-%0.2d-01' % (year,month), '>')
            search.add_filter('work_performed_date', '%s-%0.2d-01' % (end_year,end_month), '<')

            sobjects = search.get_sobjects()
        else:
            sobjects = []


        if sobjects:
            parser = ExpressionParser()
            sum = parser.eval("@SUM(%s.%s)" % (search_type,column),sobjects=sobjects)
        else:
            sum = 0

        div = DivWdg()
        div.add(sum)
        return div
Esempio n. 17
0
    def get_display(self):
        filter_data = FilterData.get_from_cgi()
        values = filter_data.get_values("custom", "year")

        year = 0
        for value in values:
            if value:
                try:
                    year = int(value)
                except:
                    pass
        if not year:
            date = Date()
            year = int(date.get_year())

        sobject = self.get_current_sobject()
        id = sobject.get_id()

        column = self.get_option("column")
        month = int(self.get_option('month'))

        end_year = year
        end_month = month + 1
        if end_month > 12:
            end_month = 1
            end_year += 1

        search_type = 'MMS/personal_time_log'

        if year:

            search = Search(search_type)
            search.add_filter('login_id', id)
            search.add_filter('work_performed_date',
                              '%s-%0.2d-01' % (year, month), '>')
            search.add_filter('work_performed_date',
                              '%s-%0.2d-01' % (end_year, end_month), '<')

            sobjects = search.get_sobjects()
        else:
            sobjects = []

        if sobjects:
            parser = ExpressionParser()
            sum = parser.eval("@SUM(%s.%s)" % (search_type, column),
                              sobjects=sobjects)
        else:
            sum = 0

        div = DivWdg()
        div.add(sum)
        return div
Esempio n. 18
0
    def get_display(my):
        sobject = my.get_current_sobject()
        expression = my.get_option("expression")

        parser = ExpressionParser()
        value = parser.eval(expression, sobject)

        div = DivWdg()
        div.add_style("text-align: center")
        if value == False:
            div.add(IconWdg("XXX", IconWdg.DOT_GREEN))
        else:
            div.add(IconWdg("YYY", IconWdg.DOT_RED))

        return div
Esempio n. 19
0
    def get_display(my):
        sobject = my.get_current_sobject()
        expression = my.get_option("expression")

        parser = ExpressionParser()
        value = parser.eval(expression, sobject)

        div = DivWdg()
        div.add_style("text-align: center")
        if value == False:
            div.add( IconWdg("XXX", IconWdg.DOT_GREEN) )
        else:
            div.add( IconWdg("YYY", IconWdg.DOT_RED) )

        return div
Esempio n. 20
0
    def get_message(my):
        search_type_obj = my.sobject.get_search_type_obj()
        title = search_type_obj.get_title()
        subject = my.get_subject()
        notification_message = my.notification.get_value("message")
        if notification_message:
            # parse it through the expression
            sudo = Sudo()
            parser = ExpressionParser()

            notification_message  = parser.eval(notification_message, my.sobject, mode='string')
            del sudo
            return notification_message

        message = "%s %s" % (title, my.sobject.get_name())
        message = '%s\n\nReport from transaction:\n%s\n' % (message, subject)
        return message
Esempio n. 21
0
    def get_bottom_wdg(my):

        my.init_kwargs()

        sobjects = my.sobjects
        # ignore the first 2 (edit and insert) if it's on the old TableLayoutWdg
        if my.get_layout_wdg().get_layout_version() == '1':
            sobjects = sobjects[2:]
        
        if not sobjects:
            return None


        expression = my.get_option("bottom")
        if not expression:
            return None

        # parse the expression
        my.vars = my.get_vars()
 
        parser = ExpressionParser()
        result = parser.eval(expression, sobjects=sobjects, vars=my.vars)

        format_str = my.kwargs.get("display_format")
        if format_str:
            from tactic.ui.widget import FormatValueWdg
            format_wdg = FormatValueWdg(format=format_str, value=result)
            result = format_wdg
        else:
            result = str(result)

        div = DivWdg()
        div.add(result)
        div.add_style("text-align: right")
        div.add_class( "spt_%s_expr_bottom" % (my.get_name()) )

        # add a listener
        for sobject in sobjects:
            if sobject.is_insert():
                continue
            if my.enable_eval_listener:
                my.add_js_expression(div, sobject, expression)

        return div
Esempio n. 22
0
    def get_item_div(my, sobject):
        ''' get the item div the sobject'''
        top = DivWdg()
        top.add_attr('title', 'Click to remove')
        # FIXME: put this here for now
        top.add_behavior({
            'type':
            'click_up',
            #'cbjs_action': '''spt.dg_table_action.sobject_drop_remove(evt,bvr)'''
            'cbjs_action':
            '''spt.drop.sobject_drop_remove(evt,bvr)'''
        })

        top.add_class("spt_drop_item")
        top.add_class("SPT_DROP_ITEM")

        item_div = DivWdg()
        item_div.add_class("hand")
        item_div.add_style("float: clear")
        top.add(item_div, "item_div")

        #my.menu.set_over(item_div, event="mousein")
        #my.menu.set_out(top, event="mouseleave")

        # set this as the place for the display value to go
        item_div.add_class("spt_drop_display_value")

        add_icon = True
        ExpressionParser.clear_cache()
        if sobject:
            if add_icon:
                my._add_icon(sobject, item_div)

            if my.display_expr:
                display_value = Search.eval(my.display_expr,
                                            sobjects=sobject,
                                            single=True)
            else:
                display_value = sobject.get_display_value()
            if isinstance(display_value, list):
                display_value = display_value[0]
            item_div.add(display_value)
            my.values.append(SearchKey.get_by_sobject(sobject))
        return top
Esempio n. 23
0
    def get_bottom_wdg(self):

        self.init_kwargs()

        sobjects = self.sobjects
        # ignore the first 2 (edit and insert) if it's on the old TableLayoutWdg
        if self.get_layout_wdg().get_layout_version() == '1':
            sobjects = sobjects[2:]

        if not sobjects:
            return None

        expression = self.get_option("bottom")
        if not expression:
            return None

        # parse the expression
        self.vars = self.get_vars()

        parser = ExpressionParser()
        result = parser.eval(expression, sobjects=sobjects, vars=self.vars)

        format_str = self.kwargs.get("display_format")
        if format_str:
            from tactic.ui.widget import FormatValueWdg
            format_wdg = FormatValueWdg(format=format_str, value=result)
            result = format_wdg
        else:
            result = str(result)

        div = DivWdg()
        div.add(result)
        div.add_style("text-align: right")
        div.add_class("spt_%s_expr_bottom" % (self.get_name()))

        # add a listener
        for sobject in sobjects:
            if sobject.is_insert():
                continue
            if self.enable_eval_listener:
                self.add_js_expression(div, sobject, expression)

        return div
Esempio n. 24
0
    def get_item_div(my, sobject):
        ''' get the item div the sobject'''
        top = DivWdg()
        top.add_style("padding: 3px 2px")
        top.add_attr('title','Click to remove')
        # FIXME: put this here for now
        top.add_behavior( {
            'type': 'click_up',
            #'cbjs_action': '''spt.dg_table_action.sobject_drop_remove(evt,bvr)'''
            'cbjs_action': '''spt.drop.sobject_drop_remove(evt,bvr)'''
        } )

        top.add_class("spt_drop_item")
        top.add_class("SPT_DROP_ITEM")

        item_div = DivWdg()
        item_div.add_class("hand")
        item_div.add_style("float: clear")
        top.add(item_div, "item_div")


        #my.menu.set_over(item_div, event="mousein")
        #my.menu.set_out(top, event="mouseleave")


        # set this as the place for the display value to go
        item_div.add_class("spt_drop_display_value")

        add_icon = True
        ExpressionParser.clear_cache()
        if sobject:
            if add_icon:
                my._add_icon(sobject, item_div)

            if my.display_expr:
                display_value = Search.eval(my.display_expr, sobjects = sobject, single=True)
            else:
                display_value = sobject.get_display_value()
            if isinstance(display_value, list):
                display_value = display_value[0]
            item_div.add( display_value )
            my.values.append( SearchKey.get_by_sobject(sobject) )
        return top
Esempio n. 25
0
    def get_display(my):
        my.sobject = my.get_current_sobject()
        if not my.sobject:
            my.sobject = my.get_sobject_from_kwargs()

        if my.sobject and my.sobject.is_insert():
            return DivWdg()



        if my.sobject:
            my.search_key = SearchKey.get_by_sobject(my.sobject)
            my.kwargs['search_key'] = my.search_key

        else:
            my.search_key = my.kwargs.get('search_key')


        html = my.kwargs.get('html')
        if not html:
            html = ""

        # DEPRECATED
        my.state = my.kwargs.get("state")
        my.state = BaseRefreshWdg.process_state(my.state)
        if not my.state:
            my.state = my.kwargs
            my.state['search_key'] = my.search_key



        my.view = my.kwargs.get('view')
        my.view = my.view.replace("/", ".")
        my.view_folder = ""

        if my.view.startswith("."):
            my.view_folder = my.kwargs.get("__view_folder__")
            if my.view_folder:
                my.view = "%s%s" % (my.view_folder, my.view)

        parts = my.view.split(".")
        my.view_folder = ".".join(parts[:-1])



        if not my.view and not html:
            raise TacticException("No view defined in custom layout")

        # If html is not a string, then convert it?
        if not isinstance(html, basestring):
            html = str(html)

        my.view_attrs = {}

        my.category = my.kwargs.get("category")
        my.search_type = my.kwargs.get("search_type")

        my.encoding = my.kwargs.get("encoding")
        if not my.encoding:
             my.encoding = 'utf-8'
        my.plugin = None

        xml = None

        
        # if html is not provided, then get it from the config
        config = None
        if not html:

            if my.config != None:
                config = my.config
            else:
                config = my.kwargs.get("config")
                if not config:
                    config = my.get_config()



            if not config:
                #div = DivWdg()
                #div.add("No config defined for view [%s] for custom layout" % my.view)
                #return div
                raise TacticException("No config defined for view [%s] for custom layout" % my.view)

            if isinstance(config, WidgetDbConfig):
                config_str = config.get_value("config")
            else:
                config_str = ''

            if config_str.startswith("<html>"):
                html = config_str
                my.def_config = None
            else:
                xml = config.get_xml()

                if my.def_config == None:
                    my.def_config = my.get_def_config(xml)

                # get the view attributes
                if isinstance(config, WidgetConfigView):
                    top_config = config.get_configs()[0]
                else:
                    top_config = config
                view_node = top_config.get_view_node()
                if view_node is None:
                    div = DivWdg("No view node found in xml. Invalid XML entry found")
                    return div
                my.view_attrs = xml.get_attributes(view_node)

                nodes = xml.get_nodes("config/%s/html/*" % my.view)
                if not nodes:
                    div = DivWdg("No definition found")
                    return div

                # convert html tag to a div
                html = cStringIO.StringIO()
                for node in nodes:
                    # unfortunately, html does not recognize <textarea/>
                    # so we have to make sure it becomes <textarea></textarea>
                    text = xml.to_string(node)
                    text = text.encode('utf-8')
                    keys = ['textarea','input']
                    for key in keys:
                        p = re.compile("(<%s.*?/>)" % key)
                        m = p.search(text)
                        if m:
                            for group in m.groups():
                                xx = group.replace("/", "")
                                xx = "%s</%s>" % (xx, key)
                                text = text.replace(group, xx)

                        text = text.replace("<%s/>" % key, "<%s></%s>" % (key, key))

                    # add linebreaks to element tag
                    key = 'element'

                    # reg full tag <element><display...></element>
                    p = re.compile(r"(<%s\b[^>]*>(?:.*?)</%s>)" % (key, key))
                    # short-hand tag <element/>
                    p1 =  re.compile("(</%s>|<%s.*?/>)" %(key, key))
                    m = p.search(text)
                    m1 = p1.search(text)
                    if m:
                        for group in m.groups():
                            if group:
                                text = text.replace(group, '\n%s\n'%group)
                    if m1:
                        for group in m1.groups():
                            if group:
                                text = text.replace(group, '\n%s\n'%group)
                       
                    html.write(text)

                html = html.getvalue()


        my.config = config
        #my.def_config = config    # This is unnessary?

        # try to get the sobject if this is in a table element widget
        if my.search_key:
            try:
                # this will raise an exception if it is not in a table element
                sobject = my.get_current_sobject()
            except:
	        sobject = SearchKey.get_by_search_key(my.search_key)
            sobjects = [sobject]
        else:
            try:
                # this will raise an exception if it is not in a table element
                sobject = my.get_current_sobject()
                if sobject:
                    sobjects = [sobject]
                else:
                    sobjects = []
            except:
                sobject = my.sobjects


        my.layout = my.get_layout_wdg()



        # preprocess using mako
        include_mako = my.kwargs.get("include_mako")
        if not include_mako:
            include_mako = my.view_attrs.get("include_mako")


        if xml:
            mako_node = xml.get_node("config/%s/mako" % my.view)
            if mako_node is not None:
                mako_str = xml.get_node_value(mako_node)
                html = "<%%\n%s\n%%>\n%s" % (mako_str, html)



        from pyasm.web import Palette
        num_palettes = Palette.num_palettes()


        #if include_mako in ['true', True]:
        if include_mako not in ['false', False]:
            html = html.replace("&lt;", "<")
            html = html.replace("&gt;", ">")

            html = my.process_mako(html)



        # preparse out expressions

        # use relative expressions - [expr]xxx[/expr]
        p = re.compile('\[expr\](.*?)\[\/expr\]')
        parser = ExpressionParser()
        matches = p.finditer(html)
        for m in matches:
            full_expr = m.group()
            expr = m.groups()[0]
            result = parser.eval(expr, sobjects, single=True, state=my.state)
            if isinstance(result, basestring):
                result = Common.process_unicode_string(result)
            else:
                result = str(result)
            html = html.replace(full_expr, result )


        # use absolute expressions - [expr]xxx[/expr]
        p = re.compile('\[abs_expr\](.*?)\[\/abs_expr\]')
        parser = ExpressionParser()
        matches = p.finditer(html)
        for m in matches:
            full_expr = m.group()
            expr = m.groups()[0]
            result = parser.eval(expr, single=True)
            if isinstance(result, basestring):
                result = Common.process_unicode_string(result)
            else:
                result = str(result)
            html = html.replace(full_expr, result )



        # need a top widget that can be used to refresh
        top = my.top
        my.set_as_panel(top)
        top.add_class("spt_custom_top")

        ignore_events = my.kwargs.get("ignore_events") in ['true', True]

        if ignore_events:
            top.add_style("pointer-events: none")


        # create the content div
        content = DivWdg()
        content.add_class("spt_custom_content")
        content.add_style("position: relative")
        if ignore_events:
            content.add_style("pointer-events: none")
        top.add(content)
        my.content = content


        is_test = Container.get("CustomLayout::is_test")
        if not is_test:
            is_test = my.kwargs.get("is_test") in [True, 'true']

        if is_test:
            Container.put("CustomLayout::is_test", True)
            my.handle_is_test(content)



        html = my.replace_elements(html)
        content.add(html)

        if xml:
            my.add_behaviors(content, xml)


        # remove all the extra palettes created
        while True:
            extra_palettes = Palette.num_palettes() - num_palettes
            if extra_palettes > 0:
                Palette.pop_palette()
            else:
                break

            
        if my.kwargs.get("is_top") in ['true', True]:
            return html

        elif my.kwargs.get("is_refresh"):
            return content
        else:
            return top
Esempio n. 26
0
    def _get_result(self, sobject, expression):
        '''get the result of the expression'''

        element_name = self.get_name()

        use_cache = self.kwargs.get("use_cache")
        if use_cache == "true":
            try:
                return sobject.get_value(element_name)
            except Exception as e:
                print "Error: ", e.message


        if type(sobject) != types.ListType:
            if sobject.is_insert():
                return ''

        self.vars = {
            'ELEMENT_NAME': element_name,
            'ELEMENT': element_name,
            'SOBJECT_ID': sobject.get_id(),
            'SOBJECT_CODE': sobject.get_code(),
        }

        return_type = self.kwargs.get("return")
        if return_type == 'single':
            single = True
            list = False
        elif return_type == 'list':
            single = False
            list = True
        else:
            single = True
            list = False

        # if this expression is an absolute expression, then don't bother
        # with the sobject
        expression_mode = self.get_option('expression_mode')
        if expression_mode == 'absolute':
            sobject = None

        calc_mode = self.get_option("calc_mode")
        if not calc_mode:
            calc_mode = 'slow'
        #calc_mode = 'fast'
        # parse the expression
        parser = ExpressionParser()
        
        if calc_mode == 'fast':
            if self.cache_results == None:
                self.cache_results = parser.eval(expression, self.sobjects, vars=self.vars, dictionary=True, show_retired=self.show_retired)
                if isinstance(self.cache_results, basestring):
                    if self.cache_results:
                        self.cache_results = eval(self.cache_results)
                    else:
                        self.cache_results = {}

            search_key = sobject.get_search_key()
            result = self.cache_results.get(search_key)
            if single:
                if result and len(result):
                    result = result[0]
                else:
                    result = ''
        else:
          
            result = parser.eval(expression, sobject, vars=self.vars, single=single, list=list, show_retired=self.show_retired)



        # FIXME: don't know how to do this any other way
        try:
            if not list:
                result = result.get_display_value()
        except AttributeError, e:
            pass
Esempio n. 27
0
    def process_data_gather(my, search_key, gather_specs, layout_html):

        sobject = Search.get_by_search_key(search_key)
        for label, info in gather_specs.iteritems():

            if label == "@":
                subs_list = info.get("element_subs")
                for sub in subs_list:
                    value = sobject.get_value(sub)
                    if not value:
                        value = "&nbsp;"
                    substitution_tag = "${@.%s}" % sub
                    layout_html = layout_html.replace(substitution_tag,
                                                      "%s" % value)

            elif info.get("type") == "sobject":
                expr = info.get("expr")
                expr_vars_list = info.get("expr_vars")
                if expr_vars_list:
                    for e_var in expr_vars_list:
                        bits = e_var.split("=")
                        var_name = bits[0]
                        value = sobject.get_value(bits[1].replace("@.", ""))
                        expr = expr.replace(var_name, "%s" % value)
                parser = ExpressionParser()
                result = parser.eval(expr)
                if result:
                    if type(result) == types.ListType:
                        other_sobject = result[0]
                    else:
                        other_sobject = result
                    subs_list = info.get("element_subs")
                    for sub in subs_list:
                        src_col = sub
                        dst_col = sub
                        if "#" in sub:
                            sub_bits = sub.split("#")
                            src_col = sub_bits[0]
                            dst_col = sub_bits[1]
                        value = other_sobject.get_value(src_col)
                        if not value:
                            value = "&nbsp;"
                        if "_date" in dst_col:
                            value = value.split(" ")[0]
                        if "_time" in dst_col:
                            time_bits = value.split(" ")[1].split(":")
                            value = "%s:%s" % (time_bits[0], time_bits[1])
                        substitution_tag = "${%s.%s}" % (label, dst_col)
                        layout_html = layout_html.replace(
                            substitution_tag, "%s" % value)

            elif info.get("type") == "gather_list_class":
                import_stmt = "%s as GatherClass" % info.get("import_stmt")
                exec import_stmt
                gc = GatherClass(sobject)
                item_list = gc.get_items()

                subs_list = info.get("element_subs")
                for c, item in enumerate(item_list):
                    for sub in subs_list:
                        substitution_tag = "${%s[%s].%s}" % (label, c, sub)
                        layout_html = layout_html.replace(
                            substitution_tag, "%s" % item[sub])

                max_id = info.get("max_id")
                if max_id > (len(item_list) - 1):
                    for c in range(len(item_list), max_id + 1):
                        for sub in subs_list:
                            substitution_tag = "${%s[%s].%s}" % (label, c, sub)
                            layout_html = layout_html.replace(
                                substitution_tag, "&nbsp;")

            elif info.get("type") == "value":
                parser = ExpressionParser()
                value = parser.eval(info.get("expr"), sobject)
                if not value:
                    value = "&nbsp;"
                layout_html = layout_html.replace("${%s}" % label,
                                                  "%s" % value)

        return layout_html
Esempio n. 28
0
    def alter_search(my, search):
        if my.is_admin_flag:
            return True

        group = "search_filter"
        search_type = search.get_base_search_type()

        my.alter_search_type_search(search)

        # qualify the key with a project_code
        #project_code = "*"
        #key = "%s?project=%s" % (key, project_code)

        rules = my.groups.get(group)
        if not rules:
            return


        from pyasm.biz import ExpressionParser
        parser = ExpressionParser()
        current_project = None

        for rule in rules.values():
            access, dct = rule
            """
            # FIXME: hacky: break the encoding done earlier
            parts = rule.split("||")
            data = parts[0]
            data = data.replace("?project=*", "")
            rule = eval(data)
            """
            rule = dct
            rule_search_type = rule.get('search_type')
            if not rule_search_type:
                print "No [search_type] defined in security rule"
                continue

            # search types must match
            if rule_search_type != search_type:
                continue

            column = rule.get('column')
            value = rule.get('value')
            project = rule.get('project')
           
            # to avoid infinite recursion, get the project here
            if not current_project:
                from pyasm.biz import Project
                current_project = Project.get_project_code()
            
            if project and project not in ['*', current_project]:
                continue
            # If a relationship is set, then use that
            # FIXME: this is not very clear how to procede.
            related = rule.get('related')
            #if search_type == 'MMS/job':
            #    related = "@SOBJECT(MMS/request)"

            sudo = Sudo()
            if related:

                sobjects = parser.eval(related)
                search.add_relationship_filters(sobjects)
                del sudo
                return



            # interpret the value
            # since the expression runs float(), we want to avoid that a number 5 being converted to 5.0
            # if we can't find @ or $
            if value.find('@') != -1 or value.find('$') != -1:
                values = parser.eval(value, list=True)
            else:
                values = [value]

            op = rule.get('op')
            

            # TODO: made this work with search.add_op_filters() with the expression parser instead of this
            # simpler implementation
            if len(values) == 1:
                if not op:
                    op = '='
                quoted = True
                # special case for NULL
                if values[0] == 'NULL':
                    quoted = False
                if op in ['not in', '!=']:
                    search.add_op('begin')
                    search.add_filter(column, values[0], op=op, quoted=quoted)
                    search.add_filter(column, None)
                    search.add_op('or')
                else:
                    search.add_filter(column, values[0], op=op, quoted=quoted)
            elif len(values) > 1:
                if not op:
                    op = 'in'
                if op in ['not in', '!=']:
                    search.add_op('begin')
                    search.add_filter(column, values, op=op)
                    search.add_filter(column, None)
                    search.add_op('or')
                else:
                    search.add_filters(column, values, op=op)

            del sudo
Esempio n. 29
0
    def process_data_gather( self, search_key, gather_specs, layout_html ):

        sobject = Search.get_by_search_key( search_key )
        for label,info in gather_specs.iteritems():

            if label == "@":
                subs_list = info.get("element_subs")
                for sub in subs_list:
                    value = sobject.get_value( sub )
                    if not value:
                        value = "&nbsp;"
                    substitution_tag = "${@.%s}" % sub
                    layout_html = layout_html.replace( substitution_tag, "%s" % value )

            elif info.get("type") == "sobject":
                expr = info.get("expr")
                expr_vars_list = info.get("expr_vars")
                if expr_vars_list:
                    for e_var in expr_vars_list:
                        bits = e_var.split("=")
                        var_name = bits[0]
                        value = sobject.get_value( bits[1].replace("@.","") )
                        expr = expr.replace( var_name, "%s" % value )
                parser = ExpressionParser()
                result = parser.eval( expr )
                if result:
                    if type(result) == types.ListType:
                        other_sobject = result[0]
                    else:
                        other_sobject = result
                    subs_list = info.get("element_subs")
                    for sub in subs_list:
                        src_col = sub
                        dst_col = sub
                        if "#" in sub:
                            sub_bits = sub.split("#")
                            src_col = sub_bits[0]
                            dst_col = sub_bits[1]
                        value = other_sobject.get_value( src_col )
                        if not value:
                            value = "&nbsp;"
                        if "_date" in dst_col:
                            value = value.split(" ")[0]
                        if "_time" in dst_col:
                            time_bits = value.split(" ")[1].split(":")
                            value = "%s:%s" % (time_bits[0], time_bits[1])
                        substitution_tag = "${%s.%s}" % (label, dst_col )
                        layout_html = layout_html.replace( substitution_tag, "%s" % value )

            elif info.get("type") == "gather_list_class":
                import_stmt = "%s as GatherClass" % info.get("import_stmt")
                exec import_stmt
                gc = GatherClass( sobject )
                item_list = gc.get_items()

                subs_list = info.get("element_subs")
                for c, item in enumerate(item_list):
                    for sub in subs_list:
                        substitution_tag = "${%s[%s].%s}" % (label, c, sub)
                        layout_html = layout_html.replace( substitution_tag, "%s" % item[ sub ] )

                max_id = info.get("max_id")
                if max_id > (len(item_list) - 1):
                    for c in range(len(item_list),max_id+1):
                        for sub in subs_list:
                            substitution_tag = "${%s[%s].%s}" % (label, c, sub)
                            layout_html = layout_html.replace( substitution_tag, "&nbsp;" )


            elif info.get("type") == "value":
                parser = ExpressionParser()
                value = parser.eval( info.get("expr"), sobject )
                if not value:
                    value = "&nbsp;"
                layout_html = layout_html.replace( "${%s}" % label, "%s" % value )

        return layout_html
Esempio n. 30
0
    def get_display(self):
        sobject = self.get_current_sobject()
        search_key = SearchKey.build_by_sobject(sobject)

        display = DivWdg()
        display.add_style("position: relative")
        display.add_class("spt_button_top")
        display.add_style("width: 26px")
        display.add_style("margin-left: auto")
        display.add_style("margin-right: auto")

        BASE = '/context/themes2/default/'
        over_div = DivWdg()
        display.add(over_div)
        over_div.add_class("spt_button_over")
        over_img = "<img src='%s/MainButton_over.png'/>" % BASE
        over_div.add(over_img)
        over_div.add_style("position: absolute")
        over_div.add_style("top: -9px")
        over_div.add_style("left: 0px")
        over_div.add_style("display: none")

        click_div = DivWdg()
        display.add(click_div)
        click_div.add_class("spt_button_click")
        click_img = "<img src='%s/MainButton_click.png'/>" % BASE
        click_div.add(click_img)
        click_div.add_style("position: absolute")
        click_div.add_style("top: -9px")
        click_div.add_style("left: 0px")
        click_div.add_style("display: none")

        if self.get_option('align') == 'left':
            display.add_style("text-align: left")
        else:
            display.add_style("text-align: center")

        icon = self.get_option("icon")
        if not icon:
            icon = "create"

        icon_tip = self.get_option("icon_tip")
        if not icon_tip:
            icon_tip = self.get_option("hint")
        if not icon_tip:
            icon_tip = ""

        enable = self.get_option("enable")
        if enable:
            result = ExpressionParser().eval(enable, sobject)
            if not result:
                return "&nbsp;"

        if not self.script_obj and not self.script:
            icon_wdg = IconButtonWdg("No Script Found", IconWdg.ERROR)
        else:
            icon_link = icon.upper()

            icon_wdg = IconButtonWdg(icon_tip, icon=icon_link)
            if not sobject.is_insert():
                icon_wdg.add_class("hand")
                #icon_wdg.add_behavior(self.behavior)
                icon_wdg.add_class("spt_button_%s" % self.name)

        icon_div = DivWdg()
        icon_div.add(icon_wdg)
        icon_div.add_style("position: absolute")
        icon_div.add_style("top: 2px")
        icon_div.add_style("left: 5px")
        display.add(icon_div)

        hit_wdg = icon_div
        hit_wdg.add_class("spt_button_hit")

        if sobject.is_insert():
            hit_wdg.add_style("opacity: 0.4")
        else:
            hit_wdg.add_class("spt_button_hit_wdg")

        display.add_style("height: 18px")
        display.add_style("min-width: 21px")
        #display.add_style("overflow: hidden")
        display.add_style("margin-top: 0px")

        expression = self.kwargs.get('expression')
        if expression:
            value = Search.eval(expression, sobject, single=True)

            if value:

                badge = DivWdg()
                badge.add_style("position: absolute")

                badge.add_style("right: -30px")
                badge.add_style("top: -2px")
                badge.add_style("margin: 4px 3px 3px 6px")
                badge.add_style("opacity: 0.5")
                badge.add_style("font-size: 0.7em")
                badge.add_class("badge")
                badge.add(value)

                display.add(badge)
                display.add_style("position: relative")

                #return top

        return display
Esempio n. 31
0
class ExpressionElementWdg(TypeTableElementWdg):
    '''General purpose element widget for expressions'''

    ARGS_KEYS = {
        'expression': {
            'description': 'Expression to evaluate the widget',
            'type': 'TextAreaWdg',
            'order': 1,
            'category': 'Options'
        },
        'display_expression': {
            'description': 'Expression for display purposes',
            'type': 'TextAreaWdg',
            'order': 2,
            'category': 'Options'
        },
        'display_format': {
            'description': 'Predefined format for display',
            'type': 'TextWdg',
            'order': 3,
            'category': 'Options'
        },
        'inline_styles':
        'Styles to add to the DIV generated that contains the result of the expression',
        'return': {
            'descripton':
            'Determines what the expression return type should be',
            'type': 'SelectWdg',
            'values': 'single|list'
        },
        'bottom': {
            'description':
            'Expression to calculate the bottom row of the table',
            'type': 'TextAreaWdg',
        },
        'group_bottom': {
            'description': 'Expression to calculate the bottom of a group',
            'type': 'TextAreaWdg',
        },
        'mode': {
            'description': 'Display mode for this widget',
            'type': 'SelectWdg',
            'values': 'value|check|boolean',
            'order': 3
        },
        'expression_mode': {
            'description':
            'If absolute mode is selected, it does not relate to the current SObject',
            'type': 'SelectWdg',
            'values': 'default|absolute',
            'order': 4
        },
        'calc_mode': {
            'description':
            '(ALPHA) fast|slow - fast uses new calculation mode. Only @SUM, @COUNT, @SOBJECT and @GET are current supported',
            'type': 'SelectWdg',
            'values': 'slow|fast',
            'order': 5
        },
        'show_retired': {
            'description':
            'true|false - true shows all the retired entries during the expression evaluation',
            'type': 'SelectWdg',
            'values': 'true|false',
            'category': 'Options',
            'order': 6
        },
        'enable_eval_listener': {
            'description':
            '''Currently javascript expression evaluation is not fully baked, so only use the client side evaluation listener when needed and NOT by default''',
            'category': 'internal',
        },
        'use_cache': {
            'description':
            'Determines whether or not to use the cached value.  Gets value from column with the same name as the element',
            'type': 'SelectWdg',
            'values': 'true|false',
            'order': 0,
            'category': 'Cache'
        },
        'order_by': {
            'description': 'Turn on Order by',
            'type': 'TextWdg',
            'order': 7,
            'category': 'Options'
        },
        'group_by': {
            'description': 'Turn on Group by',
            'type': 'SelectWdg',
            'values': 'true|false',
            'order': 8,
            'category': 'Options'
        },
        'group_by_time': {
            'description': 'Turn on Group by',
            'type': 'SelectWdg',
            'values': 'true|false',
            'order': 9,
            'category': 'Options'
        },
        'justify': {
            'description': 'Result justification',
            'type': 'SelectWdg',
            'values': 'default|left|right|center',
            'order': 91,
            'category': 'Options'
        }
    }

    def init(my):
        my.td = None
        my.expression = None
        my.alt_expression = None
        my.alt_result = None

        my.cache_results = None

    def preprocess(my):
        order_by = my.get_option("order_by")
        # for backward compatibility when order_by used to be true/false
        if not order_by or order_by == 'true':
            expression = my.get_option("expression")
            if expression.startswith("@GET(") and expression.endswith(
                    ")") and expression.count("@") == 1:
                template = expression.lstrip("@GET(")
                template = template.rstrip(")")
                # remove white spaces
                template = template.strip()
                # if it's a simple local sType expression e.g. @GET(.id), strip the .
                if template.startswith("."):
                    template = template.lstrip('.')

                my.set_option("order_by", template)

    def get_required_columns(my):
        '''method to get the require columns for this'''
        return []

    def get_header_option_wdg(my):

        return

        if my.kwargs.get("use_cache2") not in ['true', True]:
            return

        div = DivWdg()

        div.add("Last Calculated: 5 days ago<br/><hr/>")

        div.add("Recalculate")
        div.add_class("hand")

        #from tactic.ui.widget import ActionButtonWdg
        #button = ActionButtonWdg(title="Recalculate")
        #div.add(button)

        div.add_behavior({
            'type':
            'click_up',
            'cbjs_action':
            '''
        var table = bvr.src_el.getParent(".spt_table");
        //var search_keys = spt.dg_table.get_search_keys();
        var search_keys = spt.dg_table.get_selected_search_keys(table);

        if (search_keys.length == 0) {
            spt.alert("No rows selected");
            return;
        }

        var header = bvr.src_el.getParent(".spt_table_th");
        var element_name = header.getAttribute("spt_element_name");

        spt.app_busy.show("Recalculating ...");
        var kwargs = {
            element_name: element_name,
            search_keys: search_keys,
        }
        spt.app_busy.show("Recalculating ...");
        var server = TacticServerStub.get();
        var class_name = 'tactic.ui.table.ExpressionRecalculateCmd';
        server.execute_cmd(class_name, kwargs);
        spt.app_busy.hide("Recalculating ...");
        '''
        })

        return div

    def is_sortable(my):

        use_cache = my.get_option("use_cache") in ['true', True]
        if use_cache:
            return True

        order_by = my.get_option("order_by")

        # false is the word to prevent the auto-adoption (preprocess) of the expression to order-by
        if order_by and order_by != 'false':
            parts = order_by.split(".")
            if "connect" in parts:
                return False
            return True
        else:
            return False

    def is_groupable(my):

        use_cache = my.get_option("use_cache") in ['true', True]
        if use_cache:
            return True

        group_by = my.get_option("group_by")
        if group_by:
            return True
        else:
            return False

    def is_time_groupable(my):
        group_by = my.get_option("group_by_time")
        if group_by:
            return True
        else:
            return False

    def get_vars(my):
        # create variables
        element_name = my.get_name()
        my.vars = {'ELEMENT_NAME': element_name}

        # get info from search critiera
        # FIXME: this should be formalized
        search_vars = Container.get("Message:search_vars")
        if search_vars:
            for name, value in search_vars.items():
                my.vars[name] = value

        return my.vars

    def get_input_by_arg_key(my, key):
        if key == 'expression':
            input = TextAreaWdg("option_expression")
        else:
            input = TextWdg("value")
        return input

    get_input_by_arg_key = classmethod(get_input_by_arg_key)

    def handle_td(my, td):
        if my.alt_result:
            td.add_attr("spt_input_value", my.alt_result)
        elif my.alt_result:
            td.add_attr("spt_input_value", my.value)

        super(ExpressionElementWdg, my).handle_td(td)

    def is_editable(my):
        return 'optional'

    def _get_result(my, sobject, expression):
        '''get the result of the expression'''

        element_name = my.get_name()

        use_cache = my.kwargs.get("use_cache")
        if use_cache == "true":
            try:
                return sobject.get_value(element_name)
            except Exception, e:
                print "Error: ", e.message

        if type(sobject) != types.ListType:
            if sobject.is_insert():
                return ''

        my.vars = {
            'ELEMENT_NAME': element_name,
            'ELEMENT': element_name,
            'SOBJECT_ID': sobject.get_id(),
            'SOBJECT_CODE': sobject.get_code(),
        }

        return_type = my.kwargs.get("return")
        if return_type == 'single':
            single = True
            list = False
        elif return_type == 'list':
            single = False
            list = True
        else:
            single = True
            list = False

        # if this expression is an absolute expression, then don't bother
        # with the sobject
        expression_mode = my.get_option('expression_mode')
        if expression_mode == 'absolute':
            sobject = None

        calc_mode = my.get_option("calc_mode")
        if not calc_mode:
            calc_mode = 'slow'
        #calc_mode = 'fast'
        # parse the expression
        parser = ExpressionParser()

        if calc_mode == 'fast':
            if my.cache_results == None:
                my.cache_results = parser.eval(expression,
                                               my.sobjects,
                                               vars=my.vars,
                                               dictionary=True,
                                               show_retired=my.show_retired)
                if isinstance(my.cache_results, basestring):
                    if my.cache_results:
                        my.cache_results = eval(my.cache_results)
                    else:
                        my.cache_results = {}

            search_key = sobject.get_search_key()
            result = my.cache_results.get(search_key)
            if single:
                if result and len(result):
                    result = result[0]
                else:
                    result = ''
        else:

            result = parser.eval(expression,
                                 sobject,
                                 vars=my.vars,
                                 single=single,
                                 list=list,
                                 show_retired=my.show_retired)

        # FIXME: don't know how to do this any other way
        try:
            if not list:
                result = result.get_display_value()
        except AttributeError, e:
            pass
Esempio n. 32
0
    def alter_search(self, search):
        if self.is_admin_flag:
            return True

        group = "search_filter"
        search_type = search.get_base_search_type()

        self.alter_search_type_search(search)
        rules = self.groups.get(group)
        if not rules:
            return


        from pyasm.biz import ExpressionParser
        parser = ExpressionParser()
        current_project = None


        # preprocess to get a list of rule that will apply
        rules_dict = {}
        for rule_item in rules.values():
            access, dct = rule_item

            rule = dct
            rule_search_type = rule.get('search_type')
            if not rule_search_type:
                print "No [search_type] defined in security rule"
                continue

            # search types must match
            if rule_search_type != search_type:
                continue

            project = rule.get('project')
           
            # to avoid infinite recursion, get the project here
            if not current_project:
                from pyasm.biz import Project
                current_project = Project.get_project_code()
            
            if project and project not in ['*', current_project]:
                continue


            column = rule.get('column')
            rules_list = rules_dict.get(column)
            if rules_list == None:
                rules_list = []
                rules_dict[column] = rules_list

            rules_list.append(rule)



        for column, rules_list in rules_dict.items():

            if len(rules_list) > 1:
                search.add_op("begin")


            for rule in rules_list:

                column = rule.get('column')
                value = rule.get('value')
               

                # If a relationship is set, then use that
                related = rule.get('related')

                sudo = Sudo()
                if related:

                    sobjects = parser.eval(related)
                    search.add_relationship_filters(sobjects)
                    del sudo
                    return


                # interpret the value
                # since the expression runs float(), we want to avoid that a number 5 being converted to 5.0
                # if we can't find @ or $
                if value.find('@') != -1 or value.find('$') != -1:
                    values = parser.eval(value, list=True)
                elif value.find("|") == -1:
                    values = value.split("|")
                else:
                    values = [value]

                op = rule.get('op')
                

                # TODO: made this work with search.add_op_filters() with the expression parser instead of this
                # simpler implementation
                if len(values) == 1:
                    if not op:
                        op = '='
                    quoted = True
                    # special case for NULL
                    if values[0] == 'NULL':
                        quoted = False
                    if op in ['not in', '!=']:
                        search.add_op('begin')
                        search.add_filter(column, values[0], op=op, quoted=quoted)
                        search.add_filter(column, None)
                        search.add_op('or')
                    else:
                        search.add_filter(column, values[0], op=op, quoted=quoted)
                elif len(values) > 1:
                    if not op:
                        op = 'in'
                    if op in ['not in', '!=']:
                        search.add_op('begin')
                        search.add_filter(column, values, op=op)
                        search.add_filter(column, None)
                        search.add_op('or')
                    else:
                        search.add_filters(column, values, op=op)

                del sudo


            if len(rules_list) > 1:
                search.add_op("or")
Esempio n. 33
0
    def handle_sobject(my, main_sobject, caller, notification, input):

        # TODO: deal with parents later
        parent = main_sobject.get_parent()

        snapshot = input.get('snapshot')
        env_sobjects = {}
        if snapshot:
            env_sobjects = {'snapshot': snapshot}

        # get the rules from the database
        rules_xml = notification.get_xml_value("rules")
        rule_nodes = rules_xml.get_nodes("rules/rule")
        is_skipped = True

        parser = ExpressionParser()

        # process the rules
        for rule_node in rule_nodes:
            rule = []
            group_type = Xml.get_attribute(rule_node, "group")
            rule_key = Xml.get_attribute(rule_node, 'key')
            rule_value = Xml.get_attribute(rule_node, 'value')
            compare = Xml.get_attribute(rule_node, 'compare')

            # evaluate the expression if it exists
            expression = Xml.get_node_value(rule_node)
            if expression:
                result = parser.eval(expression,
                                     main_sobject,
                                     env_sobjects=env_sobjects)
                if not result:
                    break
                else:
                    continue

            # DEPRECATED: likely the expression complete replaces this
            # parse the rule
            if group_type == "sobject":
                if not my._process_sobject(main_sobject, rule_key, compare):
                    break
                value = main_sobject.get_value(rule_key, no_exception=True)
            elif group_type == "parent":
                if not parent or not my._process_sobject(
                        parent, rule_key, compare):
                    break
                value = parent.get_value(rule_key, no_exception=True)
            else:  # group_type == 'command'
                try:
                    value = caller.get_info(rule_key)
                except:
                    value = ''
            if not value:
                break

            # match the rule to the value
            p = re.compile(rule_value)
            if not p.match(value):
                print "... skipping: '%s' != %s" % (value, rule_value)
                break

        else:
            is_skipped = False

        # allow the handler to check for whether an email should be sent
        handler = my.get_email_handler(notification, main_sobject, parent,
                                       caller, input)
        if is_skipped or not handler.check_rule():
            my.add_description(
                'Notification not sent due to failure to pass the set rules. Comment out the rules for now if you are just running email test.'
            )
            return

        print "sending email!!!"

        # if all rules are met then get the groups for this notification
        try:
            to_users = handler.get_to()
            cc_users = handler.get_cc()
            bcc_users = handler.get_bcc()

            subject = handler.get_subject()
            if len(subject) > 60:
                subject = subject[0:60] + " ..."
            message = handler.get_message()
        except SObjectValueException, e:
            raise Exception("Error in running Email handler [%s]. %s" \
                    %(handler.__class__.__name__, e.__str__()))
Esempio n. 34
0
    def handle_sobject(my, main_sobject, caller, notification, input):

        # TODO: deal with parents later
        parent = main_sobject.get_parent()

        snapshot = input.get('snapshot')
        env_sobjects = {}
        if snapshot:
            env_sobjects = {
                'snapshot': snapshot
            }
        
        # get the rules from the database
        rules_xml = notification.get_xml_value("rules")
        rule_nodes = rules_xml.get_nodes("rules/rule")
        is_skipped = True

        parser = ExpressionParser()
        
        # process the rules
        for rule_node in rule_nodes:
            rule = []
            group_type = Xml.get_attribute( rule_node, "group" )
            rule_key = Xml.get_attribute(rule_node, 'key')
            rule_value = Xml.get_attribute(rule_node, 'value')
            compare = Xml.get_attribute(rule_node, 'compare')

            # evaluate the expression if it exists
            expression = Xml.get_node_value(rule_node)
            if expression:
                result = parser.eval(expression, main_sobject, env_sobjects=env_sobjects)
                if not result:
                    break
                else:
                    continue

            # DEPRECATED: likely the expression complete replaces this
            # parse the rule
            if group_type == "sobject":
                if not my._process_sobject(main_sobject, rule_key, compare):
                    break
                value = main_sobject.get_value(rule_key, no_exception=True )
            elif group_type == "parent":
                if not parent or not my._process_sobject(parent, rule_key, compare):
                    break
                value = parent.get_value(rule_key, no_exception=True )
            else: # group_type == 'command'
                try:
                    value = caller.get_info(rule_key)
                except:
                    value = ''
            if not value:
                break
            
            # match the rule to the value
            p = re.compile(rule_value)
            if not p.match(value):
                print "... skipping: '%s' != %s" % (value, rule_value)
                break

        else:
            is_skipped = False


        # allow the handler to check for whether an email should be sent
        handler = my.get_email_handler(notification, main_sobject, parent, caller, input)
        if is_skipped or not handler.check_rule():
            my.add_description('Notification not sent due to failure to pass the set rules. Comment out the rules for now if you are just running email test.')
            return

        print "sending email!!!"

        # if all rules are met then get the groups for this notification
        try:
            to_users = handler.get_to()
            cc_users = handler.get_cc()
            bcc_users = handler.get_bcc()


            subject = handler.get_subject()
            if len(subject) > 60:
                subject = subject[0:60] + " ..."
            message = handler.get_message()
        except SObjectValueException, e:
            raise Exception("Error in running Email handler [%s]. %s" \
                    %(handler.__class__.__name__, e.__str__()))
Esempio n. 35
0
    def get_mail_users(my, column):
        # mail groups
        recipients = set()

        expr = my.notification.get_value(column, no_exception=True)
        if expr:
            sudo = Sudo()
            # Introduce an environment that can be reflected
            env = {'sobject': my.sobject}

            #if expr.startswith("@"):
            #    logins = Search.eval(expr, list=True, env_sobjects=env)
            #else:
            parts = expr.split("\n")

            # go through each login and evaluate each
            logins = []
            for part in parts:
                if part.startswith("@") or part.startswith("{"):
                    results = Search.eval(part, list=True, env_sobjects=env)
                    # clear the container after each expression eval
                    ExpressionParser.clear_cache()
                    # these can just be login names, get the actual Logins
                    if results:
                        if isinstance(results[0], basestring):
                            login_sobjs = Search.eval(
                                "@SOBJECT(sthpw/login['login','in','%s'])" %
                                '|'.join(results),
                                list=True)

                            login_list = SObject.get_values(
                                login_sobjs, 'login')

                            for result in results:
                                # the original result could be an email address already
                                if result not in login_list:
                                    logins.append(result)

                            if login_sobjs:
                                logins.extend(login_sobjs)
                        else:
                            logins.extend(results)

                elif part.find("@") != -1:
                    # this is just an email address
                    logins.append(part)
                elif part:
                    # this is a group
                    group = LoginGroup.get_by_code(part)
                    if group:
                        logins.extend(group.get_logins())

            del sudo
        else:
            notification_id = my.notification.get_id()
            logins = GroupNotification.get_logins_by_id(notification_id)

        for login in logins:
            recipients.add(login)

        return recipients
Esempio n. 36
0
    def _get_result(self, sobject, expression):
        '''get the result of the expression'''

        element_name = self.get_name()

        use_cache = self.kwargs.get("use_cache")
        if use_cache == "true":
            try:
                return sobject.get_value(element_name)
            except Exception as e:
                print "Error: ", e.message

        if type(sobject) != types.ListType:
            if sobject.is_insert():
                return ''

        self.vars = {
            'ELEMENT_NAME': element_name,
            'ELEMENT': element_name,
            'SOBJECT_ID': sobject.get_id(),
            'SOBJECT_CODE': sobject.get_code(),
        }

        return_type = self.kwargs.get("return")
        if return_type == 'single':
            single = True
            list = False
        elif return_type == 'list':
            single = False
            list = True
        else:
            single = True
            list = False

        # if this expression is an absolute expression, then don't bother
        # with the sobject
        expression_mode = self.get_option('expression_mode')
        if expression_mode == 'absolute':
            sobject = None

        calc_mode = self.get_option("calc_mode")
        if not calc_mode:
            calc_mode = 'slow'
        #calc_mode = 'fast'
        # parse the expression
        parser = ExpressionParser()

        if calc_mode == 'fast':
            if self.cache_results == None:
                self.cache_results = parser.eval(
                    expression,
                    self.sobjects,
                    vars=self.vars,
                    dictionary=True,
                    show_retired=self.show_retired)
                if isinstance(self.cache_results, basestring):
                    if self.cache_results:
                        self.cache_results = eval(self.cache_results)
                    else:
                        self.cache_results = {}

            search_key = sobject.get_search_key()
            result = self.cache_results.get(search_key)
            if single:
                if result and len(result):
                    result = result[0]
                else:
                    result = ''
        else:

            result = parser.eval(expression,
                                 sobject,
                                 vars=self.vars,
                                 single=single,
                                 list=list,
                                 show_retired=self.show_retired)

        # FIXME: don't know how to do this any other way
        try:
            if not list:
                result = result.get_display_value()
        except AttributeError, e:
            pass
Esempio n. 37
0
    def get_display(my):
        sobject = my.get_current_sobject()
        search_key = SearchKey.build_by_sobject(sobject)

        display = DivWdg()
        display.add_style("position: relative")
        display.add_class("spt_button_top")

        BASE = '/context/themes2/default/'
        over_div = DivWdg()
        display.add(over_div)
        over_div.add_class("spt_button_over")
        over_img = "<img src='%s/MainButton_over.png'/>" % BASE
        over_div.add(over_img)
        over_div.add_style("position: absolute")
        over_div.add_style("top: -9px")
        over_div.add_style("left: 0px")
        over_div.add_style("display: none")

        click_div = DivWdg()
        display.add(click_div)
        click_div.add_class("spt_button_click")
        click_img = "<img src='%s/MainButton_click.png'/>" % BASE
        click_div.add(click_img)
        click_div.add_style("position: absolute")
        click_div.add_style("top: -9px")
        click_div.add_style("left: 0px")
        click_div.add_style("display: none")

        if my.get_option('align') == 'left':
            display.add_style("text-align: left")
        else:
            display.add_style("text-align: center")

        icon = my.get_option("icon")
        if not icon:
            icon = "create"

        icon_tip = my.get_option("icon_tip")
        if not icon_tip:
            icon_tip = my.get_option("hint")
        if not icon_tip:
            icon_tip = ""

        enable = my.get_option("enable")
        if enable:
            result = ExpressionParser().eval(enable, sobject)
            if not result:
                return "&nbsp;"

        if not my.script_obj and not my.script:
            icon_wdg = IconButtonWdg("No Script Found", IconWdg.ERROR)
        else:
            try:
                icon_link = eval("IconWdg.%s" % icon.upper())
            except Exception, e:
                print "WARNING: ", str(e)
                icon_link = IconWdg.ERROR

            icon_wdg = IconButtonWdg(icon_tip, icon_link)
            if not sobject.is_insert():
                icon_wdg.add_class("hand")
                #icon_wdg.add_behavior(my.behavior)
                icon_wdg.add_class("spt_button_%s" % my.name)
Esempio n. 38
0
    def alter_search(my, search):
        if my.is_admin_flag:
            return True

        group = "search_filter"
        search_type = search.get_base_search_type()

        my.alter_search_type_search(search)
        rules = my.groups.get(group)
        if not rules:
            return

        from pyasm.biz import ExpressionParser
        parser = ExpressionParser()
        current_project = None

        for rule in rules.values():
            access, dct = rule
            """
            # FIXME: hacky: break the encoding done earlier
            parts = rule.split("||")
            data = parts[0]
            data = data.replace("?project=*", "")
            rule = eval(data)
            """
            rule = dct
            rule_search_type = rule.get('search_type')
            if not rule_search_type:
                print "No [search_type] defined in security rule"
                continue

            # search types must match
            if rule_search_type != search_type:
                continue

            column = rule.get('column')
            value = rule.get('value')
            project = rule.get('project')

            # to avoid infinite recursion, get the project here
            if not current_project:
                from pyasm.biz import Project
                current_project = Project.get_project_code()

            if project and project not in ['*', current_project]:
                continue
            # If a relationship is set, then use that
            # FIXME: this is not very clear how to procede.
            related = rule.get('related')

            sudo = Sudo()
            if related:

                sobjects = parser.eval(related)
                search.add_relationship_filters(sobjects)
                del sudo
                return

            # interpret the value
            # since the expression runs float(), we want to avoid that a number 5 being converted to 5.0
            # if we can't find @ or $
            if value.find('@') != -1 or value.find('$') != -1:
                values = parser.eval(value, list=True)
            else:
                values = [value]

            op = rule.get('op')

            # TODO: made this work with search.add_op_filters() with the expression parser instead of this
            # simpler implementation
            if len(values) == 1:
                if not op:
                    op = '='
                quoted = True
                # special case for NULL
                if values[0] == 'NULL':
                    quoted = False
                if op in ['not in', '!=']:
                    search.add_op('begin')
                    search.add_filter(column, values[0], op=op, quoted=quoted)
                    search.add_filter(column, None)
                    search.add_op('or')
                else:
                    search.add_filter(column, values[0], op=op, quoted=quoted)
            elif len(values) > 1:
                if not op:
                    op = 'in'
                if op in ['not in', '!=']:
                    search.add_op('begin')
                    search.add_filter(column, values, op=op)
                    search.add_filter(column, None)
                    search.add_op('or')
                else:
                    search.add_filters(column, values, op=op)

            del sudo
Esempio n. 39
0
    def get_display(my):
        my.sobject = my.get_current_sobject()
        if not my.sobject:
            my.sobject = my.get_sobject_from_kwargs()

        if my.sobject and my.sobject.is_insert():
            return DivWdg()



        if my.sobject:
            my.search_key = SearchKey.get_by_sobject(my.sobject)
            my.kwargs['search_key'] = my.search_key

        else:
            my.search_key = my.kwargs.get('search_key')


        html = my.kwargs.get('html')
        if not html:
            html = ""

        # DEPRECATED
        my.state = my.kwargs.get("state")
        my.state = BaseRefreshWdg.process_state(my.state)
        if not my.state:
            my.state = my.kwargs
            my.state['search_key'] = my.search_key



        my.view = my.kwargs.get('view')
        my.view = my.view.replace("/", ".")
        my.view_folder = ""

        if my.view.startswith("."):
            my.view_folder = my.kwargs.get("__view_folder__")
            if my.view_folder:
                my.view = "%s%s" % (my.view_folder, my.view)

        parts = my.view.split(".")
        my.view_folder = ".".join(parts[:-1])



        if not my.view and not html:
            raise TacticException("No view defined in custom layout")

        # If html is not a string, then convert it?
        if not isinstance(html, basestring):
            html = str(html)

        my.view_attrs = {}

        my.category = my.kwargs.get("category")
        my.search_type = my.kwargs.get("search_type")

        my.encoding = my.kwargs.get("encoding")
        if not my.encoding:
             my.encoding = 'utf-8'
        my.plugin = None

        xml = None

        
        # if html is not provided, then get it from the config
        config = None
        if not html:

            if my.config != None:
                config = my.config
            else:
                config = my.kwargs.get("config")
                if not config:
                    config = my.get_config()



            if not config:
                #div = DivWdg()
                #div.add("No config defined for view [%s] for custom layout" % my.view)
                #return div
                raise TacticException("No config defined for view [%s] for custom layout" % my.view)

            if isinstance(config, WidgetDbConfig):
                config_str = config.get_value("config")
            else:
                config_str = ''

            if config_str.startswith("<html>"):
                html = config_str
                my.def_config = None
            else:
                xml = config.get_xml()

                if my.def_config == None:
                    my.def_config = my.get_def_config(xml)

                # get the view attributes
                if isinstance(config, WidgetConfigView):
                    top_config = config.get_configs()[0]
                else:
                    top_config = config
                view_node = top_config.get_view_node()
                if view_node is None:
                    div = DivWdg("No view node found in xml. Invalid XML entry found")
                    return div
                my.view_attrs = xml.get_attributes(view_node)

                nodes = xml.get_nodes("config/%s/html/*" % my.view)
                if not nodes:
                    div = DivWdg("No definition found")
                    return div

                # convert html tag to a div
                html = cStringIO.StringIO()
                for node in nodes:
                    # unfortunately, html does not recognize <textarea/>
                    # so we have to make sure it becomes <textarea></textarea>
                    text = xml.to_string(node)
                    text = text.encode('utf-8')
                    keys = ['textarea','input']
                    for key in keys:
                        p = re.compile("(<%s.*?/>)" % key)
                        m = p.search(text)
                        if m:
                            for group in m.groups():
                                xx = group.replace("/", "")
                                xx = "%s</%s>" % (xx, key)
                                text = text.replace(group, xx)

                        text = text.replace("<%s/>" % key, "<%s></%s>" % (key, key))

                    # add linebreaks to element tag
                    key = 'element'

                    # reg full tag <element><display...></element>
                    p = re.compile(r"(<%s\b[^>]*>(?:.*?)</%s>)" % (key, key))
                    # short-hand tag <element/>
                    p1 =  re.compile("(</%s>|<%s.*?/>)" %(key, key))
                    m = p.search(text)
                    m1 = p1.search(text)
                    if m:
                        for group in m.groups():
                            if group:
                                text = text.replace(group, '\n%s\n'%group)
                    if m1:
                        for group in m1.groups():
                            if group:
                                text = text.replace(group, '\n%s\n'%group)
                       
                    html.write(text)

                html = html.getvalue()


        my.config = config
        #my.def_config = config    # This is unnessary?

        # try to get the sobject if this is in a table element widget
        if my.search_key:
            try:
                # this will raise an exception if it is not in a table element
                sobject = my.get_current_sobject()
            except:
	        sobject = SearchKey.get_by_search_key(my.search_key)
            sobjects = [sobject]
        else:
            try:
                # this will raise an exception if it is not in a table element
                sobject = my.get_current_sobject()
                if sobject:
                    sobjects = [sobject]
                else:
                    sobjects = []
            except:
                sobject = my.sobjects


        my.layout = my.get_layout_wdg()



        # preprocess using mako
        include_mako = my.kwargs.get("include_mako")
        if not include_mako:
            include_mako = my.view_attrs.get("include_mako")


        if xml:
            mako_node = xml.get_node("config/%s/mako" % my.view)
            if mako_node is not None:
                mako_str = xml.get_node_value(mako_node)
                html = "<%%\n%s\n%%>\n%s" % (mako_str, html)



        from pyasm.web import Palette
        num_palettes = Palette.num_palettes()


        #if include_mako in ['true', True]:
        if include_mako not in ['false', False]:
            html = html.replace("&lt;", "<")
            html = html.replace("&gt;", ">")

            html = my.process_mako(html)



        # preparse out expressions

        # use relative expressions - [expr]xxx[/expr]
        p = re.compile('\[expr\](.*?)\[\/expr\]')
        parser = ExpressionParser()
        matches = p.finditer(html)
        for m in matches:
            full_expr = m.group()
            expr = m.groups()[0]
            result = parser.eval(expr, sobjects, single=True, state=my.state)
            if isinstance(result, basestring):
                result = Common.process_unicode_string(result)
            else:
                result = str(result)
            html = html.replace(full_expr, result )


        # use absolute expressions - [expr]xxx[/expr]
        p = re.compile('\[abs_expr\](.*?)\[\/abs_expr\]')
        parser = ExpressionParser()
        matches = p.finditer(html)
        for m in matches:
            full_expr = m.group()
            expr = m.groups()[0]
            result = parser.eval(expr, single=True)
            if isinstance(result, basestring):
                result = Common.process_unicode_string(result)
            else:
                result = str(result)
            html = html.replace(full_expr, result )



        # need a top widget that can be used to refresh
        top = my.top
        my.set_as_panel(top)
        top.add_class("spt_custom_top")


        # create the content div
        content = DivWdg()
        content.add_class("spt_custom_content")
        content.add_style("position: relative")
        top.add(content)
        my.content = content


        is_test = Container.get("CustomLayout::is_test")
        if not is_test:
            is_test = my.kwargs.get("is_test") in [True, 'true']

        if is_test:
            Container.put("CustomLayout::is_test", True)
            my.handle_is_test(content)



        html = my.replace_elements(html)
        content.add(html)

        if xml:
            my.add_behaviors(content, xml)


        # remove all the extra palettes created
        while True:
            extra_palettes = Palette.num_palettes() - num_palettes
            if extra_palettes > 0:
                Palette.pop_palette()
            else:
                break


        if my.kwargs.get("is_refresh"):
            return content
        else:
            return top