def create_project_with_attrs()

in Allura/allura/lib/project_create_helpers.py [0:0]


def create_project_with_attrs(p, nbhd, update=False, ensure_tools=False):
    # type: (object, M.Neighborhood, bool, bool) -> Union[M.Project|bool]
    M.session.artifact_orm_session._get().skip_mod_date = True
    shortname = p.shortname
    project = M.Project.query.get(shortname=shortname,
                                  neighborhood_id=nbhd._id)
    project_template = nbhd.get_project_template()

    if project and not update:
        log.warning('Skipping existing project "%s"' % (shortname))
        return False

    if not project:
        creating = True
        project = nbhd.register_project(shortname,
                                        p.admin,
                                        project_name=p.name,
                                        private_project=p.private,
                                        omit_event=True,  # because we'll fire it later after setting other fields
                                        )
    else:
        creating = False
        log.info('Updating project "%s".' % (shortname))

    project.notifications_disabled = True

    if ensure_tools and 'tools' in project_template:
        for i, tool in enumerate(project_template['tools'].keys()):
            tool_config = project_template['tools'][tool]
            if project.app_instance(tool_config['mount_point']):
                continue
            tool_options = tool_config.get('options', {})
            for k, v in list(tool_options.items()):
                if isinstance(v, str):
                    tool_options[k] = string.Template(v).safe_substitute(
                        project.root_project.__dict__.get('root_project', {}))
            project.install_app(tool,
                                mount_label=tool_config['label'],
                                mount_point=tool_config['mount_point'],
                                **tool_options)

    project.summary = p.summary
    project.short_description = p.description
    project.external_homepage = p.external_homepage
    project.video_url = p.video_url
    project.last_updated = datetime.datetime.utcnow()
    # These properties may have been populated by nbhd template defaults in
    # register_project(). Overwrite if we have data, otherwise keep defaults.
    project.labels = p.labels or project.labels
    project.trove_root_database = trove_ids(project.trove_root_database, p.trove_root_databases)
    project.trove_developmentstatus = trove_ids(project.trove_developmentstatus, p.trove_developmentstatuses)
    project.trove_audience = trove_ids(project.trove_audience, p.trove_audiences)
    project.trove_license = trove_ids(project.trove_license, p.trove_licenses)
    project.trove_os = trove_ids(project.trove_os, p.trove_oses)
    project.trove_language = trove_ids(project.trove_language, p.trove_languages)
    project.trove_topic = trove_ids(project.trove_topic, p.trove_topics)
    project.trove_natlanguage = trove_ids(project.trove_natlanguage, p.trove_natlanguages)
    project.trove_environment = trove_ids(project.trove_environment, p.trove_environments)

    project.tool_data.update(p.tool_data)

    for a in p.awards:
        M.AwardGrant(app_config_id=bson.ObjectId(),
                     award_id=a._id,
                     granted_to_project_id=project._id,
                     granted_by_neighborhood_id=nbhd._id)

    if p.icon_url:
        req = requests.get(p.icon_url, timeout=30)
        req.raise_for_status()
        project.save_icon(urlparse(p.icon_url).path,
                          BytesIO(req.content),
                          content_type=req.headers.get('Content-Type'))
    elif getattr(p, 'icon', None):
        with open(p.icon, 'rb') as icon_file:
            project.save_icon(p.icon, icon_file)

    project.notifications_disabled = False
    with h.push_config(c, project=project, user=p.admin):
        ThreadLocalODMSession.flush_all()
        if creating:
            g.post_event('project_created')
        else:
            g.post_event('project_updated')
    return project