コード例 #1
0
ファイル: search_wdg.py プロジェクト: raidios/TACTIC
    def execute(my):
        my.init()

        # create the filters
        my.filters = []
        """
        for element_name in my.config.get_element_names():
            
            filter = my.config.get_display_widget(element_name)
            my.filters.append(filter)

        # make sure there is at least one filter defined
        assert my.filters

        """
        config = "<config>\n"
        config += "<filter>\n"

        # get all of the serialized versions of the filters
        """
        for filter in my.filters:
            config += filter.serialize() + "\n"
        """
        filter_data = FilterData.get()
        json = filter_data.serialize()
        value_type = "json"
        config += "<values type='%s'>%s</values>\n" % (value_type, json)
        config += "</filter>\n"
        config += "</config>\n"

        # format the xml
        xml = Xml()
        xml.read_string(config)

        if not my.view:
            saved_view = "saved_search:%s" % my.search_type
        else:
            saved_view = my.view
        #    if my.view.startswith("saved_search:"):
        #        saved_view = my.view
        #    else:
        #        saved_view = "saved_search:%s" % my.view

        # use widget config instead
        search = Search("config/widget_config")
        search.add_filter("view", saved_view)
        search.add_filter("search_type", my.search_type)
        if my.personal:
            search.add_user_filter()
        config = search.get_sobject()

        if not config:
            config = SearchType.create("config/widget_config")
            config.set_value("view", saved_view)
            config.set_value("search_type", my.search_type)
            if my.personal:
                config.set_user()

        config.set_value("config", xml.to_string())
        config.commit()
コード例 #2
0
    def execute(my):
        my.init()

        # create the filters
        my.filters = []
        """
        for element_name in my.config.get_element_names():
            
            filter = my.config.get_display_widget(element_name)
            my.filters.append(filter)

        # make sure there is at least one filter defined
        assert my.filters

        """
        config = "<config>\n"
        config += "<filter>\n"

        # get all of the serialized versions of the filters
        """
        for filter in my.filters:
            config += filter.serialize() + "\n"
        """
        filter_data = FilterData.get()
        json = filter_data.serialize()
        value_type = "json"
        config += "<values type='%s'>%s</values>\n" % (value_type, json)
        config += "</filter>\n"
        config += "</config>\n"

        # format the xml
        xml = Xml()
        xml.read_string(config)

        if not my.view:
            saved_view = "saved_search:%s" % my.search_type
        else:
            saved_view = my.view
        #    if my.view.startswith("saved_search:"):
        #        saved_view = my.view
        #    else:
        #        saved_view = "saved_search:%s" % my.view

        # use widget config instead
        search = Search('config/widget_config')
        search.add_filter("view", saved_view)
        search.add_filter("search_type", my.search_type)
        if my.personal:
            search.add_user_filter()
        config = search.get_sobject()

        if not config:
            config = SearchType.create('config/widget_config')
            config.set_value("view", saved_view)
            config.set_value("search_type", my.search_type)
            if my.personal:
                config.set_user()

        config.set_value("config", xml.to_string())
        config.commit()
コード例 #3
0
ファイル: plugin.py プロジェクト: talha81/TACTIC-DEV
    def handle_include(my, node):
        path = my.xml.get_attribute(node, "path")
        if not path:
            raise TacticException("No path found for include in manifest")

        path = "%s/%s" % (my.plugin_dir, path)

        if path.endswith(".py"):
            from tactic.command import PythonCmd
            cmd = PythonCmd(file_path=path)
            manifest = cmd.execute()

        if not manifest:
            print "No manifest discovered in [%s]" %path
            return

        xml = Xml()
        xml.read_string(manifest)
        nodes = xml.get_nodes("manifest/*")

        sobjects = []
        for i, node in enumerate(nodes):
            name = my.xml.get_node_name(node)
            if name == 'sobject':
                dumped_sobjects = my.handle_sobject(node)
                if not dumped_sobjects:
                    dumped_sobjects = []
                sobjects.extend(dumped_sobjects)
            elif name == 'search_type':
                my.handle_search_type(node)
            elif name == 'include':
                my.handle_include(node)
コード例 #4
0
ファイル: sync_utils.py プロジェクト: rajubuddha/TACTIC
    def get_file_paths(my, transaction, mode='lib'):

        transaction_xml = transaction.get_xml_value("transaction")
        if not transaction_xml:
            return []

        from pyasm.common import Xml, Environment

        if isinstance(transaction_xml, basestring):
            xml = Xml()
            xml.read_string(transaction_xml)
        else:
            xml = transaction_xml


        base_dir = Environment.get_asset_dir()
        paths = []


        # get all of the file nodes
        nodes = xml.get_nodes("transaction/file")
        for node in nodes:

            if xml.get_attribute(node, "type") == 'create':
                src = xml.get_attribute(node, "src")

                if mode == 'relative':
                    path = src
                else:
                    path = "%s/%s" % (base_dir, src)
                paths.append(path)

        return paths
コード例 #5
0
    def handle_include(my, node):
        path = my.xml.get_attribute(node, "path")
        if not path:
            raise TacticException("No path found for include in manifest")

        path = "%s/%s" % (my.plugin_dir, path)

        if path.endswith(".py"):
            from tactic.command import PythonCmd
            cmd = PythonCmd(file_path=path)
            manifest = cmd.execute()

        if not manifest:
            print "No manifest discovered in [%s]" %path
            return

        xml = Xml()
        xml.read_string(manifest)
        nodes = xml.get_nodes("manifest/*")

        sobjects = []
        for i, node in enumerate(nodes):
            name = my.xml.get_node_name(node)
            if name == 'sobject':
                dumped_sobjects = my.handle_sobject(node)
                if not dumped_sobjects:
                    dumped_sobjects = []
                sobjects.extend(dumped_sobjects)
            elif name == 'search_type':
                my.handle_search_type(node)
            elif name == 'include':
                my.handle_include(node)
コード例 #6
0
    def delete_files(my, nodes):

        # clean out all of the files
        for node in nodes:
            name = my.xml.get_node_name(node)

            if name == "include":
                path = my.xml.get_attribute(node, "path")
                if not path:
                    print("WARNING: No path found for search type in manifest")
                    continue

                path = "%s/%s" % (my.plugin_dir, path)

                if path.endswith(".py"):
                    from tactic.command import PythonCmd
                    cmd = PythonCmd(file_path=path)
                    manifest = cmd.execute()
                    if manifest:
                        xml = Xml()
                        xml.read_string(manifest)
                        include_nodes = xml.get_nodes("manifest/*")

                        my.delete_files(include_nodes)
            elif name == "python":
                # don't delete python node file
                pass
            else:
                path = my.get_path_from_node(node)
                if path and os.path.exists(path):
                    print "Deleting: ", path
                    os.unlink(path)
コード例 #7
0
ファイル: plugin.py プロジェクト: talha81/TACTIC-DEV
    def delete_files(my, nodes):

        # clean out all of the files
        for node in nodes:
            name = my.xml.get_node_name(node)

            if name == "include":
                path = my.xml.get_attribute(node, "path")
                if not path:
                    print("WARNING: No path found for search type in manifest")
                    continue

                path = "%s/%s" % (my.plugin_dir, path)

                if path.endswith(".py"):
                    from tactic.command import PythonCmd
                    cmd = PythonCmd(file_path=path)
                    manifest = cmd.execute()
                    if manifest:
                        xml = Xml()
                        xml.read_string(manifest)
                        include_nodes = xml.get_nodes("manifest/*")

                        my.delete_files(include_nodes)
            elif name == "python":
                # don't delete python node file
                pass
            else:
                path = my.get_path_from_node(node)
                if path and os.path.exists(path):
                    print "Deleting: ", path
                    os.unlink(path)
コード例 #8
0
    def _test_guest_allow(self):
        '''test Config tag allow_guest in security tag.
        Note: Since it is hard to emulate AppServer class, 
        this is based on logic which handles in _get_display 
        of BaseAppServer.
        
        1. If allow_guest is false, then it is necessary that 
        Sudo is instantiated.

        2. If allow_guest is true, then it is necessary that 
        guest login rules are added and login_as_guest is
        executed.
        '''

        security = Security()
        Environment.set_security(security)

        #1. allow_guest is false
        fail = False
        try:
            sudo = Sudo()
        except Exception as e:
            fail = True
        self.assertEquals(False, fail)
        sudo.exit()

        key = [{'code': "*"}]
        project_access = security.check_access("project", key, "allow")
        self.assertEquals(project_access, False)

        #2. allow_guest is true
        Site.set_site("default")
        try:
            security.login_as_guest()
            ticket_key = security.get_ticket_key()
            access_manager = security.get_access_manager()
            xml = Xml()
            xml.read_string('''
            <rules>
              <rule column="login" value="{$LOGIN}" search_type="sthpw/login" access="deny" op="!=" group="search_filter"/>
              <rule group="project" code="default" access="allow"/>
            </rules>
            ''')
            access_manager.add_xml_rules(xml)
        finally:
            Site.pop_site()

        default_key = [{'code': "default"}]
        project_access = security.check_access("project", default_key, "allow")
        self.assertEquals(project_access, True)

        unittest_key = [{'code', "sample3d"}]
        project_access = security.check_access("project", unittest_key,
                                               "allow")
        self.assertEquals(project_access, False)
コード例 #9
0
ファイル: security_test.py プロジェクト: mincau/TACTIC
    def _test_guest_allow(self):
        '''test Config tag allow_guest in security tag.
        Note: Since it is hard to emulate AppServer class, 
        this is based on logic which handles in _get_display 
        of BaseAppServer.
        
        1. If allow_guest is false, then it is necessary that 
        Sudo is instantiated.

        2. If allow_guest is true, then it is necessary that 
        guest login rules are added and login_as_guest is
        executed.
        '''

        security = Security()
        Environment.set_security(security)
        
        #1. allow_guest is false
        fail = False
        try:
            sudo = Sudo()
        except Exception as e:
            fail = True
        self.assertEquals( False, fail ) 
        sudo.exit()
        
        key = [{'code': "*"}]
        project_access = security.check_access("project", key, "allow")
        self.assertEquals(project_access, False)
        
        #2. allow_guest is true
        Site.set_site("default")
        try:
            security.login_as_guest()
            ticket_key = security.get_ticket_key()
            access_manager = security.get_access_manager()
            xml = Xml()
            xml.read_string('''
            <rules>
              <rule column="login" value="{$LOGIN}" search_type="sthpw/login" access="deny" op="!=" group="search_filter"/>
              <rule group="project" code="default" access="allow"/>
            </rules>
            ''')
            access_manager.add_xml_rules(xml)
        finally:
            Site.pop_site()
       
        
        default_key = [{'code': "default"}]
        project_access = security.check_access("project", default_key, "allow")
        self.assertEquals(project_access, True)  
        
        unittest_key = [{'code', "sample3d"}]
        project_access = security.check_access("project", unittest_key, "allow")
        self.assertEquals(project_access, False)  
コード例 #10
0
ファイル: security_test.py プロジェクト: CeltonMcGrath/TACTIC
    def _test_sobject_access_manager(my):
        '''test a more realistic example'''

        # create a test person
        person = Person.create("Donald", "Duck", "DisneyLand", "A duck!!!")
        my.person = person

        for project_code in ['unittest','unittest','sample3d']:
            task = SearchType.create('sthpw/task')
            task.set_sobject_value(person)
            task.set_value('assigned', 'unittest_guy')
            task.set_value('project_code', project_code)
            task.set_value('description', 'do something good')
            task.set_value('process', 'unittest')
            task.set_value('context', 'unittest')
            task.commit()

        # an extra task for list-based search_filter test
        task = SearchType.create('sthpw/task')
        task.set_sobject_value(person)
        task.set_value('assigned', 'unittest_gal')
        task.set_value('project_code', 'unittest')
        task.set_value('description', 'do something good')
        task.set_value('process', 'unittest2')
        task.set_value('context', 'unittest2')
        task.commit()
        # add these rules to the current user
        rules = """
        <rules>
          <rule group="sobject_column" default="edit"/>
          <rule group="sobject_column" search_type="unittest/person" column="name_first" access="edit"/>
          <rule group="sobject_column" search_type="unittest/person" column="name_last" access="deny"/>
          <rule group="sobject_column" search_type="unittest/person" column="nationality" access="deny"/>
        </rules>
        """

        xml = Xml()
        xml.read_string(rules)
        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        # disable admin for this test
        access_manager.set_admin(False)


        # should succeed
        person.set_value("name_first", "Donny")
        # should fail
        try:
            person.set_value("name_last", "Ducky")
        except SecurityException, e:
            pass
コード例 #11
0
    def _test_sobject_access_manager(my):
        '''test a more realistic example'''

        # create a test person
        person = Person.create("Donald", "Duck", "DisneyLand", "A duck!!!")
        my.person = person

        for project_code in ['unittest','unittest','sample3d']:
            task = SearchType.create('sthpw/task')
            task.set_sobject_value(person)
            task.set_value('assigned', 'unittest_guy')
            task.set_value('project_code', project_code)
            task.set_value('description', 'do something good')
            task.set_value('process', 'unittest')
            task.set_value('context', 'unittest')
            task.commit()

        # an extra task for list-based search_filter test
        task = SearchType.create('sthpw/task')
        task.set_sobject_value(person)
        task.set_value('assigned', 'unittest_gal')
        task.set_value('project_code', 'unittest')
        task.set_value('description', 'do something good')
        task.set_value('process', 'unittest2')
        task.set_value('context', 'unittest2')
        task.commit()
        # add these rules to the current user
        rules = """
        <rules>
          <rule group="sobject_column" default="edit"/>
          <rule group="sobject_column" search_type="unittest/person" column="name_first" access="edit"/>
          <rule group="sobject_column" search_type="unittest/person" column="name_last" access="deny"/>
          <rule group="sobject_column" search_type="unittest/person" column="nationality" access="deny"/>
        </rules>
        """

        xml = Xml()
        xml.read_string(rules)
        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        # disable admin for this test
        access_manager.set_admin(False)


        # should succeed
        person.set_value("name_first", "Donny")
        # should fail
        try:
            person.set_value("name_last", "Ducky")
        except SecurityException, e:
            pass
コード例 #12
0
class Package(Command):
    def __init__(self, search_key, context, package):
        self.search_key = search_key
        self.context = context
        self.package = package

        self.package_xml = Xml()
        self.package_xml.read_string(package)

        super(Package, self).__init__()

    def execute(self):

        from tactic_client_lib import TacticServerStub
        server = TacticServerStub.get(protocol='local')

        # create a new snapshot
        snapshot = server.create_snapshot(self.search_key, self.context)

        # get all of the file_types

        file_nodes = self.package_xml.get_nodes("package/file_type")

        count = 0

        for file_node in file_nodes:
            name = self.package_xml.get_attribute(file_node, "name")

            values = self.package_xml.get_node_values_of_children(file_node)
            expression = values.get("expression")
            dir_naming = values.get("dir_naming")
            file_naming = values.get("file_naming")

            files = Search.eval(expression)

            for file in files:
                file_type = "%s%s" % (name, count)
                try:
                    # FIXME: the assumed action is to checkin
                    server.add_file(snapshot,
                                    file,
                                    file_type=file_type,
                                    mode='copy',
                                    dir_naming=dir_naming,
                                    file_naming=file_naming)

                    # What if we just wished to copy?  Can we run the files
                    # through a naming convention filter?

                    count += 1
                except Exception as e:
                    print "WARNING: ", str(e)
コード例 #13
0
ファイル: pipeline.py プロジェクト: zieglerm/TACTIC
    def create(name, desc, search_type, xml=None, code=None, color=None):
        '''will only create if it does not exist, otherwise it just updates'''

        if code:
            sobject = Pipeline.get_by_code(code)
        else:
            sobject = None

        if sobject == None:
            #sobject = Pipeline( Pipeline.SEARCH_TYPE )
            sobject = SearchType.create(Pipeline.SEARCH_TYPE)
        else:
            return sobject

        if not xml:
            xml = Xml()
            xml.create_doc('pipeline')

        if isinstance(xml, basestring):
            xml_string = xml
            xml = Xml()
            xml.read_string(xml_string)

        sobject.set_value("pipeline", xml.get_xml())
        sobject.set_pipeline(xml.to_string())

        sobject.set_value('timestamp',
                          Sql.get_default_timestamp_now(),
                          quoted=False)
        if code:
            sobject.set_value('code', code.strip())
        sobject.set_value('name', name.strip())
        sobject.set_value('search_type', search_type)
        sobject.set_value('description', desc)

        if color:
            sobject.set_value("color", color)

        sobject.commit()

        process_names = sobject.get_process_names()

        for i, process_name in enumerate(process_names):
            process = SearchType.create("config/process")
            process.set_value("pipeline_code", sobject.get_code())
            process.set_value("process", process_name)
            process.set_value("sort_order", i)
            process.set_value("subcontext_options", "(main)")
            process.commit()

        return sobject
コード例 #14
0
    def get_default_task_xml():
        global TASK_PIPELINE

        from pyasm.web import Palette
        palette = Palette.get()
        xml = Xml()
        xml.read_string(TASK_PIPELINE)
        nodes = Xml.get_nodes(xml, "pipeline/process")
        for node in nodes:
            process = Xml.get_attribute(node, "name")
            color = Task.get_default_color(process)
            Xml.set_attribute(node, "color", color)

        return xml.to_string()
コード例 #15
0
ファイル: search_wdg.py プロジェクト: zieglerm/TACTIC
    def execute(self):
        self.init()

        # create the filters
        self.filters = []

        config = "<config>\n"
        config += "<filter>\n"

        # get all of the serialized versions of the filters
        filter_data = FilterData.get()
        json = filter_data.serialize()
        value_type = "json"
        config += "<values type='%s'>%s</values>\n" % (value_type, json)
        config += "</filter>\n"
        config += "</config>\n"
        

        # format the xml
        xml = Xml()
        xml.read_string(config)


        if not self.view:
            saved_view = "saved_search:%s" % self.search_type
        else:
            saved_view = self.view
        #    if self.view.startswith("saved_search:"):
        #        saved_view = self.view
        #    else:
        #        saved_view = "saved_search:%s" % self.view

        # use widget config instead
        search = Search('config/widget_config')
        search.add_filter("view", saved_view)
        search.add_filter("search_type", self.search_type)
        if self.personal:
            search.add_user_filter()
        config = search.get_sobject()

        if not config:
            config = SearchType.create('config/widget_config')
            config.set_value("view", saved_view)
            config.set_value("search_type", self.search_type)
            if self.personal:
                config.set_user()

        config.set_value("category", "search_filter")
        config.set_value("config", xml.to_string())
        config.commit()
コード例 #16
0
ファイル: package.py プロジェクト: mincau/TACTIC
class Package(Command):

    def __init__(self, search_key, context, package):
        self.search_key = search_key
        self.context = context
        self.package = package

        self.package_xml = Xml()
        self.package_xml.read_string(package)

        super(Package, self).__init__()

        

    def execute(self):

        from tactic_client_lib import TacticServerStub
        server = TacticServerStub.get(protocol='local')

        # create a new snapshot
        snapshot = server.create_snapshot(self.search_key, self.context)

        # get all of the file_types

        file_nodes = self.package_xml.get_nodes("package/file_type")

        count = 0

        for file_node in file_nodes:
            name = self.package_xml.get_attribute(file_node, "name")

            values = self.package_xml.get_node_values_of_children(file_node)
            expression = values.get("expression")
            dir_naming = values.get("dir_naming")
            file_naming = values.get("file_naming")

            files =  Search.eval(expression)

            for file in files:
                file_type = "%s%s" % (name, count)
                try:
                    # FIXME: the assumed action is to checkin
                    server.add_file(snapshot, file, file_type=file_type, mode='copy', dir_naming=dir_naming, file_naming=file_naming)

                    # What if we just wished to copy?  Can we run the files
                    # through a naming convention filter?

                    count += 1
                except Exception as e:
                    print "WARNING: ", str(e)
コード例 #17
0
ファイル: task.py プロジェクト: CeltonMcGrath/TACTIC
    def get_default_task_xml():
        global TASK_PIPELINE

        from pyasm.web import Palette
        palette = Palette.get()
        xml = Xml()
        xml.read_string(TASK_PIPELINE)
        nodes = Xml.get_nodes(xml, "pipeline/process")
        for node in nodes:
            process = Xml.get_attribute(node, "name")
            color = Task.get_default_color(process)
            Xml.set_attribute(node, "color", color)

        return xml.to_string()
コード例 #18
0
ファイル: plugin.py プロジェクト: blezek/TACTIC
    def handle_include(my, node):
        path = my.xml.get_attribute(node, "path")
        if not path:
            raise TacticException("No path found for search type in manifest")

        path = "%s/%s" % (my.plugin_dir, path)

        if path.endswith(".py"):
            from tactic.command import PythonCmd
            cmd = PythonCmd(file_path=path)
            manifest = cmd.execute()

        xml = Xml()
        xml.read_string(manifest)
        nodes = xml.get_nodes("manifest/*")
        nodes.reverse()

        my.handle_nodes(nodes)
コード例 #19
0
ファイル: search_wdg.py プロジェクト: hellios78/TACTIC
 def get_default_filter_config(my):
     custom_filter_view = my.kwargs.get('custom_filter_view')
     config = '''
     <config>
     <filter>
       <element name='Filter'>
         <display class='tactic.ui.filter.GeneralFilterWdg'>
           <prefix>%(prefix_namespace)s_main_body</prefix>
           <search_type>%(search_type)s</search_type>
           <mode>sobject</mode>
         </display>
       </element>
     </filter>
     </config>
     ''' % {'search_type': my.searchable_search_type, 'prefix_namespace': my.prefix_namespace  }
     config_xml = Xml()
     config_xml.read_string(config)
     config = WidgetConfig.get(xml=config_xml, view='filter')
     return config
コード例 #20
0
ファイル: search_wdg.py プロジェクト: zieglerm/TACTIC
 def get_default_filter_config(self):
     custom_filter_view = self.kwargs.get('custom_filter_view')
     config = '''
     <config>
     <filter>
       <element name='Filter'>
         <display class='tactic.ui.filter.GeneralFilterWdg'>
           <prefix>%(prefix_namespace)s_main_body</prefix>
           <search_type>%(search_type)s</search_type>
           <mode>sobject</mode>
         </display>
       </element>
     </filter>
     </config>
     ''' % {'search_type': self.searchable_search_type, 'prefix_namespace': self.prefix_namespace  }
     config_xml = Xml()
     config_xml.read_string(config)
     config = WidgetConfig.get(xml=config_xml, view='filter')
     return config
コード例 #21
0
    def handle_include(my, node):
        path = my.xml.get_attribute(node, "path")
        if not path:
            raise TacticException("No path found for search type in manifest")

        path = "%s/%s" % (my.plugin_dir, path)

        if path.endswith(".py"):
            from tactic.command import PythonCmd
            cmd = PythonCmd(file_path=path)
            manifest = cmd.execute()

        if not manifest:
            return

        xml = Xml()
        xml.read_string(manifest)
        nodes = xml.get_nodes("manifest/*")
        nodes.reverse()

        my.handle_nodes(nodes)
コード例 #22
0
    def execute(self):

        mode = self.kwargs.get('mode')
        if not mode:
            mode = 'lib'


        transaction_xml = self.kwargs.get("transaction_xml")
        assert(transaction_xml)

        from pyasm.common import Xml, Environment

        if isinstance(transaction_xml, basestring):
            xml = Xml()
            xml.read_string(transaction_xml)
        else:
            xml = transaction_xml


        base_dir = Environment.get_asset_dir()
        paths = []


        # get all of the file nodes
        nodes = xml.get_nodes("transaction/file")
        for node in nodes:

            if xml.get_attribute(node, "type") == 'create':
                src = xml.get_attribute(node, "src")

                if mode == 'relative':
                    path = src
                else:
                    if src.startswith(base_dir):
                        path = src
                    else:
                        path = "%s/%s" % (base_dir, src)
                paths.append(path)

        return paths
