Esempio n. 1
0
def projects_from_directory(directory):
    """returns list of projects from a directory"""
    projects = []
    for entry in os.listdir(directory):
        try:
            open_environment(os.path.join(directory, entry))
        except:
            continue
        projects.append(entry)
    return projects
Esempio n. 2
0
 def __get_intertrac_ticket(self, ticket, dep_en):
     # 指定されたInterTrac形式のチケット名から情報を取得する
     # 問題があった場合はエラーを返す.
     if not ticket:
         return {'error' : None}
     project_name, id, dep = self.__split_itertrac_ticket_string(ticket)
     intertrac = self.__get_project_info(project_name)
     if intertrac is None:
         return {'error' : ERROE_MSG1 % project_name}
     if id == "": 
         return {'error' : ERROE_MSG5}
     # 依存関係を指定しているか確認する 例:(FF)
     idx = id.rfind('(')
     if dep:
         if dep_en == False:
             #依存関係を使用しない場合でカッコがあった場合は
             return {'error' : ERROE_MSG7}
         if          dep.startswith('FF')==False \
                 and dep.startswith('FS')==False \
                 and dep.startswith('SF')==False \
                 and dep.startswith('SS')==False:
             return {'error' : ERROE_MSG2}
     try:
         if self.__get_current_project_name() == project_name:
             tkt = Ticket(self.env, id)
         else:
             path = intertrac.get('path', '')
             project = open_environment(path, use_cache=True)
             tkt = Ticket(project, id)
         url = intertrac.get('url', '') + '/ticket/' + id
         dep_url = intertrac.get('url', '') + '/dependency/ticket/' + id
     except Exception, e:
         return {'error' : ERROE_MSG4 % (ticket, project_name, id)}
Esempio n. 3
0
 def load_intertrac_setting(self):
     # interTracの設定を取得します.
     self.intertracs0 = {}
     self.aliases = {}
     for key, value in self.config.options('intertrac'):
         # オプションの数のループを回り,左辺値の.を探します.
         idx = key.rfind('.')  
         if idx > 0: 
             prefix, attribute = key[:idx], key[idx+1:]
             intertrac = self.intertracs0.setdefault(prefix, {})
             intertrac[attribute] = value
             intertrac['name'] = prefix
         else:
             self.aliases[key] = value.lower()
             intertrac = self.intertracs0.setdefault(value.lower(), {})
             intertrac.setdefault('alias', []).append(key)
     keys = self.intertracs0.keys()
     for key in keys:
         intertrac = self.intertracs0[key]
         path = intertrac.get('path', '')
         label = intertrac.get('label', '')
         url = intertrac.get('url', '')
         if path == '' or url == '':
             del self.intertracs0[key]
         else:
             if label == '':
                 label = os.path.basename(self.env.path)
                 self.log.debug(IT_ERROR_MSG4, key, label)
                 self.config.set('intertrac', key + '.label', label)
             try:
                 if self.__get_current_project_name() != label:
                     project = open_environment(path, use_cache=True)
             except Exception, e:
                 self.log.error(IT_ERROR_MSG2, key)
                 del self.intertracs0[key]
Esempio n. 4
0
def main(args=sys.argv[1:]):
    parser = OptionParser('%prog [options] project <project2> <project3> ...')
    parser.add_option('-d', '--dict', dest='dict', default=None,
                      help="python file mapping of old user, new user")
    options, args = parser.parse_args(args)

    # if no projects, print usage
    if not args:
        parser.print_help()
        sys.exit(0)

    # get the environments
    envs = []
    for arg in args:
        env = open_environment(arg)
        envs.append(env)

    # get the users
    assert options.dict
    assert os.path.exists(options.dict)
    users = eval(file(options.dict).read())
    assert isinstance(users, dict)
    if not users:
        sys.exit(0) # nothing to do

    # change the permissions
    for env in envs:
        renamer = RenameTracUsers(env)
        renamer.rename_users(users)
def main():
    sys.stderr = codecs.getwriter('shift_jis')(sys.stderr)

    sys.stderr.write("Running "+sys.argv[0]+"..\n")
    env = open_environment(sys.argv[1])
    env.projkey=sys.argv[2]
    owner = sys.argv[3]
    ref = DummyRef()

    print '<?xml version="1.0"?>'
    print '<JiraJelly xmlns:jira="jelly:com.atlassian.jira.jelly.enterprise.JiraTagLib">'
    print '<jira:CreateProject key="'+env.projkey+'" name="' + env.config.get('project', 'descr') + '" lead="'+owner+'">'
    print '''
<jira:CreatePermissionScheme name="'''+env.projkey+'''-scheme">
<jira:AddPermission permissions="Assignable,Browse,Create,Assign,Resolve,Close,ModifyReporter,Attach,Comment"
group="jira-users"
type="group"/>
<jira:SelectProjectScheme/>
</jira:CreatePermissionScheme> 
	'''
    for c in Component(env).select(env):
    	createComponent(c.name,c.description,c.owner)
    for v in Version(env).select(env):
        createMilestone(v.name)
    tickets=[]
    for t in Query(env).execute(ref):
	tickets.append(int(t["id"]))
    tickets.sort()
    i = 0
    for t in tickets:

        processTicket(env, t, owner)
    print '</jira:CreateProject>'
    print '</JiraJelly>'
    def on_published(self, review_request=None, **kwargs):

        # Information about the review
        review_id = review_request.display_id
        ticket_ids = review_request.get_bug_list()

        # Connect to trac
        try:
            tracenv = env.open_environment(self.settings['tracsite'])
        except core.TracError:
            logging.error('Unable to open Trac site')
            return

        # Add the review to each trac ticket
        for ticket_id in ticket_ids:
            try:
                tracticket = ticket.Ticket(tracenv,tkt_id=ticket_id)
                addTracLink(tracticket, 
                        review_request.display_id,
                        review_request.submitter)
            except resource.ResourceNotFound:
                # Ticket doesn't exist
                pass
        
        # Cleanup
        tracenv.shutdown()
Esempio n. 7
0
    def globally_get_command_help(self, *args):
        sys_home_project_name = self.config.get('multiproject', 'sys_home_project_name')
        for env_name, in self.projects_iterator(['env_name'], batch_size=1):
            if env_name == sys_home_project_name:
                continue
            env = None

            try:
                env_path = safe_path(self.config.get('multiproject', 'sys_projects_root'),
                    env_name)
                env = open_environment(env_path, True)
            except TracError as e:
                printout(_('ERROR: Opening environment %(env_name)s failed', env_name=env_name))
                continue

            try:
                command_manager = AdminCommandManager(env)
                helps = command_manager.get_command_help(list(args))
                if not args:
                    TracAdmin.print_doc(helps, short=True)
                elif len(helps) == 1:
                    TracAdmin.print_doc(helps, long=True)
                else:
                    TracAdmin.print_doc(helps)

            except AdminCommandError as e:
                printout(_('ERROR: Getting command help in environment %(env_name)s failed: ',
                    env_name=env_name) + e)
            break
