示例#1
0
    def expand_macro(self, formatter, name, content, args=None):
        """
        Returns the outcome from macro.
        Supported arguments:

        - count: Number of entries to show

        """
        req = formatter.req
        papi = Projects()
        userstore = get_userstore()

        # Parse optional arguments
        if args is None:
            args = parse_args(content)
            if len(args) > 1:
                args = args[1]

        featured_projects = papi.get_projects_for_rss('FEATURED',
                                                      limit_count=args.get(
                                                          'count', 5))

        data = {'featured_projects': featured_projects}
        return Chrome(self.env).render_template(req,
                                                'multiproject_featured.html',
                                                data,
                                                fragment=True)
示例#2
0
    def process_request(self, req):
        """ Render welcome page
        """

        # Prepare data for template
        prjs = Projects()
        data = {}
        data['baseurl'] = conf.url_projects_path
        if req.authname == 'anonymous':
            conf.redirect(req)

        # Get project count
        data['project_count'] = prjs.project_count()

        user = get_userstore().getUser(req.authname)
        global_timeline = GlobalTimeline()

        data['show_explore'] = self.env[FindProjectsModule].has_explore_perm(req)
        data['latest_events'] = global_timeline.get_latest_events(req.authname, 5)

        # Check if user is allowed to create project
        data['can_create_project'] = user.can_create_project()

        # Configuration values the welcome page wants
        data['site_name'] = conf.site_name
        data['site_title_text'] = conf.site_title_text
        data['site_punch_line'] = conf.punch_line
        data['site_theme_path'] = conf.getThemePath()

        wiki_welcome = self._get_welcome_page(req)
        if wiki_welcome:
            data['wiki_welcome'] = wiki_welcome

        return "welcome.html", data, None
示例#3
0
    def expand_macro(self, formatter, name, content, args=None):
        """
        Returns the outcome from macro.
        Supported arguments:

        - count: Number of entries to show

        """
        req = formatter.req
        papi = Projects()
        userstore = get_userstore()
        projects = []

        # Parse optional arguments
        if args is None:
            args = parse_args(content)
            if len(args) > 1:
                args = args[1]

        projects = papi.get_projects_for_rss('MOSTACTIVE',
                                             limit_count=args.get('count', 5),
                                             limit_activity=self.min_activity)

        return Chrome(self.env).render_template(req,
                                                'multiproject_active.html',
                                                {'active_projects': projects},
                                                fragment=True)
示例#4
0
 def test_get_enabled_services(self):
     p = Projects()
     services = p.getEnabledServices(self)
     self.assertTrue(len(services) >= 3)
     self.assertIn('versioncontrol|svn|false|Subversion', services)
     self.assertIn('documenting|wiki|true|Wiki', services)
     self.assertIn('tasks|trac|true|Task management system', services)
示例#5
0
 def test_get_enabled_services(self):
     p = Projects()
     services = p.getEnabledServices(self)
     self.assertTrue(len(services) >= 3)
     self.assertIn('versioncontrol|svn|false|Subversion', services)
     self.assertIn('documenting|wiki|true|Wiki', services)
     self.assertIn('tasks|trac|true|Task management system', services)
示例#6
0
    def render_admin_panel(self, req, cat, page, path_info):
        """
        Returns the admin view and handles the form actions
        """
        req.perm.require('TRAC_ADMIN')

        project = Project.get(self.env)

        if req.method == 'POST':
            myprojects_url = conf.url_home_path + "/myprojects"
            conf.log.exception("Redirect URL: %s" % myprojects_url)
            thisurl = Href(req.base_path)(req.path_info)
            context = Context.from_request(req)

            # Handle project remove
            if 'remove' in req.args:
                # Don't allow removing home
                if project.env_name == conf.sys_home_project_name:
                    add_warning(req, 'Cannot remove home project')
                    return req.redirect(thisurl)

                # Archive the project before removal
                archive = ProjectArchive()
                archived = archive.archive(project)

                if not archived:
                    add_warning(req, 'Could not archive project "%s". Will not remove the project' % project.project_name)
                    return req.redirect(thisurl)

                # Notify listeners. The project object still exists, but database does not
                for listener in self.project_change_listeners:
                    listener.project_archived(project)

                # Do the actual project removal
                projects = Projects()
                if projects.remove_project(project):
                    # Notify listeners. The project object still exists, but database does not
                    for listener in self.project_change_listeners:
                        listener.project_deleted(project)

                    # NOTE: We no longer have project tables/session etc available
                    req.redirect(myprojects_url)

                else:
                    add_warning(req, 'Could not remove project "%s". Try again later' % project.project_name)
                    return req.redirect(thisurl)

        add_script(req, 'multiproject/js/jquery-ui.js')
        add_script(req, 'multiproject/js/multiproject.js')
        add_script(req, 'multiproject/js/admin_system.js')
        add_stylesheet(req, 'multiproject/css/jquery-ui.css')

        # NOTE: Trac automatically puts 'project' dict in chrome thus it cannot be used
        data = {'multiproject': {
            'project':project,
            'home_url':conf.url_home_path
        }}
        return 'admin_system.html', data