コード例 #23
0
    def replace_elements(my, html_str):

        """
        # NOTE: this likely is a better way to extract elements, but still
        # need to find a way to inject html back into the xml
        xml = Xml()
        xml.read_string("<div>%s</div>" % html_str)
        elements = xml.get_nodes("//element")

        for element in elements:
            # create a complete config
            full_line_str = xml.to_string(element)
            tmp_config = '''<config><tmp>%s</tmp></config>''' % full_line_str

            try:
                element_wdg = my.get_element_wdg(xml, my.def_config)
                element_html = element_wdg.get_buffer_display()
            except Exception, e:
                from pyasm.widget import ExceptionWdg
                element_html = ExceptionWdg(e).get_buffer_display()

            xml = Xml()
            try:
                xml.read_string(element_html)
            except Exception, e:
                print "Error: ", e
                xml.read_string("<h1>%s</h1>" % str(e) )
            root = xml.get_root_node()

            parent = xml.get_parent(element)
            xml.replace_child(parent, element, root)

        return xml.to_string()
        """


        # a simple readline interpreter
        html = Html()
        full_line = []
        parse_context = None
        for line in html_str.split("\n"):
            line2 = line.strip()


            #if not parse_context and not line2.startswith('<element '):
            index = line2.find('<element>')
            if index == -1:
                index = line2.find('<element ')


            if not parse_context and index == -1:
                #line = Common.process_unicode_string(line)
                html.writeln(line)
                continue

            if index != -1:
                part1 = line2[:index]
                html.write(part1)
                line2 = line2[index:]

            full_line.append(line2)
            xml = Xml()
            # determine if this is valid xml
            try:
                # create a complete config
                full_line_str = "".join(full_line)
                tmp_config = '''<config><tmp>%s</tmp></config>''' % full_line_str
                xml.read_string(tmp_config, print_error=False)

                full_line = []
                parse_context = ''

            except XmlException, e:
                parse_context = 'element'
                #raise e
                continue

            try:
                element_wdg = my.get_element_wdg(xml, my.def_config)
                if element_wdg:
                    element_html = element_wdg.get_buffer_display()
                else:
                    element_html = ''
            except Exception, e:
                from pyasm.widget import ExceptionWdg
                element_html = ExceptionWdg(e).get_buffer_display()
コード例 #24
0
class PageNavContainerWdg(BaseRefreshWdg):
    def init(self):

        link = self.kwargs.get('link')
        hash = self.kwargs.get('hash')

        self.widget = None

        if link:
            from tactic.ui.panel import SideBarBookmarkMenuWdg
            personal = False
            if '.' in link:
                personal = True

            config = SideBarBookmarkMenuWdg.get_config("SideBarWdg",
                                                       link,
                                                       personal=personal)
            options = config.get_display_options(link)

            # this is vital for view saving
            element_name = link
            attr_dict = config.get_element_attributes(link)
            title = attr_dict.get('title')

            hash = "/tab/%s" % link

            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.panel.HashPanelWdg">
                <hash>%s</hash>
                <element_name>%s</element_name>
                <title>%s</title>
              </display>
              <web/>
            </element>
            </application>
            </config>
            ''' % (hash, element_name, title)

        elif hash:
            from tactic.ui.panel import HashPanelWdg
            self.widget = HashPanelWdg.get_widget_from_hash(
                hash, force_no_index=True)
            config = None

        else:
            security = Environment.get_security()
            start_link = security.get_start_link()
            if start_link:
                self.kwargs['link'] = start_link
                return self.init()

            # search for a defined welcome view
            search = Search("config/widget_config")
            search.add_filter("category", "top_layout")
            search.add_filter("view", "welcome")
            config_sobj = search.get_sobject()
            if config_sobj:
                config = config_sobj.get_value("config")

            else:
                config = WidgetSettings.get_value_by_key("top_layout")

        if not config:
            config = self.get_default_config()

        self.config_xml = Xml()
        self.config_xml.read_string(config)

    def get_default_config(self):
        use_sidebar = self.kwargs.get('use_sidebar')
        if use_sidebar == False:
            config = '''
            <config>
            <application>
            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        else:
            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
                <auto_size>True</auto_size>
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        return config

    def set_state(self, panel_name, widget_class, options, values):
        '''this is called by side_bar.js mostly'''

        # set the class name
        display_node = self.config_xml.get_node(
            "config/application/element[@name='%s']/display" % (panel_name))
        self.config_xml.set_attribute(display_node, "class", widget_class)

        # remove all the old options
        #display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % panel_name )
        for child_node in self.config_xml.get_children(display_node):
            self.config_xml.remove_child(display_node, child_node)

        # set the options
        for name, value in options.items():
            node = self.config_xml.get_node(
                "config/application/element[@name='%s']/display/%s" %
                (panel_name, name))

            if isinstance(value, basestring):
                #print("WARNING: set application: skipping [%s] with value [%s]" % (name, value))
                #continue
                element = self.config_xml.create_text_element(name, value)
                self.config_xml.append_child(display_node, element)

            elif isinstance(value, dict):  # if it is a dictionary
                # TODO: run recursively.. supports 2 level only now
                sub_element = self.config_xml.create_element(name)
                self.config_xml.append_child(display_node, element)
                for name2, value2 in value.items():
                    if isinstance(value2, dict):
                        sub_element2 = self.config_xml.create_element(name2)
                        self.config_xml.append_child(sub_element, sub_element2)
                        for name3, value3 in value2.items():
                            element = self.config_xml.create_text_element(
                                name3, value3)
                            self.config_xml.append_child(sub_element2, element)
                    else:
                        element = self.config_xml.create_text_element(
                            name2, value2)
                        self.config_xml.append_child(sub_element, element)

        # web value node
        value_node = self.config_xml.get_node(
            "config/application/element[@name='%s']/web" % (panel_name))
        if value_node != None:
            for child_node in self.config_xml.get_children(value_node):
                self.config_xml.remove_child(value_node, child_node)
        else:  # create it
            value_node = self.config_xml.create_element('web')
            element_node = self.config_xml.get_node(
                "config/application/element[@name='%s']" % (panel_name))
            self.config_xml.append_child(element_node, value_node)

        # set the values
        for name, value in values.items():
            node = self.config_xml.get_node(
                "config/application/element[@name='%s']/web/%s" %
                (panel_name, name))

            if not isinstance(value, basestring):
                print(
                    "WARNING: set application: skipping [%s] with value [%s]" %
                    (name, value))
                continue
            element = self.config_xml.create_text_element(name, value)
            self.config_xml.append_child(value_node, element)
        WidgetSettings.set_key_values("top_layout",
                                      [self.config_xml.to_string()])

    def get_state(self):
        return self.config_xml

    def get_side_bar_cache(self, left_nav_wdg):
        project = Project.get()
        project_code = project.get_code()

        # do it with sobject
        #key = "%s_side_bar" % project.get_code()
        #cache = Search.get("sthpw/widget_cache")
        #cache.add_filter("key", key)
        #sobject = cache.get_sobject()
        #value = sobject.get_value("cache")

        login = Environment.get_user_name()
        tmp_dir = "%s/cache/side_bar" % Environment.get_tmp_dir()

        filename = "%s__%s.html" % (project_code, login)
        path = "%s/%s" % (tmp_dir, filename)

        # use files
        import os
        if os.path.exists(path):
            f = open(path, "r")
            html = f.read()
            f.close()
        else:
            dirname = os.path.dirname(path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            f = open(path, "w")
            html = left_nav_wdg.get_buffer_display()
            f.write(html)
            f.close()

        return html

    def get_display(self):
        is_admin_project = Project.get().is_admin()
        security = Environment.get_security()
        if is_admin_project and not security.check_access(
                "builtin", "view_site_admin", "allow"):
            return Error403Wdg()

        # create the elements
        config = WidgetConfig.get(xml=self.config_xml, view="application")

        left_nav_handler = config.get_display_handler("left_nav")
        left_nav_options = config.get_display_options("left_nav")

        view_side_bar = None
        if left_nav_handler:
            left_nav_wdg = Common.create_from_class_path(
                left_nav_handler, [], left_nav_options)

            # caching
            side_bar_cache = self.get_side_bar_cache(left_nav_wdg)
        else:
            view_side_bar = False

        # create the main table
        core_table = Table()
        core_table.add_tbody()
        core_table.set_style(
            "border: 0px; border-collapse: collapse; width: 100%;")

        # add a spacer row
        #spacer_tr = core_table.add_row()
        #spacer_tr.add_style("width: 100%")
        #td = core_table.add_cell()
        #td.set_style("min-height: 1px; height: 1px;")
        #core_table.add_cell()
        #core_table.add_cell()

        # determine if the side bar is visible
        if view_side_bar == None:
            view_side_bar = security.check_access("builtin",
                                                  "view_side_bar",
                                                  "allow",
                                                  default='allow')

        # add the main cells
        tr, td = core_table.add_row_cell()
        td.add_style("padding: 0px")
        td.add_style("margin: 0px")

        # add the main resizable table
        from tactic.ui.container import ResizableTableWdg
        main_table = ResizableTableWdg()
        main_table.set_keep_table_size()

        main_table.add_style("width: 100%")

        td.add(main_table)

        left_nav_td = main_table.add_cell()
        if view_side_bar:
            left_nav_td.add_class("spt_panel")
            left_nav_td.add_style("padding: 0px")

        main_body_td = main_table.add_cell(resize=False)
        main_body_td.add_style("padding: 10px")
        main_body_td.set_style(
            "width: 100%; vertical-align: top; text-align: center; padding-top: 3px"
        )

        if view_side_bar:
            left_nav_td.set_style("vertical-align: top")

            # create the left navigation panel
            left_nav_div = DivWdg()
            left_nav_td.add(left_nav_div)

            left_nav_div.set_id("side_bar")
            # add the detail to the panel
            left_nav_div.add_attr("spt_class_name", left_nav_handler)
            for name, value in left_nav_options.items():
                left_nav_div.add_attr("spt_%s" % name, value)

            left_nav_div.add_style("max_width: 185px")
            left_nav_div.add_style("width: 185px")
            left_nav_div.add_style("text-align: right")
            left_nav_div.add_style("vertical-align: top")
            left_nav_div.add_style("overflow: hidden")

            left_nav_div.add_class("spt_resizable")
            side_bar_inner = DivWdg()
            left_nav_div.add(side_bar_inner)

            #side_bar_inner.add_style("padding-left: 1px")
            side_bar_inner.add_style("width: 100%")

            # add side bar to nav
            side_bar_inner.add(side_bar_cache)

            left_nav_div.add_style("border-style: solid")
            left_nav_div.add_style("border-width: 0px 1px 0px 0px")
            #left_nav_div.add_color("border-color", "border")
            left_nav_div.add_color("border-color", "border", -10)

            web = WebContainer.get_web()
            browser = web.get_browser()
            if browser in ['Qt', 'Webkit']:
                min_width = "1px"
            else:
                min_width = "0px"

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|hide_now',
                'min_width':
                min_width,
                'cbjs_action':
                '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                bvr.src_el.setStyle("width", bvr.min_width);

                '''
            })

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|hide',
                'min_width':
                min_width,
                'cbjs_action':
                '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width);

                '''
            })

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|show',
                'min_width':
                min_width,
                'cbjs_action':
                '''
                var width = bvr.src_el.getAttribute("spt_size");
                if (!width) {
                   width = 185;
                }
                if (parseInt(width) < 5) {
                    width = 185;
                }
                //bvr.src_el.setStyle("width", width + "px");
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px");
                '''
            })

            left_nav_div.add_behavior({
                'type':
                'listen',
                'event_name':
                'side_bar|toggle',
                'cbjs_action':
                '''
                var size = bvr.src_el.getSize();
                if (size.x < 5) {
                    spt.named_events.fire_event("side_bar|show", {} );
                }
                else {
                    spt.named_events.fire_event("side_bar|hide", {} );
                }
                '''
            })

        # create the main body panel

        palette = WebContainer.get_palette()
        color = palette.color("background2")
        main_body_rounded = DivWdg()
        main_body_inner = main_body_rounded

        main_body_inner.add_style("min-height: 500px")

        # DEBREACATED
        """
        # add a breadcrumb
        breadcrumb_wdg = DivWdg()
        # hide the breadcrumb
        breadcrumb_wdg.add_style("display", "none")
        Container.put("breadcrumb", breadcrumb_wdg)
        breadcrumb_wdg.set_id("breadcrumb")
        breadcrumb_wdg.add_style("text-align: left")
        breadcrumb_wdg.add_looks( "fnt_title_3" )
        main_body_inner.add(breadcrumb_wdg)
        """

        main_body_panel = DivWdg()
        main_body_panel.set_id("main_body")
        main_body_panel.add_class("spt_main_panel")
        main_body_inner.add(main_body_panel)

        tab = MainBodyTabWdg()
        main_body_panel.add(tab)

        # TEST: NEW LAYOUT
        if Config.get_value("install", "layout") == "fixed":
            main_body_panel.add_style("margin-top: 31px")
            main_body_rounded.add_color("background", "background")
            main_body_rounded.add_style("padding: 3px 0px 0px 0px")

        # add the content to the main body panel
        try:
            if self.widget:
                tab.add(self.widget)
                element_name = self.widget.get_name()

            else:
                main_body_handler = config.get_display_handler("main_body")
                main_body_options = config.get_display_options("main_body")
                element_name = main_body_options.get("element_name")
                title = main_body_options.get("title")

                main_body_content = Common.create_from_class_path(
                    main_body_handler, [], main_body_options)
                # get the web values from top_layout
                main_body_values = config.get_web_options("main_body")
                web = WebContainer.get_web()
                if isinstance(main_body_values, dict):
                    for name, value in main_body_values.items():
                        web.set_form_value(name, value)

                main_body_content.set_name(element_name)
                tab.add(main_body_content, element_name, title)

                self.set_as_panel(main_body_panel,
                                  class_name=main_body_handler,
                                  kwargs=main_body_options)

            main_body_panel.add_behavior({
                'type':
                'load',
                'element_name':
                element_name,
                'cbjs_action':
                '''
                if (spt.help)
                    spt.help.set_view(bvr.element_name);
                '''
            })

        except Exception as e:
            # handle an error in the drawing
            buffer = self.get_buffer_on_exception()
            error_wdg = self.handle_exception(e)
            main_body_content = DivWdg()
            main_body_content.add(error_wdg)
            main_body_content = main_body_content.get_buffer_display()
            tab.add(main_body_content, element_name, title)

        # add the main container
        container_div = DivWdg()
        container_div.set_style("width: 100%;")

        # NOTE: the td should not be the sliding element! So we create a div inside the TD to be the sliding element
        main_body_div = DivWdg()
        main_body_div.set_id("horizontal_main_body_slider")

        main_body_div.add(main_body_inner)
        """
        # get the global drag_ghost_div
        drag_ghost_div = self.get_drag_ghost_div()
        drag_ghost_div.set_id( "drag_ghost_copy" )
        drag_ghost_div.add_class( "SPT_PUW" )  # make it a Page Utility Widget (now processed client side)

        drag_ghost_div.set_z_start( 400 )
        """

        from page_header_wdg import PageHeaderWdg
        header_panel = DivWdg()
        header_panel.set_id("main_header")
        header_panel.add_attr("spt_class_name", "tactic.ui.app.PageHeaderWdg")
        header_wdg = PageHeaderWdg()
        header_panel.add(header_wdg)

        container_div.add(header_panel.get_buffer_display())

        main_body_dis = main_body_div.get_buffer_display()
        main_body_td.add(main_body_dis)

        container_div.add(core_table)
        #container_div.add( drag_ghost_div )

        is_admin = False
        security = Environment.get_security()
        if security.check_access("builtin", "view_site_admin", "allow"):
            is_admin = True

        if is_admin:
            from quick_box_wdg import QuickBoxWdg
            quick_box = QuickBoxWdg()
            container_div.add(quick_box)

        container_div.add_behavior({
            'type':
            'load',
            'cbjs_action':
            '''
            spt.named_events.fire_event("close_admin_bar");
            '''
        })

        return container_div

    def handle_exception(self, e):
        '''The tab widget is a special widget concerning exceptions because
        it usually represents the outer skin of the content of the web page.
        The titles of the tab must be displayed in order for the site to remain
        functional in the case of an exception'''
        from pyasm.widget import ExceptionWdg
        widget = ExceptionWdg(e)
        self.error_wdg = Widget()
        self.error_wdg.add(widget)
        return self.error_wdg

    """
    def get_drag_ghost_div(self):
        drag_ghost_div = HtmlElement.div()
        drag_ghost_div.set_attr( "id", "drag_ghost_copy" )
        drag_ghost_div.set_attr( "element_copied", "_NONE_" )
        drag_ghost_div.add_class( "REG_ID" )
        drag_ghost_div.set_style("background: #393950; color: #c2c2c2; border: solid 1px black;' \
                                 'text-align: left; padding: 10px;', filter: alpha(opacity=60); " +
                                 "opacity: 0.6; position: absolute; display: none; left: 0px; top: 0px;" +
                                 " z-index: 110;" )
        drag_ghost_div.add("Ghost Div")
        return drag_ghost_div
    """

    def get_drag_div(self):
        drag_div = HtmlElement.div()
        drag_div.set_style(
            "position: absolute; left: 100px; top: 400px; min-width: 400px; width: 400px; "
            + "background-color: white; border: solid black;")

        drag_handle_div = HtmlElement.div()
        drag_handle_div.set_style(
            "cursor: default; background-color: gray; border-bottom: dotted black; "
            + "padding: 3px; font-family: sans-serif; font-weight: bold;")

        # NOTE: to specify behaviors on a widget, you can use the .add_behavior() method ... use one behavior
        #       specification dictionary (hash) string per call to add_behavior (but you can add multiple
        #       behaviors by making multiple calls to add_behavior)
        #
        drag_handle_div.add_behavior(
            "{type:'click', mouse_btn:'LMB', modkeys:'SHIFT', dst_el:'@.parentNode', "
            + "cbfn_action: spt.cb.change_color_action}")
        drag_handle_div.add_behavior(
            "{type:'drag', mouse_btn:'LMB', modkeys:'', src_el:'@.parentNode'}"
        )
        drag_handle_div.add("Drag Handle -- click and drag me!")

        drag_div.add(drag_handle_div)
        drag_div.add(
            "<p>This is a draggable div ... click on the drag handle above and drag this thing around!</p>"
        )

        return drag_div
コード例 #25
0
    def execute(my):
        web = WebContainer.get_web()
        alter_mode = my.kwargs.get("alter_mode")
        title = my.kwargs.get("title")
        config_mode = web.get_form_value("config_mode")
        view = web.get_form_value('view')
        constraint = web.get_form_value("config_constraint")
        data_type = ''

        if config_mode == "advanced":
            config_string = web.get_form_value("config_xml")
            if config_string:
                xml = Xml()
                xml.read_string(config_string)
                node = xml.get_root_node()
                data_type = xml.get_attribute(node, "data_type")
                nullable = xml.get_attribute(node,
                                             "nullable") in ['true', 'True']

        else:
            data_type = web.get_form_value("config_data_type")
            if data_type == 'Other...':
                data_type = web.get_form_value("config_data_type_custom")
            cb = CheckboxWdg("config_nullable")
            nullable = cb.is_checked()

        # if advanced is selected in the Widget Column view, data_type is ''
        # read from UI
        if not data_type and view == 'definition':
            data_type = web.get_form_value("config_data_type")
            if data_type == 'Other...':
                data_type = web.get_form_value("config_data_type_custom")
            cb = CheckboxWdg("config_nullable")
            nullable = cb.is_checked()

        column_name = web.get_form_value("column_name")
        search_type = web.get_form_value("target_search_type")
        if alter_mode == ManageSearchTypeDetailWdg.REMOVE_COLUMN:
            cmd = ColumnDropCmd(search_type, column_name)
            Command.execute_cmd(cmd)
            # delete widget config from definition view
            widget_config = WidgetDbConfig.get_by_search_type(
                search_type, 'definition')
            if widget_config:
                config = WidgetConfig.get(
                    'definition', xml=widget_config.get_xml_value('config'))
                config.remove_xml_element(column_name)
                new_xml = config.get_xml().to_string()
                widget_config.set_value("config", new_xml)
                widget_config.commit()
                # set cache to {}
                from pyasm.common import Container

                Container.put("WidgetConfigView:config_cache", {})
                #Container.put("WidgetConfig:config_cache", {})
        elif alter_mode == ManageSearchTypeDetailWdg.MODIFY_COLUMN:
            cmd = ColumnAlterCmd(search_type, column_name, data_type, nullable)
            Command.execute_cmd(cmd)
            element_options = {}
            element_options['type'] = data_type
            if title:
                element_options['title'] = title

            # handle the "default" view
            # update the widget config data type in the xml
            view = my.DEFAULT_VIEW
            config = WidgetDbConfig.get_by_search_type(search_type, view)
            if config:
                config.append_display_element(column_name, options={}, \
                    element_attrs=element_options)
                config.commit_config()

        elif alter_mode == ManageSearchTypeDetailWdg.ADD_COLUMN:
            cmd = ColumnAddCmd(search_type, column_name, data_type, nullable)
            Command.execute_cmd(cmd)

        if constraint:
            # add constraint
            from pyasm.command import ColumnAddIndexWdg
            cmd = ColumnAddIndexWdg()
            cmd.execute()
        else:
            # remove constraint
            pass
コード例 #26
0
    def get_widget_from_hashXX(cls, hash, return_none=False, force_no_index=False, kwargs={}):

        from pyasm.web import DivWdg
        if hash.startswith("//"):
            use_top = False
            hash = hash[1:]
        else:
            use_top = True

        import re
        p = re.compile("^/(\w+)")
        m = p.search(hash)
        if not m:
            print "Cannot parse hash[%s]" % hash
            return DivWdg("Cannot parse hash [%s]" % hash)
        key = m.groups()[0]

        # add some predefined ones
        if key == "link":
            expression = "/link/{link}"
            options = Common.extract_dict(hash, expression)

            # This is the standard way of communicating through main interface
            # It uses the link keyword to draw the main widget
            if use_top:
                top_class_name = WebEnvironment.get_top_class_name()
                kwargs = {
                    "link": options.get("link")
                }
            else:
                top_class_name = 'tactic.ui.panel.HashPanelWdg'
                kwargs = {
                    "hash": hash.replace("/link", "/tab")
                }

                
            widget = Common.create_from_class_path(top_class_name, [], kwargs) 
            return widget

            #expression = "/link/{link}"
            #options = Common.extract_dict(hash, expression)
            #return cls.build_widget(options)


        elif key == 'tab':
            # this is called by PageNav
            expression = "/tab/{link}"
            options = Common.extract_dict(hash, expression)
            link = options.get("link")

            # test link security
            project_code = Project.get_project_code()
            security = Environment.get_security()
            link = options.get("link")
            keys = [
                    { "element": link },
                    { "element": "*" },
                    { "element": link, "project": project_code },
                    { "element": "*", "project": project_code }
            ]
            if not security.check_access("link", keys, "allow", default="deny"):
                widget = DivWdg()
                widget.add_color("color", "color")
                widget.add_color("background", "background3")
                widget.add_style("width: 600px")
                widget.add_style("height: 200px")
                widget.add_style("margin: 50px auto")
                widget.add_style("text-align: center")
                widget.add_border()


                widget.add("<br/>"*5)
                widget.add("This link [%s] either does not exist or you are not permitted to see it" % link)
                return widget
 


            from tactic.ui.panel import SideBarBookmarkMenuWdg
            personal = False
            if '.' in link:
                personal = True

            config = SideBarBookmarkMenuWdg.get_config("SideBarWdg", link, personal=personal)
            options = config.get_display_options(link)

            class_name = options.get("class_name")
            widget_key = options.get("widget_key")
            if widget_key:
                class_name = WidgetClassHandler().get_display_handler(widget_key)
            elif not class_name:
                class_name = 'tactic.ui.panel.ViewPanelWdg'
            widget = Common.create_from_class_path(class_name, [], options) 

            return widget

        # these show only the widget without a top
        elif key == "encoded":
            expression = "/encoded/{encoded}"
            options = Common.extract_dict(hash, expression)
            encoded = options['encoded']
            import json, binascii
            data = json.loads( binascii.unhexlify(encoded) )
            class_name = data[0]
            args = data[1]
            kwargs = data[2]

            widget = Common.create_from_class_path(class_name, args, kwargs) 
            return cls.build_widget(options)
            
        else:
            if key == "top":
                kwargs["use_index"] = True
                sobject = None
            else:
                # look up the url
                search = Search("config/url")
                search.add_filter("url", "/%s/%%"%key, "like")
                search.add_filter("url", "/%s"%key)
                search.add_where("or")
                sobject = search.get_sobject()

                if not sobject:
                    if return_none:
                        return None
                    return DivWdg("No Widget found for hash [%s]" % hash)
 

                config = sobject.get_value("widget")
                xml = Xml()
                xml.read_string(config)


            use_index = kwargs.get("use_index")
            if use_index in [True, 'true']:
                use_index = True
            elif use_index in [False, 'false']:
                use_index = False

            use_admin = kwargs.get("use_admin")
            if use_admin in [True, 'true']:
                use_admin = True
            elif use_admin in [False, 'false']:
                use_admin = False


            use_sidebar = kwargs.get("use_sidebar")
            if use_sidebar in [False, 'false']:
                use_sidebar = False
            elif use_admin in [True, 'true']:
                use_sidebar = True


            if use_index is not None or use_admin is not None:
                pass

            elif force_no_index in [True, 'true']:
                use_index = False
            else:
                use_index = sobject.get_value("index", no_exception=True)
                if not use_index:
                    use_index = xml.get_value("/element/@index");
                    if use_index in ['true', True]:
                        use_index = True

                use_admin = sobject.get_value("admin", no_exception=True)
                if not use_admin:
                    use_admin = xml.get_value("/element/@admin");
                    if use_admin in ['true', True]:
                        use_admin = True

                    use_sidebar = xml.get_value("/element/@sidebar");
                    if use_sidebar in ['false', False]:
                        use_sidebar = False


            if use_index or use_admin:
                # check if there is an index
                search = Search("config/url")
                search.add_filter("url", "/index")
                index = search.get_sobject()

                if not index or use_admin:
                    # use admin
                    from tactic.ui.app import PageNavContainerWdg
                    top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar )

                else:
                    config = index.get_value("widget")
                    xml = Xml()
                    xml.read_string(config)
                    node = xml.get_node("element/display")

                    options = {}
                    options.update(xml.get_node_values_of_children(node))

                    class_name = xml.get_value("element/display/@class")
                    if class_name:
                        options['class_name'] = class_name

                    # this passes the hash value to the index widget
                    # which must handle it accordingly
                    if key == "top":
                        hash = hash.replace("/top", "/tab")
                    options['hash'] = hash
                    top = cls.build_widget(options)



                return top.get_buffer_display()
 

            # build the widget
            if key == "top":
                class_name = 'tactic.ui.panel.HashPanelWdg'
                options = {
                    "hash": hash.replace("/link", "/tab"),
                    "class_name": class_name
                }
            else:
                url = sobject.get_value("url")
                url = url.strip()

                
                options = Common.extract_dict(hash, url)
                for name, value in kwargs.items():
                    options[name] = value

                node = xml.get_node("element/display")
                options.update(xml.get_node_values_of_children(node))

                class_name = xml.get_value("element/display/@class")
                if class_name:
                    options['class_name'] = class_name

            widget = cls.build_widget(options)

            name = hash.lstrip("/")
            name = name.replace("/", " ")
            widget.set_name(name)

            return widget
