Beispiel #1
0
 def __init__(self, conn, table, keyfield):
     StatementCursor.__init__(self, conn, name='AllTraits')
     self.set_table(table)
     self.textfiles = TextFileManager(conn)
     self._keyfield = keyfield
     self._jtable = '%s as s join textfiles as t ' % table
     self._jtable += 'on s.scriptfile = t.fileid'
Beispiel #2
0
 def __init__(self, conn, suite):
     table = ujoin(suite, 'templates')
     TraitRelation.__init__(self, conn, suite, table, name='TraitTemplate')
     self.traitparent = TraitParent(conn, suite)
     self.template = Template()
     self.template_path = None
     self.textfiles = TextFileManager(self.conn)
     self._jtable = '%s as s join textfiles as t ' % table
     self._jtable += 'on s.templatefile = t.fileid' 
Beispiel #3
0
 def __init__(self, conn, table, keyfield):
     StatementCursor.__init__(self, conn, name='AllTraits')
     self.set_table(table)
     self.textfiles = TextFileManager(conn)
     self._keyfield = keyfield
     self._jtable = '%s as s join textfiles as t ' % table
     self._jtable += 'on s.scriptfile = t.fileid' 
Beispiel #4
0
class ScriptCursor(StatementCursor):
    def __init__(self, conn, table, keyfield):
        StatementCursor.__init__(self, conn, name='AllTraits')
        self.set_table(table)
        self.textfiles = TextFileManager(conn)
        self._keyfield = keyfield
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.scriptfile = t.fileid' 

    def _clause(self, name, keyfield=None):
        # clause = Eq(self._keyfield, keyfield) & Eq('script', name)
        # return clause
        raise Error, 'this member must be overridden'
    
    def insert_script(self, name, scriptfile):
        # current_key = self.current_trait
        # self._insert_script(name, scriptfile, current_key)
        raise Error, 'insert_script must be overridden'

    def scripts(self, key=None):
        # this is not called with the keyword arg
        # returns rows of script names for
        # current key
        raise Error, 'scripts must be overridden'
    
    def scriptfile(self, name):
        return strfile(self.scriptdata(name))
            
    def _script_row(self, name):
        table = self._jtable
        clause = self._clause(name)
        return self.select_row(fields=['*'], table=table, clause=clause)
        
    def _script_id(self, name):
        return self._script_row(name).scriptfile
        
    def scriptdata(self, name):
        return self._script_row(name).data
        
    def save_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        self.update(data=dict(scriptfile=str(id)), clause=clause)

    def remove_scriptfile(self, name):
        print 'remove_scriptfile deprecated'
        raise Error, 'remove_scriptfile is deprecated'
    
    def get(self, name):
        clause = self._clause(name)
        rows = self.select(clause=clause)
        if len(rows) == 1:
            return self.scriptfile(name)
        else:
            return None

    def read_script(self, name):
        return self.scriptdata(name)

    def _insert_script(self, name, scriptfile, current_key):
        insert_data = {}
        insert_data[self._keyfield] = current_key
        insert_data['script'] = name
        id = self.textfiles.insert_file(scriptfile)
        insert_data['scriptfile'] = str(id)
        self.insert(data=insert_data)
        
    def update_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        data = dict(scriptfile=str(id))
        self.update(data=data, clause=clause)

    def update_scriptdata(self, name, data):
        clause = self._clause(name)
        id = self.textfiles.insert_data(data)
        self.update(data=dict(scriptfile=str(id)), clause=clause)

    def export_scripts(self, bkup_path):
        for row in self.scripts():
            npath = join(bkup_path, 'script-%s' % row.script)
            nfile = self.scriptfile(row.script)
            filecopy(nfile, npath)
            nfile.close()

    def delete_script(self, name):
        clause = self._clause(name)
        self.delete(clause=clause)
Beispiel #5
0
 def __init__(self, conn, suite):
     table = ujoin(suite, 'scripts')
     TraitRelation.__init__(self, conn, suite, table, name='TraitScript')
     self.textfiles = TextFileManager(self.conn)
     self._jtable = '%s as s join textfiles as t ' % table
     self._jtable += 'on s.scriptfile = t.fileid' 