示例#7
0
    def remove_project(self, req):
        """
        Handler for removing project

        :param Request req: Trac request

        Handler expects to have following arguments in it:

        - project: Name of the project env
        - goto: Optional URL where to go after project removal. Defaults to /home/myprojects

        """
        backurl = req.args.get('goto', ProjectListModule.home('myprojects'))
        short_name = req.args.get('project')
        if not short_name:
            return self.remove_failure(req)
        if req.args.get('cancel'):
            add_notice(req, 'Project deletion cancelled')
            return self.remove_failure(req)
        author = req.authname
        project = Project.get(env_name=short_name)

        if project is None:
            add_warning(req, 'Specified project does not exist!')
            return self.remove_failure(req)

        # Don't allow removing home
        if project.env_name == conf.sys_home_project_name:
            add_warning(req, 'Cannot remove home project')
            return self.remove_failure(req)
        if req.method != 'POST':
            return self.remove_failure(req, project=project)

        try:
            project.validate()
        except ProjectValidationException:
            req.redirect(backurl)

        # Check the permissions and method
        prjs = Projects()
        if ('TRAC_ADMIN' in req.perm or prjs.is_project_owner(project.env_name, author)) and req.method == 'POST':
            archive = ProjectArchive()
            # Archive the project before removal
            if not archive.archive(project):
                add_warning(req, 'Could not archive project "%s". Will not remove the project' % project.project_name)
            elif prjs.remove_project(project):
                # Notify listeners
                for listener in self.project_change_listeners:
                    listener.project_deleted(project)
                # Notify end user
                add_notice(req, 'Project "%s" removed' % project.project_name)
            else:
                add_warning(req, 'Could not remove project "%s". Try again later' % project.project_name)
        else:
            add_warning(req, 'You are not allowed to remove project "%s" (check permissions and method)' % project.project_name)

        req.redirect(backurl)
示例#8
0
    def test_project_environment_does_not_exist(self):
        dbStub.addResult([[0]])
        p = Projects()
        self.assertFalse(p.project_environment_exists("testi"))
        self.assertTrue(dbStub.closed)

        dbStub.setExceptions(True)
        self.assertFalse(p.project_environment_exists("testi"))
        self.assertTrue(dbStub.closed)
示例#9
0
    def get_child_projects(self):
        """ Returns projects that have repository of this project
        """
        from multiproject.common.projects import Projects

        query = "SELECT * FROM projects WHERE parent_id = %d" % safe_int(self.id)
        api = Projects()

        return api.queryProjectObjects(query)
示例#10
0
    def test_project_environment_does_not_exist(self):
        dbStub.addResult([ [0] ])
        p = Projects()
        self.assertFalse(p.project_environment_exists("testi"))
        self.assertTrue(dbStub.closed)

        dbStub.setExceptions(True)
        self.assertFalse(p.project_environment_exists("testi"))
        self.assertTrue(dbStub.closed)
示例#11
0
    def _list_mostactive_public_projects(self, req):
        prjs = Projects()

        page_size = 25

        data = {}
        limit_start, page_size = self._add_rss_pagination(req, data, page_size)
        data['projects'] = prjs.get_projects_for_rss('MOSTACTIVE', limit_start=limit_start, limit_count=page_size)

        return 'rss_list.html', data, None
示例#12
0
    def get_child_projects(self):
        """ Returns projects that have repository of this project
        """
        from multiproject.common.projects import Projects

        query = "SELECT * FROM projects WHERE parent_id = %d" % safe_int(
            self.id)
        api = Projects()

        return api.queryProjectObjects(query)
示例#13
0
 def test_get_my_tasks(self):
     dbStub.addResult(project_tasks_result)
     p = Projects()
     project_list = [
         Project(1, "project1", "project1", "Project 1", 1, "2010-01-01"),
         Project(2, "project2", "project2", "Project 2", 2, "2010-01-02")
     ]
     tasks = p.get_all_user_tasks("username", project_list)
     self.assertEquals(len(tasks), 6)
     self.assertTrue(dbStub.closed)
示例#14
0
 def test_get_my_tasks(self):
     dbStub.addResult(project_tasks_result)
     p = Projects()
     project_list = [
         Project(1, "project1", "project1", "Project 1", 1, "2010-01-01"),
         Project(2, "project2", "project2", "Project 2", 2, "2010-01-02")
     ]
     tasks = p.get_all_user_tasks("username", project_list)
     self.assertEquals(len(tasks), 6)
     self.assertTrue(dbStub.closed)
示例#15
0
    def _list_recent_public_projects(self, req):
        prjs = Projects()

        page_size = 25

        data = {}
        limit_start, page_size = self._add_rss_pagination(req, data, page_size)
        min_activity = self.config.getint('multiproject-projects', 'min_activity')
        data['projects'] = prjs.get_projects_for_rss('NEWEST', limit_start=limit_start, limit_count=page_size, limit_activity=min_activity)

        return 'rss_list.html', data, None
示例#16
0
 def test_search_user_projects(self):
     dbStub.addResult(project_search_result)
     p = Projects()
     userstoreStub.user.username = "******"
     projects = p.searchUserProjects("name1 name2 name3","user")
     self.assertEquals(len(projects), 3)
     self.assertEquals(projects[0].env_name, 'project1')
     self.assertEquals(projects[0].project_name, 'Project 1')
     self.assertEquals(projects[0].author_id, 10)
     self.assertEquals(projects[0].created, '2009-01-01')
     self.assertTrue(dbStub.closed)
示例#17
0
 def test_search_user_projects(self):
     dbStub.addResult(project_search_result)
     p = Projects()
     userstoreStub.user.username = "******"
     projects = p.searchUserProjects("name1 name2 name3", "user")
     self.assertEquals(len(projects), 3)
     self.assertEquals(projects[0].env_name, 'project1')
     self.assertEquals(projects[0].project_name, 'Project 1')
     self.assertEquals(projects[0].author_id, 10)
     self.assertEquals(projects[0].created, '2009-01-01')
     self.assertTrue(dbStub.closed)
