diff --git a/osmtm/__init__.py b/osmtm/__init__.py index 2b2edc8d..0fcbf03f 100644 --- a/osmtm/__init__.py +++ b/osmtm/__init__.py @@ -70,6 +70,7 @@ def main(global_config, **settings): config.add_route('project_new_grid', '/project/new/grid') config.add_route('project_new_arbitrary', '/project/new/arbitrary') config.add_route('project_grid_simulate', '/project/grid_simulate') + config.add_route('project_clone', '/project_clone') config.add_route('project_json', '/project/{project:\d+}.json') config.add_route('project', '/project/{project:\d+}') config.add_route('project_edit', '/project/{project:\d+}/edit') diff --git a/osmtm/static/js/project.new.js b/osmtm/static/js/project.new.js index 51433897..937d5f79 100644 --- a/osmtm/static/js/project.new.js +++ b/osmtm/static/js/project.new.js @@ -263,7 +263,7 @@ osmtm.project_new = (function() { }); }); - $('#gridform, #arbitraryform').submit(function() { + $('#gridform, #arbitraryform, #cloneform').submit(function() { window.setTimeout(function() { $('input[type=submit]').attr('disabled', 'disabled'); $('.loading').removeClass('hidden'); diff --git a/osmtm/templates/project.new.mako b/osmtm/templates/project.new.mako index ff1c50e4..cf3524d9 100644 --- a/osmtm/templates/project.new.mako +++ b/osmtm/templates/project.new.mako @@ -76,6 +76,46 @@

+

+ ${_('or')} +

+

+<% + link = '%s' % (_('Clone'),) + text = _('${clone_link} an already existing project.', mapping={'clone_link': link}) +%> + ${text|n} +

+ + diff --git a/osmtm/views/project.py b/osmtm/views/project.py index abb40dce..4dcfe0bc 100644 --- a/osmtm/views/project.py +++ b/osmtm/views/project.py @@ -45,6 +45,10 @@ Feature, ) +from json import ( + loads as _loads, +) + import datetime import itertools @@ -226,6 +230,67 @@ def project_grid_simulate(request): return FeatureCollection([Feature(geometry=shape.to_shape(geometry))]) +@view_config(route_name='project_clone', permission="project_edit") +def project_clone(request): + _ = request.translate + user_id = authenticated_userid(request) + user = DBSession.query(User).get(user_id) + + try: + id = request.params['project'] + old_project = DBSession.query(Project).get(id) + new_project = Project(old_project.name, user=user) + + for att in old_project.__dict__: + if (att[0] != '_' and att not in ['area_id', 'author_id', + 'created', 'done', 'id', + 'invalidated', 'last_update', + 'priority_areas', 'status', + 'tasks', 'validated']): + setattr(new_project, att, getattr(old_project, att)) + + if new_project.zoom is not None: + new_project.auto_fill(new_project.zoom) + else: + tasks = [] + for task in old_project.tasks: + tasks.append(Task(None, None, None, 'SRID=4326;%S' % + task.geometry, _loads(task.extra_properties))) + new_project.tasks = tasks + + if old_project.priority_areas: + new_project.priority_areas = [] + for feature in old_project.priority_areas: + new_project.priority_areas.append( + PriorityArea(feature.geometry)) + + for locale, translation in old_project.translations.iteritems(): + with old_project.force_locale(locale) and \ + new_project.force_locale(locale): + for field in ['name', 'short_description', 'description', + 'instructions', 'per_task_instructions']: + if hasattr(old_project, field): + setattr(new_project, field, + getattr(translation, field)) + + DBSession.add(new_project) + DBSession.flush() + + msg = _("""Project #${new_project_id} cloned successfully from Project + #${old_project_id}""", mapping={'new_project_id': + new_project.id, + 'old_project_id': id}) + request.session.flash(msg, 'alert') + + return HTTPFound(location=route_path('project_edit', request, + project=new_project.id)) + + except Exception, e: + msg = _("Sorry, could not create the project.
%s") % e.message + request.session.flash(msg, 'alert') + return HTTPFound(location=route_path('project_new', request)) + + @view_config(route_name='project_edit', renderer='project.edit.mako', permission="project_edit") def project_edit(request):