Beispiel #6
0
class TraitScript(TraitRelation):
    def __init__(self, conn, suite):
        table = ujoin(suite, 'scripts')
        TraitRelation.__init__(self, conn, suite, table, name='TraitScript')
        self.textfiles = TextFileManager(self.conn)
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.scriptfile = t.fileid' 
        
    def scripts(self, trait=None):
        if trait is None:
            trait = self.current_trait
        self.set_clause(trait)
        rows = self.cmd.select(fields=['script'], order='script')
        self.reset_clause()
        return rows

    def scriptfile(self, name):
        return strfile(self.scriptdata(name))
            
    def _script_row(self, name):
        table = self._jtable
        clause = self._clause(name)
        return self.cmd.select_row(fields=['data'], table=table, clause=clause)
        
    def _script_id(self, name):
        return self._script_row(name).scriptfile
        
    def scriptdata(self, name):
        return self._script_row(name).data
        
    def save_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        self.cmd.update(data=dict(scriptfile=str(id)), clause=clause)

    def remove_scriptfile(self, name):
        print 'remove_scriptfile deprecated'

    def _clause(self, name, trait=None):
        if trait is None:
            trait = self.current_trait
        return Eq('trait', trait) & Eq('script', name)

    def get(self, name):
        clause = self._clause(name)
        rows = self.cmd.select(clause=clause)
        if len(rows) == 1:
            return self.scriptfile(name)
        else:
            return None

    def read_script(self, name):
        return self.scriptdata(name)
    
    def insert_script(self, name, scriptfile):
        insert_data = {'trait' : self.current_trait,
                       'script' : name}
        id = self.textfiles.insert_file(scriptfile)
        insert_data['scriptfile'] = str(id)
        self.cmd.insert(data=insert_data)

    def update_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        data = dict(scriptfile=str(id))
        self.cmd.update(data=data, clause=clause)

    def update_scriptdata(self, name, data):
        clause = self._clause(name)
        id = self.textfiles.insert_data(data)
        self.cmd.update(data=dict(scriptfile=str(id)), clause=clause)

    def export_scripts(self, bkup_path):
        for row in self.scripts():
            npath = join(bkup_path, 'script-%s' % row.script)
            nfile = self.scriptfile(row.script)
            filecopy(nfile, npath)
            nfile.close()

    def edit_script(self, name):
        sfile = self.get(name)
        tmp, path = tempfile.mkstemp('paella', 'script')
        script = sfile.read()
        sfile.close()
        tmp = file(path, 'w')
        tmp.write(script)
        tmp.close()
        os.system('$EDITOR %s' % path)
        tmp = file(path, 'r')
        mod = tmp.read()
        tmp.seek(0)
        if mod != script:
            print 'script modified'
            self.save_script(name, tmp)
        os.remove(path)
Beispiel #7
0
class ScriptCursor(StatementCursor):
    def __init__(self, conn, table, keyfield):
        StatementCursor.__init__(self, conn, name='AllTraits')
        self.set_table(table)
        self.textfiles = TextFileManager(conn)
        self._keyfield = keyfield
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.scriptfile = t.fileid'

    def _clause(self, name, keyfield=None):
        # clause = Eq(self._keyfield, keyfield) & Eq('script', name)
        # return clause
        raise Error, 'this member must be overridden'

    def insert_script(self, name, scriptfile):
        # current_key = self.current_trait
        # self._insert_script(name, scriptfile, current_key)
        raise Error, 'insert_script must be overridden'

    def scripts(self, key=None):
        # this is not called with the keyword arg
        # returns rows of script names for
        # current key
        raise Error, 'scripts must be overridden'

    def scriptfile(self, name):
        return strfile(self.scriptdata(name))

    def _script_row(self, name):
        table = self._jtable
        clause = self._clause(name)
        return self.select_row(fields=['*'], table=table, clause=clause)

    def _script_id(self, name):
        return self._script_row(name).scriptfile

    def scriptdata(self, name):
        return self._script_row(name).data

    def save_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        self.update(data=dict(scriptfile=str(id)), clause=clause)

    # we're talking to the database way
    # too much in this routine, and we need
    # to work on this in the future to minimize
    # communication with the database.
    def get(self, name):
        clause = self._clause(name)
        rows = self.select(clause=clause)
        if len(rows) == 1:
            return self.scriptfile(name)
        else:
            return None

    def read_script(self, name):
        return self.scriptdata(name)

    def _insert_script(self, name, scriptfile, current_key):
        insert_data = {}
        insert_data[self._keyfield] = current_key
        insert_data['script'] = name
        id = self.textfiles.insert_file(scriptfile)
        insert_data['scriptfile'] = str(id)
        self.insert(data=insert_data)

    def update_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        data = dict(scriptfile=str(id))
        self.update(data=data, clause=clause)

    def update_scriptdata(self, name, data):
        clause = self._clause(name)
        id = self.textfiles.insert_data(data)
        self.update(data=dict(scriptfile=str(id)), clause=clause)

    def export_scripts(self, bkup_path):
        for row in self.scripts():
            npath = join(bkup_path, 'script-%s' % row.script)
            nfile = self.scriptfile(row.script)
            filecopy(nfile, npath)
            nfile.close()

    def delete_script(self, name):
        clause = self._clause(name)
        self.delete(clause=clause)