示例#18
0
    def _list_mostactive_public_projects(self, req):
        prjs = Projects()

        page_size = 25

        data = {}
        limit_start, page_size = self._add_rss_pagination(req, data, page_size)
        data['projects'] = prjs.get_projects_for_rss('MOSTACTIVE',
                                                     limit_start=limit_start,
                                                     limit_count=page_size)

        return 'rss_list.html', data, None
示例#19
0
    def _show_regular_page(self, req):
        req_data = {}
        # Resolve some static data needed on page (categories and project count)
        cs = CQDECategoryStore()
        all_categories = cs.get_all_categories()

        all_contexts = cs.get_contexts()
        combined_context_ids, combined_contexts, non_combined_contexts = self.get_combined_contexts(
            all_contexts)

        # Total count of projects and count of projects in categories
        direct_category_counts = Projects().get_project_counts_per_category(
            req.authname)

        req_data['direct_category_counts'] = direct_category_counts
        req_data['combined_context_ids'] = combined_context_ids
        req_data['non_combined_contexts'] = non_combined_contexts

        self.set_category_data_into_request_data(all_categories, req_data)

        add_stylesheet(req, 'multiproject/css/multiproject.css')
        add_script(req, 'multiproject/js/jquery.ba-bbq.js')
        add_script(req, 'multiproject/js/explore.js')

        return "find.html", {
            'top_categories': req_data['top_categories'],
            'categories': req_data['root_categories_of_combined_contexts'],
            'nonbrowsable_cntxt': req_data['non_empty_non_combined_contexts'],
            'selected_tab': self.DEFAULT_TAB,
            'tabs': self.TABS}, \
            None
示例#20
0
    def _list_recent_public_projects(self, req):
        prjs = Projects()

        page_size = 25

        data = {}
        limit_start, page_size = self._add_rss_pagination(req, data, page_size)
        min_activity = self.config.getint('multiproject-projects',
                                          'min_activity')
        data['projects'] = prjs.get_projects_for_rss(
            'NEWEST',
            limit_start=limit_start,
            limit_count=page_size,
            limit_activity=min_activity)

        return 'rss_list.html', data, None
示例#21
0
 def __init__(self, verbose=False):
     """
     If verbose = None, be absolutely quiet
     """
     self.verbose = verbose
     self.policy = CQDEPermissionPolicy(MockEnvironment())
     self.papi = Projects()
     self.batch_size = conf.visibility_db_batch_size
     self.required_permission = 'PROJECT_VIEW'
示例#22
0
    def _add_rss_pagination(self, req, data, page_size):
        prjs = Projects()

        # Read selected page
        selected_page = req.args.get('page')
        if not selected_page:
            selected_page = 1
        selected_page = int(selected_page)
        data['selected_page'] = selected_page

        count = prjs.public_project_count()

        # Create array of page numbers that will be used on view
        page_count = int(math.ceil((float(count) / page_size)))
        data['pages'] = range(1, page_count + 1)

        # Create start point for limit and get all projects
        limit_start = (selected_page - 1) * page_size

        return limit_start, page_size
示例#23
0
    def _add_rss_pagination(self, req, data, page_size):
        prjs = Projects()

        # Read selected page
        selected_page = req.args.get('page')
        if not selected_page:
            selected_page = 1
        selected_page = int(selected_page)
        data['selected_page'] = selected_page

        count = prjs.public_project_count()

        # Create array of page numbers that will be used on view
        page_count = int(math.ceil((float(count) / page_size)))
        data['pages'] = range(1, page_count + 1)

        # Create start point for limit and get all projects
        limit_start = (selected_page - 1) * page_size

        return limit_start, page_size
示例#24
0
    def process_request(self, req):
        """ Process request for listing, creating and removing projects
        """
        prjs = Projects()
        data = {}

        data['home'] = conf.url_home_path.rstrip('/') + "/rss"
        data['tracurl'] = conf.url_home_path.rstrip('/')

        # Having url_service here is probably a good idea. Otherwise RSS readers have no idea
        # where to fetch the relative path /project from.
        data['projroot'] = conf.url_service.rstrip('/')
        data['host'] = conf.domain_name
        data['url'] = req.path_info.rstrip('/').lstrip('/')

        if re.match (r'/rss/mostactive.xml$', req.path_info):
            data['projects'] = prjs.get_projects_for_rss('MOSTACTIVE', limit_count=50)
            data['title'] = 'Most active public projects'

        elif re.match (r'/rss/newest.xml$', req.path_info):
            min_activity = self.config.getint('multiproject-projects', 'min_activity', 0)
            data['projects'] = prjs.get_projects_for_rss('NEWEST', limit_count=50, limit_activity=min_activity)
            data['title'] = 'Newest public projects'

        elif re.match (r'/rss/featured.xml$', req.path_info):
            data['projects'] = prjs.get_projects_for_rss('FEATURED', limit_count=50)
            data['title'] = 'Featured projects'

        elif re.match(r'/rss/projects/.*.xml', req.path_info):
            username = req.path_info[req.path_info.rfind('/') + 1:-4]
            # username is validated in get_participated_public_projects
            data['projects'] = prjs.get_participated_public_projects(username)
            data['title'] = '%s\'s projects' % username

        else:
            data['projects'] = None

        # Support for both RSS 2.0 (default) and RSS 1.0 formats
        if 'rss10' == req.args.get('format', 'notset'):
            return "rss_feed_template.rss10", data, 'application/rss+xml'
        return "rss_feed_template.rss", data, 'application/rss+xml'