Esempio n. 8
0
    def expand_macro(self, formatter, name, text, args):
        projects_dir = args.get('path', os.environ.get('TRAC_ENV_PARENT_DIR', '/env/trac/projects'))
	match = args.get('match', '.*')
	rawhtml = args.get('rawhtml', 'false')
	
	if not os.path.isdir(projects_dir):
	  return sys.stderr
	
        from StringIO import StringIO
        out = StringIO()
	
	for f in os.listdir(projects_dir):
	  project_dir = projects_dir + '/'+ f
	  if os.path.isdir(project_dir) and f != '.egg-cache' and re.match(match,f):
	    from trac.env import open_environment
	    selfenv = open_environment(project_dir)

	    import copy
	    context = copy.copy(formatter.context)
	    href = '/projects/' + f + '/'
	    context.href = Href(href)
	    context.req.href = context.href
	    
	    wikitext = text
	    wikitext = wikitext.replace('$dir',project_dir)
	    wikitext = wikitext.replace('$basedir',f)
	    wikitext = wikitext.replace('$name',selfenv.project_name)
	    wikitext = wikitext.replace('$href', href)
	    if rawhtml == 'false':
	      Formatter(selfenv, context).format(wikitext, out)
	    else:
	      out.write(wikitext)
	    
        return out.getvalue()
Esempio n. 9
0
    def __init__(self, hook_name, options, config_path=None, debug=False):
        '''
        '''
        if not config_path:
            config_path = os.path.dirname(__file__) + '/hooks.config'
        self.config = TracGerritHookConfig(config_path)
        self.options = options
        self.options_dict = options.__dict__

        self.repo_name = self.options.project_name

        self.section = self.config.get_section_for_repo(self.repo_name)
        if self.config.has_option(self.section, 'comment_always'):
            self.comment_always = self.config.getboolean(self.section, 'comment_always')

        self.trac_env = self.config.get_env_for_repo(self.repo_name)
        if not self.trac_env:
            sys.exit(0)

	if self.trac_env.startswith("http"):
            self.trac_over_rpc = True
        else:
            self.trac_over_rpc = False
            self.env = open_environment(self.trac_env)

        self.hook_name = hook_name
        self.debug = debug

        self.commit_msg = ""

        ## make sure PYTHON_EGG_CACHE is set
        if not 'PYTHON_EGG_CACHE' in os.environ:
            os.environ['PYTHON_EGG_CACHE'] = self.config.\
                                                get('hook-settings',
                                                    'python_egg_cache')
    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
Esempio n. 11
0
def get_sorted_dicts (env, table, other_env=None):
    if other_env:
        from trac.env import open_environment
        env_path = os.path.join(os.path.dirname(env.path), 'ncs')
        env = open_environment(env_path, use_cache=True)

    return CustomDBTableSystem(env).sorted_dicts(table)
Esempio n. 12
0
    def _expire_cookie(self, req):
        """Instruct the user agent to drop the auth_session cookie by setting
        the "expires" property to a date in the past.

        Basically, whenever "trac_auth" cookie gets expired, expire
        "trac_auth_session" too.
        """
        # First of all expire trac_auth_session cookie, if it exists.
        if 'trac_auth_session' in req.incookie:
            self._expire_session_cookie(req)
        # Capture current cookie value.
        cookie = req.incookie.get('trac_auth')
        if cookie:
            trac_auth = cookie.value
        else:
            trac_auth = None
        # Then let auth.LoginModule expire all other cookies.
        auth.LoginModule._expire_cookie(self, req)
        # And finally revoke distributed authentication data too.
        if trac_auth:
            for path in self.auth_share_participants:
                env = open_environment(path, use_cache=True)
                db = env.get_db_cnx()
                cursor = db.cursor()
                cursor.execute("""
                    DELETE FROM auth_cookie
                    WHERE  cookie=%s
                    """, (trac_auth,))
                db.commit()
                env.log.debug('Auth data revoked from: ' + \
                              req.environ.get('SCRIPT_NAME', 'unknown'))
Esempio n. 13
0
    def project_information(self):
        # interTracの設定を取得します.
        intertracs0 = {}
        for key, value in self.config.options("intertrac"):
            # オプションの数のループを回り,左辺値の.を探します.
            idx = key.rfind(".")
            if idx > 0:  # .が無い場合はショートカットでので無視します
                prefix, attribute = key[:idx], key[idx + 1 :]  # 左辺値を分割します
                intertrac = intertracs0.setdefault(prefix, {})
                intertrac[attribute] = value  # 左辺値のピリオド以降をキーで右辺値を登録
                intertrac["name"] = prefix  # プロジェクト名を設定します.

        intertracs = []
        # 取得したinterTrac設定の名前が小文字になっているので元に戻します.
        # ついでに,プロジェクトの一覧表示用のデータを作成しておきます.
        # 結局はintertrac['label'] 設定することにしたので意味はないのですが,つくっちゃったのでこのままにします.
        for prefix in intertracs0:
            intertrac = intertracs0[prefix]
            # Trac.iniのパスを取得します
            path = intertrac.get("path", "")
            # trac.iniをオープンする
            project = open_environment(path, use_cache=True)
            # 名前をtrac.iniのプロジェクト名で置き換えます.
            intertrac["name"] = intertrac["label"]
            # プロジェクトの一覧表示用のデータを作成します.
            url = intertrac.get("url", "")
            title = intertrac.get("title", url)
            name = project.project_name
            intertracs.append({"name": name, "title": title, "url": url, "path": path})
        return intertracs
Esempio n. 14
0
 def __init__(self, env=None):
     if not env:
         self.env = open_environment()
     else:
         self.env = env
     
     self._init_db()
Esempio n. 15
0
    def __init__(self, options):
        """
        Initialization and check of the options
        
        :param options: an object that holds all the info needed for the hook to proceed
        :type options: class

        options needs to have all these properties

        :param bugzilla: The bugzilla server URL (without the rest uri)
        :type bugzilla: string
        :param rest_uri: The REST part of the url
        :type rest_uri: string
        :param chglog: The changelog message (extracted from debian/changelog)
        :type chglog: string
        :param commentonly: Do only comment
        :type commentonly: bool
        :param msg: The commit message
        :type msg: string
        :param netrc: The netrc file location
        :type netrc: string
        :param proxy: Overrides the proxy in case you don't like the ENV one
        :type proxy: string
        :param rev: The revision number / commit hash
        :type rev: string
        :param tm: Whether to add the target milestone to the bug (as the current week)
        :type tm: bool
        :param user: The user that did the commit (coming from the VCS)
        :type user: string
        :param vcstype: What VCS are we working with (HG/GIT/SVN)
        :type vcstype: string
        :param vcsurl: the base url of the VCS (this is not trivial to guess, look at the code)
        :type vcsurl: string
        """
        supported_vcstypes = ['hg', 'git', 'trac', 'svn']
        if options.vcstype not in supported_vcstypes:
            print >> sys.stderr, "Unsupported vcs type. Supported types are %s " % supported_vcstypes
        self.options = options
        self.config = self.parse_config()
        if self.options.vcstype == 'svn':
            self.finalurl = os.path.join(self.options.vcsurl, self.config['svn_commiturl'], self.options.rev)
        elif self.options.vcstype == 'git':
            self.finalurl = self.options.vcsurl + self.config['git_commit_url'] % self.options.rev
        elif self.options.vcstype == 'hg':
            self.finalurl = os.path.join(self.options.vcsurl, self.config['hg_commit_url'], '%s' % self.options.rev)
        elif self.options.vcstype == 'trac':
            from trac.env import open_environment
            env = open_environment(self.options.vcsurl)
            self.finalurl = os.path.join(env.config.get('project', 'url'), self.config['trac_commit_url'], self.options.rev)
        else:
            print >> sys.stderr, 'Configuration is not complete: please check the options passed'
            sys.exit(1)

        if self.options.tm:
            year, week = datetime.now().isocalendar()[0:2]
            self.target_milestone = '%d-%02d' % (year, week)
        else:
            self.target_milestone = None
        self.open_statuses = [ 'NEW', 'ASSIGNED', 'REOPENED', 'WAITING', 'NEED_INFO' ]