Beispiel #8
0
class TraitTemplate(TraitRelation):
    def __init__(self, conn, suite):
        table = ujoin(suite, 'templates')
        TraitRelation.__init__(self, conn, suite, table, name='TraitTemplate')
        self.traitparent = TraitParent(conn, suite)
        self.template = Template()
        self.template.set_suite(suite)
        self.template_path = None
        self.textfiles = TextFileManager(self.conn)
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.templatefile = t.fileid'

    def _clause(self, package, template, trait=None):
        if trait is None:
            trait = self.current_trait
        return Eq('trait', trait) & Eq('package', package) & Eq(
            'template', template)

    def templates(self, trait=None, fields=['*']):
        if trait is None:
            trait = self.current_trait
            self.reset_clause()
            return self.cmd.select(fields=fields,
                                   order=['package', 'template'])
        else:
            self.set_clause(trait)
            rows = self.cmd.select(fields=fields,
                                   order=['package', 'template'])
            self.reset_clause()
            return rows

    def has_template(self, template):
        return self.has_it('template', template)

    def get_row(self, template):
        return _TraitRelation.get_row(self, 'template', template)

    def insert_template(self, data, templatefile):
        if type(data) is not dict:
            raise Error, 'Need to pass dict'
        if len(data) == 2 and 'template' in data and 'package' in data:
            data.update(dict(owner='root', grp_owner='root', mode='0100644'))
        insert_data = {'trait': self.current_trait}
        insert_data.update(data)
        id = self.textfiles.insert_file(templatefile)
        insert_data['templatefile'] = str(id)
        self.cmd.insert(data=insert_data)

    def update_template(self, data, templatefile):
        clause = self._clause(data['package'], data['template'])
        id = self.textfiles.insert_file(templatefile)
        fields = ['owner', 'grp_owner', 'mode']
        update = {}.fromkeys(fields)
        for field in update:
            update[field] = data[field]
        update['templatefile'] = str(id)
        self.cmd.update(data=update, clause=clause)
        self.reset_clause()

    def update_templatedata(self, package, template, data):
        clause = self._clause(package, template)
        id = self.textfiles.insert_data(data)
        self.cmd.update(data=dict(templatefile=str(id)), clause=clause)

    def drop_template(self, package, template):
        clause = self._clause(package, template)
        self._drop_template(clause)

    def _drop_template(self, clause):
        self.cmd.delete(clause=clause)
        self.reset_clause()

    def set_trait(self, trait):
        TraitRelation.set_trait(self, trait)
        self.traitparent.set_trait(trait)
        self.template.set_trait(trait)

    def set_template(self, package, template):
        self.template.set_template(self.templatefile(package, template))
        self.template.update(self.traitparent.Environment())

    def set_template_path(self, path):
        self.template_path = join(path, self.suite, self.current_trait)

    def export_templates(self, bkup_path):
        n = 0
        for t in self.templates():
            npath = join(bkup_path, 'template-%d' % n)
            tfile = self.templatefile(t.package, t.template)
            filecopy(tfile, npath)
            tfile.close()
            n += 1

    def templatefile(self, package, template):
        return strfile(self.templatedata(package, template))

    def templatedata(self, package, template):
        return self._template_row(package, template).data

    def _template_row(self, package, template):
        table = self._jtable
        clause = self._clause(package, template)
        return self.cmd.select_row(fields=['data', 'templatefile'],
                                   table=table,
                                   clause=clause)

    def _template_id(self, package, template):
        return self._template_row(package, template).templatefile

    def save_template(self, package, template, templatefile):
        id = self.textfiles.insert_file(templatefile)
        clause = self._clause(package, template)
        self.cmd.update(data=dict(templatefile=str(id)), clause=clause)

    def edit_template(self, package, template):
        data = self.templatedata(package, template)
        tmp, path = tempfile.mkstemp('paella', 'template')
        tmp = file(path, 'w')
        tmp.write(data)
        tmp.close()
        os.system('$EDITOR %s' % path)
        tmp = file(path, 'r')
        mod = tmp.read()
        tmp.seek(0)
        if mod != data:
            print 'template modified'
            self.save_template(package, template, tmp)
        os.remove(path)