示例#25
0
    def expand_macro(self, formatter, name, content, args=None):
        """
        Returns the outcome from macro.
        Supported arguments:

        - count: Number of entries to show

        """
        req = formatter.req
        papi = Projects()
        userstore = get_userstore()
        projects = []

        # Parse optional arguments
        if args is None:
            args = parse_args(content)
            if len(args) > 1:
                args = args[1]

        min_activity = self.config.getint('multiproject-projects', 'min_activity')
        projects = papi.get_projects_for_rss('NEWEST', limit_count=args.get('count', 5), limit_activity=min_activity)
        return Chrome(self.env).render_template(req, 'multiproject_recent.html', {'recent_projects': projects}, fragment=True)
示例#26
0
    def process_request(self, req):
        """ Create a simple RSS feed based on this structure that shows the number of active projects and members.
            In the future we will add more details.
        """
        prjs = Projects()

        # create a list
        items = []

        # append tuples containing items to show
        items.append(("PROJECT_COUNT", "Project count", prjs.project_count()))
        items.append(("ACTIVE_MEMBER_COUNT", "Active member count", get_userstore().getMemberCountInProjects()))

        pubdate = datetime.now()

        data = {}
        data["items"] = items
        data["site"] = conf.url_statistics

        # pubDate format: Wed, 12 Jan 2011 11:47:29 GMT
        data["pubdate"] = pubdate.strftime("%a, %d %B %Y %H:%M:%S %Z")

        return "service_statistics.rss", data, "application/rss+xml"
示例#27
0
    def process_request(self, req):
        """ Render welcome page
        """

        # Prepare data for template
        prjs = Projects()
        data = {}
        data['baseurl'] = conf.url_projects_path
        if req.authname == 'anonymous':
            conf.redirect(req)

        # Get project count
        data['project_count'] = prjs.project_count()

        user = get_userstore().getUser(req.authname)
        global_timeline = GlobalTimeline()

        data['show_explore'] = self.env[FindProjectsModule].has_explore_perm(
            req)
        data['latest_events'] = global_timeline.get_latest_events(
            req.authname, 5)

        # Check if user is allowed to create project
        data['can_create_project'] = user.can_create_project()

        # Configuration values the welcome page wants
        data['site_name'] = conf.site_name
        data['site_title_text'] = conf.site_title_text
        data['site_punch_line'] = conf.punch_line
        data['site_theme_path'] = conf.getThemePath()

        wiki_welcome = self._get_welcome_page(req)
        if wiki_welcome:
            data['wiki_welcome'] = wiki_welcome

        return "welcome.html", data, None
示例#28
0
    def expand_macro(self, formatter, name, content, args=None):
        """
        Returns the outcome from macro.
        Supported arguments:

        - count: Number of entries to show

        """
        req = formatter.req
        papi = Projects()
        userstore = get_userstore()

        # Parse optional arguments
        if args is None:
            args = parse_args(content)
            if len(args) > 1:
                args = args[1]

        featured_projects = papi.get_projects_for_rss('FEATURED', limit_count=args.get('count', 5))

        data = {
            'featured_projects': featured_projects
        }
        return Chrome(self.env).render_template(req, 'multiproject_featured.html', data, fragment=True)
示例#29
0
    def render_admin_panel(self, req, cat, page, path_info):
        """
        Renders updates admin panel page
        """
        req.perm.require('TRAC_ADMIN')

        papi = Projects()
        selected = []

        if req.method == 'POST':
            if req.args.get('searchprojects'):
                selected = papi.get_featured_projects()
                projectids = []
                for project in selected:
                    projectid = project.id
                    projectids.append(projectid)

                rawsearch = papi.search_project(req.args.get('pattern'), None,
                                                1, 50)

                for project in rawsearch:
                    if not project.id in projectids:
                        project.priority = None
                        selected.append(project)

            elif req.args.get('update'):
                selection = req.args.get('projects')
                selection = isinstance(selection, list) and selection or [
                    selection
                ]
                projects = []

                for project in selection:
                    value = req.args.get(project)
                    if value is not None and value != "remove":
                        projects.append((project, value))

                papi.update_featured_projects(projects)
                selected = papi.get_featured_projects()
        else:
            selected = papi.get_featured_projects()

        data = {'selected': selected, 'maxvalue': 20}
        return 'multiproject_featured_admin.html', data
示例#30
0
    def activities_to_classes(self, activities):
        """ Changes project activity into activity css classes of
            l,ql,qh,h (High, Quite High, Quite low, Low)
        """
        bounds = Projects().get_activity_quartals()
        project_classes = {}
        classes = ['l', 'ql', 'qh', 'h']

        # For each project_id, activity pair find correct css class
        for id, activity in activities.items():
            # low as default. Go through bounds until match
            index = 0
            for idx, bound in enumerate(bounds):
                if bound > activity:
                    break
                index = idx
            project_classes[id] = classes[index]
        return project_classes