Esempio n. 16
0
 def _get_env(self):
     if not self._env:
         assert self.exists, "Can't use a non-existant project"
         try:
             self._env = open_environment(self.env_path, use_cache=True)
             self._valid = True
         except Exception, e:
             self._env = BadEnv(self.env_path, e)
Esempio n. 17
0
 def get_projects(self, db=None):
     """Return an iterable of (shotname, env) for all known projects."""
     db = db or self.env.get_db_cnx()
     cursor = db.cursor()
     cursor.execute('SELECT name, env_path FROM tracforge_projects')
     for name, path in cursor:
         env = open_environment(path, use_cache=True)
         yield name, env
 def import_project(self, sourcepath, destinationpath, name=None, **kwargs):
     if name is None:
         raise KeyError("This importer requires a Trac project to already exist. Use --name to specify it's dir name.")
     boxqueue = Queue()
     env_path = os.path.join(destinationpath, name)
     self.env = open_environment(env_path)
     import logging
     self.env.log.setLevel(logging.WARNING)
     self.log = logging.getLogger(self.env.path + '.' + self.__class__.__name__)
     self.log.setLevel(logging.DEBUG)
     
     if os.path.isdir(sourcepath):
         self.log.info('Importing directory %s', sourcepath)
         entries = os.listdir(sourcepath)
         for entry in entries:
             fullpath = os.path.join(sourcepath, entry)
             if not os.path.isfile(fullpath):
                 continue
             boxqueue.put((fullpath, None))
     else:
         self.log.info('Importing from %s', sourcepath)
         if sourcepath.endswith('.xml'):
             mlists = self.get_listdata_from_xml(sourcepath)
         elif sourcepath.endswith('.json'):
             mlists = self.get_listdata_from_json(sourcepath)
         importdir = os.path.dirname(sourcepath)
         for mlist in mlists:
             path = os.path.join(importdir, mlist.pop('mailbox'))
             if not os.path.exists(path):
                 self.log.error("Can't find mailbox %s from %s", path, sourcepath)
                 continue
             if mlist.get('mailboxmd5'):
                 self.log.debug('Checking MD5 sum of %s...', path)
                 md5digest = md5(open(path, 'r').read()).hexdigest()
                 if md5digest != mlist['mailboxmd5']:
                     self.log.error("%s's md5 (%s) doesn't match %s from %s. Skipping it", path, md5digest, mlist['mailboxmd5'], sourcepath)
                     continue
                 self.log.debug('MD5 of %s ok', path)
             else:
                 self.log.warning("No md5 found for %s in %s", path, sourcepath)
             boxqueue.put((path, mlist))
         else:
             boxqueue.put((sourcepath, None))
     def worker(queue):
         while True:
             mbox, metadata = queue.get()
             try:
                 self.read_file(mbox, metadata)
             except:
                 self.log.exception("Error in %s", mbox)
             queue.task_done()
     for _ in range(min(boxqueue.qsize(), 5)):
         t = Thread(target=worker, args=(boxqueue,))
         t.daemon = True
         t.start()
     boxqueue.join()
Esempio n. 19
0
 def trac_projects(self):
     """returns existing Trac projects"""
     proj = {}
     for i in os.listdir(self.directory):
         try:
             env = open_environment(os.path.join(self.directory, i))
         except:
             continue
         proj[i] = env
     return proj
Esempio n. 20
0
 def _get_home_perm(self, req):
     """
     Returns permission cache from home environment
     """
     home_env = open_environment(os.path.join(
         self.env.config.get('multiproject', 'sys_projects_root'),
         self.env.config.get('multiproject', 'sys_home_project_name')),
         use_cache=True
     )
     return PermissionCache(home_env, req.authname)
Esempio n. 21
0
def _open_environment(env_path, run_once=False):
    if run_once:
        return open_environment(env_path)

    global env_cache, env_cache_lock
    env = None
    env_cache_lock.acquire()
    try:
        if not env_path in env_cache:
            env_cache[env_path] = open_environment(env_path)
        env = env_cache[env_path]
    finally:
        env_cache_lock.release()

    # Re-parse the configuration file if it changed since the last the time it
    # was parsed
    env.config.parse_if_needed()

    return env
Esempio n. 22
0
    def getVersionControlType(self, env_name):
        """
        .. WARNING::

           Do not call this unless absolutely needed
           This will initialize new trac environment which is heavy operation to do
        """
        # TODO: whole method should be removed
        env = open_environment(conf.getEnvironmentSysPath(env_name), use_cache=True)
        return env.config.get('trac', 'repository_type')
Esempio n. 23
0
    def __init__(self, project=options.project, author=AUTHOR,
                     maxage=options.maxage, url=options.url):

        self.env = open_environment(project)
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        if url is None:
        	url = self.env.config.get('trac', 'base_url')

        self.env.href = Href(url)
        self.env.abs_href = Href(url)

        self.msg = MESSAGE % (maxage)
        self.now = int(time.time())

        maxtime = int(time.time()) - (60 * 60 * 24 * maxage)

        cursor.execute("SELECT id FROM ticket t, ticket_custom c " \
                       "WHERE t.status <> %s " \
        	       "AND t.changetime < %s " \
                       "AND t.id = c.ticket " \
                       "AND c.name = %s " \
                       "AND c.value = %s ", ('closed', maxtime, 'pending', '1'))
    
        rows = cursor.fetchall()

        for row in rows:
            id = row[0]
            try:
                ticket = Ticket(self.env, id, db);

                ticket['status'] = 'closed'
                ticket['pending'] = '0';

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                	if change['permanent']:
                		cnum += 1

        
                ticket.save_changes(author, self.msg, self.now, db, cnum + 1)
                db.commit()

                print 'Closing Ticket %s (%s)\n' % (id, ticket['summary'])

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                import traceback
                traceback.print_exc(file=sys.stderr)
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (id, e)
Esempio n. 24
0
    def get_project_list(self, req):
        # get search path and base_url
        search_path, this_project = os.path.split(self.env.path)
        base_url, _ = posixpath.split(req.abs_href())

        #Closes #4158, thanks to jholg
        if 'tracforge' in self.config: 
            if self.config.get('tracforge', 'master_path') == self.env.path: 
                base_url = '/'.join((base_url, this_project, 'projects'))  

        projects = []
        for project in os.listdir(search_path):

            # skip our own project
            if project == this_project:
                continue
                
            #Include only if project is in include_projects, or include_projects is empty
            if self.include_projects and (project not in self.include_projects):
                continue

            #Exclude if project is in exclude_projcets
            if project in self.exclude_projects:
                continue

            # make up URL for project
            project_url = '/'.join( (base_url, project) )              
            project_path = os.path.join(search_path, project)
            
            if not os.path.isdir( project_path ):
                continue
            try:
                env = open_environment(project_path, use_cache = True)
            except:
                try:
                    env = open_environment(project_path)
                except:
                    continue
            
            projects.append((project, project_path, project_url, env))
            
        return projects