Beispiel #9
0
class ScriptCursor(StatementCursor):
    def __init__(self, conn, table, keyfield):
        StatementCursor.__init__(self, conn, name="AllTraits")
        self.set_table(table)
        self.textfiles = TextFileManager(conn)
        self._keyfield = keyfield
        self._jtable = "%s as s join textfiles as t " % table
        self._jtable += "on s.scriptfile = t.fileid"

    def _clause(self, name, keyfield=None):
        # clause = Eq(self._keyfield, keyfield) & Eq('script', name)
        # return clause
        raise Error, "this member must be overridden"

    def insert_script(self, name, scriptfile):
        # current_key = self.current_trait
        # self._insert_script(name, scriptfile, current_key)
        raise Error, "insert_script must be overridden"

    def scripts(self, key=None):
        # this is not called with the keyword arg
        # returns rows of script names for
        # current key
        raise Error, "scripts must be overridden"

    def scriptfile(self, name):
        return strfile(self.scriptdata(name))

    def _script_row(self, name):
        table = self._jtable
        clause = self._clause(name)
        return self.select_row(fields=["*"], table=table, clause=clause)

    def _script_id(self, name):
        return self._script_row(name).scriptfile

    def scriptdata(self, name):
        return self._script_row(name).data

    def save_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        self.update(data=dict(scriptfile=str(id)), clause=clause)

    # we're talking to the database way
    # too much in this routine, and we need
    # to work on this in the future to minimize
    # communication with the database.
    def get(self, name):
        clause = self._clause(name)
        rows = self.select(clause=clause)
        if len(rows) == 1:
            return self.scriptfile(name)
        else:
            return None

    def read_script(self, name):
        return self.scriptdata(name)

    def _insert_script(self, name, scriptfile, current_key):
        insert_data = {}
        insert_data[self._keyfield] = current_key
        insert_data["script"] = name
        id = self.textfiles.insert_file(scriptfile)
        insert_data["scriptfile"] = str(id)
        self.insert(data=insert_data)

    def update_script(self, name, scriptfile):
        id = self.textfiles.insert_file(scriptfile)
        clause = self._clause(name)
        data = dict(scriptfile=str(id))
        self.update(data=data, clause=clause)

    def update_scriptdata(self, name, data):
        clause = self._clause(name)
        id = self.textfiles.insert_data(data)
        self.update(data=dict(scriptfile=str(id)), clause=clause)

    def export_scripts(self, bkup_path):
        for row in self.scripts():
            npath = join(bkup_path, "script-%s" % row.script)
            nfile = self.scriptfile(row.script)
            filecopy(nfile, npath)
            nfile.close()

    def delete_script(self, name):
        clause = self._clause(name)
        self.delete(clause=clause)