コード例 #27
0
    def get_text(my, path, last_path=None, highlight=True):

        if path.startswith("http"):
            if path.startswith("https://docs.google.com/document"):
                # NOTE: this is very specific to google docs
                if not path.endswith("?embedded=true"):
                    path = "%s?embedded=true" % path
                is_html = True
            else:
                is_html = False

            import urllib2
            response = urllib2.urlopen(path)
            html = response.read()

            fix = '''<meta content="text/html; charset=UTF-8" http-equiv="content-type">'''
            html = html.replace(fix, "")
            html = html.replace("&", "&amp;")

            if is_html:

                xml = Xml()
                try:
                    xml.read_string(html)
                except:
                    my.doc_mode = "formatted"
                    html = html.replace("&amp;", "&")
                    print
                    print "WARNING: cannot parse as XML"
                    print
                    return html

                if my.doc_mode == "formatted":
                    return xml.to_string().replace("&amp;", "&")

                node = xml.get_node("html/body")
                text = xml.to_string(node)
                text = text.replace("<body", "<div style='margin: 0px'")
                text = text.replace("</body>", "</div>")

                text = text.replace("&amp;", "&")

            else:
                text = html

            lines2 = []
            lines = text.split("\n")
            for line in lines:
                tmp_line = line.strip()
                if tmp_line.startswith("<span"):
                    tmp_line = tmp_line.replace("<span>", "")
                    tmp_line = tmp_line.replace("</span>", "")
                    tmp_line = tmp_line.replace("<span/>", "")
                elif tmp_line.startswith("<p "):
                    continue
                elif tmp_line.startswith("</p>"):
                    continue

                # FIXME: there has to be a function to do this
                tmp_line = tmp_line.replace("&nbsp;", "")
                tmp_line = tmp_line.replace("&quot;", '"')
                tmp_line = tmp_line.replace("&#39;", "'")
                lines2.append(tmp_line)

            text = "\n".join(lines2)

            #print 'text', text
            #import html2text
            #text = html2text.html2text(html)

            # clear out any remaining html tags
            import re
            text = re.sub('<[^<]+?>', '', text)

        else:
            f = open(path)
            lines = f.readlines()
            f.close()

            #f = open(path)
            #lines2 = f.readlines()
            #f.close()

            #diff = my.get_diff(lines, lines2)
            #text = "".join(diff)

            text = "".join(lines)

        # read last text if it exists
        if last_path and os.path.exists(last_path):
            last_file = open(last_path, 'r')
            last_text = last_file.read()
            last_file.close()
        else:
            last_text = None

        if last_text != None:
            lines = text.split("\n")
            lines2 = last_text.split("\n")
            diff = my.get_diff(lines2, lines)
            diff_text = "\n".join(diff)
            text = diff_text

        if highlight:
            search_type_obj = SearchType.get(my.search_type)
            color = search_type_obj.get_value("color")
            if not color:
                color = '#0F0'

            # assemble all the lines
            data = []

            search = Search(my.search_type)
            sobjects = search.get_sobjects()
            for sobject in sobjects:
                search_key = sobject.get_search_key()

                value = sobject.get_value(my.column)
                lines = value.split("\n")
                for line in lines:
                    line = line.strip()
                    data.append([line, search_key])

            for line, search_key in data:
                if not line:
                    continue

                line = line.strip()

                text = text.replace(
                    line,
                    "<i style='color: %s; font-weight: bold; opacity: 1.0;' spt_search_key='%s' class='spt_document_item hand'>%s</i>"
                    % (color, search_key, line))

        return text
コード例 #28
0
ファイル: panel_wdg.py プロジェクト: mincau/TACTIC
    def execute(self):

        print "kwargs: ", self.kwargs

        options = {}
        class_name = "tactic.ui.panel.CustomLayoutWdg"
        widget_key = ""
        for key, value in self.kwargs.items():
            if value == '':
                continue

            if key.startswith("xxx_option"):
                parts = key.split("|")
                option_key = parts[1]

                if option_key == "display_class":
                    class_name = value
                elif option_key == "widget_key":
                    widget_key = value
                else:
                    options[option_key] = value

            elif key.startswith("option|"):
                parts = key.split("|")
                option_key = parts[1]
                options[option_key] = value



        print "options: ", options

        name = self.kwargs.get("name")
        description = self.kwargs.get("description") or " "

        if not name:
            raise Exception("No name provided")


        name = Common.clean_filesystem_name(name)

        login = Environment.get_user_name()
        view = "pages.%s.%s" % (login, name)


        # find if this user page already exists
        search = Search("config/widget_config")
        search.add_filter("category", "CustomLayoutWg")
        search.add_filter("view", view)
        config = search.get_sobject()

        if config:
            raise Exception("Page with name [%s] already exists" % name)


        option_xml = []
        for key, value in options.items():
            option_xml.append("<%s>%s</%s>" % (key, value, key))
        option_str = "\n".join(option_xml)


        if widget_key:
            display_line = '''<display widget="%s">''' % widget_key
        else:
            display_line = '''<display class="%s">''' % class_name



        # all pages are custom layouts
        config_xml = '''<config>
  <%s>
    <html>
    <div style="margin: 20px">
      <div style="font-size: 25px">%s</div>
      <div>%s</div>
      <hr/>
      <element>
        %s
        %s
        </display>
      </element>
    </div>
    </html>
  </%s>
</config>
        ''' % (view, name, description, display_line, option_str, view)

        print "config_xml: ", config_xml

        xml = Xml()
        xml.read_string(config_xml)
        config_xml = xml.to_string()

        config = SearchType.create("config/widget_config")
        config.set_value("category", "CustomLayoutWdg")
        config.set_value("view", view)
        config.set_value("config", config_xml)

        config.commit()
コード例 #29
0
ファイル: panel_wdg.py プロジェクト: mincau/TACTIC
        config.set_value("config", config_xml)

        config.commit()











if __name__ == '__main__':

    from pyasm.security import Batch
    Batch()

    from pyasm.common import Xml
    from pyasm.web import WebContainer
    WebContainer.get_buffer()


    panel = PanelWdg()
    html = panel.get_buffer_display()
    xml = Xml()
    xml.read_string(html)
    print xml.to_string()

コード例 #30
0
ファイル: test_custom_wdg.py プロジェクト: 0-T-0/TACTIC
    def get_display(my):
        

        my.kwargs['search_key'] = 'prod/asset?project=sample3d&code=chr001'



        custom = """<?xml version='1.0' encoding='UTF-8'?>
        <custom>

        <html>
        <div>
            This is html
            <textarea class='spt_test spt_input' name='description'>
</textarea>
            <input class='spt_input' type='text' name='title'/>
            <br/>
            <input class='spt_button1' type='button' value='Press Me'/>
            <input class='spt_button2' type='button' value='Press Me2'/>
            <input class='spt_button3' type='button' value='Calendar'/>
            <input class='spt_refresh' type='button' value='Refresh'/>


            <element>
              <display class='tactic.ui.widget.CalendarWdg'/>
            </element>
            Much simpler!!!
            <elemeent class='CalendarWdg' blah='adasf'/>

        </div>
        </html>
        <behavior class='spt_button1'>{
            "type": "click_up",
            "cbjs_action": '''
            app.mel('sphere');
            //var top = bvr.src_el.getParent(".spt_panel");
            //var values = spt.api.Utility.get_input_values(top);
            //console.log(values);
            '''
        }</behavior>
        <behavior class='spt_button2'>{
            "type": "click_up",
            "cbjs_action": "alert(bvr.kwargs.search_key);"
        }</behavior>
        <behavior class='spt_button3'>{
            "type": "click_up",
            "cbjs_action": '''
            spt.panel.load('main_body', bvr.class_name, bvr.kwargs);
            //spt.panel.load('main_body', 'tactic.ui.widget.CalendarWdg', bvr.kwargs);
            '''
        }</behavior>
        <behavior class='spt_refresh'>{
            "type": "click_up",
            "cbjs_action": '''
            var top = bvr.src_el.getParent(".spt_panel");
            spt.panel.refresh(top);
            '''

        }</behavior>

        </custom>

        """

        xml = Xml()
        xml.read_string(custom)

        top = DivWdg()
        my.set_as_panel(top)
        top.add_class("spt_panel")

        inner = DivWdg()
        top.add(inner)

        html_node = xml.get_node("custom/html")
        html = xml.to_string(html_node)
        inner.add(html)

        behaviors = xml.get_nodes("custom/behavior")
        for behavior in behaviors:
            css_class = Xml.get_attribute(behavior, 'class')
            value = Xml.get_node_value(behavior)
            value = eval(value)

            # add the kwargs to this so behaviors have access
            value['kwargs'] = my.kwargs
            value['class_name'] = Common.get_full_class_name(my)

            inner.add_behavior({
                'type': 'load',
                'value': value,
                'css_class': css_class,
                'cbjs_action': '''
                var el = bvr.src_el.getElement("."+bvr.css_class);
                if (!el) {
                    alert("WARNING: element ["+bvr.css_clsss+"] does not exist");
                }
                spt.behavior.add( el, bvr.value);
                '''
            })


        if my.kwargs.get("is_refresh"):
            return inner
        else:
            return top
コード例 #31
0
    def execute(self):

        web = WebContainer.get_web()

        # get command line options
        search_type = self.kwargs.get("search_type")
        assert search_type

        view = self.kwargs.get("view")
        if not view:
            view = get_template_view()

        # check if this is advanced mode
        mode = web.get_form_value("custom_mode")
        if not mode:
            mode = 'simple'

        if mode == 'xml':
            config_string = web.get_form_value("config_xml")

            # handle the "default" view
            view = DEFAULT_VIEW
            config = WidgetDbConfig.get_by_search_type(search_type, view)
            if not config:
                config = WidgetDbConfig.create(search_type, view)

            xml = Xml()
            xml.read_string(config_string)
            element_name = xml.get_value("element/@name")
            element_name = element_name.strip()
            assert element_name

            type = xml.get_value("element/@type")
            if not type:
                class_name = xml.get_value("element/display/@class")

                if not class_name:
                    raise TacticException(
                        "Either a type or class name needs to be defined in config xml."
                    )

            config.append_xml_element(element_name, config_string)
            config.commit_config()

            # create the required columns
            widget = config.get_display_widget(element_name)
            columns = widget.get_required_columns()

            if columns:
                print("WARNING: need to create columns: ", columns)

            self.info['element_name'] = element_name

            return

        type = web.get_form_value("custom_type")
        description = web.get_form_value("custom_description")
        if not description:
            description = "No descripton"

        title = web.get_form_value("custom_title")

        name = web.get_form_value("custom_name")
        name = name.strip()
        if not name:
            raise TacticException("No name specified")

        add_to_current_view = web.get_form_value("add_to_current_view")
        add_to_edit_view = web.get_form_value("add_to_edit_view")
        is_searchable = web.get_form_value("is_searchable")

        # create the column
        if type not in ['button', 'empty']:
            cmd = ColumnAddCmd(search_type, name, type)
            cmd.execute()

        # create the type
        class_name = None
        options = {}
        # this is actually element attrs
        element_options = {}
        edit_class_name = None
        edit_options = {}
        edit_attrs = {}

        element_type = type

        # Date Range is not used any more in the UI"
        if type == "Date Range":
            class_name = "GanttWdg"
            options["start_date_column"] = "%s_start_date" % name
            options["end_deate_column"] = "%s_end_date" % name

        elif type == "date":
            class_name = "DateWdg"
            #edit_class_name = "CalendarWdg"

            element_type = 'timestamp'
            edit_attrs['type'] = 'timestamp'
            edit_class_name = ""
            add_to_edit_view = True

        elif type == "foreign_key":
            class_name = ""
            edit_class_name = "SelectWdg"
            foreign_search_type = web.get_form_value(
                "foreign_key_search_select")
            edit_options["query"] = '%s|code|code' % foreign_search_type

            # turn on add to edit view
            add_to_edit_view = True

        elif type == "button":
            class_name = "tactic.ui.table.ButtonElementWdg"
            script = web.get_form_value("option_script_select")
            if script:
                options['script'] = script
            icon = web.get_form_value("option_icon_select")
            if icon:
                options['icon'] = icon

            edit_class_name = ""

            # This does not have a type
            element_type = None

        elif type == "empty":
            element_type = None
            pass

        elif type == "list":
            class_name = ""
            edit_class_name = "SelectWdg"
            list_values = web.get_form_value("list_values")
            edit_options['values'] = list_values

            add_to_edit_view = True

        element_options['type'] = element_type
        element_options['title'] = title

        # handle the "default" view
        view = DEFAULT_VIEW
        config = WidgetDbConfig.get_by_search_type(search_type, view)
        if not config:
            config = WidgetDbConfig.create(search_type, view)
        config.append_display_element(name, class_name, options=options, \
                element_attrs=element_options)
        config.commit_config()

        # get the config file
        if add_to_current_view:
            config = WidgetDbConfig.get_by_search_type(search_type, view)

            if not config:
                # if it doesn't exist, the check to see, if there is a hard
                # coded view out there
                predefined_config = WidgetConfigView.get_by_search_type(
                    search_type, view)
                xml = predefined_config.get_xml()

                # create a new db one
                config = WidgetDbConfig.create(search_type, view)

                if xml:
                    config.set_value("config", xml.to_string())
                    config._init()

            config.append_display_element(name)
            config.commit_config()

        # TODO: Need to make this searchable using simple search ?????
        if is_searchable:
            element_options['searchable'] = 'true'

        # handle the "edit"
        if add_to_edit_view and view != "edit":
            config = WidgetDbConfig.get_by_search_type(search_type, "edit")
            if not config:
                config = WidgetDbConfig.create(search_type, "edit")
            config.append_display_element(name,
                                          edit_class_name,
                                          edit_options,
                                          element_attrs=edit_attrs)
            config.commit_config()
        """
        # this sType has been deprecated
        sobject = SearchType.create("prod/custom_property")
        sobject.set_value("search_type", search_type)
        sobject.set_value("name", name)
        sobject.set_value("description", description)
        sobject.commit()
        """

        # set some information
        self.description = "Added Property [%s] of type [%s] to [%s]" % \
            (name, type, search_type)

        self.info['element_name'] = name
コード例 #32
0
ファイル: test_custom_wdg.py プロジェクト: rajubuddha/TACTIC
    def get_display(my):

        my.kwargs['search_key'] = 'prod/asset?project=sample3d&code=chr001'

        custom = """<?xml version='1.0' encoding='UTF-8'?>
        <custom>

        <html>
        <div>
            This is html
            <textarea class='spt_test spt_input' name='description'>
</textarea>
            <input class='spt_input' type='text' name='title'/>
            <br/>
            <input class='spt_button1' type='button' value='Press Me'/>
            <input class='spt_button2' type='button' value='Press Me2'/>
            <input class='spt_button3' type='button' value='Calendar'/>
            <input class='spt_refresh' type='button' value='Refresh'/>


            <element>
              <display class='tactic.ui.widget.CalendarWdg'/>
            </element>
            Much simpler!!!
            <elemeent class='CalendarWdg' blah='adasf'/>

        </div>
        </html>
        <behavior class='spt_button1'>{
            "type": "click_up",
            "cbjs_action": '''
            app.mel('sphere');
            //var top = bvr.src_el.getParent(".spt_panel");
            //var values = spt.api.Utility.get_input_values(top);
            //console.log(values);
            '''
        }</behavior>
        <behavior class='spt_button2'>{
            "type": "click_up",
            "cbjs_action": "alert(bvr.kwargs.search_key);"
        }</behavior>
        <behavior class='spt_button3'>{
            "type": "click_up",
            "cbjs_action": '''
            spt.panel.load('main_body', bvr.class_name, bvr.kwargs);
            //spt.panel.load('main_body', 'tactic.ui.widget.CalendarWdg', bvr.kwargs);
            '''
        }</behavior>
        <behavior class='spt_refresh'>{
            "type": "click_up",
            "cbjs_action": '''
            var top = bvr.src_el.getParent(".spt_panel");
            spt.panel.refresh(top);
            '''

        }</behavior>

        </custom>

        """

        xml = Xml()
        xml.read_string(custom)

        top = DivWdg()
        my.set_as_panel(top)
        top.add_class("spt_panel")

        inner = DivWdg()
        top.add(inner)

        html_node = xml.get_node("custom/html")
        html = xml.to_string(html_node)
        inner.add(html)

        behaviors = xml.get_nodes("custom/behavior")
        for behavior in behaviors:
            css_class = Xml.get_attribute(behavior, 'class')
            value = Xml.get_node_value(behavior)
            value = eval(value)

            # add the kwargs to this so behaviors have access
            value['kwargs'] = my.kwargs
            value['class_name'] = Common.get_full_class_name(my)

            inner.add_behavior({
                'type':
                'load',
                'value':
                value,
                'css_class':
                css_class,
                'cbjs_action':
                '''
                var el = bvr.src_el.getElement("."+bvr.css_class);
                if (!el) {
                    alert("WARNING: element ["+bvr.css_clsss+"] does not exist");
                }
                spt.behavior.add( el, bvr.value);
                '''
            })

        if my.kwargs.get("is_refresh"):
            return inner
        else:
            return top
コード例 #33
0
ファイル: security_test.py プロジェクト: CeltonMcGrath/TACTIC
    def _test_access_manager(my):
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = AccessManager()

        xml = Xml()
        xml.read_string('''
        <rules>
          
       
          <rule group='sobject' key='corporate/budget' access='allow'/>
          <rule group='sobject'  key='corporate/salary' access='allow'/>
          <rule group='sobject'  key='prod/asset' access='edit'/>
          <rule group='sobject' search_type='sthpw/note'  project='sample3d' access='edit'/>
          <group type='url' default='deny'>
            <rule key='/tactic/bar/Partner' access='view'/>
            <rule key='/tactic/bar/External' access='view'/>
          </group>


          
            <rule group='sobject' search_type='prod/layer'  project='sample3d' access='view'/>
            <rule column='description'  search_type='prod/shot' access='view' group='sobject_column'/>
           
          <group type='sobject_column' default='edit'>
            <rule key='prod/asset|director_notes' access='deny'/>
            <rule key='prod/asset|sensitive_data' access='deny'/>
          </group>

      
          <rule group='search_type' code='prod/asset'   access='allow'/>

          <rule group='search_type' code='sthpw/note' project='unittest' access='edit'/>
          
           
          <rule group='search_type' code='unittest/person'  project='unittest' access='allow'/>
        
           </rules>
        ''')

        
    

        access_manager.add_xml_rules(xml)

        # test sensitive sobject
        test = access_manager.get_access('sobject', 'corporate/budget')
        my.assertEquals(test, "allow")

        # test allowed sobject
        test = access_manager.get_access('sobject', 'prod/asset')
        my.assertEquals(test, "edit")

        test = access_manager.get_access('sobject', [{'search_type':'sthpw/note', 'project':'sample3d'}])
        my.assertEquals(test, "edit")
        # test url
        test = access_manager.get_access('url', '/tactic/bar/Partner')
        my.assertEquals(test, "view")

        # test with access values ... a more typical usage
        test = access_manager.check_access('sobject','prod/asset','view')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject','corporate/budget','edit')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject_column', 'prod/asset|director_notes','deny')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject_column',{'search_type':'prod/shot','column':'description'},'edit')
        my.assertEquals(test, False)

        test = access_manager.check_access('sobject_column',{'search_type':'prod/shot','column':'description'},'view')
        my.assertEquals(test, True)


        test = access_manager.get_access('sobject',  {'search_type':'sthpw/note', 'project':'sample3d'} )
        my.assertEquals(test, "edit")
        test = access_manager.get_access('sobject', {'search_type':'sthpw/note'} )
        my.assertEquals(test, None)

        test = access_manager.get_access('sobject', {'search_type':'prod/layer', 'project':'sample3d'} )
        my.assertEquals(test, "view")
        test = access_manager.get_access('sobject', 'prod/layer' )
        my.assertEquals(test, None)

        # security version 2 uses group = search_type
        asset = SearchType.create('prod/asset')
        asset.set_value('name','unit test obj')
        asset.commit(triggers=False)
        # replace the access manager with this 
        Environment.get_security()._access_manager = access_manager
        
        test = access_manager.check_access('search_type',{'search_type':'prod/asset','project':'sample3d'},'delete')
        my.assertEquals(test, False)

        asset.delete()

        note = SearchType.create('sthpw/note')
        note.set_value('note','unit test note obj')
        note.set_value('project_code','unittest')
        note.commit(triggers=False)
        

        test = access_manager.get_access('search_type', [{'code':'sthpw/note', 'project':'unittest'}] )
        my.assertEquals(test, 'edit')
        msg = ''
        # delete of unittest note should fail
        try:
            note.delete()
        except SObjectException, e:
            msg = 'delete error'