Esempio n. 25
0
    def move(self, ticket_id, author, env, delete=False):
        """
        move a ticket to another environment
        
        env: environment to move to
        """
        tables = {"attachment": "id", "ticket_change": "ticket"}

        # open the environment if it is a string
        if isinstance(env, basestring):
            base_path, _project = os.path.split(self.env.path)
            env = open_environment(os.path.join(base_path, env), use_cache=True)

        # get the old ticket
        old_ticket = Ticket(self.env, ticket_id)

        # make a new ticket from the old ticket values
        new_ticket = Ticket(env)
        new_ticket.values = old_ticket.values.copy()
        new_ticket.insert(when=old_ticket.time_created)

        # copy the changelog and attachment DBs
        for table, _id in tables.items():
            for row in get_all_dict(self.env, "SELECT * FROM %s WHERE %s=%%s" % (table, _id), str(ticket_id)):
                row[_id] = new_ticket.id
                insert_row_from_dict(env, table, row)

        # copy the attachments
        src_attachment_dir = os.path.join(self.env.path, "attachments", "ticket", str(ticket_id))
        if os.path.exists(src_attachment_dir):
            dest_attachment_dir = os.path.join(env.path, "attachments", "ticket")
            if not os.path.exists(dest_attachment_dir):
                os.makedirs(dest_attachment_dir)
            dest_attachment_dir = os.path.join(dest_attachment_dir, str(new_ticket.id))
            shutil.copytree(src_attachment_dir, dest_attachment_dir)

        # note the previous location on the new ticket
        new_ticket.save_changes(author, "moved from %s" % self.env.abs_href("ticket", ticket_id))

        # location of new ticket
        new_location = env.abs_href.ticket(new_ticket.id)

        if delete:
            old_ticket.delete()
        else:
            # close old ticket and point to new one
            old_ticket["status"] = u"closed"
            old_ticket["resolution"] = u"moved"
            old_ticket.save_changes(author, u"moved to %s" % new_location)

        if env.config["trac"].get("base_url"):
            return new_location
        else:
            return None
Esempio n. 26
0
def send_project_index(environ, start_response, parent_dir=None,
                       env_paths=None):
    req = Request(environ, start_response)

    loadpaths = [pkg_resources.resource_filename('trac', 'templates')]
    if req.environ.get('trac.env_index_template'):
        env_index_template = req.environ['trac.env_index_template']
        tmpl_path, template = os.path.split(env_index_template)
        loadpaths.insert(0, tmpl_path)
    else:
        template = 'index.html'

    data = {'trac': {'version': TRAC_VERSION,
                     'time': user_time(req, format_datetime)},
            'req': req}
    if req.environ.get('trac.template_vars'):
        for pair in req.environ['trac.template_vars'].split(','):
            key, val = pair.split('=')
            data[key] = val
    try:
        href = Href(req.base_path)
        projects = []
        for env_name, env_path in get_environments(environ).items():
            try:
                env = open_environment(env_path,
                                       use_cache=not environ['wsgi.run_once'])
                proj = {
                    'env': env,
                    'name': env.project_name,
                    'description': env.project_description,
                    'href': href(env_name)
                }
            except Exception as e:
                proj = {'name': env_name, 'description': to_unicode(e)}
            projects.append(proj)
        projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))

        data['projects'] = projects

        loader = TemplateLoader(loadpaths, variable_lookup='lenient',
                                default_encoding='utf-8')
        tmpl = loader.load(template)
        stream = tmpl.generate(**data)
        if template.endswith('.xml'):
            output = stream.render('xml')
            req.send(output, 'text/xml')
        else:
            output = stream.render('xhtml', doctype=DocType.XHTML_STRICT,
                                   encoding='utf-8')
            req.send(output, 'text/html')

    except RequestDone:
        pass
Esempio n. 27
0
 def __init__(self, trac=options.trac, project=options.project):
     self.env = open_environment(trac)
     self.trac = trac
     self.project = project
     self.now = datetime.now(utc)
     #Convert the timestamp from a float to an int to drop the .0
     self.stamp = int(math.floor(time.time()))
     self.github = 'https://github.com/api/v2/json'
     try:
         self.db = self.env.get_db_cnx()
     except TracError, e:
         print_error(e.message)
Esempio n. 28
0
 def search_userProfile(self, userProfileTemplate=None):
     if self.masterUserProfilesStore=='':
         return []
     
     _masterEnv = open_environment(self.masterUserProfilesStore)
     
     def _changeStore(userProfile):
         userProfile.project_name = userProfile.store.env.project_name
         userProfile.store=self
         return userProfile
     
     return map( _changeStore, UserProfilesSystem(_masterEnv).search_userProfile(userProfileTemplate) )
    def __init__(self, project=options.project, author=options.user,
                 rev=options.rev, url=options.url):
        self.env = open_environment(project)
        repos = self.env.get_repository()
        repos.sync()
        
        # Instead of bothering with the encoding, we'll use unicode data
        # as provided by the Trac versioncontrol API (#1310).
        try:
            chgset = repos.get_changeset(rev)
        except NoSuchChangeset:
            return # out of scope changesets are not cached
        self.author = chgset.author
        self.rev = rev
        self.msg = "(In [%s]) %s" % (rev, chgset.message)
        self.now = datetime.now(utc)

        cmd_groups = command_re.findall(self.msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = CommitHook._supported_cmds.get(cmd.lower(), '')
            if funcname:
                for tkt_id in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append(func)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()
                
                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number... 
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1
                
                ticket.save_changes(self.author, self.msg, self.now, db, cnum+1)
                db.commit()
                
                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                # import traceback
                # traceback.print_exc(file=sys.stderr)
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)
Esempio n. 30
0
    def __init__(self, project):
        """
        Initiates the class.

        :param project: Instance of the :class:`Project` to backup/restore
        """
        self.project = project
        self.env = open_environment(self.project.trac_fs_path, use_cache=True)
        backup_dir = self.env.config.get('trac', 'backup_dir', '/tmp')
        self.backup_path_tmpl =  backup_dir + '/project-%s.snapshot-%d.sql'
        self.mysql_path = self.env.config.get('trac', 'mysql_path', 'mysql')

        self.dm = DatabaseManager(self.env)