Beispiel #10
0
class TraitTemplate(TraitRelation):
    def __init__(self, conn, suite):
        table = ujoin(suite, 'templates')
        TraitRelation.__init__(self, conn, suite, table, name='TraitTemplate')
        self.traitparent = TraitParent(conn, suite)
        self.template = Template()
        self.template.set_suite(suite)
        self.template_path = None
        self.textfiles = TextFileManager(self.conn)
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.templatefile = t.fileid' 

    def _clause(self, template, trait=None):
        if trait is None:
            trait = self.current_trait
        return Eq('trait', trait) & Eq('template', template)
    
    def templates(self, trait=None, fields=['*']):
        if trait is None:
            trait = self.current_trait
            self.reset_clause()
            return self.cmd.select(fields=fields, order=['template'])
        else:
            self.set_clause(trait)
            rows = self.cmd.select(fields=fields, order=['template'])
            self.reset_clause()
            return rows

    def has_template(self, template):
        return self.has_it('template', template)

    def get_row(self, template):
        return TraitRelation.get_row(self, 'template', template)

    def insert_template(self, data, templatefile):
        if type(data) is not dict:
            raise Error, 'Need to pass dict'
        if len(data) == 2 and 'template' in data and 'package' in data:
            data.update(dict(owner='root', grp_owner='root', mode='0100644'))
        insert_data = {'trait' : self.current_trait}
        insert_data.update(data)
        txtid = self.textfiles.insert_file(templatefile)
        insert_data['templatefile'] = str(txtid)
        self.cmd.insert(data=insert_data)

    def insert_template_from_tarfile(self, template_path, tarfileobj):
        templatefile = tarfileobj.extractfile(template_path)
        info = tarfileobj.getmember(template_path)
        data = dict(owner=info.uname, grp_owner=info.gname,
                    mode=oct(info.mode), template=template_path)
        self.insert_template(data, templatefile)

    def update_template(self, template, data=None, templatefile=None,
                        contents=None):
        if templatefile is not None and contents is not None:
            raise RuntimeError, 'must either pass a file object or a string but not both'
        clause = self._clause(template)
        txtid = None
        if templatefile is not None:
            txtid = self.textfiles.insert_file(templatefile)
        if contents is not None:
            txtid = self.textfiles.insert_data(contents)
        update = {}
        if txtid is not None:
            update.update(dict(templatefile=str(txtid)))
        if data is not None:
            update.update(data)
        self.cmd.update(data=update, clause=clause)
        
    def convert_to_cheetah(self, template):
        text = self.templatedata(template)
        tmpl = convert_text_to_cheetah_template(text)
        sefl.update_template(self, template, data=str(tmpl))
        
        
    
    def update_templatedata(self, template, data):
        deprecated('update_templatedata is deprecated use update_template instead')
        self.update_template(template, contents=data)
        
        

    def drop_template(self, template):
        clause = self._clause(template)
        self._drop_template(clause)
        
    def _drop_template(self, clause):
        self.cmd.delete(clause=clause)
        self.reset_clause()

    def set_trait(self, trait):
        TraitRelation.set_trait(self, trait)
        self.traitparent.set_trait(trait)
        self.template.set_trait(trait)
        
    def set_template(self, template):
        self.template.set_template(self.templatefile(template))
        self.template.update(self.traitparent.Environment())

    def set_template_path(self, path):
        self.template_path = join(path, self.suite, self.current_trait)

        
        
    # set a keyword argument (to be removed sometime in the future)
    # to revert to previous way of naming template files.  The default is to
    # use the new method.
    def export_templates(self, bkup_path, numbered_templates=False):
        n = 0
        for t in self.templates():
            if numbered_templates:
                filename  = join(bkup_path, 'template-%d' % n)
            else:
                template_id = t.template.replace('/', '-slash-')
                filename = join(bkup_path, 'template-%s' % template_id)
            tfile = self.templatefile(t.template)
            filecopy(tfile, filename)
            tfile.close()
            n += 1
            
    def templatefile(self, template):
        return strfile(self.templatedata(template))
    
    def templatedata(self, template):
        return self._template_row(template).data

    def _template_row(self, template):
        table = self._jtable
        clause = self._clause(template)
        return self.cmd.select_row(fields=['data', 'templatefile'], table=table, clause=clause)

    def _template_id(self, template):
        return self._template_row(template).templatefile

    def save_template(self, template, templatefile):
        id = self.textfiles.insert_file(templatefile)
        clause = self._clause(template)
        self.cmd.update(data=dict(templatefile=str(id)), clause=clause)

    def edit_template(self, template):
        data = self.templatedata(template)
        tmp, path = tempfile.mkstemp('paella', 'template')
        tmp = file(path, 'w')
        tmp.write(data)
        tmp.close()
        os.system('$EDITOR %s' % path)
        tmp = file(path, 'r')
        mod = tmp.read()
        tmp.seek(0)
        if mod != data:
            print 'template modified'
            self.save_template(template, tmp)
        os.remove(path)