コード例 #34
0
ファイル: pipeline.py プロジェクト: zieglerm/TACTIC
class Pipeline(SObject):
    '''Represents a pipeline of process and their relationships'''
    SEARCH_TYPE = "sthpw/pipeline"

    def __init__(self,
                 search_type="sthpw/pipeline",
                 columns=None,
                 result=None,
                 fast_data=None):
        super(Pipeline, self).__init__(search_type,
                                       columns,
                                       result,
                                       fast_data=fast_data)

        self.processes = []
        self.recursive_processes = []
        self.connects = {}
        self.pipeline_dict = {}
        #if columns != None:
        # putting no exception here to ensure that this can be put into
        # a select widget which no uses distinct for the value column
        xml_str = self.get_value("pipeline", no_exception=True)

        # don't cache a potential empty xml when Pipeline.create() is call
        if xml_str:
            self.set_pipeline(xml_str, cache=False)

        self.process_sobjects = None

    def get_defaults(self):
        '''The default, if not specified is to set the current project'''
        defaults = {}

        project_code = Project.get_project_code()
        defaults['project_code'] = project_code

        self.update_dependencies()

        return defaults

    def on_updateX(self):

        # initialize the triggers for the workflow
        """
        event = "change|sthpw/pipeline"
        trigger = SearchType.create("sthpw/trigger")
        trigger.set_value("event", event)
        trigger.set_value("class_name", ProjectPipelineTrigger)
        trigger.set_value("mode", "same process,same transaction")
        Trigger.append_static_trigger(trigger, startup=startup)
        """

        if self.SEARCH_TYPE == "config/pipeline":
            return

        code = self.get_value("code")
        search = Search("config/pipeline")
        search.add_filter("code", code)
        pipeline = search.get_sobject()

        if not pipeline:
            pipeline = SearchType.create("config/pipeline")

        items = self.data.items()

        for name, value in items:
            if name.startswith("__"):
                continue
            if name in ["id", "project_code"]:
                continue
            if not value:
                continue
            pipeline.set_value(name, value)

        pipeline.commit(triggers="none")

    def on_insertX(self):

        # Copy this to the config/pipeline table.  Currently this table
        # is not being used, however, pipelines really should be defined
        # there.  It is an unfortunate historical wart that pipelines
        # are stored in the sthpw database.  In some future release of
        # TACTIC, the pipeline table in the sthpw database will be deprecated
        # This copy will ensure that over time, the impact of this move over
        # will be minimized
        if self.SEARCH_TYPE == "config/pipeline":
            return
        search = Search("config/pipeline")
        search.add_filter("code", self.get_code())
        pipeline = search.get_sobject()

        if not pipeline:
            pipeline = SearchType.create("config/pipeline")
        for name, value in self.get_data().items():
            if name.startswith("__"):
                continue
            if name in ["id", "project_code"]:
                continue
            if not value:
                continue

            pipeline.set_value(name, value)

        pipeline.commit(triggers="none")

    def on_deleteX(self):
        if self.SEARCH_TYPE == "config/pipeline":
            return

        search = Search("config/pipeline")
        search.add_filter("code", self.get_code())
        pipeline = search.get_sobject()
        if pipeline:
            pipeline.delete()

    def update_dependencies(self):
        '''Function that should be run on insert/update. It's already automatically called during insert.
        On update, the caller needs to call this explicitly. It checks the search type
        this pipeline is associated with and if there is no pipeline code
        column, then update it.  It updates the process table also.'''
        search_type = self.get_value('search_type')
        self.update_process_table(search_type=search_type)

        # don't do anything for task sType
        if search_type == 'sthpw/task':
            return

        if not search_type:
            return

        if ProdSetting.get_value_by_key('autofill_pipeline_code') != 'false':
            try:
                columns = SearchType.get_columns(search_type)
                if not 'pipeline_code' in columns:
                    # add the pipeline code column
                    from pyasm.command import ColumnAddCmd
                    cmd = ColumnAddCmd(search_type, "pipeline_code", "varchar")
                    cmd.execute()
            except SqlException as e:
                print("Error creating column [pipeline_code] for %" %
                      search_type)
                pass

            # go through all of the sobjects and set all the empty ones
            # to the new pipeline
            search = Search(search_type)
            search.add_op("begin")
            search.add_filter("pipeline_code", "NULL", op='is', quoted=False)
            search.add_filter("pipeline_code", "")
            search.add_op("or")
            sobject_ids = search.get_sobject_ids()

            if sobject_ids:
                # this is much faster and memory efficient
                db_resource = SearchType.get_db_resource_by_search_type(
                    search_type)
                sql = DbContainer.get(db_resource)
                tbl = search.get_table()
                sobject_ids = [str(x) for x in sobject_ids]
                pipeline_code = self.get_value("code")
                sql.do_update(
                    '''UPDATE "%s" SET "pipeline_code" = '%s' WHERE id in (%s) '''
                    % (tbl, pipeline_code, ','.join(sobject_ids)))
            """
            for sobject in sobjects:    
                if not sobject.get_value("pipeline_code"):
                    sobject.set_value("pipeline_code", self.get_value("code") )
                    sobject.commit(triggers=False)
            """

    def update_process_table(self, search_type=None):
        ''' make sure to update process table'''

        template = self.get_template_pipeline()
        if template:
            if template.get_code() == self.get_code():
                template_processes = []
            else:
                template_processes = template.get_process_names()
        else:
            template_processes = []

        process_names = self.get_process_names()
        pipeline_code = self.get_code()

        search = Search("config/process")
        search.add_filter("pipeline_code", pipeline_code)
        process_sobjs = search.get_sobjects()
        existing_names = SObject.get_values(process_sobjs, 'process')

        pipeline_has_updates = False
        count = 1
        for process_name in process_names:

            exists = False
            for process_sobj in process_sobjs:
                # if it already exist, then update
                if process_sobj.get_value("process") == process_name:
                    exists = True
                    break

            if not exists:
                process_sobj = SearchType.create("config/process")

                # default to (main) for non-task status pipeline
                if search_type and search_type != 'sthpw/task':
                    process_sobj.set_value('subcontext_options', '(main)')
                process_sobj.set_value("pipeline_code", pipeline_code)
                process_sobj.set_value("process", process_name)

            # copy information over from the template
            if process_name in template_processes:
                template_attrs = template.get_process_attrs(process_name)
                process = self.get_process(process_name)
                for name, value in template_attrs.items():
                    if name in ['xpos', 'ypos', 'name']:
                        continue
                    process.set_attribute(name, value)
                    pipeline_has_updates = True

                search = Search("config/process")
                search.add_filter("process", process_name)
                # NEED ANOTHER FILTER for templates here
                search.add_filter("pipeline_code", "%/__TEMPLATE__", op="like")

                # copy certain values from the template
                template_process = search.get_sobject()
                for name, value in template_process.get_data().items():
                    if not value:
                        continue
                    if name in ['checkin_mode']:
                        process_sobj.set_value(name, value)

            attrs = self.get_process_attrs(process_name)
            color = attrs.get('color')
            if color:
                process_sobj.set_value("color", color)

            process_sobj.set_value("sort_order", count)
            process_sobj.commit()
            count += 1

        if pipeline_has_updates:
            self.set_value("pipeline", self.get_pipeline_xml().to_string())
            self.commit()

        # delete obsolete
        obsolete = set(existing_names) - set(process_names)
        if obsolete:
            for obsolete_name in obsolete:
                for process_sobj in process_sobjs:
                    if process_sobj.get_value("process") != obsolete_name:
                        continue
                    # FIXME: this node type is always None
                    process_obj = self.get_process(obsolete_name)
                    if process_obj:
                        node_type = process_obj.get_type()
                        try:
                            from pyasm.command import CustomProcessConfig
                            handler = CustomProcessConfig.get_delete_handler(
                                node_type, {})
                        except Exception as e:
                            handler = None

                        if handler:
                            handler.execute()

                    # delete it
                    process_sobj.delete()

    def get_name(self, long=False):
        '''this is the old function, kept for backward-compatibility'''
        #TODO: remove this function here
        return self.get_code()

    def set_pipeline(self, pipeline_xml, cache=True):
        '''set the pipeline externally'''
        # cache according to pipeline code, which will share the same xml object
        if self.is_insert():
            cache = False

        search_key = self.get_search_key()

        xml_dict = Container.get("Pipeline:xml")

        if xml_dict == None:
            xml_dict = {}
            Container.put("Pipeline:xml", xml_dict)

        self.xml = xml_dict.get(search_key)

        if self.xml == None:
            self.xml = Xml()
            if cache:
                xml_dict[search_key] = self.xml

            if not pipeline_xml:
                pipeline_xml = "<pipeline/>"

            try:
                self.xml.read_string(pipeline_xml)
            except XmlException as e:
                self.xml.read_string("<pipeline/>")

        # clear these again when set externally
        self.processes = []
        self.recursive_processes = []

        # create the process and pipelines
        process_nodes = self.xml.get_nodes(
            "pipeline/process | pipeline/pipeline")
        for node in process_nodes:
            node_name = self.xml.get_node_name(node)
            process = Process(node)
            process.set_parent_pipeline_code(self.get_code())
            self.processes.append(process)

            if node_name == "pipeline":
                name = Xml.get_attribute(node, "name")

                # prevent infinite loop
                if name == self.get_code():
                    continue

                child = Pipeline.get_by_code(name)
                if not child:
                    continue
                self.pipeline_dict[name] = child
                process.set_child_pipeline(child)

    def get_pipeline_xml(self):
        return self.xml

    def to_string(self):
        return self.xml.to_string()

    def get_process(self, name):
        '''returns a Process object'''
        if type(name) not in types.StringTypes:
            name = name.get_name()

        # first try the top level
        for process in self.processes:
            if process.get_name() == name:
                return process

        # Then iterate.  This may be slow
        processes = self.get_processes(recurse=True)

        for process in processes:
            if process.get_full_name() == name:
                return process
        return None
        #raise PipelineException( "Pipeline '%s' does not have process '%s'" % \
        #    (self.get_name(),name) )

    def get_processes(self, recurse=False, type=None):
        '''returns all the Process objects in this pipeline'''

        if type and isinstance(type, basestring):
            types = [type]
        else:
            types = type

        if recurse:
            if self.recursive_processes:
                return self.recursive_processes
            else:
                # add child processes
                for process in self.processes:

                    if types and process.get_type() not in types:
                        continue

                    self.recursive_processes.append(process)

                    child_pipeline = process.get_child_pipeline()
                    if not child_pipeline:
                        continue

                    child_processes = child_pipeline.get_processes(
                        recurse=recurse)
                    for x in child_processes:
                        x.set_sub_pipeline_process(True)
                    self.recursive_processes.extend(child_processes)
                return self.recursive_processes

        else:
            if types:
                ret_processes = []
                for process in self.processes:
                    if process.get_type() not in types:
                        continue
                    ret_processes.append(process)
                return ret_processes
            else:
                return self.processes

    def get_process_attrs(self, name):
        process = self.get_process(name)
        if process:
            return process.get_attributes()
        else:
            return {}

    def get_process_names(self, recurse=False, type=None):
        '''returns all the Process names in this pipeline'''

        if type and isinstance(type, basestring):
            types = [type]
        else:
            types = type

        processes = self.get_processes(recurse, type=types)
        if recurse:
            process_names = []
            for process in processes:
                if types and process.get_type() not in types:
                    continue

                if process.is_from_sub_pipeline():
                    process_names.append(process.get_full_name())
                else:
                    process_names.append(process.get_name())
            return process_names
        else:
            return [process.get_name() for process in processes]

    def get_process_sobject(self, process):
        # search all processes and cache all of the sobject locally
        if self.process_sobjects == None:

            search = Search("config/process")
            search.add_filter("pipeline_code", self.get_code())
            sobjects = search.get_sobjects()

            self.process_sobjects = {}

            for process_sobject in sobjects:
                # prevent changing variable process
                pcs = process_sobject.get("process")
                self.process_sobjects[pcs] = process_sobject

        process_sobject = self.process_sobjects.get(process)
        return process_sobject

    def get_process_sobjects(self):

        process_name = "dummy"

        self.get_process_sobject(process_name)

        return self.process_sobjects

    def get_index(self, name):
        index = 0
        for process in self.processes:
            if process.get_name() == name:
                return index
            index += 1

    def _get_connects(self, process="", direction='from'):

        if direction == "from":
            opposite = "to"
        else:
            opposite = "from"

        if not process:
            connect_nodes = self.xml.get_nodes("pipeline/connect")
        else:
            connect_nodes = self.xml.get_nodes(\
                "pipeline/connect[@%s='%s' or @%s='*']" % (direction, process, direction))
        connects = []
        for node in connect_nodes:
            opposite_name = Xml.get_attribute(node, opposite)
            full_name = "%s/%s" % (self.get_name(), opposite_name)
            if process == opposite_name or process == full_name:
                continue
            connects.append(ProcessConnect(node))
        return connects

    def get_input_processes(self, process, type=None, to_attr=None):
        connects = self._get_connects(process, direction='to')
        processes = []
        for connect in connects:

            if to_attr:
                connect_to_attr = connect.get_attr("to_attr")
                if connect_to_attr != to_attr:
                    continue

            from_connect = connect.get_from()
            process = self.get_process(from_connect)
            if process:
                if type and process.get_type() != type:
                    continue
                processes.append(process)

        return processes

    def get_input_process_names(self, process, type=None, from_attr=None):
        input_processes = self.get_input_processes(process, type, from_attr)
        process_names = [x.get_name() for x in input_processes]
        return process_names

    def get_output_processes(self, process, type=None, from_attr=None):
        connects = self._get_connects(process, direction="from")
        if not connects:
            return []

        processes = []
        for connect in connects:
            # make sure there are no empty contexts
            to = connect.get_to()

            if from_attr:
                connect_from_attr = connect.get_attr("from_attr")
                if connect_from_attr != from_attr:
                    continue

            to_pipeline = connect.get_to_pipeline()
            if to_pipeline:
                pipeline = Pipeline.get_by_code(to_pipeline)
                process = pipeline.get_process(to)

                if type and process.get_type() != type:
                    continue

                if process:
                    processes.append(process)

            else:
                process = self.get_process(to)
                if process:
                    processes.append(process)

        return processes

    def get_output_process_names(self, process, type=None, from_attr=None):
        output_processes = self.get_output_processes(process, type, from_attr)
        process_names = [x.get_name() for x in output_processes]
        return process_names

    def get_output_contexts(self, process, show_process=False):
        connects = self._get_connects(process, direction="from")
        if not connects:
            if show_process:
                data = (None, process)
            else:
                data = process
            return [data]

        contexts = []
        for connect in connects:
            # make sure there are no empty contexts
            context = connect.get_context()
            if not context:
                context = connect.get_to()

            if show_process:
                data = (connect.get_to(), context)
            else:
                data = context
            contexts.append(data)

        return contexts

    def get_input_contexts(self, process, show_process=False):
        connects = self._get_connects(process, direction='to')
        contexts = []
        for connect in connects:
            # make sure there are no empty contexts
            context = connect.get_context()
            if not context:
                context = connect.get_from()
            if show_process:
                data = (connect.get_from(), context)
            else:
                data = context
            contexts.append(data)

        return contexts

    def get_group(self, process_name):
        process = self.get_process(process_name)
        return process.get_group()

    def get_input_connects(self, process):
        connects = self._get_connects(process, direction="to")
        if not connects:
            return []
        else:
            return connects

    def get_output_connects(self, process):
        connects = self._get_connects(process, direction="from")
        if not connects:
            return []
        else:
            return connects

    # DEPRECATED
    def get_forward_connects(self, process):
        connects = self._get_connects(process)
        process_names = []
        for connect in connects:
            process_names.append(connect.get_to())

        return process_names

    # DEPRECATED
    def get_backward_connects(self, process):
        connects = self._get_connects(process, direction='to')

        process_names = []
        for connect in connects:
            process_names.append(connect.get_from())

        return process_names

    def get_all_contexts(self):
        connects = self._get_connects()

        contexts = []
        for connect in connects:
            context = connect.get_context()
            if context not in contexts:
                contexts.append(context)

        return contexts

    #
    # support for new pipeline methods
    #
    def get_input_snapshots(self,
                            sobject,
                            process_name,
                            input_name,
                            version='latest'):
        '''gets the snapshots of the input'''
        assert version in ['latest', 'current']

        process_node = self.xml.get_node(
            "pipeline/process[@name='%s']/input[@name='%s']" %
            (process_name, input_name))

        search_type = Xml.get_attribute(process_node, "search_type")
        context = Xml.get_attribute(process_node, "context")
        filter = Xml.get_attribute(process_node, "filter")

        # get the sobjects
        sobjects = sobject.get_all_children(search_type)

        # get the snapshots
        search = Search("sthpw/snapshot")
        search.add_filter('context', context)
        #if version == 'latest':
        #    search.add_filter("is_latest", 1)
        #elif version == 'current':
        #    search.add_filter("is_current", 1)

        # build filters for search_type, search_id combinations
        filters = []
        for sobject in sobjects:
            filter = "(\"search_type\" = '%s' and \"search_id\" = %s)" % (
                sobject.get_search_type(), sobject.get_id())
            filters.append(filter)

        search.add_where("( %s )" % " or ".join(filters))

        snapshots = search.get_sobjects()
        return snapshots

    #
    # Static methods
    #

    def create(name, desc, search_type, xml=None, code=None, color=None):
        '''will only create if it does not exist, otherwise it just updates'''

        if code:
            sobject = Pipeline.get_by_code(code)
        else:
            sobject = None

        if sobject == None:
            #sobject = Pipeline( Pipeline.SEARCH_TYPE )
            sobject = SearchType.create(Pipeline.SEARCH_TYPE)
        else:
            return sobject

        if not xml:
            xml = Xml()
            xml.create_doc('pipeline')

        if isinstance(xml, basestring):
            xml_string = xml
            xml = Xml()
            xml.read_string(xml_string)

        sobject.set_value("pipeline", xml.get_xml())
        sobject.set_pipeline(xml.to_string())

        sobject.set_value('timestamp',
                          Sql.get_default_timestamp_now(),
                          quoted=False)
        if code:
            sobject.set_value('code', code.strip())
        sobject.set_value('name', name.strip())
        sobject.set_value('search_type', search_type)
        sobject.set_value('description', desc)

        if color:
            sobject.set_value("color", color)

        sobject.commit()

        process_names = sobject.get_process_names()

        for i, process_name in enumerate(process_names):
            process = SearchType.create("config/process")
            process.set_value("pipeline_code", sobject.get_code())
            process.set_value("process", process_name)
            process.set_value("sort_order", i)
            process.set_value("subcontext_options", "(main)")
            process.commit()

        return sobject

    create = staticmethod(create)

    def get_by_code(cls, code, allow_default=False):
        '''it is fatal not to have a pipeline, so put a default'''
        if not code:
            return None

        # first look at project specific pipeline
        pipeline = Search.get_by_code("config/pipeline", code)

        if not pipeline:
            pipeline = super(Pipeline, cls).get_by_code(code)

        if not pipeline:
            if code == 'task':

                # Remap this to a default from projects settings
                task_code = ProjectSetting.get_by_key("task_pipeline")
                if not task_code:
                    task_code = "task"

                # Create a default task pipeline
                pipeline = SearchType.create("sthpw/pipeline")
                pipeline.set_value("code", task_code)
                from pyasm.biz import Task
                xml = Task.get_default_task_xml()
                pipeline.set_value("pipeline", xml)
                pipeline.set_pipeline(xml)
                pipeline.set_value("search_type", "sthpw/task")

            elif code == 'approval':
                # Create a default task approval pipeline
                pipeline = SearchType.create("sthpw/pipeline")
                pipeline.set_value("code", "approval")
                from pyasm.biz import Task
                xml = Task.get_default_approval_xml()
                pipeline.set_value("pipeline", xml)
                pipeline.set_pipeline(xml)
                pipeline.set_value("search_type", "sthpw/task")

            elif code == 'dependency':
                pipeline = SearchType.create("sthpw/pipeline")
                pipeline.set_value("code", "dependency")
                from pyasm.biz import Task
                xml = Task.get_default_dependency_xml()
                pipeline.set_value("pipeline", xml)
                pipeline.set_pipeline(xml)
                pipeline.set_value("search_type", "sthpw/task")

            elif code == 'progress':
                pipeline = SearchType.create("sthpw/pipeline")
                pipeline.set_value("code", "progress")
                from pyasm.biz import Task
                xml = Task.get_default_dependency_xml()
                pipeline.set_value("pipeline", xml)
                pipeline.set_pipeline(xml)
                pipeline.set_value("search_type", "sthpw/task")

            elif code == 'milestone':
                pipeline = SearchType.create("sthpw/pipeline")
                pipeline.set_value("code", "milestone")
                from pyasm.biz import Task
                xml = Task.get_default_milestone_xml()
                pipeline.set_value("pipeline", xml)
                pipeline.set_pipeline(xml)
                pipeline.set_value("search_type", "sthpw/milestone")

            elif code == 'snapshot':
                pipeline = SearchType.create("sthpw/pipeline")
                pipeline.set_value("code", "snapshot")
                from pyasm.biz import Task
                xml = Task.get_default_snapshot_xml()
                pipeline.set_value("pipeline", xml)
                pipeline.set_pipeline(xml)
                pipeline.set_value("search_type", "sthpw/snapshot")

        if not pipeline and allow_default:
            search = Search(cls)
            search.add_filter('code', 'default')
            pipeline = search.get_sobject()
            if not pipeline:

                pipeline = cls.create('default',  \
                    'default pipeline', '')

                xml = pipeline.get_xml_value("pipeline")

                # create a default process for the table
                root = xml.get_root_node()
                element = xml.create_element("process")
                Xml.set_attribute(element, "name", "default_process")
                Xml.append_child(root, element)

                pipeline.set_value('pipeline', xml.get_xml())
                pipeline.commit()

                # set the pipeline
                pipeline.set_pipeline(pipeline.get_value('pipeline'))
                Environment.add_warning("pipeline autogenerated", \
                    "[default] pipeline has just been created.")
        # Sometimes, a pipeline is instantiated without calling set_pipeline()
        # to be looked into
        if pipeline and not pipeline.get_processes():
            pipeline.set_pipeline(pipeline.get_value('pipeline'))
        return pipeline

    get_by_code = classmethod(get_by_code)

    # DEPRECATED
    def get_by_name(name):
        ''' for backward-compatibility, name has been renamed as code '''
        return Pipeline.get_by_code(name)

    get_by_name = staticmethod(get_by_name)

    def get_by_search_type(cls, search_type, project_code=''):
        # make sure this is a be search type
        assert search_type
        search_type_obj = SearchType.get(search_type)
        if not search_type_obj:
            return []
        search_type = search_type_obj.get_base_key()

        cache_key = "%s|%s" % (search_type, project_code)

        # commenting out until we have a full implementation of
        # project pipelines
        """
        search = Search("config/pipeline")
        if search_type:
            search.add_filter("search_type", search_type)
        search.add_project_filter(project_code)
        pipelines = cls.get_by_search(search, cache_key, is_multi=True)
        """

        search = Search("sthpw/pipeline")
        if search_type:
            search.add_filter("search_type", search_type)
        search.add_project_filter(project_code)
        pipelines = cls.get_by_search(search, cache_key, is_multi=True)
        if not pipelines:
            return []
        for pipe in pipelines:
            code = pipe.get_code()
            cls.cache_sobject('sthpw/pipeline|%s' % code, pipe)
        return pipelines

    get_by_search_type = classmethod(get_by_search_type)

    def get_process_name_dict(search_type,
                              project_code='',
                              is_group_restricted=False,
                              sobject=None):
        '''get process names for pipelines with a particular search type'''
        pipes = []
        if sobject:
            pipe_code = sobject.get_value('pipeline_code', no_exception=True)
            if pipe_code:
                pipe = Pipeline.get_by_code(pipe_code)
                if pipe:
                    pipes = [pipe]

        if not pipes:
            pipes = Pipeline.get_by_search_type(search_type, project_code)

        process_name_dict = {}

        my_group_names = LoginGroup.get_group_names()
        if pipes:
            for pipe in pipes:

                visible_process_names = []
                process_names = pipe.get_process_names(recurse=True)
                if is_group_restricted:
                    for process_name in process_names:
                        group_name = pipe.get_group(process_name)
                        if group_name and group_name not in my_group_names:
                            continue
                        else:
                            visible_process_names.append(process_name)
                else:
                    visible_process_names.extend(process_names)

                process_name_dict[pipe.get_code()] = visible_process_names

        return process_name_dict

    get_process_name_dict = staticmethod(get_process_name_dict)

    def get_default():
        return Pipeline.get_by_code("default")

    get_default = staticmethod(get_default)

    def get_process_select_data(search_type,
                                extra_process=[],
                                project_code='',
                                is_filter=False,
                                is_group_restricted=False,
                                sobject=None):
        '''get a tuple of data used for the SelectWdg'''
        context_dict = Pipeline.get_process_name_dict(search_type,
                                                      project_code,
                                                      is_group_restricted,
                                                      sobject=sobject)
        labels = []
        values = []
        keys = context_dict.keys()
        keys.sort()
        process_values = Common.sort_dict(context_dict)
        for idx, value in enumerate(process_values):
            key = keys[idx]
            labels.append('&lt;&lt; %s &gt;&gt;' % key)
            if is_filter:
                # add all the process names in this pipeline into the value
                values.append(','.join(value))
            else:
                values.append('')
            # extra process may not be needed
            if extra_process:
                value.extend(extra_process)

            if len(context_dict) > 1 and idx < len(context_dict) - 1:
                value.append('')

            values.extend(value)
            labels.extend(value)
        return labels, values

    get_process_select_data = staticmethod(get_process_select_data)

    def get_by_sobject(sobject, allow_default=False):
        ''' get the pipeline of the sobject'''
        pipeline_name = ''
        if not sobject:
            return None
        if sobject.has_value("pipeline_code"):
            pipeline_name = sobject.get_value("pipeline_code")
        elif sobject.has_value("pipeline"):
            pipeline_name = sobject.get_value("pipeline")
        pipeline = Pipeline.get_by_code(pipeline_name,
                                        allow_default=allow_default)
        return pipeline

    get_by_sobject = staticmethod(get_by_sobject)

    def get_template_pipeline(cls, search_type=None):
        search = Search("sthpw/pipeline")
        search.add_filter("name", "VFX Processes")
        pipeline = search.get_sobject()
        return pipeline

    get_template_pipeline = classmethod(get_template_pipeline)

    def create_pipeline_xml(cls,
                            statuses,
                            process_types=[],
                            process_xpos=[],
                            process_ypos=[]):
        '''create regular pipeline with process_types, xpos, ypos or plain task status pipeline'''
        if not statuses:
            statuses = []

        xml = []

        xml.append('''<pipeline>''')

        if process_types:

            for i, status in enumerate(statuses):

                if status == '':
                    continue

                process_type = process_types[i]

                if len(process_xpos) > i:
                    xpos = process_xpos[i]
                else:
                    xpos = None
                if len(process_ypos) > i:
                    ypos = process_ypos[i]
                else:
                    ypos = None

                if xpos and ypos:
                    xml.append(
                        '''  <process name="%s" type="%s" xpos="%s" ypos="%s"/>'''
                        % (status, process_type, xpos, ypos))
                else:
                    xml.append('''  <process name="%s" type="%s"/>''' %
                               (status, process_type))
        else:
            for status in statuses:
                if status == '':
                    continue
                xml.append('''  <process name="%s"/>''' % status)

        last_status = None
        for i, status in enumerate(statuses):
            if status == '':
                continue

            if i == 0 or last_status == None:
                last_status = status
                continue

            xml.append('''  <connect from="%s" to="%s"/>''' %
                       (last_status, status))
            last_status = status

        xml.append('''</pipeline>''')
        return "\n".join(xml)

    create_pipeline_xml = classmethod(create_pipeline_xml)