示例#31
0
    def createProject(self, req, projectid, projectname, description, project_visibility, serviceslist):
        """ Request to create a new project
        """
        services = {}

        if str(projectid).strip() == '':
            e = exceptions.Exception
            raise e("Incorrect project identification name")

        if str(projectname).strip() == '':
            e = exceptions.Exception
            raise e("Incorrect project name")

        users = get_userstore()
        author = users.getUser(req.authname)

        if not author.can_create_project():
            raise Exception("You are not allowed to create projects")
        
        public = False
        published = None
        if project_visibility == "on" or project_visibility == "true":
            public = True
            published = datetime.now()

        # Create project class
        project = Project(id=None,
                          env_name=unicode(projectid),
                          project_name=projectname,
                          description=description,
                          author_id=author.id,
                          created=None,
                          public=public,
                          published=published)

        if project_visibility == "on" or project_visibility == "true":
            services['project_visibility'] = 'on'
        else:
            services['project_visibility'] = 'off'

        projects = Projects()
        projects.getServices(services, serviceslist)

        # Create project
        try:
            projects.create_project(project, services)
            return self.get_scm_repository_url(project.env_name)
        except ProjectValidationException as exc:
            raise Exception(exc.value)
        except:
            raise Exception("Creating project failed. Try again later.")
示例#32
0
    def render_admin_panel(self, req, cat, page, path_info):
        """
        Renders updates admin panel page
        """
        req.perm.require('TRAC_ADMIN')

        papi = Projects()
        selected = []

        if req.method == 'POST':
            if req.args.get('searchprojects'):
                selected = papi.get_featured_projects()

                projectids = []
                for project in selected:
                    projectid = project['project_id']
                    projectids.append(projectid)

                rawsearch = papi.search_project(req.args.get('pattern'), None, 1, 50)

                for project in rawsearch:
                    if not project['project_id'] in projectids:
                        project['priority'] = None
                        selected += tuple([project])

            elif req.args.get('update'):
                selection = req.args.get('projects')
                selection = isinstance(selection, list) and selection or [selection]
                projects = []

                for project in selection:
                    value = req.args.get(project)
                    if value is not None and value != "remove":
                        projects.append((project, value))

                papi.update_featured_projects(projects)
                selected = papi.get_featured_projects()
        else:
            selected = papi.get_featured_projects()

        data = {
            'selected': selected,
            'maxvalue': 20
        }
        return 'multiproject_featured_admin.html', data
示例#33
0
    def searchProjects(self, req, namelike, categories):
        """ Returns project list, what user owns or have access to
        """
        namelike = namelike.strip()

        if namelike == '' or namelike == '*' or namelike is None:
            namelike = None
        else:
            namelike = namelike.replace('%', '\%')
            namelike = namelike.replace('_', '\_')
            namelike = namelike.replace('\\', '\\\\')

        if categories == '':
            categories = None

        myprojects = Projects().get_projects_with_params(req.authname, "VERSION_CONTROL_VIEW",
                                                         namelike, categories)

        projectlist = []
        for project in myprojects:
            projectlist.append(project.env_name + '|' + project.project_name)
        return projectlist
示例#34
0
    def render_admin_panel(self, req, cat, page, path_info):
        """
        Renders updates admin panel page
        """
        req.perm.require("TRAC_ADMIN")

        papi = Projects()
        selected = []

        if req.method == "POST":
            if req.args.get("searchprojects"):
                selected = papi.get_featured_projects()
                projectids = []
                for project in selected:
                    projectid = project.id
                    projectids.append(projectid)

                rawsearch = papi.search_project(req.args.get("pattern"), None, 1, 50)

                for project in rawsearch:
                    if not project.id in projectids:
                        project.priority = None
                        selected.append(project)

            elif req.args.get("update"):
                selection = req.args.get("projects")
                selection = isinstance(selection, list) and selection or [selection]
                projects = []

                for project in selection:
                    value = req.args.get(project)
                    if value is not None and value != "remove":
                        projects.append((project, value))

                papi.update_featured_projects(projects)
                selected = papi.get_featured_projects()
        else:
            selected = papi.get_featured_projects()

        data = {"selected": selected, "maxvalue": 20}
        return "multiproject_featured_admin.html", data
示例#35
0
    def process_request(self, req):
        """ Process request for listing, creating and removing projects
        """
        prjs = Projects()
        data = {}

        data['home'] = conf.url_home_path.rstrip('/') + "/rss"
        data['tracurl'] = conf.url_home_path.rstrip('/')

        # Having url_service here is probably a good idea. Otherwise RSS readers have no idea
        # where to fetch the relative path /project from.
        data['projroot'] = conf.url_service.rstrip('/')
        data['host'] = conf.domain_name
        data['url'] = req.path_info.rstrip('/').lstrip('/')

        if re.match(r'/rss/mostactive.xml$', req.path_info):
            data['projects'] = prjs.get_projects_for_rss('MOSTACTIVE',
                                                         limit_count=50)
            data['title'] = 'Most active public projects'

        elif re.match(r'/rss/newest.xml$', req.path_info):
            min_activity = self.config.getint('multiproject-projects',
                                              'min_activity', 0)
            data['projects'] = prjs.get_projects_for_rss(
                'NEWEST', limit_count=50, limit_activity=min_activity)
            data['title'] = 'Newest public projects'

        elif re.match(r'/rss/featured.xml$', req.path_info):
            data['projects'] = prjs.get_projects_for_rss('FEATURED',
                                                         limit_count=50)
            data['title'] = 'Featured projects'

        elif re.match(r'/rss/projects/.*.xml', req.path_info):
            username = req.path_info[req.path_info.rfind('/') + 1:-4]
            # username is validated in get_participated_public_projects
            data['projects'] = prjs.get_participated_public_projects(username)
            data['title'] = '%s\'s projects' % username

        else:
            data['projects'] = None

        # Support for both RSS 2.0 (default) and RSS 1.0 formats
        if 'rss10' == req.args.get('format', 'notset'):
            return "rss_feed_template.rss10", data, 'application/rss+xml'
        return "rss_feed_template.rss", data, 'application/rss+xml'