Beispiel #11
0
class TraitTemplate(TraitRelation):
    def __init__(self, conn, suite):
        table = ujoin(suite, 'templates')
        TraitRelation.__init__(self, conn, suite, table, name='TraitTemplate')
        self.traitparent = TraitParent(conn, suite)
        self.template = Template()
        self.template_path = None
        self.textfiles = TextFileManager(self.conn)
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.templatefile = t.fileid' 

    def _clause(self, template, trait=None):
        if trait is None:
            trait = self.current_trait
        return Eq('trait', trait) & Eq('template', template)
    
    def templates(self, trait=None, fields=['*']):
        if trait is None:
            trait = self.current_trait
            self.reset_clause()
            return self.cmd.select(fields=fields, order=['template'])
        else:
            self.set_clause(trait)
            rows = self.cmd.select(fields=fields, order=['template'])
            self.reset_clause()
            return rows

    def has_template(self, template):
        return self.has_it('template', template)

    def get_row(self, template):
        return TraitRelation.get_row(self, 'template', template)

    def insert_template(self, data, templatefile):
        if type(data) is not dict:
            raise Error, 'Need to pass dict'
        if len(data) == 2 and 'template' in data and 'package' in data:
            data.update(dict(owner='root', grp_owner='root', mode='0100644'))
        insert_data = {'trait' : self.current_trait}
        insert_data.update(data)
        txtid = self.textfiles.insert_file(templatefile)
        insert_data['templatefile'] = str(txtid)
        self.cmd.insert(data=insert_data)

    def insert_template_from_tarfile(self, template_path, tarfileobj):
        templatefile = tarfileobj.extractfile(template_path)
        info = tarfileobj.getmember(template_path)
        data = dict(owner=info.uname, grp_owner=info.gname,
                    mode=oct(info.mode), template=template_path)
        self.insert_template(data, templatefile)

    def update_template(self, template, data=None, templatefile=None,
                        contents=None):
        if templatefile is not None and contents is not None:
            raise RuntimeError , 'must either pass a file object or a string but not both'
        clause = self._clause(template)
        txtid = None
        if templatefile is not None:
            txtid = self.textfiles.insert_file(templatefile)
        if contents is not None:
            txtid = self.textfiles.insert_data(contents)
        update = {}
        if txtid is not None:
            update.update(dict(templatefile=str(txtid)))
        if data is not None:
            update.update(data)
        self.cmd.update(data=update, clause=clause)
        
    def drop_template(self, template):
        clause = self._clause(template)
        self._drop_template(clause)
        
    def _drop_template(self, clause):
        self.cmd.delete(clause=clause)
        self.reset_clause()

    def set_trait(self, trait):
        TraitRelation.set_trait(self, trait)
        self.traitparent.set_trait(trait)
        
    def set_template(self, template):
        self.template.set_template(self.templatedata(template))
        self.template.update(self.traitparent.Environment())

    def set_template_path(self, path):
        self.template_path = join(path, self.suite, self.current_trait)

    def export_templates(self, bkup_path):
        for t in self.templates():
            template_id = t.template.replace('/', '-slash-')
            filename = join(bkup_path, 'template-%s' % template_id)
            tfile = self.templatefile(t.template)
            filecopy(tfile, filename)
            tfile.close()
            
    def templatefile(self, template):
        return strfile(self.templatedata(template))
    
    def templatedata(self, template):
        return self._template_row(template).data

    def _template_row(self, template):
        table = self._jtable
        clause = self._clause(template)
        return self.cmd.select_row(fields=['data', 'templatefile'], table=table, clause=clause)

    def _template_id(self, template):
        return self._template_row(template).templatefile

    def save_template(self, template, templatefile):
        id = self.textfiles.insert_file(templatefile)
        clause = self._clause(template)
        self.cmd.update(data=dict(templatefile=str(id)), clause=clause)

    def edit_template(self, template):
        data = self.templatedata(template)
        tmp, path = tempfile.mkstemp('paella', 'template')
        tmp = file(path, 'w')
        tmp.write(data)
        tmp.close()
        os.system('$EDITOR %s' % path)
        tmp = file(path, 'r')
        mod = tmp.read()
        tmp.seek(0)
        if mod != data:
            print 'template modified'
            self.save_template(template, tmp)
        os.remove(path)
