2525
2626logtag = __name__ .split ('.' )[- 1 ]
2727logname = "user.log"
28- syslog .openlog (logname , syslog .LOG_PID , syslog .LOG_USER )
28+ syslog .openlog (logtag , syslog .LOG_PID , syslog .LOG_USER )
2929
3030class Command (BaseCommand ):
3131 help = "Create group wikis for WGs, RGs and Areas which don't have one."
3232
3333 option_list = BaseCommand .option_list + (
34- make_option ('--wiki-dir-pattern' , dest = 'wiki_dir_pattern' , help = 'A pattern with %s placeholder for group wiki path' ),
35- make_option ('--svn-dir-pattern' , dest = 'svn_dir_pattern' , help = 'A pattern with %s placeholder for group svn path' ),
36- )
34+ make_option ('--wiki-dir-pattern' , dest = 'wiki_dir_pattern' ,
35+ default = settings .TRAC_WIKI_DIR_PATTERN ,
36+ help = 'A pattern with %s placeholder for group wiki path' ),
37+ make_option ('--svn-dir-pattern' , dest = 'svn_dir_pattern' ,
38+ default = settings .TRAC_SVN_DIR_PATTERN ,
39+ help = 'A pattern with %s placeholder for group svn path' ),
40+ make_option ('--group-list' , '-g' , dest = 'group_list' , help = 'Limit processing to groups with the given acronyms (a comma-separated list)' ),
41+ make_option ('--dummy-run' , '-n' , default = False , action = 'store_true' , dest = 'dummy_run' , help = 'Make no changes, just show what would be done' ),
42+ )
3743
3844 def note (self , msg ):
3945 if self .verbosity > 1 :
@@ -47,14 +53,17 @@ def log(self, msg):
4753
4854 def do_cmd (self , cmd , * args ):
4955 quoted_args = [ '"%s"' % a if ' ' in a else a for a in args ]
50- self .note ("Running %s %s ..." % (os .path .basename (cmd ), " " .join (quoted_args )))
51- command = [ cmd , ] + list (args )
52- code , out , err = pipe (command )
53- msg = None
54- if code != 0 :
55- msg = "Error %s: %s when executing '%s'" % (code , err , " " .join (command ))
56- self .log (msg )
57- return msg , out
56+ if self .dummy_run :
57+ self .note ("Would run %s %s ..." % (os .path .basename (cmd ), " " .join (quoted_args )))
58+ else :
59+ self .note ("Running %s %s ..." % (os .path .basename (cmd ), " " .join (quoted_args )))
60+ command = [ cmd , ] + list (args )
61+ code , out , err = pipe (command )
62+ msg = None
63+ if code != 0 :
64+ msg = "Error %s: %s when executing '%s'" % (code , err , " " .join (command ))
65+ self .log (msg )
66+ return msg , out
5867
5968 def svn_admin_cmd (self , * args ):
6069 return self .do_cmd (settings .SVN_ADMIN_COMMAND , * args )
@@ -142,81 +151,94 @@ def create_trac(self, group):
142151 options [i ] = sect , key , val
143152 # Try to creat ethe environment, remove unwanted defaults, and add
144153 # custom pages and settings.
145- try :
146- env = Environment (group .trac_dir , create = True , options = options )
147- self .remove_demo_components (group , env )
148- self .remove_demo_milestones (group , env )
149- self .maybe_add_group_url (group , 'Wiki' , settings .TRAC_WIKI_URL_PATTERN % group .acronym )
150- self .maybe_add_group_url (group , 'Issue tracker' , settings .TRAC_ISSUE_URL_PATTERN % group .acronym )
151- # Use custom assets (if any) from the master setup
152- self .symlink_to_master_assets (group , env )
153- if group .type_id == 'wg' :
154- self .add_wg_draft_states (group , env )
155- self .add_custom_wiki_pages (group , env )
156- self .add_default_wiki_pages (group , env )
157- self .sync_default_repository (group , env )
158- # Components (i.e., drafts) will be handled during components
159- # update later
160- # Permissions will be handled during permission update later.
161- return env
162- except TracError as e :
163- self .log ("While creating trac instance for %s: %s" % (group , e ))
164- raise
165- return None
154+ if self .dummy_run :
155+ self .note ("Would create Trac for group '%s' at %s" % (group .acronym , group .trac_dir ))
156+ return True
157+ else :
158+ try :
159+ self .note ("Creating Trac for group '%s' at %s" % (group .acronym , group .trac_dir ))
160+ env = Environment (group .trac_dir , create = True , options = options )
161+ self .remove_demo_components (group , env )
162+ self .remove_demo_milestones (group , env )
163+ self .maybe_add_group_url (group , 'Wiki' , settings .TRAC_WIKI_URL_PATTERN % group .acronym )
164+ self .maybe_add_group_url (group , 'Issue tracker' , settings .TRAC_ISSUE_URL_PATTERN % group .acronym )
165+ # Use custom assets (if any) from the master setup
166+ self .symlink_to_master_assets (group , env )
167+ if group .type_id == 'wg' :
168+ self .add_wg_draft_states (group , env )
169+ self .add_custom_wiki_pages (group , env )
170+ self .add_default_wiki_pages (group , env )
171+ self .sync_default_repository (group , env )
172+ # Components (i.e., drafts) will be handled during components
173+ # update later
174+ # Permissions will be handled during permission update later.
175+ return env
176+ except TracError as e :
177+ self .log ("While creating Trac instance for %s: %s" % (group , e ))
178+ raise
179+ return None
166180
167181 def update_trac_permissions (self , group , env ):
168- mgr = PermissionSystem (env )
169- permission_list = mgr .get_all_permissions ()
170- permission_list = [ (u ,a ) for (u ,a ) in permission_list if not u in ['anonymous' , 'authenticated' ]]
171- permissions = {}
172- for user , action in permission_list :
173- if not user in permissions :
174- permissions [user ] = []
175- permissions [user ].append (action )
176- roles = group .role_set .filter (name_id__in = ['chair' , 'secr' , 'ad' ])
177- users = []
178- for role in roles :
179- user = role .email .address .lower ()
180- users .append (user )
181- if not user in permissions :
182- try :
183- mgr .grant_permission (user , 'TRAC_ADMIN' )
184- self .note (" Granting admin permission for %s" % user )
185- except TracError as e :
186- self .log ("While adding admin permission for %s: %s" (user , e ))
187- for user in permissions :
188- if not user in users :
189- if 'TRAC_ADMIN' in permissions [user ]:
182+ if self .dummy_run :
183+ self .note ("Would update Trac permissions for group '%s'" % group .acronym )
184+ else :
185+ self .note ("Updating Trac permissions for group '%s'" % group .acronym )
186+ mgr = PermissionSystem (env )
187+ permission_list = mgr .get_all_permissions ()
188+ permission_list = [ (u ,a ) for (u ,a ) in permission_list if not u in ['anonymous' , 'authenticated' ]]
189+ permissions = {}
190+ for user , action in permission_list :
191+ if not user in permissions :
192+ permissions [user ] = []
193+ permissions [user ].append (action )
194+ roles = group .role_set .filter (name_id__in = ['chair' , 'secr' , 'ad' ])
195+ users = []
196+ for role in roles :
197+ user = role .email .address .lower ()
198+ users .append (user )
199+ if not user in permissions :
190200 try :
191- self . note ( " Revoking admin permission for %s" % user )
192- mgr . revoke_permission ( user , 'TRAC_ADMIN' )
201+ mgr . grant_permission ( user , 'TRAC_ADMIN' )
202+ self . note ( " Granting admin permission for %s" % user )
193203 except TracError as e :
194- self .log ("While revoking admin permission for %s: %s" (user , e ))
204+ self .log ("While adding admin permission for %s: %s" (user , e ))
205+ for user in permissions :
206+ if not user in users :
207+ if 'TRAC_ADMIN' in permissions [user ]:
208+ try :
209+ self .note (" Revoking admin permission for %s" % user )
210+ mgr .revoke_permission (user , 'TRAC_ADMIN' )
211+ except TracError as e :
212+ self .log ("While revoking admin permission for %s: %s" (user , e ))
195213
196214 def update_trac_components (self , group , env ):
197- components = Component .select (env )
198- comp_names = [ c .name for c in components ]
199- group_docs = group .document_set .filter (states__slug = 'active' , type_id = 'draft' ).distinct ()
200- group_comp = []
201- for doc in group_docs :
202- if not doc .name .startswith ('draft-' ):
203- self .log ("While adding components: unexpectd %s group doc name: %s" % (group .acronym , doc .name ))
204- continue
205- name = doc .name [len ('draft-' ):]
206- if name .startswith ('ietf-' ):
207- name = name [len ('ietf-' ):]
208- elif name .startswith ('irtf-' ):
209- name = name [len ('ietf-' ):]
210- if name .startswith (group .acronym + '-' ):
211- name = name [len (group .acronym + '-' ):]
212- group_comp .append (name )
213- if not name in comp_names and not doc .name in comp_names :
214- self .note (" Group draft: %s" % doc .name )
215- self .note (" Adding component %s" % name )
216- comp = Component (env )
217- comp .name = name
218- comp .owner = "%s@ietf.org" % doc .name
219- comp .insert ()
215+ if self .dummy_run :
216+ self .note ("Would update Trac components for group '%s'" % group .acronym )
217+ else :
218+ self .note ("Updating Trac componets for group '%s'" % group .acronym )
219+ components = Component .select (env )
220+ comp_names = [ c .name for c in components ]
221+ group_docs = group .document_set .filter (states__slug = 'active' , type_id = 'draft' ).distinct ()
222+ group_comp = []
223+ for doc in group_docs :
224+ if not doc .name .startswith ('draft-' ):
225+ self .log ("While adding components: unexpectd %s group doc name: %s" % (group .acronym , doc .name ))
226+ continue
227+ name = doc .name [len ('draft-' ):]
228+ if name .startswith ('ietf-' ):
229+ name = name [len ('ietf-' ):]
230+ elif name .startswith ('irtf-' ):
231+ name = name [len ('ietf-' ):]
232+ if name .startswith (group .acronym + '-' ):
233+ name = name [len (group .acronym + '-' ):]
234+ group_comp .append (name )
235+ if not name in comp_names and not doc .name in comp_names :
236+ self .note (" Group draft: %s" % doc .name )
237+ self .note (" Adding component %s" % name )
238+ comp = Component (env )
239+ comp .name = name
240+ comp .owner = "%s@ietf.org" % doc .name
241+ comp .insert ()
220242
221243 def maybe_add_group_url (self , group , name , url ):
222244 urls = [ u for u in group .groupurl_set .all () if name .lower () in u .name .lower () ]
@@ -239,21 +261,34 @@ def handle(self, *filenames, **options):
239261 self .errors = 0
240262 self .wiki_dir_pattern = options .get ('wiki_dir_pattern' , settings .TRAC_WIKI_DIR_PATTERN )
241263 self .svn_dir_pattern = options .get ('svn_dir_pattern' , settings .TRAC_SVN_DIR_PATTERN )
264+ self .group_list = options .get ('group_list' , None )
265+ self .dummy_run = options .get ('dummy_run' , False )
266+
267+ if not self .group_list is None :
268+ self .group_list = self .group_list .split ('.' )
242269
243270 if isinstance (self .verbosity , (type ("" ), type (u"" ))) and self .verbosity .isdigit ():
244271 self .verbosity = int (self .verbosity )
245272
273+ if self .dummy_run and self .verbosity < 2 :
274+ self .verbosity = 2
275+
246276 if not os .path .exists (os .path .dirname (self .wiki_dir_pattern )):
247277 raise CommandError ('The Wiki base direcory specified for the wiki directories (%s) does not exist.' % os .path .dirname (self .wiki_dir_pattern ))
248278
279+ if not os .path .exists (os .path .dirname (self .svn_dir_pattern )):
280+ raise CommandError ('The SVN base direcory specified for the SVN directories (%s) does not exist.' % os .path .dirname (self .svn_dir_pattern ))
281+
249282 groups = Group .objects .filter (
250283 type__slug__in = ['wg' ,'rg' ,'area' ],
251- state__slug = 'active'
284+ state__slug = 'active' ,
252285 ).order_by ('acronym' )
286+ if self .group_list :
287+ groups = groups .filter (acronym__in = self .group_list )
253288
254289 for group in groups :
255290 try :
256- self .note ("Processing group %s " % group .acronym )
291+ self .note ("Processing group '%s' " % group .acronym )
257292 group .trac_dir = self .wiki_dir_pattern % group .acronym
258293 group .svn_dir = self .svn_dir_pattern % group .acronym
259294
@@ -265,9 +300,10 @@ def handle(self, *filenames, **options):
265300 trac_env = self .create_trac (group )
266301 self .errors += 1 if not trac_env else 0
267302 else :
268- trac_env = Environment (group .trac_dir )
303+ if not self .dummy_run :
304+ trac_env = Environment (group .trac_dir )
269305
270- if not trac_env :
306+ if not trac_env and not self . dummy_run :
271307 continue
272308
273309 self .update_trac_permissions (group , trac_env )
0 commit comments