示例#36
0
 def test_is_project_owner_error(self):
     dbStub.addResult([[1]])  # user id
     userstoreStub.user.id = 0
     p = Projects()
     self.assertFalse(p.is_project_owner("project", "nobody"))
     self.assertTrue(dbStub.closed)
示例#37
0
 def _list_forkable_projects(self, req):
     projects = Projects()
     projects = projects.get_forkable_projects(req.authname)
     return 'project_select_box.html', {'projects': projects}, None
示例#38
0
    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')
        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

        identifier = req.args.get('prj_short_name')
        name = req.args.get('prj_long_name')
        public = 'prj_is_public' in req.args

        published = None
        if public:
            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()
            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)

        # Notify listeners. The project object still exists, but database does not
        for listener in self.project_change_listeners:
            listener.project_created(project)
            if public:
                listener.project_set_public(project)

        return self.create_success(req, project)
示例#39
0
    def _filtered_resultset_partial(self, req, rss=False):
        # Fetch request arguments
        filter, category_id_list, sub_page = self.fetch_req_args(req)

        # Which tab is requested
        tab = self.resolve_tab(req)

        # Get optional number of results per page.
        # If not set, or bigger than max, default to MAX_RESULTS_TO_DISPLAY
        numresults = req.args.get('numresults', '')
        if not numresults or not numresults.isdigit():
            numresults = self.DEFAULT_RESULTS_TO_DISPLAY
        elif int(numresults) > self.MAX_RESULTS_TO_DISPLAY:
            numresults = self.MAX_RESULTS_TO_DISPLAY
        numresults = int(numresults)

        # Fetch projects based on tab
        if tab == "download":
            projects = Projects().searchMostDownloaded()
            activities = None
            if projects is None:
                project_count = 0
            else:
                project_count = len(projects)
        else:
            projects, activities, project_count = Projects().search(
                filter, category_id_list, req.authname, tab, sub_page,
                numresults)

        # Some calculations for pagination
        # NOTE: math.ceil returns a float
        total_page_count = int(math.ceil(float(project_count) / numresults))

        range_center_point = sub_page
        if range_center_point <= self.SUBPAGE_RANGE:
            range_center_point = 1 + self.SUBPAGE_RANGE

        if range_center_point + 1 >= total_page_count:
            range_center_point = total_page_count - self.SUBPAGE_RANGE

        start_page = range_center_point - self.SUBPAGE_RANGE
        if start_page < 1:
            start_page = 1

        end_page = range_center_point + self.SUBPAGE_RANGE
        if end_page > total_page_count:
            end_page = total_page_count

        if projects or len(projects) > 0:
            # Activity css classes for activity meters
            if activities:
                activity_classes = self.activities_to_classes(activities)
            else:
                activity_classes = {}
            # Get categories for projects that was searched
            project_categories = self.get_project_categories(projects)
            # Get number of project watchers
            project_watchers = self.get_project_watchers(projects)
        else:
            activity_classes = {}
            project_categories = ""
            project_watchers = ""
        if project_count:
            if tab == 'recent':
                showing_clause = _(
                    "Showing %(start)s - %(end)s most recent projects out of %(total)s",
                    start=(sub_page - 1) * numresults + 1,
                    end=min(sub_page * numresults, project_count),
                    total=project_count)
            elif tab == 'download':
                showing_clause = _(
                    "Showing %(start)s - %(end)s most recent projects out of %(total)s",
                    start=(sub_page - 1) * numresults + 1,
                    end=min(sub_page * numresults, project_count),
                    total=project_count)
            else:
                showing_clause = _(
                    "Showing %(start)s - %(end)s active projects out of %(total)s",
                    start=(sub_page - 1) * numresults + 1,
                    end=min(sub_page * numresults, project_count),
                    total=project_count)
        else:
            showing_clause = _("No results")

        if not rss:

            return "projects_partial.html", {
                'projects': projects,
                'project_categories': project_categories,
                'project_watchers': project_watchers,
                'selected_categories': category_id_list,
                'selected_tab': tab,
                'tabs': self.TABS,
                'total_pages': total_page_count,
                'start_page': start_page,
                'end_page': end_page,
                'sub_page': sub_page,
                'showing_clause': showing_clause,
                'activity_classes': activity_classes,
                'search_filter': filter or 'Search Projects'
            }, None
        else:
            data = {}
            data['projects'] = projects
            data['projroot'] = conf.url_service
            data['host'] = conf.domain_name
            if tab == 'active':
                data['sorting'] = "most active"
            elif tab == 'recent':
                data['sorting'] = "most recent"
            else:
                data['sorting'] = ""

            # TODO: optimize find_categories
            categories = self._find_categories(category_id_list)
            cat_string = ""
            sec_string = ""
            if len(categories) == 1:
                cat_string = "in " + categories[0] + " category"
                sec_string = "in " + categories[0] + " section"
            elif len(categories) > 1:
                cat_string = "in " + ", ".join(categories) + " categories"
                sec_string = "in " + ", ".join(categories) + " sections"
            data['category_string'] = cat_string
            data['section_string'] = sec_string
            data['resultslink'] = conf.url_service + req.href(
            ) + req.path_info + "#" + req.query_string

            return "project_list.rss", data, 'application/rss+xml'