コード例 #35
0
class PageNavContainerWdg(BaseRefreshWdg):

    def init(self):

        link = self.kwargs.get('link')
        hash = self.kwargs.get('hash')
        
        self.widget = None

        if link:
            from tactic.ui.panel import SideBarBookmarkMenuWdg
            personal = False
            if '.' in link:
                personal = True

            config = SideBarBookmarkMenuWdg.get_config("SideBarWdg", link, personal=personal)
            options = config.get_display_options(link)

            # this is vital for view saving
            element_name = link
            attr_dict = config.get_element_attributes(link)
            title = attr_dict.get('title')

            hash = "/tab/%s" % link

           
            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.panel.HashPanelWdg">
                <hash>%s</hash>
                <element_name>%s</element_name>
                <title>%s</title>
              </display>
              <web/>
            </element>
            </application>
            </config>
            ''' % (hash, element_name, title)


        elif hash:
            from tactic.ui.panel import HashPanelWdg
            self.widget = HashPanelWdg.get_widget_from_hash(hash, force_no_index=True)
            config = None
 
        else:
            security = Environment.get_security()
            start_link = security.get_start_link()
            if start_link:
                self.kwargs['link'] = start_link
                return self.init()



            # search for a defined welcome view
            search = Search("config/widget_config")
            search.add_filter("category", "top_layout")
            search.add_filter("view", "welcome")
            config_sobj = search.get_sobject()
            if config_sobj:
                config = config_sobj.get_value("config")

            else:
                config = WidgetSettings.get_value_by_key("top_layout")


        if not config:
            config = self.get_default_config()


        self.config_xml = Xml()
        self.config_xml.read_string(config)



    def get_default_config(self):
        use_sidebar = self.kwargs.get('use_sidebar')
        if use_sidebar==False:
            config = '''
            <config>
            <application>
            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        else:
            config = '''
            <config>
            <application>
            <element name="left_nav">
              <display class="tactic.ui.panel.SideBarPanelWdg">
                <auto_size>True</auto_size>
              </display>
            </element>

            <element name="main_body">
              <display class="tactic.ui.startup.MainWdg"/>
              <web/>
            </element>
            </application>
            </config>
            '''
        return config









    def set_state(self, panel_name, widget_class, options, values):
        '''this is called by side_bar.js mostly'''

        # set the class name
        display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % (panel_name) )
        self.config_xml.set_attribute(display_node, "class", widget_class)

        # remove all the old options
        #display_node = self.config_xml.get_node("config/application/element[@name='%s']/display" % panel_name )
        for child_node in self.config_xml.get_children(display_node):
            self.config_xml.remove_child(display_node, child_node)

        # set the options
        for name, value in options.items():
            node = self.config_xml.get_node("config/application/element[@name='%s']/display/%s" % (panel_name, name) )

            if isinstance( value, basestring ):
                #print("WARNING: set application: skipping [%s] with value [%s]" % (name, value))
                #continue
                element = self.config_xml.create_text_element(name, value)
                self.config_xml.append_child(display_node, element)

            elif isinstance( value, dict): # if it is a dictionary
                # TODO: run recursively.. supports 2 level only now
                sub_element = self.config_xml.create_element(name)
                self.config_xml.append_child(display_node, element)
                for name2, value2 in value.items():
                    if isinstance(value2, dict):
                        sub_element2 = self.config_xml.create_element(name2)
                        self.config_xml.append_child(sub_element, sub_element2)
                        for name3, value3 in value2.items():
                            element = self.config_xml.create_text_element(name3, value3)
                            self.config_xml.append_child(sub_element2, element)
                    else:        
                        element = self.config_xml.create_text_element(name2, value2)
                        self.config_xml.append_child(sub_element, element)
                    
                
        # web value node
        value_node = self.config_xml.get_node("config/application/element[@name='%s']/web" % (panel_name) )
        if value_node != None:
            for child_node in self.config_xml.get_children(value_node):
                self.config_xml.remove_child(value_node, child_node)
        else: # create it
            value_node = self.config_xml.create_element('web')
            element_node = self.config_xml.get_node("config/application/element[@name='%s']" % (panel_name) )
            self.config_xml.append_child(element_node, value_node)

        # set the values
        for name, value in values.items():
            node = self.config_xml.get_node("config/application/element[@name='%s']/web/%s" % (panel_name, name) )

            if not isinstance(value, basestring):
                print("WARNING: set application: skipping [%s] with value [%s]" % (name, value))
                continue
            element = self.config_xml.create_text_element(name, value)
            self.config_xml.append_child(value_node, element)
        WidgetSettings.set_key_values("top_layout", [self.config_xml.to_string()])



    def get_state(self):
        return self.config_xml



    def get_side_bar_cache(self, left_nav_wdg):
        project = Project.get()
        project_code = project.get_code()

        # do it with sobject
        #key = "%s_side_bar" % project.get_code()
        #cache = Search.get("sthpw/widget_cache")
        #cache.add_filter("key", key)
        #sobject = cache.get_sobject()
        #value = sobject.get_value("cache")

        login = Environment.get_user_name()
        tmp_dir = "%s/cache/side_bar" % Environment.get_tmp_dir()

        filename = "%s__%s.html" % (project_code, login)
        path = "%s/%s" % (tmp_dir, filename)

        # use files
        import os
        if os.path.exists(path):
            f = open(path, "r")
            html = f.read()
            f.close()
        else:            
            dirname = os.path.dirname(path)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            f = open(path, "w")
            html = left_nav_wdg.get_buffer_display()
            f.write(html)
            f.close()

        return html




    def get_display(self):
        is_admin_project = Project.get().is_admin()
        security = Environment.get_security() 
        if is_admin_project and not security.check_access("builtin", "view_site_admin", "allow"):
            return Error403Wdg()
                
        # create the elements
        config = WidgetConfig.get(xml=self.config_xml, view="application")

        left_nav_handler = config.get_display_handler("left_nav")
        left_nav_options = config.get_display_options("left_nav")

        view_side_bar = None
        if left_nav_handler:
            left_nav_wdg = Common.create_from_class_path(left_nav_handler, [], left_nav_options)

            # caching
            side_bar_cache = self.get_side_bar_cache(left_nav_wdg)
        else:
            view_side_bar = False

        # create the main table
        core_table = Table()
        core_table.add_tbody()
        core_table.set_style("border: 0px; border-collapse: collapse; width: 100%;")


        # add a spacer row
        #spacer_tr = core_table.add_row()
        #spacer_tr.add_style("width: 100%")
        #td = core_table.add_cell()
        #td.set_style("min-height: 1px; height: 1px;")
        #core_table.add_cell()
        #core_table.add_cell()

        # determine if the side bar is visible
        if view_side_bar == None:
            view_side_bar = security.check_access("builtin", "view_side_bar", "allow", default='allow')


        # add the main cells
        tr, td = core_table.add_row_cell()
        td.add_style("padding: 0px")
        td.add_style("margin: 0px")

        # add the main resizable table
        from tactic.ui.container import ResizableTableWdg
        main_table = ResizableTableWdg()
        main_table.set_keep_table_size()

        main_table.add_style("width: 100%")

        td.add(main_table)

        left_nav_td = main_table.add_cell()
        if view_side_bar:
            left_nav_td.add_class("spt_panel")
            left_nav_td.add_style("padding: 0px")

        main_body_td = main_table.add_cell(resize=False)
        main_body_td.add_style("padding: 10px")
        main_body_td.set_style( "width: 100%; vertical-align: top; text-align: center; padding-top: 3px" )

        if view_side_bar:
            left_nav_td.set_style( "vertical-align: top" )

            # create the left navigation panel
            left_nav_div = DivWdg()
            left_nav_td.add(left_nav_div)

            left_nav_div.set_id("side_bar" )
            # add the detail to the panel
            left_nav_div.add_attr("spt_class_name", left_nav_handler)
            for name, value in left_nav_options.items():
                left_nav_div.add_attr("spt_%s" % name, value)


            left_nav_div.add_style("max_width: 185px")
            left_nav_div.add_style("width: 185px")
            left_nav_div.add_style("text-align: right")
            left_nav_div.add_style("vertical-align: top")
            left_nav_div.add_style("overflow: hidden")

            left_nav_div.add_class("spt_resizable")
            side_bar_inner = DivWdg()
            left_nav_div.add(side_bar_inner)

            #side_bar_inner.add_style("padding-left: 1px")
            side_bar_inner.add_style("width: 100%")

            # add side bar to nav
            side_bar_inner.add(side_bar_cache)

            left_nav_div.add_style("border-style: solid")
            left_nav_div.add_style("border-width: 0px 1px 0px 0px")
            #left_nav_div.add_color("border-color", "border")
            left_nav_div.add_color("border-color", "border", -10)

            web = WebContainer.get_web()
            browser = web.get_browser()
            if browser in ['Qt','Webkit']:
                min_width = "1px"
            else:
                min_width = "0px"

            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|hide_now',
                'min_width': min_width,
                'cbjs_action': '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                bvr.src_el.setStyle("width", bvr.min_width);

                '''
            } )


            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|hide',
                'min_width': min_width,
                'cbjs_action': '''
                var size = bvr.src_el.getSize();
                bvr.src_el.setAttribute("spt_size", size.x);
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width);

                '''
            } )


            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|show',
                'min_width': min_width,
                'cbjs_action': '''
                var width = bvr.src_el.getAttribute("spt_size");
                if (!width) {
                   width = 185;
                }
                if (parseInt(width) < 5) {
                    width = 185;
                }
                //bvr.src_el.setStyle("width", width + "px");
                new Fx.Tween(bvr.src_el, {duration:'short'}).start('width', bvr.min_width, width+"px");
                '''
            } )


            left_nav_div.add_behavior( {
                'type': 'listen',
                'event_name': 'side_bar|toggle',
                'cbjs_action': '''
                var size = bvr.src_el.getSize();
                if (size.x < 5) {
                    spt.named_events.fire_event("side_bar|show", {} );
                }
                else {
                    spt.named_events.fire_event("side_bar|hide", {} );
                }
                '''
            } )




        # create the main body panel

        palette = WebContainer.get_palette()
        color = palette.color("background2")
        main_body_rounded = DivWdg()
        main_body_inner = main_body_rounded

        main_body_inner.add_style("min-height: 500px")


        # DEBREACATED
        """
        # add a breadcrumb
        breadcrumb_wdg = DivWdg()
        # hide the breadcrumb
        breadcrumb_wdg.add_style("display", "none")
        Container.put("breadcrumb", breadcrumb_wdg)
        breadcrumb_wdg.set_id("breadcrumb")
        breadcrumb_wdg.add_style("text-align: left")
        breadcrumb_wdg.add_looks( "fnt_title_3" )
        main_body_inner.add(breadcrumb_wdg)
        """

        main_body_panel = DivWdg()
        main_body_panel.set_id("main_body")
        main_body_panel.add_class("spt_main_panel")
        main_body_inner.add(main_body_panel)


        tab = MainBodyTabWdg()
        main_body_panel.add(tab)

        # TEST: NEW LAYOUT
        if Config.get_value("install", "layout") == "fixed":
            main_body_panel.add_style("margin-top: 31px")
            main_body_rounded.add_color("background", "background")
            main_body_rounded.add_style("padding: 3px 0px 0px 0px")



        # add the content to the main body panel
        try:
            if self.widget:
                tab.add(self.widget)
                element_name = self.widget.get_name()

            else:
                main_body_handler = config.get_display_handler("main_body")
                main_body_options = config.get_display_options("main_body")
                element_name = main_body_options.get("element_name")
                title = main_body_options.get("title")

                main_body_content = Common.create_from_class_path(main_body_handler, [], main_body_options)
                # get the web values from top_layout
                main_body_values = config.get_web_options("main_body")
                web = WebContainer.get_web()
                if isinstance(main_body_values, dict):
                    for name, value in main_body_values.items():
                        web.set_form_value(name, value)

                main_body_content.set_name(element_name)
                tab.add(main_body_content, element_name, title)

                self.set_as_panel(main_body_panel, class_name=main_body_handler, kwargs=main_body_options)

            main_body_panel.add_behavior( {
                'type': 'load',
                'element_name': element_name,
                'cbjs_action': '''
                if (spt.help)
                    spt.help.set_view(bvr.element_name);
                '''
            } )


           
        except Exception as e:
            # handle an error in the drawing
            buffer = self.get_buffer_on_exception()
            error_wdg = self.handle_exception(e)
            main_body_content = DivWdg()
            main_body_content.add(error_wdg)
            main_body_content = main_body_content.get_buffer_display()
            tab.add(main_body_content, element_name, title)


        # add the main container
        container_div = DivWdg()
        container_div.set_style("width: 100%;")


        # NOTE: the td should not be the sliding element! So we create a div inside the TD to be the sliding element
        main_body_div = DivWdg()
        main_body_div.set_id("horizontal_main_body_slider")

        main_body_div.add(main_body_inner)



        """
        # get the global drag_ghost_div
        drag_ghost_div = self.get_drag_ghost_div()
        drag_ghost_div.set_id( "drag_ghost_copy" )
        drag_ghost_div.add_class( "SPT_PUW" )  # make it a Page Utility Widget (now processed client side)

        drag_ghost_div.set_z_start( 400 )
        """
       

        from page_header_wdg import PageHeaderWdg
        header_panel = DivWdg()
        header_panel.set_id("main_header")
        header_panel.add_attr("spt_class_name", "tactic.ui.app.PageHeaderWdg")
        header_wdg = PageHeaderWdg()
        header_panel.add(header_wdg)

        container_div.add( header_panel.get_buffer_display() )
       

        main_body_dis = main_body_div.get_buffer_display()
        main_body_td.add(main_body_dis) 


        container_div.add( core_table )
        #container_div.add( drag_ghost_div )


        is_admin = False
        security = Environment.get_security()
        if security.check_access("builtin", "view_site_admin", "allow"):
            is_admin = True

        if is_admin:
            from quick_box_wdg import QuickBoxWdg
            quick_box = QuickBoxWdg()
            container_div.add(quick_box)


        container_div.add_behavior( {
            'type': 'load',
            'cbjs_action': '''
            spt.named_events.fire_event("close_admin_bar");
            '''
        } )


        return container_div



    def handle_exception(self, e):
        '''The tab widget is a special widget concerning exceptions because
        it usually represents the outer skin of the content of the web page.
        The titles of the tab must be displayed in order for the site to remain
        functional in the case of an exception'''
        from pyasm.widget import ExceptionWdg
        widget = ExceptionWdg(e)
        self.error_wdg = Widget()
        self.error_wdg.add(widget)
        return self.error_wdg



    """
    def get_drag_ghost_div(self):
        drag_ghost_div = HtmlElement.div()
        drag_ghost_div.set_attr( "id", "drag_ghost_copy" )
        drag_ghost_div.set_attr( "element_copied", "_NONE_" )
        drag_ghost_div.add_class( "REG_ID" )
        drag_ghost_div.set_style("background: #393950; color: #c2c2c2; border: solid 1px black;' \
                                 'text-align: left; padding: 10px;', filter: alpha(opacity=60); " +
                                 "opacity: 0.6; position: absolute; display: none; left: 0px; top: 0px;" +
                                 " z-index: 110;" )
        drag_ghost_div.add("Ghost Div")
        return drag_ghost_div
    """


    def get_drag_div(self):
        drag_div = HtmlElement.div()
        drag_div.set_style( "position: absolute; left: 100px; top: 400px; min-width: 400px; width: 400px; " +
                            "background-color: white; border: solid black;" )

        drag_handle_div = HtmlElement.div()
        drag_handle_div.set_style( "cursor: default; background-color: gray; border-bottom: dotted black; " +
                                    "padding: 3px; font-family: sans-serif; font-weight: bold;" )

        # NOTE: to specify behaviors on a widget, you can use the .add_behavior() method ... use one behavior
        #       specification dictionary (hash) string per call to add_behavior (but you can add multiple
        #       behaviors by making multiple calls to add_behavior)
        #
        drag_handle_div.add_behavior( "{type:'click', mouse_btn:'LMB', modkeys:'SHIFT', dst_el:'@.parentNode', " +
                                      "cbfn_action: spt.cb.change_color_action}" )
        drag_handle_div.add_behavior( "{type:'drag', mouse_btn:'LMB', modkeys:'', src_el:'@.parentNode'}" )
        drag_handle_div.add("Drag Handle -- click and drag me!")

        drag_div.add( drag_handle_div )
        drag_div.add( "<p>This is a draggable div ... click on the drag handle above and drag this thing around!</p>" )

        return drag_div
コード例 #36
0
    def _test_access_manager(my):
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = Environment.get_security().get_access_manager()

        xml = Xml()
        xml.read_string('''
        <rules>
          
       
          <rule group='sobject' key='corporate/budget' access='allow'/>
          <rule group='sobject'  key='corporate/salary' access='allow'/>
          <rule group='sobject'  key='prod/asset' access='edit'/>
          <rule group='sobject' search_type='sthpw/note'  project='sample3d' access='edit'/>
          <group type='url' default='deny'>
            <rule key='/tactic/bar/Partner' access='view'/>
            <rule key='/tactic/bar/External' access='view'/>
          </group>


          
            <rule group='sobject' search_type='prod/layer'  project='sample3d' access='view'/>
            <rule column='description'  search_type='prod/shot' access='view' group='sobject_column'/>
           
          <group type='sobject_column' default='edit'>
            <rule key='prod/asset|director_notes' access='deny'/>
            <rule key='prod/asset|sensitive_data' access='deny'/>
          </group>

      
          <rule group='search_type' code='prod/asset'   access='allow'/>

          <rule group='search_type' code='sthpw/note' project='unittest' access='edit'/>
          
           
          <rule group='search_type' code='unittest/person'  project='unittest' access='allow'/>
          <rule group='builtin' key='view_site_admin' access='allow'/>
          <rule group='builtin' key='export_all_csv' project='unittest' access='allow'/>
          <rule group='builtin' key='import_csv' access='allow'/>

          <rule group='builtin' key='retire_delete' project='*' access='allow'/>
          <rule group='builtin' key='view_side_bar' access='allow'/>
                  
           </rules>
        ''')
        access_manager.add_xml_rules(xml)

        # try mixing in a 2nd login_group rule with a project override, mimmicking a
        # login_group with project_code. but project group is special it doesn't get the usual
        # project_override treatment
        xml2 = Xml()
        xml2.read_string('''
        <rules>
          <rule group="project" code="sample3d" access="allow"/>
          <rule group="project" code="unittest" access="allow"/>

          <rule group='builtin' key='view_side_bar' project='sample3d' access='allow'/>
        </rules>
        ''')

        access_manager.add_xml_rules(xml2)

        access_manager.print_rules('project')

        test = access_manager.check_access('builtin', 'view_site_admin',
                                           'allow')
        my.assertEquals(test, True)

        Project.set_project('sample3d')
        test = access_manager.check_access('builtin', 'export_all_csv',
                                           'allow')
        my.assertEquals(test, False)

        # old way of checking project
        test = access_manager.check_access('project', 'sample3d', 'allow')
        my.assertEquals(test, True)

        Project.set_project('unittest')
        # old way should work as well
        test = access_manager.check_access('builtin', 'export_all_csv',
                                           'allow')
        my.assertEquals(test, True)

        # default to the system's hardcoded deny for builtin
        test = access_manager.check_access('builtin',
                                           'export_all_csv',
                                           'allow',
                                           default='deny')
        my.assertEquals(test, True)

        # this is the new way to control per project csv export
        keys = [{
            'key': 'export_all_csv',
            'project': 'unittest'
        }, {
            'key': 'export_all_csv',
            'project': '*'
        }]
        test = access_manager.check_access('builtin', keys, 'allow')
        my.assertEquals(test, True)
        keys = [{
            'key': 'import_csv',
            'project': '*'
        }, {
            'key': 'import_csv',
            'project': Project.get_project_code()
        }]
        test = access_manager.check_access('builtin', keys, 'allow')
        my.assertEquals(test, True)

        test = access_manager.check_access('builtin', 'view_side_bar', 'allow')
        my.assertEquals(test, True)
        key = {"project": 'unittest', 'key': 'view_side_bar'}
        key1 = {"project": 'sample3d', 'key': 'view_side_bar'}
        key2 = {"project": "*", 'key': 'view_side_bar'}
        keys = [key, key2]
        test = access_manager.check_access('builtin', keys, 'allow')
        my.assertEquals(test, True)
        keys = [key1, key2]
        test = access_manager.check_access('builtin', keys, 'allow')
        my.assertEquals(test, True)

        test = access_manager.check_access('builtin', 'retire_delete', 'allow')

        my.assertEquals(test, True)

        # test sensitive sobject
        test = access_manager.get_access('sobject', 'corporate/budget')
        my.assertEquals(test, "allow")

        # test allowed sobject
        test = access_manager.get_access('sobject', 'prod/asset')
        my.assertEquals(test, "edit")

        test = access_manager.get_access('sobject', [{
            'search_type': 'sthpw/note',
            'project': 'sample3d'
        }])
        my.assertEquals(test, "edit")
        # test url
        test = access_manager.get_access('url', '/tactic/bar/Partner')
        my.assertEquals(test, "view")

        # test with access values ... a more typical usage
        test = access_manager.check_access('sobject', 'prod/asset', 'view')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject', 'corporate/budget',
                                           'edit')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject_column',
                                           'prod/asset|director_notes', 'deny')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject_column', {
            'search_type': 'prod/shot',
            'column': 'description'
        }, 'edit')
        my.assertEquals(test, False)

        test = access_manager.check_access('sobject_column', {
            'search_type': 'prod/shot',
            'column': 'description'
        }, 'view')
        my.assertEquals(test, True)

        test = access_manager.get_access('sobject', {
            'search_type': 'sthpw/note',
            'project': 'sample3d'
        })
        my.assertEquals(test, "edit")
        test = access_manager.get_access('sobject',
                                         {'search_type': 'sthpw/note'})
        my.assertEquals(test, None)

        test = access_manager.get_access('sobject', {
            'search_type': 'prod/layer',
            'project': 'sample3d'
        })
        my.assertEquals(test, "view")
        test = access_manager.get_access('sobject', 'prod/layer')
        my.assertEquals(test, None)

        Project.set_project('sample3d')
        # security version 2 uses group = search_type
        asset = SearchType.create('prod/asset')
        asset.set_value('name', 'unit test obj')
        asset.commit(triggers=False)
        # replace the access manager with this
        Environment.get_security()._access_manager = access_manager

        test = access_manager.check_access('search_type', {
            'search_type': 'prod/asset',
            'project': 'sample3d'
        }, 'delete')
        my.assertEquals(test, False)

        asset.delete()

        note = SearchType.create('sthpw/note')
        note.set_value('note', 'unit test note obj')
        note.set_value('project_code', 'unittest')
        note.commit(triggers=False)

        test = access_manager.get_access('search_type', [{
            'code': 'sthpw/note',
            'project': 'unittest'
        }])
        my.assertEquals(test, 'edit')
        msg = ''
        # delete of unittest note should fail
        try:
            note.delete()
        except SObjectException, e:
            msg = 'delete error'
コード例 #37
0
    def _test_search_filter(my):

        # NOTE: this unittest is flawed because it relies on project
        # that may not exist

        my.security.set_admin(False)

        # exclude sample3d tasks and include unittest tasks only
        rules = """
        <rules>
        <rule value='sample3d' search_type='sthpw/task' column='project_code' op='!=' group='search_filter'/>
        <rule value='unittest' search_type='sthpw/task' column='project_code' group='search_filter'/>
        </rules>
        """

        xml = Xml()
        xml.read_string(rules)
        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        search = Search('sthpw/task')
        tasks = search.get_sobjects()
        project_codes = SObject.get_values(tasks,'project_code', unique=True)
        my.assertEquals(False, 'sample3d' in project_codes)
        my.assertEquals(True, 'unittest' in project_codes)

        # test list-based expression
        rules = """
        <rules>
        <rule value='$PROJECT' search_type='sthpw/task' column='project_code' group='search_filter'/>
        <rule value="@GET(sthpw/login['login','EQ','unittest'].login)" search_type='sthpw/task' op='in' column='assigned' group='search_filter' project='*'/>
        </rules>
        """
        xml = Xml()
        xml.read_string(rules)
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        search = Search('sthpw/task')
        tasks = search.get_sobjects()
        # 3 tasks were created above for a person
        my.assertEquals(3, len(tasks))
        assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
        project_codes = SObject.get_values(tasks,'project_code', unique=True)
        my.assertEquals({'unittest_guy': 1,'unittest_gal': 1}, my.count(assigned_codes))
        my.assertEquals(True, ['unittest'] == project_codes)

        rules = """
        <rules>
        <rule group="project" code='sample3d' access='allow'/>
        <rule group="project" code='unittest' access='allow'/>
        <rule group="project" code='art' access='allow'/>
        <rule value='$PROJECT' search_type='sthpw/task' column='project_code' group='search_filter'/>
        <rule value='@GET(login.login)' search_type='sthpw/task' column='assigned' group='search_filter' project='*'/>
        </rules>
        """
        xml = Xml()
        xml.read_string(rules)
        # reset it
        security = Environment.get_security()
        security.reset_access_manager()

        access_manager = security.get_access_manager()
        access_manager.add_xml_rules(xml)

        search = Search('sthpw/task')
        tasks = search.get_sobjects()

        # 2 tasks were created above for unittest_guy
        my.assertEquals(2, len(tasks))
        assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
        project_codes = SObject.get_values(tasks,'project_code', unique=True)
        my.assertEquals(True, ['unittest_guy'] == assigned_codes)
        my.assertEquals(True, ['unittest'] == project_codes)

        Project.set_project('sample3d')
        try:
            search = Search('sthpw/task')
            tasks = search.get_sobjects()

            my.assertEquals(1, len(tasks))
            assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
            project_codes = SObject.get_values(tasks,'project_code', unique=True)
            my.assertEquals(True, ['unittest_guy'] == assigned_codes)
            my.assertEquals(True, ['sample3d'] == project_codes)
        finally:
            Project.set_project('unittest')


      

        # project specific rule
        proj_rules = """
        <rules>
        <rule group="project" code='sample3d' access='allow'/>
        <rule group="project" code='unittest' access='allow'/>
        <rule value='$PROJECT' search_type='sthpw/task' column='project_code' group='search_filter'/>
        <rule value='@GET(login.login)' search_type='sthpw/task' column='assigned' group='search_filter' project='unittest'/>
        <rule group="process" process="anim" access="allow"/>
        <rule group="process" process="comp" access="allow"/>
        </rules>
        """
        xml = Xml()
        xml.read_string(proj_rules)
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        project = Project.get_by_code('sample3d')
        if project:
            Project.set_project('sample3d')
            search = Search('sthpw/task')
            tasks = search.get_sobjects()

            assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
            project_codes = SObject.get_values(tasks,'project_code', unique=True)
            # should fail since project is switched to sample3d.. and it should have more than just unittest
            my.assertEquals(False, ['unittest'] == assigned_codes)
            my.assertEquals(True, ['sample3d'] == project_codes)




            # unittest specific rule that uses negation !=, this takes care of NULL value automatically
            rules = """
            <rules>
                <rule group="project" code='sample3d' access='allow'/>
                <rule value='5' search_type='sthpw/task' column='priority' op='!=' group='search_filter' project='sample3d'/>
                 <rule group="process" process="anim" access="allow"/>
                <rule group="process" process="comp" access="allow"/>
            </rules>
            """
            xml = Xml()
            xml.read_string(rules)
            # reset it
            Environment.get_security().reset_access_manager()

            access_manager = Environment.get_security().get_access_manager()
            access_manager.add_xml_rules(xml)

            Project.set_project('sample3d')
            search = Search('sthpw/task')
            tasks = search.get_sobjects()

            priorities = SObject.get_values(tasks,'priority', unique=True)
            #project_codes = SObject.get_values(tasks,'project_code', unique=True)
            
            for p in priorities:
                my.assertEquals(True, p != 5)
      
        try: 
            Project.set_project('unittest')
        except SecurityException, e:
            # should get an SecurityException
            my.assertEquals('User [unittest_guy] is not permitted to view project [unittest]', e.__str__())
            xml = Xml()
            xml.read_string(proj_rules)
            # reset it
            Environment.get_security().reset_access_manager()


            access_manager = Environment.get_security().get_access_manager()
            access_manager.add_xml_rules(xml)
コード例 #38
0
ファイル: search_wdg.py プロジェクト: hellios78/TACTIC
    def get_default_filter_config(my):
        custom_filter_view = my.kwargs.get('custom_filter_view')

        if not custom_filter_view:
            custom_filter_view=''

        config = []
        config.append("<config>\n")
        config.append("<filter>\n")

        config.append('''
        <element name='Keyword Search'>
          <display class='tactic.ui.filter.SObjectSearchFilterWdg'>
            <search_type>%s</search_type>
            <prefix>quick</prefix>
          </display>
        </element>
        ''' % my.search_type)

        config.append('''
        <element name='Custom'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>custom</prefix>
            <search_type>%s</search_type>
            <mode>custom</mode>
            <custom_filter_view>%s</custom_filter_view>
          </display>
        </element>
        ''' % (my.search_type, custom_filter_view) )


        config.append('''
        <element name='Filter'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
             <prefix>main_body</prefix>
             <search_type>%s</search_type>
             <mode>sobject</mode>
           </display>
        </element>
        ''' % my.search_type)

        """
        config.append('''
        <element name='Filter2'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
             <prefix>filter2</prefix>
             <search_type>%s</search_type>
             <mode>sobject</mode>
           </display>
        </element>
        ''' % my.search_type)
        """


        config.append('''
        <element name='Parent'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>parent</prefix>
            <search_type>%s</search_type>
            <mode>parent</mode>
          </display>
        </element>
        ''' % my.search_type)


        config.append('''
        <element name='Children'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>children</prefix>
            <search_type>%s</search_type>
            <mode>child</mode>
          </display>
        </element>
        ''' % my.search_type)


        """
        config.append('''
        <element name='Related'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>related</prefix>
            <search_type>%s</search_type>
            <mode>child</mode>
          </display>
        </element>
        ''' % my.search_type)
        """




        config.append("</filter>\n")
        config.append("</config>\n")

        config = ''.join(config)

        config_xml = Xml()
        config_xml.read_string(config)
        config = WidgetConfig.get(xml=config_xml, view='filter')
        return config
コード例 #39
0
    def _test_access_manager(my):
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = AccessManager()

        xml = Xml()
        xml.read_string('''
        <rules>
          
       
          <rule group='sobject' key='corporate/budget' access='allow'/>
          <rule group='sobject'  key='corporate/salary' access='allow'/>
          <rule group='sobject'  key='prod/asset' access='edit'/>
          <rule group='sobject' search_type='sthpw/note'  project='sample3d' access='edit'/>
          <group type='url' default='deny'>
            <rule key='/tactic/bar/Partner' access='view'/>
            <rule key='/tactic/bar/External' access='view'/>
          </group>


          
            <rule group='sobject' search_type='prod/layer'  project='sample3d' access='view'/>
            <rule column='description'  search_type='prod/shot' access='view' group='sobject_column'/>
           
          <group type='sobject_column' default='edit'>
            <rule key='prod/asset|director_notes' access='deny'/>
            <rule key='prod/asset|sensitive_data' access='deny'/>
          </group>

      
          <rule group='search_type' code='prod/asset'   access='allow'/>

          <rule group='search_type' code='sthpw/note' project='unittest' access='edit'/>
          
           
          <rule group='search_type' code='unittest/person'  project='unittest' access='allow'/>
          <rule group='builtin' key='view_site_admin' access='allow'/>
          <rule group='builtin' key='export_all_csv' project='unittest' access='allow'/>
          <rule group='builtin' key='retire_delete' project='*' access='allow'/>
        
           </rules>
        ''')

        
    

        access_manager.add_xml_rules(xml)

        test = access_manager.check_access('builtin', 'view_site_admin','allow')
        my.assertEquals(test, True)

        test = access_manager.check_access('builtin', 'export_all_csv','allow')
        my.assertEquals(test, False)

        # this is the new way to control per project csv export
        keys = [{'key':'export_all_csv', 'project': 'unittest'}, {'key':'export_all_csv'}]
        test = access_manager.check_access('builtin', keys ,'allow')
        my.assertEquals(test, True)


        test = access_manager.check_access('builtin', 'retire_delete','allow')

        my.assertEquals(test, True)

        # test sensitive sobject
        test = access_manager.get_access('sobject', 'corporate/budget')
        my.assertEquals(test, "allow")

        # test allowed sobject
        test = access_manager.get_access('sobject', 'prod/asset')
        my.assertEquals(test, "edit")

        test = access_manager.get_access('sobject', [{'search_type':'sthpw/note', 'project':'sample3d'}])
        my.assertEquals(test, "edit")
        # test url
        test = access_manager.get_access('url', '/tactic/bar/Partner')
        my.assertEquals(test, "view")

        # test with access values ... a more typical usage
        test = access_manager.check_access('sobject','prod/asset','view')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject','corporate/budget','edit')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject_column', 'prod/asset|director_notes','deny')
        my.assertEquals(test, True)

        test = access_manager.check_access('sobject_column',{'search_type':'prod/shot','column':'description'},'edit')
        my.assertEquals(test, False)

        test = access_manager.check_access('sobject_column',{'search_type':'prod/shot','column':'description'},'view')
        my.assertEquals(test, True)


        test = access_manager.get_access('sobject',  {'search_type':'sthpw/note', 'project':'sample3d'} )
        my.assertEquals(test, "edit")
        test = access_manager.get_access('sobject', {'search_type':'sthpw/note'} )
        my.assertEquals(test, None)

        test = access_manager.get_access('sobject', {'search_type':'prod/layer', 'project':'sample3d'} )
        my.assertEquals(test, "view")
        test = access_manager.get_access('sobject', 'prod/layer' )
        my.assertEquals(test, None)

        # security version 2 uses group = search_type
        asset = SearchType.create('prod/asset')
        asset.set_value('name','unit test obj')
        asset.commit(triggers=False)
        # replace the access manager with this 
        Environment.get_security()._access_manager = access_manager
        
        test = access_manager.check_access('search_type',{'search_type':'prod/asset','project':'sample3d'},'delete')
        my.assertEquals(test, False)

        asset.delete()

        note = SearchType.create('sthpw/note')
        note.set_value('note','unit test note obj')
        note.set_value('project_code','unittest')
        note.commit(triggers=False)
        

        test = access_manager.get_access('search_type', [{'code':'sthpw/note', 'project':'unittest'}] )
        my.assertEquals(test, 'edit')
        msg = ''
        # delete of unittest note should fail
        try:
            note.delete()
        except SObjectException, e:
            msg = 'delete error'
コード例 #40
0
ファイル: security_test.py プロジェクト: pombredanne/TACTIC
    def _test_access_manager(my):
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = AccessManager()

        xml = Xml()
        xml.read_string(
            """
        <rules>
          
       
          <rule group='sobject' key='corporate/budget' access='allow'/>
          <rule group='sobject'  key='corporate/salary' access='allow'/>
          <rule group='sobject'  key='prod/asset' access='edit'/>
          <rule group='sobject' search_type='sthpw/note'  project='sample3d' access='edit'/>
          <group type='url' default='deny'>
            <rule key='/tactic/bar/Partner' access='view'/>
            <rule key='/tactic/bar/External' access='view'/>
          </group>


          
            <rule group='sobject' search_type='prod/layer'  project='sample3d' access='view'/>
            <rule column='description'  search_type='prod/shot' access='view' group='sobject_column'/>
           
          <group type='sobject_column' default='edit'>
            <rule key='prod/asset|director_notes' access='deny'/>
            <rule key='prod/asset|sensitive_data' access='deny'/>
          </group>

      
          <rule group='search_type' code='prod/asset'   access='allow'/>

          <rule group='search_type' code='sthpw/note' project='unittest' access='edit'/>
          
           
          <rule group='search_type' code='unittest/person'  project='unittest' access='allow'/>
          <rule group='builtin' key='view_site_admin' access='allow'/>
          <rule group='builtin' key='export_all_csv' project='unittest' access='allow'/>
          <rule group='builtin' key='retire_delete' project='*' access='allow'/>
        
           </rules>
        """
        )

        access_manager.add_xml_rules(xml)

        test = access_manager.check_access("builtin", "view_site_admin", "allow")
        my.assertEquals(test, True)

        test = access_manager.check_access("builtin", "export_all_csv", "allow")
        my.assertEquals(test, False)

        # this is the new way to control per project csv export
        keys = [{"key": "export_all_csv", "project": "unittest"}, {"key": "export_all_csv"}]
        test = access_manager.check_access("builtin", keys, "allow")
        my.assertEquals(test, True)

        test = access_manager.check_access("builtin", "retire_delete", "allow")

        my.assertEquals(test, True)

        # test sensitive sobject
        test = access_manager.get_access("sobject", "corporate/budget")
        my.assertEquals(test, "allow")

        # test allowed sobject
        test = access_manager.get_access("sobject", "prod/asset")
        my.assertEquals(test, "edit")

        test = access_manager.get_access("sobject", [{"search_type": "sthpw/note", "project": "sample3d"}])
        my.assertEquals(test, "edit")
        # test url
        test = access_manager.get_access("url", "/tactic/bar/Partner")
        my.assertEquals(test, "view")

        # test with access values ... a more typical usage
        test = access_manager.check_access("sobject", "prod/asset", "view")
        my.assertEquals(test, True)

        test = access_manager.check_access("sobject", "corporate/budget", "edit")
        my.assertEquals(test, True)

        test = access_manager.check_access("sobject_column", "prod/asset|director_notes", "deny")
        my.assertEquals(test, True)

        test = access_manager.check_access(
            "sobject_column", {"search_type": "prod/shot", "column": "description"}, "edit"
        )
        my.assertEquals(test, False)

        test = access_manager.check_access(
            "sobject_column", {"search_type": "prod/shot", "column": "description"}, "view"
        )
        my.assertEquals(test, True)

        test = access_manager.get_access("sobject", {"search_type": "sthpw/note", "project": "sample3d"})
        my.assertEquals(test, "edit")
        test = access_manager.get_access("sobject", {"search_type": "sthpw/note"})
        my.assertEquals(test, None)

        test = access_manager.get_access("sobject", {"search_type": "prod/layer", "project": "sample3d"})
        my.assertEquals(test, "view")
        test = access_manager.get_access("sobject", "prod/layer")
        my.assertEquals(test, None)

        # security version 2 uses group = search_type
        asset = SearchType.create("prod/asset")
        asset.set_value("name", "unit test obj")
        asset.commit(triggers=False)
        # replace the access manager with this
        Environment.get_security()._access_manager = access_manager

        test = access_manager.check_access(
            "search_type", {"search_type": "prod/asset", "project": "sample3d"}, "delete"
        )
        my.assertEquals(test, False)

        asset.delete()

        note = SearchType.create("sthpw/note")
        note.set_value("note", "unit test note obj")
        note.set_value("project_code", "unittest")
        note.commit(triggers=False)

        test = access_manager.get_access("search_type", [{"code": "sthpw/note", "project": "unittest"}])
        my.assertEquals(test, "edit")
        msg = ""
        # delete of unittest note should fail
        try:
            note.delete()
        except SObjectException, e:
            msg = "delete error"
コード例 #41
0
    def get_display(my):

        top_wdg = DivWdg()
        top_wdg.add_style("color: black")
        top_wdg.add_style("width: 350px")
        top_wdg.add_style("margin-top: 10px")
        top_wdg.add_style("padding: 10px")
        top_wdg.add_border()
        title = DivWdg()
        title.add_style("color: black")
        title.add_style("margin-top: -22px")

        top_wdg.add(title)
        #if not my.name_string:
        #    title.add('No database column')
        #    return top_wdg

        title.add("Widget Definition")

        widget_types = {
            'foreign_key': 'tactic.ui.table.ForeignKeyElementWdg',
            'button': 'tactic.ui.table.ButtonElementWdg',
            'expression': 'tactic.ui.table.ExpressionElementWdg'
        }

        web = WebContainer.get_web()
        config_string = web.get_form_value("config_xml")
        if not config_string:
            config_string = '<config/>'
        xml = Xml()
        xml.read_string(config_string)

        #print "config_string: ", config_string

        # get values from the config file
        element_name = xml.get_value('element/@name')

        config = WidgetConfig.get(
            view='element',
            xml='<config><element>%s</element></config>' % config_string)
        display_options = config.get_display_options(element_name)

        title = xml.get_value('element/@title')
        display_handler = xml.get_value('element/display/@class')
        if not display_handler:
            display_handler = 'tactic.ui.panel.TypeTableElementWdg'

        widget_name = xml.get_value('element/display/@widget')
        if not widget_name:
            widget_name = 'custom'

        custom_table = Table()
        custom_table.add_style("color: black")
        top_wdg.add(custom_table)

        name_text = DivWdg()
        name_text.add_style("color: black")
        name_text.add(element_name)
        custom_table.add_row()
        custom_table.add_cell("Name: ")
        custom_table.add_cell(name_text)

        # add title
        custom_table.add_row()
        title_wdg = TextWdg("custom_title")
        title_wdg.set_value(title)
        title_wdg.add_attr("size", "50")
        custom_table.add_cell("Title: ")
        custom_table.add_cell(title_wdg)

        # add description
        #custom_table.add_row()
        #description_wdg = TextAreaWdg("custom_description")
        #td = custom_table.add_cell( "Description: " )
        #td.add_style("vertical-align: top")
        #custom_table.add_cell( description_wdg )

        type_select = SelectWdg("custom_type")
        #type_select.add_empty_option("-- Select --")

        type_select.set_option(
            "values",
            "string|integer|float|boolean|currency|date|foreign_key|link|list|button|custom"
        )
        type_select.set_option(
            "labels",
            "String(db)|Integer(db)|Float(db)|Boolean(db)|Currency(db)|Date(db)|Foreign Key|Link|List|Button|Custom"
        )
        type_select.set_value(widget_name)

        #type_select.set_option("values", "string|integer|float|boolean|currency|date|link|list|foreign_key|button|empty")
        #type_select.set_option("labels", "String|Integer|Float|Boolean|Currency|Date|Link|List|Foreign Key|Button|Empty")
        custom_table.add_row()
        td = custom_table.add_cell("Widget Type: ")
        td.add_style("vertical-align: top")
        td = custom_table.add_cell(type_select)
        type_select.add_event(
            "onchange", "spt.CustomProject.property_type_select_cbk(this)")

        td.add(HtmlElement.br())
        display_handler_text = TextWdg("display_handler")
        display_handler_text.add_attr("size", "50")
        display_handler_text.set_value(display_handler)
        td.add(display_handler_text)

        # extra info for foreign key
        custom_table.add_row()
        div = DivWdg()
        div.add_class("foreign_key_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")
        div.add("Options")
        div.add(HtmlElement.br())

        # extra info for foreign key
        custom_table.add_row()
        div = DivWdg()
        div.add_class("foreign_key_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")
        div.add("Options")
        div.add(HtmlElement.br())
        # TODO: this class should not be in prod!!
        from pyasm.prod.web import SearchTypeSelectWdg
        div.add("Relate to: ")
        search_type_select = SearchTypeSelectWdg(
            "foreign_key_search_select",
            mode=SearchTypeSelectWdg.CURRENT_PROJECT)
        div.add(search_type_select)
        td.add(div)

        # extra info for list
        custom_table.add_row()
        div = DivWdg()
        div.add_class("list_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")
        div.add("Options")
        div.add(HtmlElement.br())
        # TODO: this class should not be in prod!!
        from pyasm.prod.web import SearchTypeSelectWdg
        div.add("Values: ")
        search_type_text = TextWdg("list_values")
        div.add(search_type_text)
        td.add(div)

        # extra info for button
        custom_table.add_row()
        div = DivWdg()
        div.add_style("color: black")
        div.add_class("button_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")

        #class_path = "tactic.ui.table.ButtonElementWdg"
        class_path = display_handler
        button = Common.create_from_class_path(class_path)
        args_keys = button.get_args_keys()

        div.add("Options")
        div.add(HtmlElement.br())

        for key in args_keys.keys():
            option_name_text = HiddenWdg("option_name")
            option_name_text.set_value(key)
            div.add(option_name_text)

            div.add("%s: " % key)
            div.add(" &nbsp; &nbsp;")

            input = button.get_input_by_arg_key(key)

            value = display_options.get(key)
            if value:
                input.set_value(value)

            div.add(input)
            div.add(HtmlElement.br())
        td.add(div)

        # is searchable checkbox
        #custom_table.add_row()
        #current_searchable_wdg = CheckboxWdg("is_searchable")
        #current_view_wdg.set_checked()
        #custom_table.add_cell("Searchable? ")
        #td = custom_table.add_cell(current_searchable_wdg)

        custom_table.close_tbody()

        return top_wdg
コード例 #42
0
    def add_xml_rules(my, xml):
        '''xml should be an XML object with the data in the form of
        <rules>
          <group type='sobject' default='<default>'>
            <rule key='<key>' access='<access>'/>
          </group>
        </rules>
        '''

        if isinstance(xml, basestring):
            xmlx = Xml()
            xmlx.read_string(xml)
            xml = xmlx


        my.xml = xml

        # parse shorthand rules
        rule_nodes = xml.get_nodes("rules/rule")
        if not rule_nodes:
            return


        if my.project_codes == None:
            search = Search('sthpw/project')
            projects = search.get_sobjects()
            my.project_codes = [x.get_code() for x in projects]
            my.project_codes.append('*')

        for rule_node in rule_nodes:
            # initiate the project_code here for each loop
            project_code = '*'
            group_type = Xml.get_attribute( rule_node, "group" )
            if not group_type:
                # category is the preferred name over group now
                # TODO: phase out the use of group completely
                group_type = Xml.get_attribute( rule_node, "category" )

            # get an existing rule set or create a new one
            if my.groups.has_key(group_type):
                rules = my.groups[group_type]
            else:
                rules = {}
                my.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( rule_node, "default" )
            if group_default:
                rules['__DEFAULT__'] = group_default
                continue


            # generate the rule key
            #rule_key = xml.get_attribute(rule_node, 'key')
            attrs = xml.get_attributes(rule_node)
            attrs2 = {}
            count = 0
            for name, value in attrs.items():
                if name in ['access', 'group', 'category', 'project']:
                    continue
                # have to turn everything into strings
                attrs2[str(name)] = str(value)
                count += 1


            if count == 1 and attrs2.has_key('key'):
                # backwards compatibility
                rule_key = attrs2['key']
            else:
                #rule_key = str(attrs2)
                rule_key = str(Common.get_dict_list(attrs2))

            rule_project =  xml.get_attribute(rule_node, 'project')
            if rule_project:
                project_code = rule_project
                # special treatment for search_filter to enable
                # project-specific search
                if group_type=='search_filter':
                    attrs2['project'] = rule_project
            
            # if there is a value, then combine it with the key
            rule_value = xml.get_attribute(rule_node, 'value')
            if rule_value:
                rule_key = "%s||%s" % (rule_key, rule_value)

            # add a project code qualifier
            rule_keys = []
            if project_code == '*' and group_type != 'search_filter':
                for code in my.project_codes:
                    key = "%s?project=%s" % (rule_key, code)
                    rule_keys.append(key)
            else:
                key= "%s?project=%s" % (rule_key, project_code)

                #key = str(key) # may need to stringify unicode string
                rule_keys.append(key)

            rule_access = xml.get_attribute(rule_node, 'access')

            #if rule_access == "":
            #    raise AccessException("Cannot have empty 'access':\n%s" \
            #        % xml.to_string(rule_node) )

            # if no key is specified, it is considered a DEFAULT
            if not rule_keys and not rule_value:
                rule_keys = ['__DEFAULT__']
            for rule_key in rule_keys:
                # check if rule_access exists first, which doesn't for search_filter,
                # but it has to go into the rules regardless
                # if the rule already exists, take the highest one
                if rule_access and rules.has_key(rule_key):
                    curr_access, cur_attrs = rules[rule_key]

                    try:
                        access_enum = my._get_access_enum(rule_access)
                        if my._get_access_enum(curr_access) > access_enum:
                            continue
                    except:
                        if group_type == "builtin":
                            continue
                        else:
                            raise


                rules[rule_key] = rule_access, attrs2


        #for rule, values in rules.items():
        #    print "rule: ", rule, values[0]


        # FIXME: this one doesn't support the multi-attr structure
        # convert this to a python data structure
        group_nodes = xml.get_nodes("rules/group")
        for group_node in group_nodes:

            group_type = Xml.get_attribute( group_node, "type" )

            # get an existing rule set or create a new one
            if my.groups.has_key(group_type):
                rules = my.groups[group_type]
            else:
                rules = {}
                my.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( group_node, "default" )
            if group_default != "":
                rules['__DEFAULT__'] = group_default


            # get all of the rule nodes
            rule_nodes = Xml.get_children(group_node)
            for rule_node in rule_nodes:
                project_code='*'

                if Xml.get_node_name(rule_node) != 'rule':
                    continue

                rule_key = xml.get_attribute(rule_node, 'key')
                rule_access = xml.get_attribute(rule_node, 'access')

                rule_project =  xml.get_attribute(rule_node, 'project')
                if rule_project:
                    project_code = rule_project
                if rule_access == "":
                    raise AccessException("Cannot have empty 'access':\n%s" \
                        % xml.to_string(rule_node) )

                rule_keys = []
                attrs2 = {'key': rule_key}

                # add a project code qualifier
                if project_code == '*' and group_type != 'search_filter':
                    for code in my.project_codes:
                        key = "%s?project=%s" % (rule_key, code)
                        rule_keys.append(key)
                else:
                    key= "%s?project=%s" % (rule_key, project_code)
                    rule_keys.append(key)

                for rule_key in rule_keys:
                    rules[rule_key] = rule_access, attrs2
コード例 #43
0
ファイル: task.py プロジェクト: CeltonMcGrath/TACTIC
  <process completion="20" color="#e9e386" name="In Progress"/>
  <process completion="20" color="#a96ccf" name="Waiting"/>
  <process completion="30" color="#a96ccf" name="Need Assistance"/>
  <process completion="80" color="#e84a4d" name="Review"/>
  <process completion="100" color="#a3d991" name="Approved"/>
  <connect to="Review" from="Need Assistance"/>
  <connect to="In Progress" from="Pending"/>
  <connect to="Pending" from="Assignment"/>
  <connect to="Need Assistance" from="Waiting"/>
  <connect to="Waiting" from="In Progress"/>
  <connect to="Approved" from="Review"/>
</pipeline>
'''

