def get_project_events(self, project, days, minutes): """ List all events in project that happened in a given time span. """ events = [] project_href = Href(conf.url_projects_path + "/" + project.env_name) req = DummyReq('user', 'password', 'method', 'uri', 'args') req.permissions = ('TICKET_VIEW', 'CHANGESET_VIEW', 'WIKI_VIEW', 'ATTACHMENT_VIEW', 'DISCUSSION_VIEW', 'MILESTONE_VIEW') req.authname = 'authname' req.abs_href = project_href project_env = open_environment(conf.getEnvironmentSysPath( project.env_name), use_cache=True) event_provider = ProjectTimelineEvents(project_env) last_events = event_provider.get_timeline_events( req, time_in_days=days, time_in_minutes=minutes) for event in last_events: context = Context(resource=Resource(), href=project_href) context.req = req context.perm = req.perm events.append([project, event, context]) events.sort(lambda x, y: cmp(y[1]['date'], x[1]['date'])) return events
def get_project_events(self, project, days, minutes): """ List all events in project that happened in a given time span. """ events = [] project_href = Href(conf.url_projects_path + "/" + project.env_name) req = DummyReq('user', 'password', 'method', 'uri', 'args') req.permissions = ( 'TICKET_VIEW', 'CHANGESET_VIEW', 'WIKI_VIEW', 'ATTACHMENT_VIEW', 'DISCUSSION_VIEW', 'MILESTONE_VIEW') req.authname = 'authname' req.abs_href = project_href project_env = open_environment(conf.getEnvironmentSysPath(project.env_name), use_cache=True) event_provider = ProjectTimelineEvents(project_env) last_events = event_provider.get_timeline_events(req, time_in_days=days, time_in_minutes=minutes) for event in last_events: context = Context(resource=Resource(), href=project_href) context.req = req context.perm = req.perm events.append([project, event, context]) events.sort(lambda x, y: cmp(y[1]['date'], x[1]['date'])) return events
def __init__(self, project, settings): Command.__init__(self) self.project = project self.env_path = conf.getEnvironmentSysPath(project.env_name) self.conf_file = self.env_path + '/conf/trac.ini' self.conf_file_back = self.conf_file + '.back' self.vcs_type = settings['vcs_type'] self.name = "ConfigureTrac"
def send_mail(message, receiver): env = Environment(conf.getEnvironmentSysPath(conf.sys_home_project_name)) notifier = NotificationSystem(env) from_email = env.config['notification'].get('smtp_from') replyto_email = env.config['notification'].get('smtp_replyto') sender = from_email or replyto_email try: notifier.send_email(sender, receiver, message) except Exception as e: error_exit(e) return True
def __init__(self, project, settings): Command.__init__(self) self.vcs_type = settings['vcs_type'] self.short_name = project.env_name self.long_name = project.project_name self.author = project.author self.env_path = conf.getEnvironmentSysPath(self.short_name) self.db_string = conf.getEnvironmentDbPath(self.short_name) self.vcs_path = conf.getEnvironmentVcsPath(self.short_name) self.args = "'" + self.long_name + "'" + " " + self.db_string self.args += " " + self.vcs_type + " " + self.vcs_path self.args += " --inherit=" + conf.global_conf_path self.name = "CreateTracEnvironment"
def __init__(self, project, settings): Command.__init__(self) self.vcs_type = settings['vcs_type'] self.vcs_name = settings['vcs_name'] self.short_name = project.env_name self.long_name = project.project_name self.author = project.author self.env_path = conf.getEnvironmentSysPath(self.short_name) self.db_string = conf.getEnvironmentDbPath(self.short_name) self.vcs_path = conf.getEnvironmentVcsPath(self.short_name, self.vcs_type, self.vcs_name) self.args = "'" + self.long_name + "'" + " " + self.db_string self.args += " " + self.vcs_type + " " + self.vcs_path self.args += " --inherit=" + conf.global_conf_path self.name = "CreateTracEnvironment"
def main(watchlist_type): """ Creates the infamous Configuration object to dig out home project env and sends watchlist notifications to all users that have registered to them. :param str watchlist_type: immediate, daily or weekly notification. """ env = Environment(conf.getEnvironmentSysPath(conf.sys_home_project_name)) try: module = WatchlistNotifier(env) module.notify_now(watchlist_type) except Exception, e: env.log.exception("Failed to send watchlist messages") return str(e)
def refresh_project(self, project_identifier, from_date, to_date=datetime.now(datefmt.localtz), afilters=None, update=False): """ Will refresh a project events in cache in given date range. .. NOTE:: Dates needs to be given in datefmt.localtz form """ # Initialize objects project = Project.get(env_name=project_identifier) if not project: conf.log.warning('Project {0} is already removed from system or it cannot be found'.format(project_identifier)) return e = open_environment(conf.getEnvironmentSysPath(project.env_name), use_cache=True) pte = ProjectTimelineEvents(e) providers = pte.event_providers project_href = Href(conf.url_projects_path + '/' + project.env_name) context = Context(resource=Resource(), href=project_href) req = self._create_dummy_req(project_identifier) context.req = req context.perm = req.perm # Read events from timeline events = [] for provider in providers: try: # Use filters in parameter or check filters from providers if afilters: filters = afilters else: available_filters = provider.get_timeline_filters(req) or [] filters = [f[0] for f in available_filters] for event in provider.get_timeline_events(req, from_date, to_date, filters): event_data = self._event_data(provider, event) if event_data['author'] != 'trac': # Skip system events events.append(CachedEvent.from_event_data(project, event_data, context, filters[0])) except: conf.log.error("Could not read timeline events for %s from %s" % (project_identifier, str(provider))) # Write events into sql table self._write_events_into_cache(events, update)
def __init__(self, project): Command.__init__(self) self.project = project self.name = "ConfigureFSPermissions" self.env_path = conf.getEnvironmentSysPath(project.env_name) self.conf_file = self.env_path + '/conf/trac.ini' self.egid = os.getegid() self.euid = os.geteuid() import stat self._perms = { # u+rw,g+r "conf": stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP, # u+rw,g+rw "log": stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP }
from trac.env import Environment from multiproject.core.configuration import conf from multiproject.home.admin.storageusage import StorageUsageNotifier module = StorageUsageNotifier() module.notify_now( Environment(conf.getEnvironmentSysPath(conf.sys_home_project_name)))
def main(): if '-h' in sys.argv or '--help' in sys.argv: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " sys.exit() from_batch = 0 if '--batch' in sys.argv: from_batch_index = sys.argv.index('--batch')+1 if len(sys.argv) > from_batch_index: from_batch = int(sys.argv[int(from_batch_index)]) else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " print " (--batch used incorrectly)" sys.exit() from_sleep = 5 if '--sleep' in sys.argv: from_sleep_index = sys.argv.index('--sleep')+1 if len(sys.argv) > from_sleep_index: from_sleep = int(sys.argv[int(from_sleep_index)]) else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " print " (--sleep used incorrectly)" sys.exit() total_batch_count = -1 if '--limit' in sys.argv: from_limit_index = sys.argv.index('--limit')+1 if len(sys.argv) > from_limit_index: total_batch_count = int(sys.argv[int(from_limit_index)]) else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " print " (--limit used incorrectly)" sys.exit() env_name = 'HelpAndSupport' if '--env' in sys.argv: env_index = sys.argv.index('--env')+1 if len(sys.argv) > env_index: env_name = sys.argv[int(env_index)] else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [-n] [--env ENV] " print " (--env used incorrectly)" sys.exit() debug_only = False if '-n' in sys.argv: debug_only = True header = '' message = '' with open('message.txt') as fd: message = fd.read() with open('subject.txt') as fd: lines = fd.read().splitlines() for line in lines: if line: header = line mailNotifier = EmailNotifier(Environment(conf.getEnvironmentSysPath(env_name)), header, message) print "header: '%s'" % header print "message:\n---\n'%s'\n---\n" % message print "debug?:%s"%debug_only with open('project_admins.txt') as fd: users = fd.read().splitlines() index = 0 counter = 0 sent_batch_count = 0 for chunk in chunks(users, 5): counter += 1 if from_batch <= counter and (total_batch_count == -1 or total_batch_count > sent_batch_count): print "sending batch %s, from %s to %s, emails: %s" % (counter, index+1, index+len(chunk), chunk) if not debug_only: mailNotifier.notify(chunk) time.sleep(from_sleep) sent_batch_count += 1 index += 5
def main(): if '-h' in sys.argv or '--help' in sys.argv: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " sys.exit() from_batch = 0 if '--batch' in sys.argv: from_batch_index = sys.argv.index('--batch') + 1 if len(sys.argv) > from_batch_index: from_batch = int(sys.argv[int(from_batch_index)]) else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " print " (--batch used incorrectly)" sys.exit() from_sleep = 5 if '--sleep' in sys.argv: from_sleep_index = sys.argv.index('--sleep') + 1 if len(sys.argv) > from_sleep_index: from_sleep = int(sys.argv[int(from_sleep_index)]) else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " print " (--sleep used incorrectly)" sys.exit() total_batch_count = -1 if '--limit' in sys.argv: from_limit_index = sys.argv.index('--limit') + 1 if len(sys.argv) > from_limit_index: total_batch_count = int(sys.argv[int(from_limit_index)]) else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [--sleep N] [-n] [--env ENV] " print " (--limit used incorrectly)" sys.exit() env_name = 'HelpAndSupport' if '--env' in sys.argv: env_index = sys.argv.index('--env') + 1 if len(sys.argv) > env_index: env_name = sys.argv[int(env_index)] else: print "Usage: python send_mail_to_project_admins.py [--batch N] [--limit N] [-n] [--env ENV] " print " (--env used incorrectly)" sys.exit() debug_only = False if '-n' in sys.argv: debug_only = True header = '' message = '' with open('message.txt') as fd: message = fd.read() with open('subject.txt') as fd: lines = fd.read().splitlines() for line in lines: if line: header = line mailNotifier = EmailNotifier( Environment(conf.getEnvironmentSysPath(env_name)), header, message) print "header: '%s'" % header print "message:\n---\n'%s'\n---\n" % message print "debug?:%s" % debug_only with open('project_admins.txt') as fd: users = fd.read().splitlines() index = 0 counter = 0 sent_batch_count = 0 for chunk in chunks(users, 5): counter += 1 if from_batch <= counter and ( total_batch_count == -1 or total_batch_count > sent_batch_count): print "sending batch %s, from %s to %s, emails: %s" % ( counter, index + 1, index + len(chunk), chunk) if not debug_only: mailNotifier.notify(chunk) time.sleep(from_sleep) sent_batch_count += 1 index += 5
from trac.env import Environment from multiproject.core.configuration import conf from multiproject.home.admin.storageusage import StorageUsageNotifier module = StorageUsageNotifier() module.notify_now(Environment(conf.getEnvironmentSysPath(conf.sys_home_project_name)))
def create_project(self, req): """ Handler for creating project request """ req.perm.require("PROJECT_CREATE") if req.method != 'POST': return self.create_failure( req, 'POST request needed when creating a new project') author = get_context(req)['author'] # If agreement needed but not getting it, show failure if conf.project_requires_agreed_terms and not self._is_active_user( req): return self.create_failure( req, 'You need to approve legal text to create a project!') # Read and transform some variables vcs_type = req.args.get('vcstype') vcs_name = req.args.get('vcs_name') if not self.validate_repository_name(vcs_name): return self.create_failure(req, 'Check repository name.') parent_project = None if "_project_" in req.args: parent_project = Project.get(env_name=req.args.get('_project_')) self.__require_permissions_for_cloning(req.authname, parent_project) vcs_type = conf.getVersionControlType( parent_project.env_name ) # TODO: expensive call, probably needed # Read settings settings = {} if vcs_type: settings['vcs_type'] = vcs_type if vcs_name: settings['vcs_name'] = vcs_name identifier = req.args.get('prj_short_name') name = req.args.get('prj_long_name') project_visibility = 'prj_is_public' in req.args public = False published = None if project_visibility: public = True published = datetime.now() # Create project object project = Project( id=None, env_name=identifier, project_name=name, description=req.args.get('prj_description'), author_id=author.id, created=None, # Use default which is now() public=public, published=published) # Create project environment projects = Projects() try: projects.create_project(project, settings) except ProjectValidationException as exc: self.log.warning( 'Project creation failed due the validation: {0}'.format( exc.value)) return self.create_failure(req, exc.value) except: self.log.exception('Project creation failed') return self.create_failure( req, _("Creating project failed. Try again later.")) if public: projects.add_public_project_visibility(project.id) #Add author to follow project watch_store = CQDEWatchlistStore() watch_store.watch_project(author.id, project.id) #Change project trac.ini to support multiple repositories project_env_path = conf.getEnvironmentSysPath(project.env_name) repo_env_path = conf.getEnvironmentVcsPath(project.env_name, vcs_type, vcs_name) os.rename(project_env_path + '/conf/trac.ini', project_env_path + '/conf/trac.ini.bak') oldfile = open(project_env_path + '/conf/trac.ini.bak', 'r') newfile = open(project_env_path + '/conf/trac.ini', 'w') lines = oldfile.readlines() for line in lines: newfile.write(line) if line.startswith('database ='): break newfile.write( 'repository_dir =\nrepository_type = svn\n\n[repositories]\n') newfile.write('%s.dir = %s\n' % (vcs_name, repo_env_path)) newfile.write('%s.type = %s\n' % (vcs_name, vcs_type)) newfile.close() oldfile.close() os.remove(project_env_path + '/conf/trac.ini.bak') # Notify listeners. The project object still exists, but database does not for listener in self.project_change_listeners: try: listener.project_created(project) listener.project_watchers(project) if public: listener.project_set_public(project) except: pass return self.create_success(req, project)
def create_project(self, req): """ Handler for creating project request """ req.perm.require("PROJECT_CREATE") if req.method != 'POST': return self.create_failure(req, 'POST request needed when creating a new project') author = get_context(req)['author'] # If agreement needed but not getting it, show failure if conf.project_requires_agreed_terms and not self._is_active_user(req): return self.create_failure(req, 'You need to approve legal text to create a project!') # Read and transform some variables vcs_type = req.args.get('vcstype') vcs_name = req.args.get('vcs_name') if not self.validate_repository_name(vcs_name): return self.create_failure(req, 'Check repository name.') parent_project = None if "_project_" in req.args: parent_project = Project.get(env_name=req.args.get('_project_')) self.__require_permissions_for_cloning(req.authname, parent_project) vcs_type = conf.getVersionControlType(parent_project.env_name) # TODO: expensive call, probably needed # Read settings settings = {} if vcs_type: settings['vcs_type'] = vcs_type if vcs_name: settings['vcs_name'] = vcs_name identifier = req.args.get('prj_short_name') name = req.args.get('prj_long_name') project_visibility = 'prj_is_public' in req.args public = False published = None if project_visibility: public = True published = datetime.now() # Create project object project = Project( id = None, env_name = identifier, project_name = name, description = req.args.get('prj_description'), author_id = author.id, created = None, # Use default which is now() public = public, published = published ) # Create project environment projects = Projects() try: projects.create_project(project, settings) except ProjectValidationException as exc: self.log.warning('Project creation failed due the validation: {0}'.format(exc.value)) return self.create_failure(req, exc.value) except: self.log.exception('Project creation failed') return self.create_failure(req, _("Creating project failed. Try again later.")) if public: projects.add_public_project_visibility(project.id) #Add author to follow project watch_store = CQDEWatchlistStore() watch_store.watch_project(author.id, project.id) #Change project trac.ini to support multiple repositories project_env_path = conf.getEnvironmentSysPath(project.env_name) repo_env_path = conf.getEnvironmentVcsPath(project.env_name, vcs_type, vcs_name) os.rename(project_env_path + '/conf/trac.ini', project_env_path + '/conf/trac.ini.bak') oldfile = open(project_env_path + '/conf/trac.ini.bak', 'r') newfile = open(project_env_path + '/conf/trac.ini', 'w') lines = oldfile.readlines() for line in lines: newfile.write(line) if line.startswith('database ='): break newfile.write('repository_dir =\nrepository_type = svn\n\n[repositories]\n') newfile.write('%s.dir = %s\n' % (vcs_name, repo_env_path)) newfile.write('%s.type = %s\n' % (vcs_name, vcs_type)) newfile.close() oldfile.close() os.remove(project_env_path + '/conf/trac.ini.bak') # Notify listeners. The project object still exists, but database does not for listener in self.project_change_listeners: try: listener.project_created(project) listener.project_watchers(project) if public: listener.project_set_public(project) except: pass return self.create_success(req, project)
def has_permission(self): """ Returns True, if has permission, otherwise False. Must be called after the is_blocked. """ node = None destination_node = None try: node = self.target_node if self.method in DAVAccessControl.DAV_DESTINATION_METHODS: destination_node = self.destination_node except NodeError as e: conf.log.warning("Failed to get node %s %s %s"%(self.method, self.req.uri, str(e))) return False if not self.user: # User was not found: for example, 'anonymous' does not exist return False env = open_environment(conf.getEnvironmentSysPath(self._download_config.env_name), use_cache=True) perm = PermissionCache(env, self.username) timeline_notifier = FilesEventNotifier(env) depth = self._get_header('Depth') # ("0" | "1" | "infinity") # When checking, let the server to decide whether or not to return 412: Precondition Failed overwrite = self._get_header('Overwrite') == 'T' # ( "T" | "F" ) self._req_data = { 'uploader_id': self.user.id, 'perm': perm, 'context': 'webdav', 'timeline_notifier': timeline_notifier, 'username': self.user.username, } if self.method in self.DAV_READ_METHODS: try: node.show_check(self._req_data) except PermissionError as e: conf.log.debug("PermissionError node %s %s", self.method, self.req.uri) return False # Special case: copy for Collection with depth 0 is equivalent to MKCOL elif ((self.method == 'COPY' and depth == '0' and node.is_dir()) or self.method == 'MKCOL' or self.method == 'PUT'): if self.method == 'COPY' and depth == '0' and node.is_dir(): # For our causes, this method is 'MKCOL', even if it was 'COPY' self.method = 'MKCOL' node = destination_node self._target_node = node self._req_data.update({ 'update_also': False, # It seems that creating files and folders will overwrite existing ones 'overwrite': True, 'type': 'file' if self.method == 'PUT' else 'dir', 'sanity_check': False, }) try: node.create_check(self._req_data) except TracError as e: return False except PermissionError as e: conf.log.debug("PermissionError node %s %s", self.method, self.req.uri) return False elif self.method in self.DAV_DESTINATION_METHODS: self._req_data.update({ 'update_also': False, 'overwrite': overwrite, 'is_move': self.method == 'MOVE', 'sanity_check': False, }) try: node.move_check(destination_node, self._req_data) except TracError as e: return False except PermissionError as e: conf.log.debug("PermissionError node %s %s", self.method, self.req.uri) return False elif self.method == 'DELETE': self._req_data.update({ 'sanity_check': False, 'force_remove': True, }) try: node.remove_check(self._req_data) except TracError as e: return False except PermissionError as e: conf.log.debug("PermissionError node %s %s", self.method, self.req.uri) return False else: conf.log.warning("Unknown webdav method: '%s', '%s'", self.method, self.req.uri) return False return True