示例#40
0
 def test_is_project_owner(self):
     dbStub.addResult([[1]])  # user id
     userstoreStub.user.id = 1
     p = Projects()
     self.assertTrue(p.is_project_owner("project", "user"))
     self.assertTrue(dbStub.closed)
示例#41
0
 def getTracServices(self, req):
     """ Returns available services
     """
     prjs = Projects()
     return prjs.getEnabledServices(self.env)
示例#42
0
    def render_admin_panel(self, req, cat, page, path_info):
        """ Overrides BasicsAdminPanel rendering function.

            Handle project info update (update global db) and then
            delegate handling back to BasicsAdminPanel
        """
        req.perm.require('TRAC_ADMIN')
        userstore = get_userstore()
        user = userstore.getUser(req.authname)
        project = Project.get(self.env)

        # Update database if form posted
        if req.method == 'POST':
            papi = Projects()

            # Set public pressed
            if 'makepublic' in req.args:
                if conf.allow_public_projects:
                    self._make_public(req, project)
                    papi.add_public_project_visibility(project.id)
                else:
                    raise TracError("Public projects are disabled", "Error!")

            # Set private pressed
            if 'makeprivate' in req.args:
                self._make_private(req, project)
                papi.remove_public_project_visibility(project.id)

            # Remove icon if requested
            if 'reset' in req.args:
                # NOTE: Icon is removed from filesystem already at this point
                self._unset_icon(req, project)
                project.icon_name = None

            # Update icon if set
            if not isinstance(req.args.get('icon', ''), basestring):
                icon_name = self._set_icon(req, project)
                if icon_name:
                    # If image is changed
                    if icon_name != project.icon_name:
                        self._unset_icon(req, project)
                    project.icon_name = icon_name
                else:
                    add_warning(req, 'Failed to set the project icon')

            # Save changes in database
            if 'apply' in req.args:
                self._apply_changes(req, project)

            # Reload page
            return req.redirect(req.href(req.path_info))

        data = {
            'user': user,
            'icon_size': self.icon_size,
            'mproject': project,
            'is_public': project.public,
            'allow_public_projects': conf.allow_public_projects
        }

        # Add javascript libraries for datepicker and autocomplete
        add_script(req, 'multiproject/js/jquery-ui.js')
        add_stylesheet(req, 'multiproject/css/jquery-ui.css')
        add_script(req, 'multiproject/js/multiproject.js')
        add_script(req, 'multiproject/js/admin_basics.js')

        Chrome(self.env).add_textarea_grips(req)
        return 'admin_basics_replacement.html', data
示例#43
0
    def render_admin_panel(self, req, cat, page, path_info):
        """
        Returns the admin view and handles the form actions
        """
        req.perm.require('TRAC_ADMIN')

        project = Project.get(self.env)

        if req.method == 'POST':
            myprojects_url = conf.url_home_path + "/myprojects"
            conf.log.exception("Redirect URL: %s" % myprojects_url)
            thisurl = Href(req.base_path)(req.path_info)
            context = Context.from_request(req)

            # Handle project remove
            if 'remove' in req.args:
                # Don't allow removing home
                if project.env_name == conf.sys_home_project_name:
                    add_warning(req, 'Cannot remove home project')
                    return req.redirect(thisurl)

                # Archive the project before removal
                archive = ProjectArchive()
                archived = archive.archive(project)

                if not archived:
                    add_warning(
                        req,
                        'Could not archive project "%s". Will not remove the project'
                        % project.project_name)
                    return req.redirect(thisurl)

                # Notify listeners. The project object still exists, but database does not
                for listener in self.project_change_listeners:
                    listener.project_archived(project)

                # Do the actual project removal
                projects = Projects()
                if projects.remove_project(project):
                    # Notify listeners. The project object still exists, but database does not
                    for listener in self.project_change_listeners:
                        listener.project_deleted(project)

                    # NOTE: We no longer have project tables/session etc available
                    req.redirect(myprojects_url)

                else:
                    add_warning(
                        req, 'Could not remove project "%s". Try again later' %
                        project.project_name)
                    return req.redirect(thisurl)

        add_script(req, 'multiproject/js/jquery-ui.js')
        add_script(req, 'multiproject/js/multiproject.js')
        add_script(req, 'multiproject/js/admin_system.js')
        add_stylesheet(req, 'multiproject/css/jquery-ui.css')

        # NOTE: Trac automatically puts 'project' dict in chrome thus it cannot be used
        data = {
            'multiproject': {
                'project': project,
                'home_url': conf.url_home_path
            }
        }
        return 'admin_system.html', data
示例#44
0
 def _list_forkable_projects(self, req):
     projects = Projects()
     projects = projects.get_forkable_projects(req.authname)
     return 'project_select_box.html', {'projects':projects}, None
示例#45
0
 def test_project_environment_exists(self):
     dbStub.addResult([ [1] ])
     p = Projects()
     self.assertTrue(p.project_environment_exists("testi"))
     self.assertTrue(dbStub.closed)
示例#46
0
 def test_project_count(self):
     dbStub.addResult([ [3] ])
     p = Projects()
     self.assertEquals(p.project_count(), 3)
     self.assertTrue(dbStub.closed)