default_xml = Xml()
default_xml.read_string(TASK_PIPELINE)

OTHER_COLORS = {
    "Complete": "#a3d991",
    "Done":     "#a3d991",
    "Final":    "#a3d991",
    "Revise":   "#e84a4d",
    "Ready":    "#a3d991",
    "In_Progress":"#e9e386",
}



class Task(SObject):

    SEARCH_TYPE = "sthpw/task"
コード例 #44
0
ファイル: security_test.py プロジェクト: CeltonMcGrath/TACTIC
    def _test_search_filter(my):

        # NOTE: this unittest is flawed because it relies on project
        # that may not exist

        my.security.set_admin(False)

        # exclude sample3d tasks and include unittest tasks only
        rules = """
        <rules>
        <rule value='sample3d' search_type='sthpw/task' column='project_code' op='!=' group='search_filter'/>
        <rule value='unittest' search_type='sthpw/task' column='project_code' group='search_filter'/>
        </rules>
        """

        xml = Xml()
        xml.read_string(rules)
        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        search = Search('sthpw/task')
        tasks = search.get_sobjects()
        project_codes = SObject.get_values(tasks,'project_code', unique=True)
        my.assertEquals(False, 'sample3d' in project_codes)
        my.assertEquals(True, 'unittest' in project_codes)

        # test list-based expression
        rules = """
        <rules>
        <rule value='$PROJECT' search_type='sthpw/task' column='project_code' group='search_filter'/>
        <rule value="@GET(sthpw/login['login','EQ','unittest'].login)" search_type='sthpw/task' op='in' column='assigned' group='search_filter' project='*'/>
        </rules>
        """
        xml = Xml()
        xml.read_string(rules)
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        search = Search('sthpw/task')
        tasks = search.get_sobjects()
        # 3 tasks were created above for a person
        my.assertEquals(3, len(tasks))
        assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
        project_codes = SObject.get_values(tasks,'project_code', unique=True)
        my.assertEquals({'unittest_guy': 1,'unittest_gal': 1}, my.count(assigned_codes))
        my.assertEquals(True, ['unittest'] == project_codes)

        rules = """
        <rules>
        <rule group="project" code='sample3d' access='allow'/>
        <rule group="project" code='unittest' access='allow'/>
        <rule group="project" code='art' access='allow'/>
        <rule value='$PROJECT' search_type='sthpw/task' column='project_code' group='search_filter'/>
        <rule value='@GET(login.login)' search_type='sthpw/task' column='assigned' group='search_filter' project='*'/>
        </rules>
        """
        xml = Xml()
        xml.read_string(rules)
        # reset it
        security = Environment.get_security()
        security.reset_access_manager()

        access_manager = security.get_access_manager()
        access_manager.add_xml_rules(xml)

        search = Search('sthpw/task')
        tasks = search.get_sobjects()

        # 2 tasks were created above for unittest_guy
        my.assertEquals(2, len(tasks))
        assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
        project_codes = SObject.get_values(tasks,'project_code', unique=True)
        my.assertEquals(True, ['unittest_guy'] == assigned_codes)
        my.assertEquals(True, ['unittest'] == project_codes)

        Project.set_project('sample3d')
        try:
            search = Search('sthpw/task')
            tasks = search.get_sobjects()

            my.assertEquals(1, len(tasks))
            assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
            project_codes = SObject.get_values(tasks,'project_code', unique=True)
            my.assertEquals(True, ['unittest_guy'] == assigned_codes)
            my.assertEquals(True, ['sample3d'] == project_codes)
        finally:
            Project.set_project('unittest')


      

        # project specific rule
        proj_rules = """
        <rules>
        <rule group="project" code='sample3d' access='allow'/>
        <rule group="project" code='unittest' access='allow'/>
        <rule value='$PROJECT' search_type='sthpw/task' column='project_code' group='search_filter'/>
        <rule value='@GET(login.login)' search_type='sthpw/task' column='assigned' group='search_filter' project='unittest'/>
        <rule group="process" process="anim" access="allow"/>
        <rule group="process" process="comp" access="allow"/>
        </rules>
        """
        xml = Xml()
        xml.read_string(proj_rules)
        # reset it
        Environment.get_security().reset_access_manager()

        access_manager = Environment.get_security().get_access_manager()
        access_manager.add_xml_rules(xml)

        project = Project.get_by_code('sample3d')
        if project:
            Project.set_project('sample3d')
            search = Search('sthpw/task')
            tasks = search.get_sobjects()

            assigned_codes = SObject.get_values(tasks,'assigned', unique=True)
            project_codes = SObject.get_values(tasks,'project_code', unique=True)
            # should fail since project is switched to sample3d.. and it should have more than just unittest
            my.assertEquals(False, ['unittest'] == assigned_codes)
            my.assertEquals(True, ['sample3d'] == project_codes)




            # unittest specific rule that uses negation !=, this takes care of NULL value automatically
            rules = """
            <rules>
                <rule group="project" code='sample3d' access='allow'/>
                <rule value='5' search_type='sthpw/task' column='priority' op='!=' group='search_filter' project='sample3d'/>
                 <rule group="process" process="anim" access="allow"/>
                <rule group="process" process="comp" access="allow"/>
            </rules>
            """
            xml = Xml()
            xml.read_string(rules)
            # reset it
            Environment.get_security().reset_access_manager()

            access_manager = Environment.get_security().get_access_manager()
            access_manager.add_xml_rules(xml)

            Project.set_project('sample3d')
            search = Search('sthpw/task')
            tasks = search.get_sobjects()

            priorities = SObject.get_values(tasks,'priority', unique=True)
            #project_codes = SObject.get_values(tasks,'project_code', unique=True)
            
            for p in priorities:
                my.assertEquals(True, p != 5)
      
        try: 
            Project.set_project('unittest')
        except SecurityException, e:
            # should get an SecurityException
            my.assertEquals('User [unittest_guy] is not permitted to view project [unittest]', e.__str__())
            xml = Xml()
            xml.read_string(proj_rules)
            # reset it
            Environment.get_security().reset_access_manager()


            access_manager = Environment.get_security().get_access_manager()
            access_manager.add_xml_rules(xml)