Esempio n. 31
0
parser.add_option('-c', '--component', dest='component', type='string')
parser.add_option('-p',
                  '--project',
                  dest='project',
                  type='string',
                  help='Path to the project')
options, args = parser.parse_args()

if None in (options.summary, options.description, options.reporter,
            options.owner, options.component, options.project):
    sys.stderr.write("Please make sure that summary, description, reporter,"
                     " owner, componnet and project are defined")
    sys.stderr.flush()
    sys.exit(1)

env = open_environment(options.project)

t = model.Ticket(env)
t['status'] = options.status
t['summary'] = options.summary
t['description'] = options.description.replace("\\n", "\n")
t['reporter'] = options.reporter
t['owner'] = options.owner
t['type'] = options.type
t['component'] = options.component
t.insert()

try:
    tn = TicketNotifyEmail(env)
    tn.notify(t, newticket=True)
except Exception, e:
Esempio n. 32
0
    def expand_macro(self, formatter, name, content, args=None):
        """
        Expand the macro. We will accept a parameter to point us to another project
        if necessary.
        """

        if name != 'Announcements':
            return None

        data = {}
        req = formatter.req

        env_name = None
        count = 0
        title = None
        env = None

        # Parse settings for the macro
        env_name, count, title = self._parse_args(args, content)

        if not count:
            self.log.debug("Defaulting count to 5")
            count = 5

        data['news_title'] = title
        current_env_name = self.env.project_identifier

        if not env_name:
            env_name = current_env_name

        data['env_name'] = env_name

        # Check if the project exists.
        mpp_env = None
        try:
            mpp_env = TracEnvironment.read(env_name)
        except TracError:
            data['news_error'] = "Couldn't find project '{0}'".format(env_name)
            self.log.error(data['news_error'])

        # Then check the permissions
        if mpp_env:
            # Check if project's announcements have been configured as hidden
            if env_name != current_env_name:
                env = open_environment(os.path.join(
                    self.config.get('multiproject', 'sys_projects_root'),
                    env_name),
                                       use_cache=True)
            else:
                env = self.env

            if not env.config.getbool('discussion', 'show_news_forum', True):
                self.log.debug(
                    "Project announcements hidden, not showing with macro")
                return None

            # Check permission in specified environment
            permcache = PermissionCache(env, username=req.authname)
            if 'DISCUSSION_VIEW' in permcache:
                try:
                    news = ProjectNews(env_name)
                    data['newsitems'] = news.get_project_news(
                        limit=count, f_name="Announcements")
                    data['news_forum_id'] = news.get_news_forum_id()
                except Exception, e:
                    self.log.exception(
                        "Failed to read project {0} news.".format(env_name))
                    raise TracError(
                        "Couldn't read news for project '{0}': {1}".format(
                            env_name, e))
            else:
                data[
                    'news_error'] = "No permission to read news from project '{0}'".format(
                        env_name)
 def _resolve_env(self, name):
     from trac.env import open_environment
     import os.path
     dir_ = self._intertracs[name]
     path = os.path.join(os.path.dirname(self.env.path), dir_)
     return open_environment(path, True)
Esempio n. 34
0
    def open_environment(self, environ, start_response):
        env_path = environ.get('trac.env_path')
        if not env_path:
            env_parent_dir = environ.get('trac.env_parent_dir')
            env_paths = environ.get('trac.env_paths')
            if env_parent_dir or env_paths:
                # The first component of the path is the base name of the
                # environment
                path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
                env_name = path_info.pop(0)

                if not env_name:
                    # No specific environment requested, so render an environment
                    # index page
                    send_project_index(environ, start_response, env_parent_dir,
                                       env_paths)
                    raise RequestDone

                errmsg = None

                # To make the matching patterns of request handlers work, we append
                # the environment name to the `SCRIPT_NAME` variable, and keep only
                # the remaining path in the `PATH_INFO` variable.
                script_name = environ.get('SCRIPT_NAME', '')
                try:
                    script_name = unicode(script_name, 'utf-8')
                    # (as Href expects unicode parameters)
                    environ['SCRIPT_NAME'] = Href(script_name)(env_name)
                    environ['PATH_INFO'] = '/' + '/'.join(path_info)

                    if env_parent_dir:
                        env_path = os.path.join(env_parent_dir, env_name)
                    else:
                        env_path = get_environments(environ).get(env_name)

                    if not env_path or not os.path.isdir(env_path):
                        errmsg = 'Environment not found'
                except UnicodeDecodeError:
                    errmsg = 'Invalid URL encoding (was %r)' % script_name

                if errmsg:
                    write = start_response('404 Not Found',
                                   [('Content-Type', 'text/plain'),
                                    ('Content-Length', str(len(errmsg)))])
                    write(errmsg)
                    raise RequestDone

        if not env_path:
            raise EnvironmentError('The environment options "TRAC_ENV" or '
                                   '"TRAC_ENV_PARENT_DIR" or the mod_python '
                                   'options "TracEnv" or "TracEnvParentDir" are '
                                   'missing. Trac requires one of these options '
                                   'to locate the Trac environment(s).')
        run_once = environ['wsgi.run_once']

        env = None
        self.global_env = global_env = None
        try:
            self.global_env = global_env = open_environment(env_path, use_cache=not run_once)
            factory = environment_factory(global_env)
            factory_env = factory().open_environment(environ, env_path, global_env, use_cache=not run_once) if factory \
                            else None
            env = factory_env if factory_env else global_env
        except Exception:
            raise
        return env