class TraitTemplate(TraitRelation):
    def __init__(self, conn, suite):
        table = ujoin(suite, 'templates')
        TraitRelation.__init__(self, conn, suite, table, name='TraitTemplate')
        self.traitparent = TraitParent(conn, suite)
        self.template = Template()
        self.template.set_suite(suite)
        self.template_path = None
        self.textfiles = TextFileManager(self.conn)
        self._jtable = '%s as s join textfiles as t ' % table
        self._jtable += 'on s.templatefile = t.fileid' 

    def _clause(self, package, template, trait=None):
        if trait is None:
            trait = self.current_trait
        return Eq('trait', trait) & Eq('package', package) & Eq('template', template)
    
    def templates(self, trait=None, fields=['*']):
        if trait is None:
            trait = self.current_trait
            self.reset_clause()
            return self.cmd.select(fields=fields, order=['package', 'template'])
        else:
            self.set_clause(trait)
            rows = self.cmd.select(fields=fields, order=['package', 'template'])
            self.reset_clause()
            return rows

    def has_template(self, template):
        return self.has_it('template', template)

    def get_row(self, template):
        return _TraitRelation.get_row(self, 'template', template)

    def insert_template(self, data, templatefile):
        if type(data) is not dict:
            raise Error, 'Need to pass dict'
        if len(data) == 2 and 'template' in data and 'package' in data:
            data.update(dict(owner='root', grp_owner='root', mode='0100644'))
        insert_data = {'trait' : self.current_trait}
        insert_data.update(data)
        id = self.textfiles.insert_file(templatefile)
        insert_data['templatefile'] = str(id)
        self.cmd.insert(data=insert_data)

    def update_template(self, data, templatefile):
        clause = self._clause(data['package'], data['template'])
        id = self.textfiles.insert_file(templatefile)
        fields = ['owner', 'grp_owner', 'mode']
        update = {}.fromkeys(fields)
        for field in update:
            update[field] = data[field]
        update['templatefile'] = str(id)
        self.cmd.update(data=update, clause=clause)
        self.reset_clause()

    def update_templatedata(self, package, template, data):
        clause = self._clause(package, template)
        id = self.textfiles.insert_data(data)
        self.cmd.update(data=dict(templatefile=str(id)), clause=clause)
        

    def drop_template(self, package, template):
        clause = self._clause(package, template)
        self._drop_template(clause)
        
    def _drop_template(self, clause):
        self.cmd.delete(clause=clause)
        self.reset_clause()

    def set_trait(self, trait):
        TraitRelation.set_trait(self, trait)
        self.traitparent.set_trait(trait)
        self.template.set_trait(trait)
        
    def set_template(self, package, template):
        self.template.set_template(self.templatefile(package, template))
        self.template.update(self.traitparent.Environment())

    def set_template_path(self, path):
        self.template_path = join(path, self.suite, self.current_trait)
        
        
    def export_templates(self, bkup_path):
        n = 0
        for t in self.templates():
            npath = join(bkup_path, 'template-%d' % n)
            tfile = self.templatefile(t.package, t.template)
            filecopy(tfile, npath)
            tfile.close()
            n += 1
            
    def templatefile(self, package, template):
        return strfile(self.templatedata(package, template))
    
    def templatedata(self, package, template):
        return self._template_row(package, template).data

    def _template_row(self, package, template):
        table = self._jtable
        clause = self._clause(package, template)
        return self.cmd.select_row(fields=['data', 'templatefile'], table=table, clause=clause)

    def _template_id(self, package, template):
        return self._template_row(package, template).templatefile

    def save_template(self, package, template, templatefile):
        id = self.textfiles.insert_file(templatefile)
        clause = self._clause(package, template)
        self.cmd.update(data=dict(templatefile=str(id)), clause=clause)

    def edit_template(self, package, template):
        data = self.templatedata(package, template)
        tmp, path = tempfile.mkstemp('paella', 'template')
        tmp = file(path, 'w')
        tmp.write(data)
        tmp.close()
        os.system('$EDITOR %s' % path)
        tmp = file(path, 'r')
        mod = tmp.read()
        tmp.seek(0)
        if mod != data:
            print 'template modified'
            self.save_template(package, template, tmp)
        os.remove(path)