コード例 #45
0
ファイル: custom_property_wdg.py プロジェクト: 0-T-0/TACTIC
    def execute(my):

        web = WebContainer.get_web()

        # get command line options
        search_type = my.kwargs.get("search_type")
        assert search_type

        view = my.kwargs.get("view")
        if not view:
            view = get_template_view()



        # check if this is advanced mode
        mode = web.get_form_value("custom_mode")
        if not mode:
            mode = 'simple'

        if mode == 'xml':
            config_string = web.get_form_value("config_xml")

            # handle the "default" view
            view = DEFAULT_VIEW
            config = WidgetDbConfig.get_by_search_type(search_type, view)
            if not config:
                config = WidgetDbConfig.create(search_type, view)

            xml = Xml()
            xml.read_string(config_string)
            element_name = xml.get_value("element/@name")
            element_name = element_name.strip()
            assert element_name

            type = xml.get_value("element/@type")
            if not type:
                class_name = xml.get_value("element/display/@class")

                if not class_name:
                    raise TacticException("Either a type or class name needs to be defined in config xml.")

            config.append_xml_element(element_name,config_string)
            config.commit_config()

            # create the required columns
            widget = config.get_display_widget(element_name)
            columns = widget.get_required_columns()

            if columns:
                print "WARNING: need to create columns: ", columns

            my.info['element_name'] = element_name

            return



        type = web.get_form_value("custom_type")
        description = web.get_form_value("custom_description")
        if not description:
            description = "No descripton"

        title = web.get_form_value("custom_title")



        name = web.get_form_value("custom_name")
        name = name.strip()
        if not name:
            raise TacticException("No name specified")


        add_to_current_view = web.get_form_value("add_to_current_view")
        add_to_edit_view = web.get_form_value("add_to_edit_view")
        is_searchable = web.get_form_value("is_searchable")

        # create the column
        if type not in ['button', 'empty']:
            cmd = ColumnAddCmd(search_type, name, type)
            cmd.execute()

        
        # create the type
        class_name = None
        options = {}
        # this is actually element attrs
        element_options = {}
        edit_class_name = None
        edit_options = {}
        edit_attrs = {}

        element_type = type

        # Date Range is not used any more in the UI"
        if type == "Date Range":
            class_name = "GanttWdg"
            options["start_date_column"] = "%s_start_date" % name
            options["end_deate_column"] = "%s_end_date" % name

        elif type == "date":
            class_name = "DateWdg"
            #edit_class_name = "CalendarWdg"

            element_type = 'timestamp'
            edit_attrs['type'] = 'timestamp'
            edit_class_name = ""
            add_to_edit_view = True

        elif type == "foreign_key":
            class_name = ""
            edit_class_name = "SelectWdg"
            foreign_search_type = web.get_form_value("foreign_key_search_select")
            edit_options["query"] = '%s|code|code' % foreign_search_type

            # turn on add to edit view
            add_to_edit_view = True

        elif type == "button":
            class_name = "tactic.ui.table.ButtonElementWdg"
            script = web.get_form_value("option_script_select")
            if script:
                options['script'] = script
            icon = web.get_form_value("option_icon_select")
            if icon:
                options['icon'] = icon


            edit_class_name = ""

            # This does not have a type
            element_type = None


        elif type == "empty":
            element_type = None
            pass


        elif type == "list":
            class_name = ""
            edit_class_name = "SelectWdg"
            list_values = web.get_form_value("list_values")
            edit_options['values'] = list_values

            add_to_edit_view = True

        element_options['type'] = element_type
        element_options['title'] = title
        

        # handle the "default" view
        view = DEFAULT_VIEW
        config = WidgetDbConfig.get_by_search_type(search_type, view)
        if not config:
            config = WidgetDbConfig.create(search_type, view)
        config.append_display_element(name, class_name, options=options, \
                element_attrs=element_options)
        config.commit_config()


        # get the config file
        if add_to_current_view:
            config = WidgetDbConfig.get_by_search_type(search_type, view)

            if not config:
                # if it doesn't exist, the check to see, if there is a hard
                # coded view out there
                predefined_config = WidgetConfigView.get_by_search_type(search_type, view)
                xml = predefined_config.get_xml()

                # create a new db one
                config = WidgetDbConfig.create(search_type, view)

                if xml:
                    config.set_value("config", xml.to_string())
                    config._init()

            config.append_display_element(name)
            config.commit_config()

        # TODO: Need to make this searchable using simple search ?????
        if is_searchable:
            element_options['searchable'] = 'true'

        # handle the "edit"
        if add_to_edit_view and view != "edit":
            config = WidgetDbConfig.get_by_search_type(search_type, "edit")
            if not config:
                config = WidgetDbConfig.create(search_type, "edit")
            config.append_display_element(name, edit_class_name, edit_options,element_attrs=edit_attrs)
            config.commit_config()


        """
        # this sType has been deprecated
        sobject = SearchType.create("prod/custom_property")
        sobject.set_value("search_type", search_type)
        sobject.set_value("name", name)
        sobject.set_value("description", description)
        sobject.commit()
        """

        # set some information
        my.description = "Added Property [%s] of type [%s] to [%s]" % \
            (name, type, search_type)

        my.info['element_name'] = name
コード例 #46
0
    def execute(self):
        web = WebContainer.get_web()
        alter_mode = self.kwargs.get("alter_mode")
        title = self.kwargs.get("title")
        config_mode = web.get_form_value("config_mode")
        view = web.get_form_value('view')
        constraint = web.get_form_value("config_constraint")
        data_type = ''

        if config_mode == "advanced" :
            config_string = web.get_form_value("config_xml")
            if config_string:
                xml = Xml()
                xml.read_string(config_string)
                node = xml.get_root_node()
                data_type = xml.get_attribute(node, "data_type")
                nullable = xml.get_attribute(node, "nullable") in ['true','True']
            
        else:
            data_type = web.get_form_value("config_data_type")
            if data_type == 'Other...':
                data_type = web.get_form_value("config_data_type_custom")
            cb = CheckboxWdg("config_nullable")
            nullable = cb.is_checked()

        # if advanced is selected in the Widget Column view, data_type is ''
        # read from UI
        if not data_type and view == 'definition':
            data_type = web.get_form_value("config_data_type")
            if data_type == 'Other...':
                data_type = web.get_form_value("config_data_type_custom")
            cb = CheckboxWdg("config_nullable")
            nullable = cb.is_checked()


        column_name = web.get_form_value("column_name")
        search_type = web.get_form_value("target_search_type")
        if alter_mode == ManageSearchTypeDetailWdg.REMOVE_COLUMN:
            cmd = ColumnDropCmd(search_type, column_name)
            Command.execute_cmd(cmd)
            # delete widget config from definition view
            widget_config = WidgetDbConfig.get_by_search_type(search_type, 'definition')
            if widget_config:
                config = WidgetConfig.get('definition', xml=widget_config.get_xml_value('config'))
                config.remove_xml_element(column_name)
                new_xml = config.get_xml().to_string()
                widget_config.set_value("config", new_xml)
                widget_config.commit()
                # set cache to {}
                from pyasm.common import Container
                 
                Container.put("WidgetConfigView:config_cache", {})
                #Container.put("WidgetConfig:config_cache", {})
        elif alter_mode == ManageSearchTypeDetailWdg.MODIFY_COLUMN:
            cmd = ColumnAlterCmd(search_type, column_name, data_type, nullable)
            Command.execute_cmd(cmd)
            element_options = {}
            element_options['type'] = data_type
            if title:
            	element_options['title'] = title
        

            # handle the "default" view
            # update the widget config data type in the xml
            view = self.DEFAULT_VIEW
            config = WidgetDbConfig.get_by_search_type(search_type, view)
            if config:
                config.append_display_element(column_name, options={}, \
                    element_attrs=element_options)
                config.commit_config()

        elif alter_mode == ManageSearchTypeDetailWdg.ADD_COLUMN:
            cmd = ColumnAddCmd(search_type, column_name, data_type, nullable)
            Command.execute_cmd(cmd)


        if constraint:
            # add constraint
            from pyasm.command import ColumnAddIndexWdg
            cmd = ColumnAddIndexWdg()
            cmd.execute()
        else:
            # remove constraint
            pass
コード例 #47
0
    def get_widget_from_hash(cls, hash, return_none=False, force_no_index=False, kwargs={}):

        from pyasm.web import DivWdg
        if hash.startswith("//"):
            use_top = False
            hash = hash[1:]
        else:
            use_top = True

        import re
        p = re.compile("^/(\w+)")
        m = p.search(hash)
        if not m:
            if return_none:
                return None
            print "Cannot parse hash[%s]" % hash
            return DivWdg("Cannot parse hash [%s]" % hash)
        key = m.groups()[0]
        

        # guest user should never be able to see admin site
        if key != 'login':
            security = Environment.get_security()
            login = security.get_user_name()
            if login == "guest" and key == 'admin':
                from pyasm.widget import WebLoginWdg
                # HACK: if the guest access is full, the the outer form
                # is not defined ... force it in here.  This is because the
                # top used it TopWdg and not TitleTopWdg
                div = DivWdg()
                div.add("<form id='form' name='form' method='post' enctype='multipart/form-data'>\n")
                web_login_wdg = WebLoginWdg().get_buffer_display()
                div.add(web_login_wdg)
                div.add("</form>\n")
                return div





        sobject = cls._get_predefined_url(key, hash)

        # look up the url
        if not sobject:
            search = Search("config/url")
            search.add_filter("url", "/%s/%%"%key, "like")
            search.add_filter("url", "/%s"%key)
            search.add_where("or")
            sobject = search.get_sobject()

        if not sobject:
            if return_none:
                return None
            return DivWdg("No Widget found for hash [%s]" % hash)



        config = sobject.get_value("widget")
        config = config.replace('&','&amp;')

        url = sobject.get_value("url")
        url = url.strip()

        # update the config value with expressions
        options = Common.extract_dict(hash, url)
        for name, value in options.items():
            config = config.replace("{%s}" % name, value)


        xml = Xml()
        xml.read_string(config)


        use_index, use_admin, use_sidebar = cls._get_flags(xml, sobject, force_no_index, kwargs)

        # add the admin bar
        security = Environment.get_security()
        is_admin = security.check_access("builtin", "view_site_admin", "allow")

        if is_admin and use_admin:
            # use admin
            from tactic.ui.app import PageNavContainerWdg
            top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar )
            return top.get_buffer_display()

        elif use_index:

            # check if there is an index
            search = Search("config/url")
            search.add_filter("url", "/index")
            index = search.get_sobject()
            # just use admin if no index page is found
            if not index:
                from tactic.ui.app import PageNavContainerWdg
                top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar )
                return top.get_buffer_display()
                
            config = index.get_value("widget")
            xml = Xml()
            xml.read_string(config)
            node = xml.get_node("element/display")

            options.update(xml.get_node_values_of_children(node))

            class_name = xml.get_value("element/display/@class")
            if class_name:
                options['class_name'] = class_name

            # this passes the hash value to the index widget
            # which must handle it accordingly
            options['hash'] = hash
            top = cls.build_widget(options)

            return top.get_buffer_display()




        # process the options and then build the widget from the xml


        options = Common.extract_dict(hash, url)
        for name, value in kwargs.items():
            options[name] = value

        node = xml.get_node("element/display")
        options.update(xml.get_node_values_of_children(node))

        class_name = xml.get_value("element/display/@class")
        if class_name:
            options['class_name'] = class_name

        widget = cls.build_widget(options)

        name = hash.lstrip("/")
        name_array = name.split("/")
        if name_array:
            name_end = name_array[-1]
            name_end = name_end.replace("_", " ")
            widget.set_name(name_end)
        else:
            widget.set_name(name)

        return widget
コード例 #48
0
    def get_display(self):

        top_wdg = DivWdg()
        top_wdg.add_style("color: black")
        top_wdg.add_style("width: 350px")
        top_wdg.add_style("margin-top: 10px")
        top_wdg.add_style("padding: 10px")
        top_wdg.add_border()
        title = DivWdg()
        title.add_style("color: black")
        title.add_style("margin-top: -22px")

        top_wdg.add(title)
        #if not self.name_string:
        #    title.add('No database column')
        #    return top_wdg
        
        title.add("Widget Definition")

        widget_types = {
            'foreign_key': 'tactic.ui.table.ForeignKeyElementWdg',
            'button': 'tactic.ui.table.ButtonElementWdg',
            'expression': 'tactic.ui.table.ExpressionElementWdg'
        }


        web = WebContainer.get_web()
        config_string = web.get_form_value("config_xml")
        if not config_string:
            config_string = '<config/>'
        xml = Xml()
        xml.read_string(config_string)

        #print "config_string: ", config_string

        # get values from the config file
        element_name = xml.get_value('element/@name')

        config = WidgetConfig.get(view='element',xml='<config><element>%s</element></config>' % config_string)
        display_options = config.get_display_options(element_name)


        title = xml.get_value('element/@title')
        display_handler = xml.get_value('element/display/@class')
        if not display_handler:
            display_handler = 'tactic.ui.panel.TypeTableElementWdg'

        widget_name = xml.get_value('element/display/@widget')
        if not widget_name:
            widget_name = 'custom'

 
        custom_table = Table()
        custom_table.add_style("color: black")
        top_wdg.add(custom_table)

        name_text = DivWdg()
        name_text.add_style("color: black")
        name_text.add(element_name)
        custom_table.add_row()
        custom_table.add_cell("Name: ")
        custom_table.add_cell(name_text)



        # add title
        custom_table.add_row()
        title_wdg = TextWdg("custom_title")
        title_wdg.set_value(title)
        title_wdg.add_attr("size", "50")
        custom_table.add_cell( "Title: " )
        custom_table.add_cell( title_wdg )

        # add description
        #custom_table.add_row()
        #description_wdg = TextAreaWdg("custom_description")
        #td = custom_table.add_cell( "Description: " )
        #td.add_style("vertical-align: top")
        #custom_table.add_cell( description_wdg )


        type_select = SelectWdg("custom_type")
        #type_select.add_empty_option("-- Select --")

        type_select.set_option("values", "string|integer|float|boolean|currency|date|foreign_key|link|list|button|custom")
        type_select.set_option("labels", "String(db)|Integer(db)|Float(db)|Boolean(db)|Currency(db)|Date(db)|Foreign Key|Link|List|Button|Custom")
        type_select.set_value(widget_name)

        #type_select.set_option("values", "string|integer|float|boolean|currency|date|link|list|foreign_key|button|empty")
        #type_select.set_option("labels", "String|Integer|Float|Boolean|Currency|Date|Link|List|Foreign Key|Button|Empty")
        custom_table.add_row()
        td = custom_table.add_cell("Widget Type: ")
        td.add_style("vertical-align: top")
        td = custom_table.add_cell(type_select)
        type_select.add_event("onchange", "spt.CustomProject.property_type_select_cbk(this)")


        td.add(HtmlElement.br())
        display_handler_text = TextWdg("display_handler")
        display_handler_text.add_attr("size", "50")
        display_handler_text.set_value(display_handler)
        td.add(display_handler_text)



        # extra info for foreign key
        custom_table.add_row()
        div = DivWdg()
        div.add_class("foreign_key_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")
        div.add("Options")
        div.add(HtmlElement.br())



        # extra info for foreign key
        custom_table.add_row()
        div = DivWdg()
        div.add_class("foreign_key_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")
        div.add("Options")
        div.add(HtmlElement.br())
        # TODO: this class should not be in prod!!
        from pyasm.prod.web import SearchTypeSelectWdg
        div.add("Relate to: ")
        search_type_select = SearchTypeSelectWdg("foreign_key_search_select", mode=SearchTypeSelectWdg.CURRENT_PROJECT)
        div.add(search_type_select)
        td.add(div)



        # extra info for list
        custom_table.add_row()
        div = DivWdg()
        div.add_class("list_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")
        div.add("Options")
        div.add(HtmlElement.br())
        # TODO: this class should not be in prod!!
        from pyasm.prod.web import SearchTypeSelectWdg
        div.add("Values: ")
        search_type_text = TextWdg("list_values")
        div.add(search_type_text)
        td.add(div)




        # extra info for button
        custom_table.add_row()
        div = DivWdg()
        div.add_style("color: black")
        div.add_class("button_options")
        div.add_style("display: none")
        div.add_style("margin-top: 10px")

        #class_path = "tactic.ui.table.ButtonElementWdg"
        class_path = display_handler
        button = Common.create_from_class_path(class_path)
        args_keys = button.get_args_keys()


        div.add("Options")
        div.add(HtmlElement.br())

        for key in args_keys.keys():
            option_name_text = HiddenWdg("option_name")
            option_name_text.set_value(key)
            div.add(option_name_text)

            div.add("%s: " % key)
            div.add(" &nbsp; &nbsp;")

            input = button.get_input_by_arg_key(key)

            value = display_options.get(key)
            if value:
                input.set_value(value)

            div.add(input)
            div.add(HtmlElement.br())
        td.add(div)






        # is searchable checkbox
        #custom_table.add_row()
        #current_searchable_wdg = CheckboxWdg("is_searchable")
        #current_view_wdg.set_checked()
        #custom_table.add_cell("Searchable? ")
        #td = custom_table.add_cell(current_searchable_wdg)

        custom_table.close_tbody()


        return top_wdg