Esempio n. 35
0
def env(env_path):
    return open_environment(env_path, use_cache=True)
    def __init__(self,
                 project=options.project,
                 author=options.user,
                 rev=options.rev,
                 url=options.url,
                 reponame=options.repos):
        self.env = open_environment(project)
        self.reponame = reponame
        if reponame:
            repos = self.env.get_repository(reponame)
            revstring = rev + '/' + reponame
        else:
            repos = self.env.get_repository()
            revstring = rev
        repos.sync()

        # Instead of bothering with the encoding, we'll use unicode data
        # as provided by the Trac versioncontrol API (#1310).
        try:
            chgset = repos.get_changeset(rev)
        except NoSuchChangeset:
            return  # out of scope changesets are not cached
        self.author = chgset.author
        self.rev = rev
        self.msg = "(In [%s]) %s" % (revstring, chgset.message)
        self.now = datetime.now(utc)

        cmd_groups = command_re.findall(self.msg)

        log("cmd_groups:%s", cmd_groups)
        tickets = {}
        # \todo Explain what xxx1 and xxx2 do; I can't see more params
        # in command_re.
        for cmd, tkts, xxx1, xxx2 in cmd_groups:
            log("cmd:%s, tkts%s ", cmd, tkts)
            funcname = _supported_cmds.get(cmd.lower(), '')
            if funcname:
                for tkt_id, spent in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append([func, spent])

        for tkt_id, vals in tickets.iteritems():
            log("tkt_id:%s, vals%s ", tkt_id, vals)
            spent_total = 0.0
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for (cmd, spent) in vals:
                    cmd(ticket)
                    if spent:
                        spent_total += float(spent)

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                if spent_total:
                    self._setTimeTrackerFields(ticket, spent_total)
                ticket.save_changes(self.author, self.msg, self.now, db,
                                    cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                # import traceback
                # traceback.print_exc(file=sys.stderr)
                log('Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e))
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)
Esempio n. 37
0
 def get_trac_environment(self):
     """Returns a Trac environment object"""
     return open_environment(self.tracdir, use_cache=True)
Esempio n. 38
0
    def __init__(self,
                 project=options.project,
                 author=options.user,
                 rev=options.rev,
                 url=options.url):
        self.env = open_environment(project)
        repos = self.env.get_repository()
        repos.sync()

        # Instead of bothering with the encoding, we'll use unicode data
        # as provided by the Trac versioncontrol API (#1310).
        try:
            chgset = repos.get_changeset(rev)
        except NoSuchChangeset:
            return  # out of scope changesets are not cached
        self.author = chgset.author
        self.rev = rev
        lines = []
        #print chgset.message
        for line in chgset.message.splitlines():
            if line.startswith("*"):
                lines.append(" " + line)
            else:
                lines.append(line)
        msg = "\n".join(lines)
        #print msg
        self.msg = "(In [%s]) %s" % (rev, msg)
        self.now = datetime.now(utc)

        cmd_groups = command_re.findall(self.msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = CommitHook._supported_cmds.get(cmd.lower(), '')
            if funcname:
                for tkt_id in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append(func)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                ticket.save_changes(self.author, self.msg, self.now, db,
                                    cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                # import traceback
                # traceback.print_exc(file=sys.stderr)
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)
            print 'Unexpected error while processing commit %s :' % commit
            print 'ticket ID %s: %s' % (tkt_id, e)
            sys.exit(3)


def handle_ref(old, new, ref, env):
    # If something else than the master branch (or whatever is contained by the
    # constant BRANCHES) was pushed, skip this ref.
    if not ref.startswith('refs/heads/') or ref[11:] not in BRANCHES:
        return

    # Get the list of hashs for commits in the changeset.
    args = (old == '0' * 40) and [new] or [new, '^' + old]
    pending_commits = call_git('rev-list', args).splitlines()

    for commit in pending_commits:
        try:
            handle_commit(commit, env)
        except Exception, e:
            print 'Unexpected error while processing commit %s: %s' % (
                commit[:7], e)
            sys.exit(4)


if __name__ == '__main__':
    from trac.env import open_environment
    env = open_environment(TRAC_ENV)

    for line in sys.stdin:
        handle_ref(env=env, *line.split())
Esempio n. 40
0
def send_project_index(environ,
                       start_response,
                       parent_dir=None,
                       env_paths=None):
    req = Request(environ, start_response)

    loadpaths = [pkg_resources.resource_filename('trac', 'templates')]
    if req.environ.get('trac.env_index_template'):
        env_index_template = req.environ['trac.env_index_template']
        tmpl_path, template = os.path.split(env_index_template)
        loadpaths.insert(0, tmpl_path)
    else:
        template = 'index.html'

    data = {
        'trac': {
            'version': TRAC_VERSION,
            'time': user_time(req, format_datetime)
        },
        'req': req
    }
    if req.environ.get('trac.template_vars'):
        for pair in req.environ['trac.template_vars'].split(','):
            key, val = pair.split('=')
            data[key] = val
    try:
        href = Href(req.base_path)
        projects = []
        for env_name, env_path in get_environments(environ).items():
            try:
                env = open_environment(env_path,
                                       use_cache=not environ['wsgi.run_once'])
                proj = {
                    'env': env,
                    'name': env.project_name,
                    'description': env.project_description,
                    'href': href(env_name)
                }
            except Exception as e:
                proj = {'name': env_name, 'description': to_unicode(e)}
            projects.append(proj)
        projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))

        data['projects'] = projects

        loader = TemplateLoader(loadpaths,
                                variable_lookup='lenient',
                                default_encoding='utf-8')
        tmpl = loader.load(template)
        stream = tmpl.generate(**data)
        if template.endswith('.xml'):
            output = stream.render('xml')
            req.send(output, 'text/xml')
        else:
            output = stream.render('xhtml',
                                   doctype=DocType.XHTML_STRICT,
                                   encoding='utf-8')
            req.send(output, 'text/html')

    except RequestDone:
        pass
Esempio n. 41
0
def dispatch_request(environ, start_response):
    """Main entry point for the Trac web interface.
    
    @param environ: the WSGI environment dict
    @param start_response: the WSGI callback for starting the response
    """

    # SCRIPT_URL is an Apache var containing the URL before URL rewriting
    # has been applied, so we can use it to reconstruct logical SCRIPT_NAME
    script_url = environ.get('SCRIPT_URL')
    if script_url is not None:
        path_info = environ.get('PATH_INFO')
        if not path_info:
            environ['SCRIPT_NAME'] = script_url
        elif script_url.endswith(path_info):
            environ['SCRIPT_NAME'] = script_url[:-len(path_info)]

    # If the expected configuration keys aren't found in the WSGI environment,
    # try looking them up in the process environment variables
    environ.setdefault('trac.env_path', os.getenv('TRAC_ENV'))
    environ.setdefault('trac.env_parent_dir', os.getenv('TRAC_ENV_PARENT_DIR'))
    environ.setdefault('trac.env_index_template',
                       os.getenv('TRAC_ENV_INDEX_TEMPLATE'))
    environ.setdefault('trac.template_vars', os.getenv('TRAC_TEMPLATE_VARS'))
    environ.setdefault('trac.locale', '')
    environ.setdefault('trac.base_url', os.getenv('TRAC_BASE_URL'))

    locale.setlocale(locale.LC_ALL, environ['trac.locale'])

    # Determine the environment
    env_path = environ.get('trac.env_path')
    if not env_path:
        env_parent_dir = environ.get('trac.env_parent_dir')
        env_paths = environ.get('trac.env_paths')
        if env_parent_dir or env_paths:
            # The first component of the path is the base name of the
            # environment
            path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
            env_name = path_info.pop(0)

            if not env_name:
                # No specific environment requested, so render an environment
                # index page
                send_project_index(environ, start_response, env_parent_dir,
                                   env_paths)
                return []

            errmsg = None

            # To make the matching patterns of request handlers work, we append
            # the environment name to the `SCRIPT_NAME` variable, and keep only
            # the remaining path in the `PATH_INFO` variable.
            script_name = environ.get('SCRIPT_NAME', '')
            try:
                script_name = unicode(script_name, 'utf-8')
                # (as Href expects unicode parameters)
                environ['SCRIPT_NAME'] = Href(script_name)(env_name)
                environ['PATH_INFO'] = '/' + '/'.join(path_info)

                if env_parent_dir:
                    env_path = os.path.join(env_parent_dir, env_name)
                else:
                    env_path = get_environments(environ).get(env_name)

                if not env_path or not os.path.isdir(env_path):
                    errmsg = 'Environment not found'
            except UnicodeDecodeError:
                errmsg = 'Invalid URL encoding (was %r)' % script_name

            if errmsg:
                start_response('404 Not Found',
                               [('Content-Type', 'text/plain'),
                                ('Content-Length', str(len(errmsg)))])
                return [errmsg]

    if not env_path:
        raise EnvironmentError('The environment options "TRAC_ENV" or '
                               '"TRAC_ENV_PARENT_DIR" or the mod_python '
                               'options "TracEnv" or "TracEnvParentDir" are '
                               'missing. Trac requires one of these options '
                               'to locate the Trac environment(s).')
    run_once = environ['wsgi.run_once']

    env = env_error = None
    try:
        env = open_environment(env_path, use_cache=not run_once)
        if env.base_url_for_redirect:
            environ['trac.base_url'] = env.base_url

        # Web front-end type and version information
        if not hasattr(env, 'webfrontend'):
            mod_wsgi_version = environ.get('mod_wsgi.version')
            if mod_wsgi_version:
                mod_wsgi_version = (
                    "%s (WSGIProcessGroup %s WSGIApplicationGroup %s)" %
                    ('.'.join([str(x) for x in mod_wsgi_version
                               ]), environ.get('mod_wsgi.process_group'),
                     environ.get('mod_wsgi.application_group') or '%{GLOBAL}'))
                environ.update({
                    'trac.web.frontend': 'mod_wsgi',
                    'trac.web.version': mod_wsgi_version
                })
            env.webfrontend = environ.get('trac.web.frontend')
            if env.webfrontend:
                env.systeminfo.append(
                    (env.webfrontend, environ['trac.web.version']))
    except Exception, e:
        env_error = e
