Ticket #1072: datamoverplugin.3.patch

File datamoverplugin.3.patch, 47.5 kB (added by eridius, 2 years ago)
  • datamover/attachment.py

    old new  
     1from trac.core import * 
     2from trac.web.main import _open_environment 
     3from trac.attachment import Attachment 
     4from trac.wiki.api import WikiSystem 
     5from trac.wiki.model import WikiPage 
     6 
     7from webadmin.web_ui import IAdminPageProvider 
     8 
     9from api import DatamoverSystem 
     10from util import copy_attachment 
     11 
     12try: 
     13    set = set 
     14except NameError: 
     15    from sets import Set as set 
     16 
     17class DatamoverAttachmentModule(Component): 
     18    """The attachment moving component of the datamover plugin.""" 
     19 
     20    implements(IAdminPageProvider) 
     21     
     22    # IAdminPageProvider methods 
     23    def get_admin_pages(self, req): 
     24        if req.perm.has_permission('TRAC_ADMIN'): 
     25            yield ('mover', 'Data Mover', 'attachment', 'Attachments') 
     26     
     27    def process_admin_request(self, req, cat, page, path_info): 
     28        envs = DatamoverSystem(self.env).all_environments() 
     29        source_db = self.env.get_db_cnx() 
     30        source_cursor = source_db.cursor() 
     31        source_cursor.execute("SELECT id FROM attachment WHERE type = 'wiki'") 
     32        wiki_pages = list(set([a for (a,) in source_cursor])) # kill duplicates 
     33        wiki_pages.sort() 
     34         
     35        if req.method == 'POST': 
     36            source_type = req.args.get('source') 
     37            if not source_type or source_type not in ('type', 'wiki', 'ticket', 'all'): 
     38                raise TracError, "Source type not specified or invalid" 
     39            source = req.args.get(source_type) 
     40            dest = req.args.get('destination') 
     41            action = None 
     42            if 'copy' in req.args.keys(): 
     43                action = 'copy' 
     44            elif 'move' in req.args.keys(): 
     45                action = 'move' 
     46            else: 
     47                raise TracError, 'Action not specified or invalid' 
     48                 
     49            action_verb = {'copy':'Copied', 'move':'Moved'}[action] 
     50             
     51            att_filter = None 
     52            if source_type == 'type': 
     53                in_type = req.args.get('type') 
     54                att_filter = lambda a: a.parent_type == in_type 
     55            elif source_type == 'wiki': 
     56                in_pages = req.args.getlist('wiki') 
     57                att_filter = lambda a: a.parent_type == 'wiki' and a.parent_id in in_pages 
     58            elif source_type == 'ticket': 
     59                in_ticket = req.args.get('ticket') 
     60                att_filter = lambda a: a.parent_type == 'ticket' and a.parent_id == in_ticket 
     61            elif source_type == 'all': 
     62                att_filter = lambda c: True 
     63             
     64            try: 
     65                source_cursor.execute('SELECT type,id,filename FROM attachment') 
     66                attachments = [Attachment(self.env,t,i,f) for (t,i,f) in source_cursor] 
     67                sel_attachments = [a for a in attachments if att_filter(a)] 
     68                dest_db = _open_environment(dest).get_db_cnx() 
     69                for att in sel_attachments: 
     70                    copy_attachment(self.env, dest, att.parent_type, att.parent_id, att.filename, dest_db) 
     71                dest_db.commit() 
     72                     
     73                if action == 'move': 
     74                    for att in sel_attachments: 
     75                        att.delete() 
     76                     
     77                req.hdf['datamover.message'] = '%s attachments %s'%(action_verb, ', '.join(["%s:%s" % (a.parent_id, a.filename) for a in sel_attachments])) 
     78            except TracError, e: 
     79                req.hdf['datamover.message'] = "An error has occured: \n"+str(e) 
     80                self.log.warn(req.hdf['datamover.message'], exc_info=True) 
     81         
     82         
     83        req.hdf['datamover.envs'] = envs 
     84        req.hdf['datamover.wiki_pages'] = wiki_pages 
     85        return 'datamover_attachment.cs', None 
  • datamover/permission.py

    old new  
     1from trac.core import * 
     2from trac.web.main import _open_environment 
     3from trac.perm import PermissionSystem 
     4 
     5from webadmin.web_ui import IAdminPageProvider 
     6 
     7from api import DatamoverSystem 
     8 
     9class DatamoverPermissionModule(Component): 
     10    """The permission moving component of the datamover plugin.""" 
     11 
     12    implements(IAdminPageProvider) 
     13     
     14    # IAdminPageProvider methods 
     15    def get_admin_pages(self, req): 
     16        if req.perm.has_permission('TRAC_ADMIN'): 
     17            yield ('mover', 'Data Mover', 'permission', 'Permissions') 
     18     
     19    def process_admin_request(self, req, cat, page, path_info): 
     20        envs = DatamoverSystem(self.env).all_environments() 
     21        permissions = PermissionSystem(self.env).get_all_permissions() 
     22         
     23        if req.method == 'POST': 
     24            source_type = req.args.get('source') 
     25            if not source_type or source_type not in ('permission', 'all'): 
     26                raise TracError, "Source type not specified or invalid" 
     27            source = req.args.get(source_type) 
     28            dest = req.args.get('destination') 
     29            action = None 
     30            if 'copy' in req.args.keys(): 
     31                action = 'copy' 
     32            elif 'move' in req.args.keys(): 
     33                action = 'move' 
     34            else: 
     35                raise TracError, 'Action not specified or invalid' 
     36                 
     37            action_verb = {'copy':'Copied', 'move':'Moved'}[action] 
     38             
     39            perm_filter = None 
     40            if source_type == 'permission': 
     41                in_permissions = [tuple(p.split(':', 2)) for p in req.args.getlist('perm')] 
     42                perm_filter = lambda p: p in in_permissions 
     43            elif source_type == 'all': 
     44                perm_filter = lambda p: True 
     45             
     46            try: 
     47                sel_permissions = [p for p in permissions if perm_filter(p)] 
     48                dest_env = _open_environment(dest) 
     49                for perm in sel_permissions: 
     50                    # revoke first in case it's already there 
     51                    # also, go directly to the store to bypass validity checks 
     52                    PermissionSystem(dest_env).store.revoke_permission(perm[0], perm[1]) 
     53                    PermissionSystem(dest_env).store.grant_permission(perm[0], perm[1]) 
     54                 
     55                if action == 'move': 
     56                    for perm in sel_permissions: 
     57                        PermissionSystem(self.env).revoke_permission(perm[0], perm[1]) 
     58                 
     59                req.hdf['datamover.message'] = '%s permissions %s'%(action_verb, ', '.join(["%s:%s" % (u,a) for u,a in sel_permissions])) 
     60            except TracError, e: 
     61                req.hdf['datamover.message'] = "An error has occured: \n"+str(e) 
     62                self.log.warn(req.hdf['datamover.message'], exc_info=True) 
     63         
     64         
     65        req.hdf['datamover.envs'] = envs 
     66        req.hdf['datamover.permissions'] = permissions 
     67        return 'datamover_permission.cs', None 
  • datamover/milestone.py

    old new  
     1from trac.core import * 
     2from trac.web.main import _open_environment 
     3from trac.ticket.model import Milestone 
     4 
     5from webadmin.web_ui import IAdminPageProvider 
     6 
     7from api import DatamoverSystem 
     8from util import copy_milestone 
     9 
     10class DatamoverMilestoneModule(Component): 
     11    """The milestone moving component of the datamover plugin.""" 
     12 
     13    implements(IAdminPageProvider) 
     14     
     15    # IAdminPageProvider methods 
     16    def get_admin_pages(self, req): 
     17        if req.perm.has_permission('TRAC_ADMIN'): 
     18            yield ('mover', 'Data Mover', 'milestone', 'Milestones') 
     19     
     20    def process_admin_request(self, req, cat, page, path_info): 
     21        envs = DatamoverSystem(self.env).all_environments() 
     22        milestones = [m.name for m in Milestone.select(self.env)] 
     23         
     24        if req.method == 'POST': 
     25            source_type = req.args.get('source') 
     26            if not source_type or source_type not in ('milestone', 'all'): 
     27                raise TracError, "Source type not specified or invalid" 
     28            source = req.args.get(source_type) 
     29            dest = req.args.get('destination') 
     30            action = None 
     31            if 'copy' in req.args.keys(): 
     32                action = 'copy' 
     33            elif 'move' in req.args.keys(): 
     34                action = 'move' 
     35            else: 
     36                raise TracError, 'Action not specified or invalid' 
     37                 
     38            action_verb = {'copy':'Copied', 'move':'Moved'}[action] 
     39             
     40            milestone_filter = None 
     41            if source_type == 'milestone': 
     42                in_milestones = req.args.getlist('milestone') 
     43                milestone_filter = lambda c: c in in_milestones 
     44            elif source_type == 'all': 
     45                milestone_filter = lambda c: True 
     46             
     47            try: 
     48                sel_milestones = [m for m in milestones if milestone_filter(m)] 
     49                dest_db = _open_environment(dest).get_db_cnx() 
     50                for milestone in sel_milestones: 
     51                    copy_milestone(self.env, dest, milestone, dest_db) 
     52                dest_db.commit() 
     53                     
     54                if action == 'move': 
     55                    for milestone in sel_milestones: 
     56                        Milestone(self.env, milestone).delete() 
     57                     
     58                req.hdf['datamover.message'] = '%s milestones %s'%(action_verb, ', '.join(sel_milestones)) 
     59            except TracError, e: 
     60                req.hdf['datamover.message'] = "An error has occured: \n"+str(e) 
     61                self.log.warn(req.hdf['datamover.message'], exc_info=True) 
     62         
     63         
     64        req.hdf['datamover.envs'] = envs 
     65        req.hdf['datamover.milestones'] = milestones 
     66        return 'datamover_milestone.cs', None 
  • datamover/component.py

    old new  
     1from trac.core import * 
     2from trac.web.main import _open_environment 
     3from trac.ticket.model import Component as TicketComponent 
     4 
     5from webadmin.web_ui import IAdminPageProvider 
     6 
     7from api import DatamoverSystem 
     8from util import copy_component 
     9 
     10class DatamoverComponentModule(Component): 
     11    """The ticket component moving component of the datamover plugin.""" 
     12 
     13    implements(IAdminPageProvider) 
     14     
     15    # IAdminPageProvider methods 
     16    def get_admin_pages(self, req): 
     17        if req.perm.has_permission('TRAC_ADMIN'): 
     18            yield ('mover', 'Data Mover', 'component', 'Components') 
     19     
     20    def process_admin_request(self, req, cat, page, path_info): 
     21        envs = DatamoverSystem(self.env).all_environments() 
     22        components = [c.name for c in TicketComponent.select(self.env)] 
     23         
     24        if req.method == 'POST': 
     25            source_type = req.args.get('source') 
     26            if not source_type or source_type not in ('component', 'all'): 
     27                raise TracError, "Source type not specified or invalid" 
     28            source = req.args.get(source_type) 
     29            dest = req.args.get('destination') 
     30            action = None 
     31            if 'copy' in req.args.keys(): 
     32                action = 'copy' 
     33            elif 'move' in req.args.keys(): 
     34                action = 'move' 
     35            else: 
     36                raise TracError, 'Action not specified or invalid' 
     37                 
     38            action_verb = {'copy':'Copied', 'move':'Moved'}[action] 
     39             
     40            comp_filter = None 
     41            if source_type == 'component': 
     42                in_components = req.args.getlist('component') 
     43                comp_filter = lambda c: c in in_components 
     44            elif source_type == 'all': 
     45                comp_filter = lambda c: True 
     46             
     47            try: 
     48                sel_components = [c for c in components if comp_filter(c)] 
     49                dest_db = _open_environment(dest).get_db_cnx() 
     50                for comp in sel_components: 
     51                    copy_component(self.env, dest, comp, dest_db) 
     52                dest_db.commit() 
     53                     
     54                if action == 'move': 
     55                    for comp in sel_components: 
     56                        TicketComponent(self.env, comp).delete() 
     57                     
     58                req.hdf['datamover.message'] = '%s components %s'%(action_verb, ', '.join(sel_components)) 
     59            except TracError, e: 
     60                req.hdf['datamover.message'] = "An error has occured: \n"+str(e) 
     61                self.log.warn(req.hdf['datamover.message'], exc_info=True) 
     62         
     63         
     64        req.hdf['datamover.envs'] = envs 
     65        req.hdf['datamover.components'] = components 
     66        return 'datamover_component.cs', None 
  • datamover/wiki.py

    old new  
    2727         
    2828        if req.method == 'POST': 
    2929            source_type = req.args.get('source') 
    30             if not source_type or source_type not in ('prefix', 'glob', 'regex'): 
     30            if not source_type or source_type not in ('prefix', 'glob', 'regex', 'all'): 
    3131                raise TracError, "Source type not specified or invalid" 
    3232            source = req.args.get(source_type) 
    3333            dest = req.args.get('destination') 
     
    4848                page_filter = lambda p: fnmatch.fnmatch(p, source) 
    4949            elif source_type == 'regex': 
    5050                page_filter = lambda p: re.search(re.compile(source, re.U), p) 
     51            elif source_type == 'all': 
     52                page_filter = lambda p: True 
    5153                 
    5254                             
    5355            try: 
  • datamover/enum.py

    old new  
     1from trac.core import * 
     2from trac.web.main import _open_environment 
     3 
     4from webadmin.web_ui import IAdminPageProvider 
     5 
     6from api import DatamoverSystem 
     7from util import copy_enum 
     8 
     9class DatamoverEnumModule(Component): 
     10    """The ticket enum moving component of the datamover plugin.""" 
     11 
     12    implements(IAdminPageProvider) 
     13     
     14    # IAdminPageProvider methods 
     15    def get_admin_pages(self, req): 
     16        if req.perm.has_permission('TRAC_ADMIN'): 
     17            yield ('mover', 'Data Mover', 'enum', 'Enums') 
     18     
     19    def process_admin_request(self, req, cat, page, path_info): 
     20        envs = DatamoverSystem(self.env).all_environments() 
     21        enums = [] 
     22        source_db = self.env.get_db_cnx() 
     23        source_cursor = source_db.cursor() 
     24        source_cursor.execute('SELECT type,name FROM enum') 
     25        for row in source_cursor: 
     26            enums.append(row) 
     27        hashedEnums = {} 
     28        for enum in enums: 
     29            enum_type = enum[0] 
     30            enum_name = enum[1] 
     31            if not hashedEnums.has_key(enum_type): 
     32                hashedEnums[enum_type] = [] 
     33            hashedEnums[enum_type].append(enum_name) 
     34         
     35        if req.method == 'POST': 
     36            source_type = req.args.get('source') 
     37            if not source_type or source_type not in ('type', 'enum', 'all'): 
     38                raise TracError, "Source type not specified or invalid" 
     39            source = req.args.get(source_type) 
     40            dest = req.args.get('destination') 
     41            action = None 
     42            if 'copy' in req.args.keys(): 
     43                action = 'copy' 
     44            elif 'move' in req.args.keys(): 
     45                action = 'move' 
     46            else: 
     47                raise TracError, 'Action not specified or invalid' 
     48                 
     49            action_verb = {'copy':'Copied', 'move':'Moved'}[action] 
     50             
     51            enum_filter = None 
     52            if source_type == 'type': 
     53                sel_type = req.args.get('enumtype') 
     54                enum_filter = lambda e: e[0] == sel_type 
     55            elif source_type == 'enum': 
     56                sel_enums = [(k,v) for k,v in req.args.items() if k.startswith('enum[')] 
     57                enum_filter = lambda e: ('enum[%s]' % e[0], e[1]) in sel_enums 
     58            elif source_type == 'all': 
     59                enum_filter = lambda c: True 
     60             
     61            try: 
     62                filtered_enums = [e for e in enums if enum_filter(e)] 
     63                dest_db = _open_environment(dest).get_db_cnx() 
     64                for enum in filtered_enums: 
     65                    copy_enum(self.env, dest, enum[0], enum[1], dest_db) 
     66                dest_db.commit() 
     67                     
     68                if action == 'move': 
     69                    for enum in filtered_enums: 
     70                        source_cursor.execute('DELETE FROM enum WHERE type=%s AND name=%s', (enum[0],enum[1])) 
     71                     
     72                req.hdf['datamover.message'] = '%s enums %s'%(action_verb, ', '.join(['%s:%s'%e for e in filtered_enums])) 
     73            except TracError, e: 
     74                req.hdf['datamover.message'] = "An error has occured: \n"+str(e) 
     75                self.log.warn(req.hdf['datamover.message'], exc_info=True) 
     76         
     77         
     78        req.hdf['datamover.envs'] = envs 
     79        for k in hashedEnums: 
     80            req.hdf['datamover.enums.' + k] = hashedEnums[k] 
     81        req.hdf['datamover.enumtypes'] = hashedEnums.keys() 
     82        return 'datamover_enum.cs', None 
  • datamover/templates/datamover_milestone.cs

    old new  
     1<h2>Move Milestones</h2> 
     2 
     3<?cs if:datamover.message ?> 
     4<div id="datamover_message" style="font-weight: bold"> 
     5<?cs var:datamover.message ?> 
     6</div> 
     7<?cs /if ?> 
     8 
     9<form class="mod" method="post" action=""> 
     10 
     11<fieldset> 
     12    <legend>Source</legend> 
     13    <div class="field"> 
     14        <label><input type="radio" name="source" value="milestone" id="source_milestone_radio" checked="checked" /> 
     15            Milestone 
     16        </label> 
     17        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     18            All 
     19        </label> 
     20    </div> 
     21    <div class="field" id="source_milestone_div"> 
     22        <label>Milestone: 
     23            <?cs each:milestone = datamover.milestones ?> 
     24            <br/> 
     25            <input type="checkbox" name="milestone" value="<?cs var:milestone ?>"><?cs var:milestone ?></input> 
     26            <?cs /each ?> 
     27        </label> 
     28    </div> 
     29    <div class="field" id="source_all_div" style="display: none"> 
     30        &nbsp; 
     31    </div> 
     32</fieldset> 
     33 
     34<fieldset> 
     35    <legend>Destination</legend> 
     36    <div class="field"> 
     37        <label>Environment: 
     38            <select name="destination"> 
     39                <?cs each:env = datamover.envs ?> 
     40                <option value="<?cs name:env ?>"><?cs var:env.name ?></option> 
     41                <?cs /each ?> 
     42            </select> 
     43        </label> 
     44    </div> 
     45</fieldset> 
     46 
     47<div class="buttons"> 
     48    <input type="submit" name="copy" value="Copy" />&nbsp; 
     49    <input type="submit" name="move" value="Move" /> 
     50</div> 
     51     
     52</form> 
     53     
     54     
     55<script type="text/javascript"> 
     56<!-- 
     57    var current_div = 'source_milestone_div'; 
     58     
     59    function show_div(d) { 
     60        document.getElementById(current_div).style.display = 'none'; 
     61        document.getElementById(d).style.display = 'block'; 
     62        current_div = d; 
     63    } 
     64     
     65    function do_addEvent(d) { 
     66        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
     67    } 
     68     
     69    do_addEvent('source_milestone'); 
     70    do_addEvent('source_all'); 
     71//--> 
     72</script> 
     73 
  • datamover/templates/datamover_component.cs

    old new  
     1<h2>Move Components</h2> 
     2 
     3<?cs if:datamover.message ?> 
     4<div id="datamover_message" style="font-weight: bold"> 
     5<?cs var:datamover.message ?> 
     6</div> 
     7<?cs /if ?> 
     8 
     9<form class="mod" method="post" action=""> 
     10 
     11<fieldset> 
     12    <legend>Source</legend> 
     13    <div class="field"> 
     14        <label><input type="radio" name="source" value="component" id="source_component_radio" checked="checked" /> 
     15            Component 
     16        </label> 
     17        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     18            All 
     19        </label> 
     20    </div> 
     21    <div class="field" id="source_component_div"> 
     22        <label>Component: 
     23            <?cs each:comp = datamover.components ?> 
     24            <br/> 
     25            <input type="checkbox" name="component" value="<?cs var:comp ?>"><?cs var:comp ?></input> 
     26            <?cs /each ?> 
     27        </label> 
     28    </div> 
     29    <div class="field" id="source_all_div" style="display: none"> 
     30        &nbsp; 
     31    </div> 
     32</fieldset> 
     33 
     34<fieldset> 
     35    <legend>Destination</legend> 
     36    <div class="field"> 
     37        <label>Environment: 
     38            <select name="destination"> 
     39                <?cs each:env = datamover.envs ?> 
     40                <option value="<?cs name:env ?>"><?cs var:env.name ?></option> 
     41                <?cs /each ?> 
     42            </select> 
     43        </label> 
     44    </div> 
     45</fieldset> 
     46 
     47<div class="buttons"> 
     48    <input type="submit" name="copy" value="Copy" />&nbsp; 
     49    <input type="submit" name="move" value="Move" /> 
     50</div> 
     51     
     52</form> 
     53     
     54     
     55<script type="text/javascript"> 
     56<!-- 
     57    var current_div = 'source_component_div'; 
     58     
     59    function show_div(d) { 
     60        document.getElementById(current_div).style.display = 'none'; 
     61        document.getElementById(d).style.display = 'block'; 
     62        current_div = d; 
     63    } 
     64     
     65    function do_addEvent(d) { 
     66        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
     67    } 
     68     
     69    do_addEvent('source_component'); 
     70    do_addEvent('source_all'); 
     71//--> 
     72</script> 
     73 
  • datamover/templates/datamover_ticket.cs

    old new  
    2222        </label> 
    2323        <label><input type="radio" name="source" value="query" id="source_query_radio" /> 
    2424            Query 
    25         </label>        
     25        </label> 
    2626    </div> 
    2727    <div class="field" id="source_component_div"> 
    2828        <label>Component: 
     
    8080    } 
    8181     
    8282    function do_addEvent(d) { 
    83         addEvent(document.getElementById(d+'_radio'), 'change', function() { show_div(d+'_div'); }); 
     83        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
    8484    } 
    8585     
    8686    do_addEvent('source_component'); 
  • datamover/templates/datamover_wiki.cs

    old new  
    2020        <label><input type="radio" name="source" value="regex" id="source_regex_radio" /> 
    2121            Regex 
    2222        </label> 
     23        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     24            All 
     25        </label> 
    2326    </div> 
    2427    <div class="field" id="source_prefix_div"> 
    2528        <label>Prefix: 
     
    3639            <input type="text" name="regex" /> 
    3740        </label> 
    3841    </div> 
     42    <div class="field" id="source_all_div" style="display: none"> 
     43        &nbsp; 
     44    </div> 
    3945</fieldset> 
    4046 
    4147<fieldset> 
     
    7076    } 
    7177     
    7278    function do_addEvent(d) { 
    73         addEvent(document.getElementById(d+'_radio'), 'change', function() { show_div(d+'_div'); }); 
     79        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
    7480    } 
    7581     
    7682    do_addEvent('source_prefix'); 
    7783    do_addEvent('source_glob'); 
    7884    do_addEvent('source_regex'); 
     85    do_addEvent('source_all'); 
    7986//--> 
    8087</script> 
    8188 
  • datamover/templates/datamover_enum.cs

    old new  
     1<h2>Move Enums</h2> 
     2 
     3<?cs if:datamover.message ?> 
     4<div id="datamover_message" style="font-weight: bold"> 
     5<?cs var:datamover.message ?> 
     6</div> 
     7<?cs /if ?> 
     8 
     9<form class="mod" method="post" action=""> 
     10 
     11<fieldset> 
     12    <legend>Source</legend> 
     13    <div class="field"> 
     14        <label><input type="radio" name="source" value="type" id="source_type_radio" checked="checked" /> 
     15            Enum Type 
     16        </label> 
     17        <label><input type="radio" name="source" value="enum" id="source_enum_radio" /> 
     18            Selected Enums 
     19        </label> 
     20        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     21            All 
     22        </label> 
     23    </div> 
     24    <div class="field" id="source_type_div"> 
     25        <label>Enum Type: 
     26            <select name="enumtype"> 
     27                <?cs each:enum = datamover.enums ?> 
     28                <option value="<?cs name:enum ?>"><?cs name:enum ?></option> 
     29                <?cs /each ?> 
     30            </select> 
     31        </label> 
     32    </div> 
     33    <div class="field" id="source_enum_div" style="display: none"> 
     34        <label>Enums: 
     35            <br/> 
     36            <table> 
     37            <?cs each:enum = datamover.enums ?> 
     38            <tr><td valign="top" align="right"><b><?cs name:enum ?>: </b></td> 
     39            <td> 
     40                <?cs each:name = enum ?> 
     41                <input type="checkbox" name="enum[<?cs name:enum ?>]" value="<?cs var:name ?>"><?cs var:name ?></input><br/> 
     42                <?cs /each ?> 
     43            </td></tr> 
     44            <?cs /each ?> 
     45            </table> 
     46        </label> 
     47    </div> 
     48    <div class="field" id="source_all_div" style="display: none"> 
     49        &nbsp; 
     50    </div> 
     51</fieldset> 
     52 
     53<fieldset> 
     54    <legend>Destination</legend> 
     55    <div class="field"> 
     56        <label>Environment: 
     57            <select name="destination"> 
     58                <?cs each:env = datamover.envs ?> 
     59                <option value="<?cs name:env ?>"><?cs var:env.name ?></option> 
     60                <?cs /each ?> 
     61            </select> 
     62        </label> 
     63    </div> 
     64</fieldset> 
     65 
     66<div class="buttons"> 
     67    <input type="submit" name="copy" value="Copy" />&nbsp; 
     68    <input type="submit" name="move" value="Move" /> 
     69</div> 
     70     
     71</form> 
     72     
     73     
     74<script type="text/javascript"> 
     75<!-- 
     76    var current_div = 'source_type_div'; 
     77     
     78    function show_div(d) { 
     79        document.getElementById(current_div).style.display = 'none'; 
     80        document.getElementById(d).style.display = 'block'; 
     81        current_div = d; 
     82    } 
     83     
     84    function do_addEvent(d) { 
     85        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
     86    } 
     87     
     88    do_addEvent('source_type'); 
     89    do_addEvent('source_enum'); 
     90    do_addEvent('source_all'); 
     91//--> 
     92</script> 
     93 
  • datamover/templates/datamover_version.cs

    old new  
     1<h2>Move Versions</h2> 
     2 
     3<?cs if:datamover.message ?> 
     4<div id="datamover_message" style="font-weight: bold"> 
     5<?cs var:datamover.message ?> 
     6</div> 
     7<?cs /if ?> 
     8 
     9<form class="mod" method="post" action=""> 
     10 
     11<fieldset> 
     12    <legend>Source</legend> 
     13    <div class="field"> 
     14        <label><input type="radio" name="source" value="version" id="source_version_radio" checked="checked" /> 
     15            Version 
     16        </label> 
     17        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     18            All 
     19        </label> 
     20    </div> 
     21    <div class="field" id="source_version_div"> 
     22        <label>Version: 
     23            <?cs each:version = datamover.versions ?> 
     24            <br/> 
     25            <input type="checkbox" name="version" value="<?cs var:version ?>"><?cs var:version ?></input> 
     26            <?cs /each ?> 
     27        </label> 
     28    </div> 
     29    <div class="field" id="source_all_div" style="display: none"> 
     30        &nbsp; 
     31    </div> 
     32</fieldset> 
     33 
     34<fieldset> 
     35    <legend>Destination</legend> 
     36    <div class="field"> 
     37        <label>Environment: 
     38            <select name="destination"> 
     39                <?cs each:env = datamover.envs ?> 
     40                <option value="<?cs name:env ?>"><?cs var:env.name ?></option> 
     41                <?cs /each ?> 
     42            </select> 
     43        </label> 
     44    </div> 
     45</fieldset> 
     46 
     47<div class="buttons"> 
     48    <input type="submit" name="copy" value="Copy" />&nbsp; 
     49    <input type="submit" name="move" value="Move" /> 
     50</div> 
     51     
     52</form> 
     53     
     54     
     55<script type="text/javascript"> 
     56<!-- 
     57    var current_div = 'source_version_div'; 
     58     
     59    function show_div(d) { 
     60        document.getElementById(current_div).style.display = 'none'; 
     61        document.getElementById(d).style.display = 'block'; 
     62        current_div = d; 
     63    } 
     64     
     65    function do_addEvent(d) { 
     66        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
     67    } 
     68     
     69    do_addEvent('source_version'); 
     70    do_addEvent('source_all'); 
     71//--> 
     72</script> 
     73 
  • datamover/templates/datamover_attachment.cs

    old new  
     1<h2>Move Attachments</h2> 
     2 
     3<?cs if:datamover.message ?> 
     4<div id="datamover_message" style="font-weight: bold"> 
     5<?cs var:datamover.message ?> 
     6</div> 
     7<?cs /if ?> 
     8 
     9<form class="mod" method="post" action=""> 
     10 
     11<fieldset> 
     12    <legend>Source</legend> 
     13    <div class="field"> 
     14        <label><input type="radio" name="source" value="type" id="source_type_radio" checked="checked" /> 
     15            Type 
     16        </label> 
     17        <label><input type="radio" name="source" value="wiki" id="source_wiki_radio" /> 
     18            Wiki Page 
     19        </label> 
     20        <label><input type="radio" name="source" value="ticket" id="source_ticket_radio" /> 
     21            Ticket 
     22        </label> 
     23        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     24            All 
     25        </label> 
     26    </div> 
     27    <div class="field" id="source_type_div"> 
     28        <label>Type: 
     29            <select name="type"> 
     30                <option value="wiki">Wiki</option> 
     31                <option value="ticket">Ticket</option> 
     32            </select> 
     33        </label> 
     34    </div> 
     35    <div class="field" id="source_wiki_div" style="display: none"> 
     36        <label>Wiki Page (only showing pages with attachments): 
     37            <br/> 
     38            <?cs each:page = datamover.wiki_pages ?> 
     39            <br/> 
     40            <input type="checkbox" name="wiki" value="<?cs var:page ?>"><?cs var:page ?></input> 
     41            <?cs /each ?> 
     42        </label> 
     43    </div> 
     44    <div class="field" id="source_ticket_div" style="display: none"> 
     45        <label>Ticket ID: 
     46            <input type="text" name="ticket" /> 
     47        </label> 
     48    </div> 
     49    <div class="field" id="source_all_div" style="display: none"> 
     50        <p style="font-style: italic">Note: this will take a while</p> 
     51    </div> 
     52</fieldset> 
     53 
     54<fieldset> 
     55    <legend>Destination</legend> 
     56    <div class="field"> 
     57        <label>Environment: 
     58            <select name="destination"> 
     59                <?cs each:env = datamover.envs ?> 
     60                <option value="<?cs name:env ?>"><?cs var:env.name ?></option> 
     61                <?cs /each ?> 
     62            </select> 
     63        </label> 
     64    </div> 
     65</fieldset> 
     66 
     67<div class="buttons"> 
     68    <input type="submit" name="copy" value="Copy" />&nbsp; 
     69    <input type="submit" name="move" value="Move" /> 
     70</div> 
     71     
     72</form> 
     73     
     74     
     75<script type="text/javascript"> 
     76<!-- 
     77    var current_div = 'source_type_div'; 
     78     
     79    function show_div(d) { 
     80        document.getElementById(current_div).style.display = 'none'; 
     81        document.getElementById(d).style.display = 'block'; 
     82        current_div = d; 
     83    } 
     84     
     85    function do_addEvent(d) { 
     86        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
     87    } 
     88     
     89    do_addEvent('source_type'); 
     90    do_addEvent('source_wiki'); 
     91    do_addEvent('source_ticket'); 
     92    do_addEvent('source_all'); 
     93//--> 
     94</script> 
     95 
  • datamover/templates/datamover_permission.cs

    old new  
     1<h2>Move Permissions</h2> 
     2 
     3<?cs if:datamover.message ?> 
     4<div id="datamover_message" style="font-weight: bold"> 
     5<?cs var:datamover.message ?> 
     6</div> 
     7<?cs /if ?> 
     8 
     9<form class="mod" method="post" action=""> 
     10 
     11<fieldset> 
     12    <legend>Source</legend> 
     13    <div class="field"> 
     14        <label><input type="radio" name="source" value="permission" id="source_permission_radio" checked="checked" /> 
     15            Permission 
     16        </label> 
     17        <label><input type="radio" name="source" value="all" id="source_all_radio" /> 
     18            All 
     19        </label> 
     20    </div> 
     21    <div class="field" id="source_permission_div"> 
     22        <label>Permission: 
     23            <table class="listing"> 
     24                <thead> 
     25                    <tr> 
     26                        <th class="sel">&nbsp;</th> 
     27                        <th>Subject</th> 
     28                        <th>Action</th> 
     29                    </tr> 
     30                </thead> 
     31                <?cs each:perm = datamover.permissions ?> 
     32                <tr> 
     33                    <td><input type="checkbox" name="perm" value="<?cs var:perm.0 ?>:<?cs var:perm.1 ?>"></input></td> 
     34                    <td><?cs var:perm.0 ?></td> 
     35                    <td><?cs var:perm.1 ?></td> 
     36                </tr> 
     37                <?cs /each ?> 
     38            </table> 
     39        </label> 
     40    </div> 
     41    <div class="field" id="source_all_div" style="display: none"> 
     42        &nbsp; 
     43    </div> 
     44</fieldset> 
     45 
     46<fieldset> 
     47    <legend>Destination</legend> 
     48    <div class="field"> 
     49        <label>Environment: 
     50            <select name="destination"> 
     51                <?cs each:env = datamover.envs ?> 
     52                <option value="<?cs name:env ?>"><?cs var:env.name ?></option> 
     53                <?cs /each ?> 
     54            </select> 
     55        </label> 
     56    </div> 
     57</fieldset> 
     58 
     59<div class="buttons"> 
     60    <input type="submit" name="copy" value="Copy" />&nbsp; 
     61    <input type="submit" name="move" value="Move" /> 
     62</div> 
     63     
     64</form> 
     65     
     66     
     67<script type="text/javascript"> 
     68<!-- 
     69    var current_div = 'source_permission_div'; 
     70     
     71    function show_div(d) { 
     72        document.getElementById(current_div).style.display = 'none'; 
     73        document.getElementById(d).style.display = 'block'; 
     74        current_div = d; 
     75    } 
     76     
     77    function do_addEvent(d) { 
     78        addEvent(document.getElementById(d+'_radio'), 'click', function() { show_div(d+'_div'); }); 
     79    } 
     80     
     81    do_addEvent('source_permission'); 
     82    do_addEvent('source_all'); 
     83//--> 
     84</script> 
     85 
  • datamover/util.py

    old new  
     1from trac.core import TracError 
    12from trac.env import Environment 
    23from trac.web.main import _open_environment 
    34from trac.wiki.model import WikiPage 
     5from trac.ticket.model import Component as TicketComponent, Milestone, Version 
     6from trac.attachment import Attachment 
    47 
    5 __all__ = ['copy_ticket', 'copy_wiki_page'] 
     8from shutil import copyfile 
     9import os 
     10__all__ = ['copy_ticket', 'copy_wiki_page', 'copy_component', 'copy_enum', 'copy_milestone', 'copy_attachment',