コード例 #49
0
ファイル: doc_tool_wdg.py プロジェクト: mincau/TACTIC
    def get_text(self, path, last_path=None, highlight=True):


        if path.startswith("http"):
            if path.startswith("https://docs.google.com/document"):
                # NOTE: this is very specific to google docs
                if not path.endswith("?embedded=true"):
                    path = "%s?embedded=true" % path
                is_html = True
            else:
                is_html = False

            import urllib2
            response = urllib2.urlopen(path)
            html = response.read()


            fix = '''<meta content="text/html; charset=UTF-8" http-equiv="content-type">'''
            html = html.replace(fix, "")
            html = html.replace("&", "&amp;")

            if is_html:

                xml = Xml()
                try:
                    xml.read_string(html)
                except:
                    self.doc_mode = "formatted"
                    html = html.replace("&amp;", "&")
                    print
                    print "WARNING: cannot parse as XML"
                    print
                    return html


                if self.doc_mode == "formatted":
                    return xml.to_string().replace("&amp;", "&")


                node = xml.get_node("html/body")
                text = xml.to_string(node)
                text = text.replace("<body", "<div style='margin: 0px'")
                text = text.replace("</body>", "</div>")

                text = text.replace("&amp;", "&")

            else:
                text = html


            lines2 = []
            lines = text.split("\n")
            for line in lines:
                tmp_line = line.strip()
                if tmp_line.startswith("<span"):
                    tmp_line = tmp_line.replace("<span>", "")
                    tmp_line = tmp_line.replace("</span>", "")
                    tmp_line = tmp_line.replace("<span/>", "")
                elif tmp_line.startswith("<p "):
                    continue
                elif tmp_line.startswith("</p>"):
                    continue

                # FIXME: there has to be a function to do this
                tmp_line = tmp_line.replace("&nbsp;", "")
                tmp_line = tmp_line.replace("&quot;", '"')
                tmp_line = tmp_line.replace("&#39;", "'")
                lines2.append(tmp_line)

            text = "\n".join(lines2)


            #print 'text', text
            #import html2text
            #text = html2text.html2text(html)

            # clear out any remaining html tags
            import re
            text = re.sub('<[^<]+?>', '', text)


        else:
            f = open(path)
            lines = f.readlines()
            f.close()



            #f = open(path)
            #lines2 = f.readlines()
            #f.close()

            #diff = self.get_diff(lines, lines2)
            #text = "".join(diff)

            text = "".join(lines)


        # read last text if it exists
        if last_path and os.path.exists(last_path):
            last_file = open(last_path, 'r')
            last_text = last_file.read()
            last_file.close()
        else:
            last_text = None

        if last_text != None:
            lines = text.split("\n")
            lines2 = last_text.split("\n")
            diff = self.get_diff(lines2, lines)
            diff_text = "\n".join(diff)
            text = diff_text


        if highlight:
            search_type_obj = SearchType.get(self.search_type)
            color = search_type_obj.get_value("color")
            if not color:
                color = '#0F0'

            # assemble all the lines
            data = []

            search = Search(self.search_type)
            sobjects = search.get_sobjects()
            for sobject in sobjects:
                search_key = sobject.get_search_key()

                value = sobject.get_value(self.column)
                lines = value.split("\n")
                for line in lines:
                    line = line.strip()
                    data.append( [line, search_key] )
                

            for line, search_key in data:
                if not line:
                    continue

                line = line.strip()

                text = text.replace(line, "<i style='color: %s; font-weight: bold; opacity: 1.0;' spt_search_key='%s' class='spt_document_item hand'>%s</i>" % (color, search_key, line))



        return text
コード例 #50
0
class SObjectDefaultConfig(Base):
    '''An artificial config file is made if none are found'''
    def __init__(self, search_type, view, config_base=None, mode="columns"):

        self.search_type = search_type

        if view:
            self.view = view
        else:
            self.view = config_base
        if not self.view:
            self.view = "table"

        # bit of protection ... : have been known to show up in view names
        self.view = self.view.replace(":", '_')

        #mode = "basic"

        self.xml = Xml()

        if mode == 'columns':
            self.handle_columns_mode()
        else:
            self.handle_basic_mode()

    def get_columns(self, required_only=False):
        if self.search_type == 'sthpw/virtual':
            return []

        search_type_obj = SearchType.get(self.search_type)
        table = search_type_obj.get_table()

        from pyasm.biz import Project
        db_resource = Project.get_db_resource_by_search_type(self.search_type)
        database_name = db_resource.get_database()
        db = DbContainer.get(db_resource)

        # table may not exist
        try:
            all_columns = db.get_columns(table)
            columns = []
            if required_only:
                nullables = db.get_column_nullables(table)
                for column in all_columns:
                    null_ok = nullables.get(column)
                    if not null_ok:
                        columns.append(column)

                # if there are no required columns
                if not columns:
                    columns = all_columns

            else:
                columns = all_columns
        except SqlException:
            Environment.add_warning(
                'missing table', 'Table [%s] does not exist in database [%s]' %
                (table, database_name))
            return []

        return columns

    def handle_basic_mode(self):

        doc = self.xml.create_doc("config")
        root = self.xml.get_root_node()

        db_columns = self.get_columns()

        if "code" in db_columns:
            columns = ["preview", "code"]
        elif "name" in db_columns:
            columns = ["preview", "name"]
        elif "id" in db_columns:
            columns = ["preview", "id"]

        table = self.xml.create_element("table")
        Xml.append_child(root, table)
        for column in ["preview", "code"]:
            element = self.xml.create_element("element")
            Xml.set_attribute(element, "name", column)
            Xml.append_child(table, element)

        # create the edit
        edit = self.xml.create_element("edit")
        Xml.append_child(root, edit)

        for column in ["preview", "code"]:
            element = self.xml.create_element("element")
            Xml.set_attribute(element, "name", column)
            Xml.append_child(edit, element)

        # create the manual publish view
        publish = self.xml.create_element("publish")
        Xml.append_child(root, publish)
        element = self.xml.create_element("element")
        Xml.set_attribute(element, "name", "image")
        Xml.append_child(publish, element)
        dis_element = self.xml.create_element("display")
        Xml.set_attribute(dis_element, "class", "ThumbInputWdg")
        act_element = self.xml.create_element("action")
        Xml.set_attribute(act_element, "class", "NullAction")
        Xml.append_child(element, dis_element)
        Xml.append_child(element, act_element)

        element = self.xml.create_element("element")
        Xml.set_attribute(element, "name", "publish_files")
        Xml.append_child(publish, element)
        dis_element = self.xml.create_element("display")
        Xml.set_attribute(dis_element, "class", "UploadWdg")
        # add options
        option = self.xml.create_text_element('names',
                                              'publish_icon|publish_main')
        Xml.append_child(dis_element, option)
        option = self.xml.create_text_element('required', 'false|true')
        Xml.append_child(dis_element, option)

        act_element = self.xml.create_element("action")
        Xml.set_attribute(act_element, "class", "MultiUploadAction")
        # add options
        option = self.xml.create_text_element('names',
                                              'publish_icon|publish_main')
        Xml.append_child(act_element, option)
        option = self.xml.create_text_element('types', 'icon_main|main')
        Xml.append_child(act_element, option)
        Xml.append_child(element, dis_element)
        Xml.append_child(element, act_element)

        value = self.xml.to_string()
        self.xml = Xml()
        self.xml.read_string(value)

    def handle_columns_mode(self):

        doc = self.xml.create_doc("config")
        root = self.xml.get_root_node()

        columns = self.get_columns()
        if len(columns) == 1 and columns[0] == "id":
            columns = self.get_columns(required_only=False)

        # create the table
        # search is a special view for SearchWdg and it should not be created
        if self.view not in ['search', 'publish']:
            if self.view.find('@') != -1:
                table = self.xml.create_element('view',
                                                attrs={'name': self.view})
            else:
                table = self.xml.create_element(self.view)
            self.xml.append_child(root, table)
            for column in columns:
                if column in ["_id", "id", "oid", "s_status"]:
                    continue
                element = self.xml.create_element("element")
                Xml.set_attribute(element, "name", column)
                self.xml.append_child(table, element)

            # add history, input and output for the load view (designed for app loading)
            if self.view == 'load':
                element = self.xml.create_element("element")
                Xml.set_attribute(element, "name", "checkin")
                self.xml.append_child(table, element)
                for column in ['input', 'output']:
                    element = self.xml.create_element("element")
                    Xml.set_attribute(element, "name", column)
                    Xml.set_attribute(element, "edit", "false")
                    display_element = self.xml.create_element("display")

                    Xml.set_attribute(display_element, "class",
                                      "tactic.ui.cgapp.LoaderElementWdg")
                    self.xml.append_child(element, display_element)

                    stype, key = SearchType.break_up_key(self.search_type)
                    op1 = self.xml.create_text_element("search_type", stype)
                    op2 = self.xml.create_text_element("mode", column)

                    self.xml.append_child(display_element, op1)
                    self.xml.append_child(display_element, op2)

                    self.xml.append_child(table, element)

        value = self.xml.to_string()

        self.xml = Xml()
        self.xml.read_string(value)

    def get_type(self, element_name):
        xpath = "config/%s/element[@name='%s']/@type" % (self.view,
                                                         element_name)
        type = self.xml.get_value(xpath)

        if not type:
            xpath = "config/%s/element[@name='%s']/@type" % ("definition",
                                                             element_name)
            type = self.xml.get_value(xpath)

        return type

    def get_xml(self):
        return self.xml
コード例 #51
0
    def add_xml_rules(self, xml, project_code=None):
        '''xml should be an XML object with the data in the form of
        <rules>
          <group type='sobject' default='<default>'>
            <rule key='<key>' access='<access>'/>
          </group>
        </rules>
        '''

        from pyasm.search import SObject
        if isinstance(xml, SObject):
            sobject = xml
            xml = sobject.get_xml_value("access_rules")
            if not project_code:
                project_code = sobject.get_value("project_code")

        project_override = project_code
        if isinstance(xml, basestring):
            xmlx = Xml()
            xmlx.read_string(xml)
            xml = xmlx


        # parse shorthand rules
        rule_nodes = xml.get_nodes("rules/rule")
        if not rule_nodes:
            return

        # store all of the project codes (this will only run once)
        if self.project_codes == None:
            search = Search('sthpw/project')
            projects = search.get_sobjects()
            self.project_codes = [x.get_code() for x in projects]
            self.project_codes.append('*')

        for rule_node in rule_nodes:
            # initiate the project_code here for each loop
            project_code = '*'
            group_type = Xml.get_attribute( rule_node, "group" )
            if not group_type:
                # category is the preferred name over group now
                # TODO: phase out the use of group completely
                group_type = Xml.get_attribute( rule_node, "category" )

            # get an existing rule set or create a new one
            if self.groups.has_key(group_type):
                rules = self.groups[group_type]
            else:
                rules = {}
                self.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( rule_node, "default" )
            if group_default:
                rules['__DEFAULT__'] = group_default
                continue


            # generate the rule key
            #rule_key = xml.get_attribute(rule_node, 'key')
            attrs = xml.get_attributes(rule_node)
            attrs2 = {}
            count = 0
            for name, value in attrs.items():
                if name in ['access', 'group', 'category', 'project']:
                    continue
                # have to turn everything into strings
                attrs2[str(name)] = str(value)
                count += 1


            if count == 1 and attrs2.has_key('key'):
                # backwards compatibility
                rule_key = attrs2['key']
            else:
                #rule_key = str(attrs2)
                rule_key = str(Common.get_dict_list(attrs2))

            if project_override:
                rule_project = project_override
            else:
                rule_project =  xml.get_attribute(rule_node, 'project')

            if rule_project:
                project_code = rule_project
                # special treatment for search_filter to enable
                # project-specific search
                if group_type=='search_filter':
                    attrs2['project'] = rule_project
            
            # if there is a value, then combine it with the key
            rule_value = xml.get_attribute(rule_node, 'value')
            if rule_value:
                rule_key = "%s||%s" % (rule_key, rule_value)

            # add a project code qualifier
            rule_keys = []
         
            # project rule is special
            if group_type == 'project':
                key = str(rule_key)
                rule_keys.append(key)
            elif project_code == '*' and group_type != 'search_filter':
                for code in self.project_codes:
                    key = "%s?project=%s" % (rule_key, code)
                    rule_keys.append(key)
            else:
                key= "%s?project=%s" % (rule_key, project_code)

                #key = str(key) # may need to stringify unicode string
                rule_keys.append(key)
                    
                #key= "%s?project=*" % (rule_key)
                #rule_keys.append(key)

            rule_access = xml.get_attribute(rule_node, 'access')

            #if rule_access == "":
            #    raise AccessException("Cannot have empty 'access':\n%s" \
            #        % xml.to_string(rule_node) )

            # if no key is specified, it is considered a DEFAULT
            if not rule_keys and not rule_value:
                rule_keys = ['__DEFAULT__']
            for rule_key in rule_keys:
                # check if rule_access exists first, which doesn't for search_filter,
                # but it has to go into the rules regardless
                # if the rule already exists, take the highest one
                if rule_access and rules.has_key(rule_key):
                    curr_access, cur_attrs = rules[rule_key]

                    try:
                        access_enum = self._get_access_enum(rule_access)
                        if self._get_access_enum(curr_access) > access_enum:
                            continue
                    except:
                        if group_type == "builtin":
                            continue
                        else:
                            raise


                rules[rule_key] = rule_access, attrs2
            

        # FIXME: this one doesn't support the multi-attr structure
        # convert this to a python data structure
        group_nodes = xml.get_nodes("rules/group")
        for group_node in group_nodes:

            group_type = Xml.get_attribute( group_node, "type" )

            # get an existing rule set or create a new one
            if self.groups.has_key(group_type):
                rules = self.groups[group_type]
            else:
                rules = {}
                self.groups[group_type] = rules

            # set the default, if specified
            group_default = xml.get_attribute( group_node, "default" )
            if group_default != "":
                rules['__DEFAULT__'] = group_default


            # get all of the rule nodes
            rule_nodes = Xml.get_children(group_node)
            for rule_node in rule_nodes:
                project_code='*'

                if Xml.get_node_name(rule_node) != 'rule':
                    continue

                rule_key = xml.get_attribute(rule_node, 'key')
                rule_access = xml.get_attribute(rule_node, 'access')

                if project_override:
                    rule_project = project_override
                else:
                    rule_project =  xml.get_attribute(rule_node, 'project')

                if rule_project:
                    project_code = rule_project
                if rule_access == "":
                    raise AccessException("Cannot have empty 'access':\n%s" \
                        % xml.to_string(rule_node) )

                rule_keys = []
                attrs2 = {'key': rule_key}

                # add a project code qualifier
                if project_code == '*' and group_type != 'search_filter':
                    for code in self.project_codes:
                        key = "%s?project=%s" % (rule_key, code)
                        rule_keys.append(key)
                else:
                    key= "%s?project=%s" % (rule_key, project_code)
                    rule_keys.append(key)

                for rule_key in rule_keys:
                    rules[rule_key] = rule_access, attrs2
コード例 #52
0
APPROVAL_PIPELINE = '''
<pipeline type="serial">
  <process completion="10" color="#8ad3e5" name="Pending"/>
  <process completion="10" color="#8ad3e5" name="Review"/>
  <process completion="50" color="#e84a4d" name="Revise"/>
  <process completion="100" color="#a3d991" name="Approve"/>
  <connect to="Review" from="Pending"/>
  <connect to="Revise" from="Review"/>
  <connect to="Approve" from="Review"/>
</pipeline>

'''


default_xml = Xml()
default_xml.read_string(TASK_PIPELINE)

OTHER_COLORS = {
    "Complete": "#a3d991",
    "Done":     "#a3d991",
    "Final":    "#a3d991",
    "Revise":   "#e84a4d",
    "Ready":    "#a3d991",
    "In_Progress":"#e9e386",
}



class Task(SObject):

    SEARCH_TYPE = "sthpw/task"
コード例 #53
0
ファイル: custom_layout_wdg.py プロジェクト: hellios78/TACTIC
    def replace_elements(my, html_str):

        """
        # NOTE: this likely is a better way to extract elements, but still
        # need to find a way to inject html back into the xml
        xml = Xml()
        xml.read_string("<div>%s</div>" % html_str)
        elements = xml.get_nodes("//element")

        for element in elements:
            # create a complete config
            full_line_str = xml.to_string(element)
            tmp_config = '''<config><tmp>%s</tmp></config>''' % full_line_str

            try:
                element_wdg = my.get_element_wdg(xml, my.def_config)
                element_html = element_wdg.get_buffer_display()
            except Exception, e:
                from pyasm.widget import ExceptionWdg
                element_html = ExceptionWdg(e).get_buffer_display()

            xml = Xml()
            try:
                xml.read_string(element_html)
            except Exception, e:
                print "Error: ", e
                xml.read_string("<h1>%s</h1>" % str(e) )
            root = xml.get_root_node()

            parent = xml.get_parent(element)
            xml.replace_child(parent, element, root)

        return xml.to_string()
        """


        # a simple readline interpreter
        html = Html()
        full_line = []
        parse_context = None
        for line in html_str.split("\n"):
            line2 = line.strip()


            #if not parse_context and not line2.startswith('<element '):
            index = line2.find('<element>')
            if index == -1:
                index = line2.find('<element ')


            if not parse_context and index == -1:
                #line = Common.process_unicode_string(line)
                html.writeln(line)
                continue

            if index != -1:
                part1 = line2[:index]
                html.write(part1)
                line2 = line2[index:]

            full_line.append(line2)
            xml = Xml()
            # determine if this is valid xml
            try:
                # create a complete config
                full_line_str = "".join(full_line)
                tmp_config = '''<config><tmp>%s</tmp></config>''' % full_line_str
                xml.read_string(tmp_config, print_error=False)

                full_line = []
                parse_context = ''

            except XmlException, e:
                parse_context = 'element'
                #raise e
                continue

            try:
                element_wdg = my.get_element_wdg(xml, my.def_config)
                if element_wdg:
                    element_html = element_wdg.get_buffer_display()
                else:
                    element_html = ''
            except Exception, e:
                from pyasm.widget import ExceptionWdg
                element_html = ExceptionWdg(e).get_buffer_display()
コード例 #54
0
    def get_default_filter_config(my):
        custom_filter_view = my.kwargs.get('custom_filter_view')

        if not custom_filter_view:
            custom_filter_view = ''

        config = []
        config.append("<config>\n")
        config.append("<filter>\n")

        config.append('''
        <element name='Combination'>
          <display class='tactic.ui.filter.SObjectSearchFilterWdg'>
            <search_type>%s</search_type>
            <prefix>quick</prefix>
          </display>
        </element>
        ''' % my.search_type)

        config.append('''
        <element name='Custom'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>custom</prefix>
            <search_type>%s</search_type>
            <mode>custom</mode>
            <custom_filter_view>%s</custom_filter_view>
          </display>
        </element>
        ''' % (my.search_type, custom_filter_view))

        config.append('''
        <element name='Filter'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
             <prefix>main_body</prefix>
             <search_type>%s</search_type>
             <mode>sobject</mode>
           </display>
        </element>
        ''' % my.search_type)
        """
        config.append('''
        <element name='Filter2'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
             <prefix>filter2</prefix>
             <search_type>%s</search_type>
             <mode>sobject</mode>
           </display>
        </element>
        ''' % my.search_type)
        """

        config.append('''
        <element name='Parent'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>parent</prefix>
            <search_type>%s</search_type>
            <mode>parent</mode>
          </display>
        </element>
        ''' % my.search_type)

        config.append('''
        <element name='Children'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>children</prefix>
            <search_type>%s</search_type>
            <mode>child</mode>
          </display>
        </element>
        ''' % my.search_type)
        """
        config.append('''
        <element name='Related'>
          <display class='tactic.ui.filter.GeneralFilterWdg'>
            <prefix>related</prefix>
            <search_type>%s</search_type>
            <mode>child</mode>
          </display>
        </element>
        ''' % my.search_type)
        """

        config.append("</filter>\n")
        config.append("</config>\n")

        config = ''.join(config)

        config_xml = Xml()
        config_xml.read_string(config)
        config = WidgetConfig.get(xml=config_xml, view='filter')
        return config
コード例 #55
0
ファイル: hash_panel_wdg.py プロジェクト: lucasnemeth/TACTIC
    def get_widget_from_hash(cls, hash, return_none=False, force_no_index=False, kwargs={}):

        from pyasm.web import DivWdg
        if hash.startswith("//"):
            use_top = False
            hash = hash[1:]
        else:
            use_top = True

        import re
        p = re.compile("^/(\w+)")
        m = p.search(hash)
        if not m:
            if return_none:
                return None
            print "Cannot parse hash[%s]" % hash
            return DivWdg("Cannot parse hash [%s]" % hash)
        key = m.groups()[0]

        # guest user should never be able to see admin site
        if key != 'login':
            security = Environment.get_security()
            login = security.get_user_name()
            if login == "guest" and key == 'admin':
                from pyasm.widget import Error403Wdg
                return Error403Wdg().get_buffer_display()


        sobject = cls._get_predefined_url(key, hash)

        # look up the url
        if not sobject:
            search = Search("config/url")
            search.add_filter("url", "/%s/%%"%key, "like")
            search.add_filter("url", "/%s"%key)
            search.add_where("or")
            sobject = search.get_sobject()

        if not sobject:
            if return_none:
                return None
            return DivWdg("No Widget found for hash [%s]" % hash)



        config = sobject.get_value("widget")
        config = config.replace('&','&amp;')

        url = sobject.get_value("url")
        url = url.strip()

        # update the config value with expressions
        options = Common.extract_dict(hash, url)
        for name, value in options.items():
            config = config.replace("{%s}" % name, value)


        xml = Xml()
        xml.read_string(config)


        use_index, use_admin, use_sidebar = cls._get_flags(xml, sobject, force_no_index, kwargs)


        if use_admin:
            # use admin
            from tactic.ui.app import PageNavContainerWdg
            top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar )
            return top.get_buffer_display()

        elif use_index:

            # check if there is an index
            search = Search("config/url")
            search.add_filter("url", "/index")
            index = search.get_sobject()
            # just use admin if no index page is found
            if not index:
                from tactic.ui.app import PageNavContainerWdg
                top = PageNavContainerWdg( hash=hash, use_sidebar=use_sidebar )
                return top.get_buffer_display()
                
            config = index.get_value("widget")
            xml = Xml()
            xml.read_string(config)
            node = xml.get_node("element/display")

            options.update(xml.get_node_values_of_children(node))

            class_name = xml.get_value("element/display/@class")
            if class_name:
                options['class_name'] = class_name

            # this passes the hash value to the index widget
            # which must handle it accordingly
            options['hash'] = hash
            top = cls.build_widget(options)

            return top.get_buffer_display()




        # process the options and then build the widget from the xml


        options = Common.extract_dict(hash, url)
        for name, value in kwargs.items():
            options[name] = value

        node = xml.get_node("element/display")
        options.update(xml.get_node_values_of_children(node))

        class_name = xml.get_value("element/display/@class")
        if class_name:
            options['class_name'] = class_name

        widget = cls.build_widget(options)

        name = hash.lstrip("/")
        name = name.replace("/", " ")
        widget.set_name(name)

        return widget
コード例 #56
0
ファイル: panel_wdg.py プロジェクト: zieglerm/TACTIC
    def execute(self):

        print "kwargs: ", self.kwargs

        options = {}
        class_name = "tactic.ui.panel.CustomLayoutWdg"
        widget_key = ""
        for key, value in self.kwargs.items():
            if value == '':
                continue

            if key.startswith("xxx_option"):
                parts = key.split("|")
                option_key = parts[1]

                if option_key == "display_class":
                    class_name = value
                elif option_key == "widget_key":
                    widget_key = value
                else:
                    options[option_key] = value

            elif key.startswith("option|"):
                parts = key.split("|")
                option_key = parts[1]
                options[option_key] = value

        print "options: ", options

        name = self.kwargs.get("name")
        description = self.kwargs.get("description") or " "

        if not name:
            raise Exception("No name provided")

        name = Common.clean_filesystem_name(name)

        login = Environment.get_user_name()
        view = "pages.%s.%s" % (login, name)

        # find if this user page already exists
        search = Search("config/widget_config")
        search.add_filter("category", "CustomLayoutWg")
        search.add_filter("view", view)
        config = search.get_sobject()

        if config:
            raise Exception("Page with name [%s] already exists" % name)

        option_xml = []
        for key, value in options.items():
            option_xml.append("<%s>%s</%s>" % (key, value, key))
        option_str = "\n".join(option_xml)

        if widget_key:
            display_line = '''<display widget="%s">''' % widget_key
        else:
            display_line = '''<display class="%s">''' % class_name

        # all pages are custom layouts
        config_xml = '''<config>
  <%s>
    <html>
    <div style="margin: 20px">
      <div style="font-size: 25px">%s</div>
      <div>%s</div>
      <hr/>
      <element>
        %s
        %s
        </display>
      </element>
    </div>
    </html>
  </%s>
</config>
        ''' % (view, name, description, display_line, option_str, view)

        print "config_xml: ", config_xml

        xml = Xml()
        xml.read_string(config_xml)
        config_xml = xml.to_string()

        config = SearchType.create("config/widget_config")
        config.set_value("category", "CustomLayoutWdg")
        config.set_value("view", view)
        config.set_value("config", config_xml)

        config.commit()