Esempio n. 42
0
    def process_request(self, req):
        req.perm.assert_permission('ROADMAP_VIEW')

        #If the page was posted, a filter was applied. Build and redirect using query strnig
        if req.args.has_key('update'):
            req.redirect(self._get_href(req))

        req.hdf['title'] = 'Project List'

        #Process filtering arguments
        self.status = req.args.has_key('status') and req.args['status'] or None

        #Process sorting arguments
        self.desc = req.args.has_key(
            'desc') and req.args['desc'] == '1' or None
        self.order = req.args.has_key(
            'order') and req.args['order'] or DEFAULT_SORT_FIELD

        #Get search path and base_url
        search_path, this_project = os.path.split(self.env.path)
        base_url, _ = posixpath.split(req.abs_href())
        href = Href(base_url)

        #Start with an empty project list
        projects = []
        for project in os.listdir(search_path):

            #Open the project environment
            project_path = os.path.join(search_path, project)
            env = open_environment(project_path)

            #Check if DB needs upgrading
            check_upgrade(env)

            #Trim project description if too long
            if len(env.project_description) <= 60:
                description = env.project_description
            else:
                description = "%s..." % env.project_description[:60]

            #Get last_login timestamp, and convert to human readable
            last_login = int(get_property(env, 'last_login', 0))
            if last_login == 0:
                last_login = ''
            else:
                last_login = datetime.fromtimestamp(last_login).strftime(
                    TIME_FORMAT)

            #Filter by status
            project_status = get_property(env, 'status', 'unknown')
            if self.status and project_status != self.status:
                continue

            projects.append({
                'name':
                env.project_name,
                'description':
                description,
                'company':
                get_property(env, 'company'),
                'created':
                get_property(env, 'date_created'),
                'started':
                get_property(env, 'date_started'),
                'scheduled':
                get_property(env, 'date_scheduled'),
                'finished':
                get_property(env, 'date_finished'),
                'percent_finished':
                get_property(env, 'percent', '0'),
                'percent_remaining':
                100 - int(get_property(env, 'percent', '0')),
                'status':
                STATUS[project_status],
                'client':
                get_property(env, 'client'),
                'manager':
                get_property(env, 'manager'),
                'last_login':
                last_login,
                'href':
                href(project)
            })

        #Status selection
        sorted_keys = STATUS.keys()
        sorted_keys.sort()
        statuses = [dict(name='', label='*', selected=self.status == None)]
        statuses += [
            dict(name=x, label=STATUS[x], selected=self.status == x)
            for x in sorted_keys
        ]

        ####################################
        ## Functions for project sorting, depending on the field
        def cmp_datetime(x, y):
            try:
                return datetime.strptime(x, TIME_FORMAT) < datetime.strptime(
                    y, TIME_FORMAT) and -1 or 1
            except:
                return x.lower() < y.lower() and -1 or 1

        def cmp_date(x, y):
            try:
                return datetime.strptime(x, DATE_FORMAT) < datetime.strptime(
                    y, DATE_FORMAT) and -1 or 1
            except:
                return x.lower() < y.lower() and -1 or 1

        def cmp_int(x, y):
            try:
                return int(x) < int(y) and -1 or 1
            except:
                return x < y and -1 or 1

        def cmp_str_nocase(x, y):
            try:
                return x.lower() < y.lower() and -1 or 1
            except:
                return x < y and -1 or 1

        #################################

        #For some fields, use a special comparison function
        if self.order in ('created', 'last_login'):
            cmp = lambda x, y: cmp_datetime(x[self.order], y[self.order])
        if self.order in ('started', 'scheduled', 'finished'):
            cmp = lambda x, y: cmp_date(x[self.order], y[self.order])
        if self.order in ('percent_finished'):
            cmp = lambda x, y: cmp_int(x[self.order], y[self.order])
        else:
            cmp = lambda x, y: cmp_str_nocase(x[self.order], y[self.order])

        projects.sort(cmp=cmp, reverse=self.desc and True or False)

        #Set template HDF
        req.hdf['projects'] = projects
        req.hdf['statuses'] = statuses
        req.hdf['status'] = self.status
        req.hdf['order'] = self.order
        req.hdf['desc'] = self.desc

        add_stylesheet(req, 'tracprojectmanager/css/projectlist.css')

        return 'projectlist.cs', None
Esempio n. 43
0
 def accessor(self, *args, **kwords):
     val = super(EnvironmentOption,self).accessor(*args, **kwords)
     assert val, 'You must configure a valid Trac environment path for [%s] %s'%(self.section, self.name)
     return open_environment(val, use_cache=True)