示例#47
0
 def getCount(self, req):
     """ Returns project count from server
     """
     prjs = Projects()
     return prjs.project_count()
示例#48
0
 def getTracServices(self, req):
     """ Returns available services
     """
     prjs = Projects()
     return prjs.getEnabledServices(self.env)
示例#49
0
 def projectExists(self, req, short_name):
     """ Returns True / False depending if project exists
     """
     prjs = Projects()
     return prjs.project_environment_exists(short_name)
示例#50
0
 def getCount(self, req):
     """ Returns project count from server
     """
     prjs = Projects()
     return prjs.project_count()
示例#51
0
 def test_project_count(self):
     dbStub.addResult([[3]])
     p = Projects()
     self.assertEquals(p.project_count(), 3)
     self.assertTrue(dbStub.closed)
示例#52
0
    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)
示例#53
0
 def test_is_project_owner(self):
     dbStub.addResult([ [1] ]) # user id
     userstoreStub.user.id = 1
     p = Projects()
     self.assertTrue(p.is_project_owner("project", "user"))
     self.assertTrue(dbStub.closed)
示例#54
0
 def test_is_project_owner_error(self):
     dbStub.addResult([ [1] ]) # user id
     userstoreStub.user.id = 0
     p = Projects()
     self.assertFalse(p.is_project_owner("project", "nobody"))
     self.assertTrue(dbStub.closed)
示例#55
0
    def test_get_services(self):
        p = Projects()
        res={}
        p.getServices(res,"test, dummy, Subversion, Perforce, test")
        self.assertEquals(res['vcs_type'], "perforce")

        p.getServices(res,"test, dummy, Subversion, test")
        self.assertEquals(res['vcs_type'], "svn")

        p.getServices(res,"another test, Versioncontrol|Mercurial, test")
        self.assertEquals(res['vcs_type'], "hg")

        p.getServices(res," versioncontrol|git ")
        self.assertEquals(res['vcs_type'], "git")

        res['vcs_type']=None
        p.getServices(res,"test, test")
        self.assertEquals(res['vcs_type'], None)

        res['vcs_type']=None
        p.getServices(res,"")
        self.assertEquals(res['vcs_type'], None)

        p.getServices(res," versioncontrol|svn,versioncontrol|something")
        self.assertEquals(res['vcs_type'], "svn")

        res['vcs_type']=None
示例#56
0
    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)
示例#57
0
    def remove_project(self, req):
        """
        Handler for removing project

        :param Request req: Trac request

        Handler expects to have following arguments in it:

        - project: Name of the project env
        - goto: Optional URL where to go after project removal. Defaults to /home/myprojects

        """
        backurl = req.args.get('goto', ProjectListModule.home('myprojects'))
        short_name = req.args.get('project')
        if not short_name:
            return self.remove_failure(req)
        if req.args.get('cancel'):
            add_notice(req, 'Project deletion cancelled')
            return self.remove_failure(req)
        author = req.authname
        project = Project.get(env_name=short_name)

        if project is None:
            add_warning(req, 'Specified project does not exist!')
            return self.remove_failure(req)

        # Don't allow removing home
        if project.env_name == conf.sys_home_project_name:
            add_warning(req, 'Cannot remove home project')
            return self.remove_failure(req)
        if req.method != 'POST':
            return self.remove_failure(req, project=project)

        try:
            project.validate()
        except ProjectValidationException:
            req.redirect(backurl)

        # Check the permissions and method
        prjs = Projects()
        if ('TRAC_ADMIN' in req.perm or prjs.is_project_owner(
                project.env_name, author)) and req.method == 'POST':
            archive = ProjectArchive()
            # Archive the project before removal
            if not archive.archive(project):
                add_warning(
                    req,
                    'Could not archive project "%s". Will not remove the project'
                    % project.project_name)
            elif prjs.remove_project(project):
                # Notify listeners
                for listener in self.project_change_listeners:
                    listener.project_deleted(project)
                # Notify end user
                add_notice(req, 'Project "%s" removed' % project.project_name)
            else:
                add_warning(
                    req, 'Could not remove project "%s". Try again later' %
                    project.project_name)
        else:
            add_warning(
                req,
                'You are not allowed to remove project "%s" (check permissions and method)'
                % project.project_name)

        req.redirect(backurl)
示例#58
0
    def test_get_services(self):
        p = Projects()
        res = {}
        p.getServices(res, "test, dummy, Subversion, Perforce, test")
        self.assertEquals(res['vcs_type'], "perforce")

        p.getServices(res, "test, dummy, Subversion, test")
        self.assertEquals(res['vcs_type'], "svn")

        p.getServices(res, "another test, Versioncontrol|Mercurial, test")
        self.assertEquals(res['vcs_type'], "hg")

        p.getServices(res, " versioncontrol|git ")
        self.assertEquals(res['vcs_type'], "git")

        res['vcs_type'] = None
        p.getServices(res, "test, test")
        self.assertEquals(res['vcs_type'], None)

        res['vcs_type'] = None
        p.getServices(res, "")
        self.assertEquals(res['vcs_type'], None)

        p.getServices(res, " versioncontrol|svn,versioncontrol|something")
        self.assertEquals(res['vcs_type'], "svn")

        res['vcs_type'] = None
示例#59
0
 def test_project_environment_exists(self):
     dbStub.addResult([[1]])
     p = Projects()
     self.assertTrue(p.project_environment_exists("testi"))
     self.assertTrue(dbStub.closed)