blob: fc09a78ab559576a469157339587fa994803c28c [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from __future__ import unicode_literals
from __future__ import absolute_import
import json
import logging
import sys
from io import open
from ming.orm import session
import colander
from allura import model as M
from allura.lib.project_create_helpers import create_project_with_attrs, make_newproject_schema, deserialize_project
log = logging.getLogger(__name__)
def main(options):
root_logger = logging.getLogger()
root_logger.addHandler(logging.StreamHandler(sys.stdout))
root_logger.setLevel(getattr(logging, options.log_level.upper()))
log.debug(options)
nbhd = M.Neighborhood.query.get(name=options.neighborhood)
if not nbhd:
return 'Invalid neighborhood "%s".' % options.neighborhood
data = json.load(open(options.file, 'r'))
projectSchema = make_newproject_schema(nbhd, options.update)
# allow 'icon' as a local filesystem path via this script only
projectSchema.add(colander.SchemaNode(colander.Str(), name='icon', missing=None))
projects = []
for datum in data:
try:
if options.update and not datum.get('shortname'):
log.warning('Shortname not provided with --update; this will create new projects instead of updating')
projects.append(deserialize_project(datum, projectSchema, nbhd))
except Exception:
keep_going = options.validate_only
log.error('Error on %s\n%s', datum['shortname'], datum, exc_info=keep_going)
if not keep_going:
raise
log.debug(projects)
if options.validate_only:
return
for p in projects:
log.info('Creating%s project "%s".' % ('/updating' if options.update else '', p.shortname))
try:
project = create_project_with_attrs(p, nbhd, update=options.update, ensure_tools=options.ensure_tools)
except Exception as e:
log.exception('%s' % (str(e)))
project = False
if not project:
log.warning('Stopping due to error.')
return 1
session(project).clear()
log.warning('Done.')
return 0
def parse_options():
import argparse
parser = argparse.ArgumentParser(
description='Import Allura project(s) from JSON file')
parser.add_argument('file', metavar='JSON_FILE', type=str,
help='Path to JSON file containing project data.')
parser.add_argument('neighborhood', metavar='NEIGHBORHOOD', type=str,
help='Neighborhood name like "Projects"')
parser.add_argument('--log', dest='log_level', default='INFO',
help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
parser.add_argument('--update', dest='update', default=False,
action='store_true',
help='Update existing projects. Without this option, existing '
'projects will be skipped.')
parser.add_argument('--ensure-tools', dest='ensure_tools', default=False,
action='store_true',
help='Check nbhd project template for default tools, and install '
'them on the project(s) if not already installed.')
parser.add_argument('--validate-only', '-v', action='store_true', dest='validate_only',
help='Validate ALL records, make no changes')
return parser.parse_args()
if __name__ == '__main__':
sys.exit(main(parse_options()))