Esempio n. 44
0
def dispatch_request(environ, start_response):
    """Main entry point for the Trac web interface.

    :param environ: the WSGI environment dict
    :param start_response: the WSGI callback for starting the response
    """

    global _warn_setuptools
    if _warn_setuptools is False:
        _warn_setuptools = True
        warn_setuptools_issue(out=environ.get('wsgi.errors'))

    # SCRIPT_URL is an Apache var containing the URL before URL rewriting
    # has been applied, so we can use it to reconstruct logical SCRIPT_NAME
    script_url = environ.get('SCRIPT_URL')
    if script_url is not None:
        path_info = environ.get('PATH_INFO')
        if not path_info:
            environ['SCRIPT_NAME'] = script_url
        else:
            # mod_wsgi squashes slashes in PATH_INFO (!)
            script_url = _slashes_re.sub('/', script_url)
            path_info = _slashes_re.sub('/', path_info)
            if script_url.endswith(path_info):
                environ['SCRIPT_NAME'] = script_url[:-len(path_info)]

    # If the expected configuration keys aren't found in the WSGI environment,
    # try looking them up in the process environment variables
    environ.setdefault('trac.env_path', os.getenv('TRAC_ENV'))
    environ.setdefault('trac.env_parent_dir', os.getenv('TRAC_ENV_PARENT_DIR'))
    environ.setdefault('trac.env_index_template',
                       os.getenv('TRAC_ENV_INDEX_TEMPLATE'))
    environ.setdefault('trac.template_vars', os.getenv('TRAC_TEMPLATE_VARS'))
    environ.setdefault('trac.locale', '')
    environ.setdefault('trac.base_url', os.getenv('TRAC_BASE_URL'))

    locale.setlocale(locale.LC_ALL, environ['trac.locale'])

    # Determine the environment
    env_path = environ.get('trac.env_path')
    if not env_path:
        env_parent_dir = environ.get('trac.env_parent_dir')
        env_paths = environ.get('trac.env_paths')
        if env_parent_dir or env_paths:
            # The first component of the path is the base name of the
            # environment
            path_info = environ.get('PATH_INFO', '').lstrip('/').split('/')
            env_name = path_info.pop(0)

            if not env_name:
                # No specific environment requested, so render an environment
                # index page
                send_project_index(environ, start_response, env_parent_dir,
                                   env_paths)
                return []

            errmsg = None

            # To make the matching patterns of request handlers work, we append
            # the environment name to the `SCRIPT_NAME` variable, and keep only
            # the remaining path in the `PATH_INFO` variable.
            script_name = environ.get('SCRIPT_NAME', '')
            try:
                script_name = unicode(script_name, 'utf-8')
                # (as Href expects unicode parameters)
                environ['SCRIPT_NAME'] = Href(script_name)(env_name)
                environ['PATH_INFO'] = '/' + '/'.join(path_info)

                if env_parent_dir:
                    env_path = os.path.join(env_parent_dir, env_name)
                else:
                    env_path = get_environments(environ).get(env_name)

                if not env_path or not os.path.isdir(env_path):
                    errmsg = 'Environment not found'
            except UnicodeDecodeError:
                errmsg = 'Invalid URL encoding (was %r)' % script_name

            if errmsg:
                start_response('404 Not Found',
                               [('Content-Type', 'text/plain'),
                                ('Content-Length', str(len(errmsg)))])
                return [errmsg]

    if not env_path:
        raise EnvironmentError('The environment options "TRAC_ENV" or '
                               '"TRAC_ENV_PARENT_DIR" or the mod_python '
                               'options "TracEnv" or "TracEnvParentDir" are '
                               'missing. Trac requires one of these options '
                               'to locate the Trac environment(s).')
    run_once = environ['wsgi.run_once']

    env = env_error = None
    try:
        env = open_environment(env_path, use_cache=not run_once)
        if env.base_url_for_redirect:
            environ['trac.base_url'] = env.base_url

        # Web front-end type and version information
        if not hasattr(env, 'webfrontend'):
            mod_wsgi_version = environ.get('mod_wsgi.version')
            if mod_wsgi_version:
                mod_wsgi_version = (
                    "%s (WSGIProcessGroup %s WSGIApplicationGroup %s)" %
                    ('.'.join([str(x) for x in mod_wsgi_version
                               ]), environ.get('mod_wsgi.process_group'),
                     environ.get('mod_wsgi.application_group') or '%{GLOBAL}'))
                environ.update({
                    'trac.web.frontend': 'mod_wsgi',
                    'trac.web.version': mod_wsgi_version
                })
            env.webfrontend = environ.get('trac.web.frontend')
            if env.webfrontend:
                env.webfrontend_version = environ['trac.web.version']
    except Exception as e:
        env_error = e

    req = RequestWithSession(environ, start_response)
    translation.make_activable(lambda: req.locale, env.path if env else None)
    try:
        return _dispatch_request(req, env, env_error)
    finally:
        translation.deactivate()
        if env and not run_once:
            env.shutdown(threading._get_ident())
            # Now it's a good time to do some clean-ups
            #
            # Note: enable the '##' lines as soon as there's a suspicion
            #       of memory leak due to uncollectable objects (typically
            #       objects with a __del__ method caught in a cycle)
            #
            ##gc.set_debug(gc.DEBUG_UNCOLLECTABLE)
            unreachable = gc.collect()
    def move(self, ticket_id, author, env, delete=False):
        """
        move a ticket to another environment

        env: environment to move to
        """
        self.log.info(
            "Starting move of ticket %d to environment %r. delete: %r",
            ticket_id, env, delete)

        tables = {'attachment': 'id', 'ticket_change': 'ticket'}

        # open the environment if it is a string
        if isinstance(env, basestring):
            base_path, _project = os.path.split(self.env.path)
            env = open_environment(os.path.join(base_path, env),
                                   use_cache=True)
            PermissionCache(env, author).require('TICKET_CREATE')

        # get the old ticket
        old_ticket = Ticket(self.env, ticket_id)

        # make a new ticket from the old ticket values
        new_ticket = Ticket(env)
        new_ticket.values = old_ticket.values.copy()
        new_ticket.insert(when=old_ticket.values['time'])
        self.log.debug("Ticket inserted into target environment as id %s",
                       new_ticket.id)

        # copy the changelog and attachment DBs
        for table, _id in tables.items():
            for row in get_all_dict(
                    self.env, "SELECT * FROM %s WHERE %s = %%s" % (table, _id),
                    str(ticket_id)):
                row[_id] = new_ticket.id
                insert_row_from_dict(env, table, row)
            self.log.debug("Finished copying data from %r table", table)

        # copy the attachments
        src_attachment_dir = os.path.join(self.env.path, 'attachments',
                                          'ticket', str(ticket_id))
        if os.path.exists(src_attachment_dir):
            self.log.debug("Copying attachements from %r", src_attachment_dir)
            dest_attachment_dir = os.path.join(env.path, 'attachments',
                                               'ticket')
            if not os.path.exists(dest_attachment_dir):
                os.makedirs(dest_attachment_dir)
            dest_attachment_dir = os.path.join(dest_attachment_dir,
                                               str(new_ticket.id))
            shutil.copytree(src_attachment_dir, dest_attachment_dir)

        # note the previous location on the new ticket
        if delete:
            new_ticket.save_changes(
                author, 'moved from %s (ticket deleted)' % self.env.abs_href())
        else:
            new_ticket.save_changes(
                author,
                'moved from %s' % self.env.abs_href('ticket', ticket_id))
        self.log.info("Finished making new ticket @ %r",
                      env.abs_href('ticket', ticket_id))

        if delete:
            self.log.debug("Deleting old ticket")
            old_ticket.delete()
            if env.base_url:
                return env.abs_href('ticket', new_ticket.id)
        else:
            self.log.debug("Marking old ticket as duplicate.")
            # location of new ticket
            if env.base_url:
                target_name = env.abs_href('ticket', new_ticket.id)
            else:
                target_name = "{0}:#{1}".format(env.project_name,
                                                new_ticket.id)

            # close old ticket and point to new one
            old_ticket['status'] = u'closed'
            old_ticket['resolution'] = u'duplicate'
            old_ticket.save_changes(author, u'moved to %s' % target_name)