Import and export timelines

remotes/origin/enhancement/email-actions
Alejandro Alonso 2015-04-10 11:14:16 +02:00 committed by David Barragán Merino
parent f3d1de684d
commit ce3d9aaf48
6 changed files with 77 additions and 2 deletions

View File

@ -65,6 +65,14 @@ def store_user_stories(project, data):
return results return results
def store_timeline_entries(project, data):
results = []
for timeline in data.get('timeline', []):
tl = service.store_timeline_entry(project, timeline)
results.append(tl)
return results
def store_issues(project, data): def store_issues(project, data):
issues = [] issues = []
for issue in data.get('issues', []): for issue in data.get('issues', []):
@ -167,4 +175,11 @@ def dict_to_project(data, owner=None):
store_tags_colors(proj, data) store_tags_colors(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing colors')
store_timeline_entries(proj, data)
if service.get_errors(clear=False):
raise TaigaImportError('error importing timelines')
return proj return proj

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64 import base64
import copy
import os import os
from collections import OrderedDict from collections import OrderedDict
@ -39,6 +40,8 @@ from taiga.projects.milestones import models as milestones_models
from taiga.projects.wiki import models as wiki_models from taiga.projects.wiki import models as wiki_models
from taiga.projects.history import models as history_models from taiga.projects.history import models as history_models
from taiga.projects.attachments import models as attachments_models from taiga.projects.attachments import models as attachments_models
from taiga.timeline import models as timeline_models
from taiga.timeline import service as timeline_service
from taiga.users import models as users_models from taiga.users import models as users_models
from taiga.projects.votes import services as votes_service from taiga.projects.votes import services as votes_service
from taiga.projects.history import services as history_service from taiga.projects.history import services as history_service
@ -548,6 +551,39 @@ class WikiLinkExportSerializer(serializers.ModelSerializer):
exclude = ('id', 'project') exclude = ('id', 'project')
class TimelineDataField(serializers.WritableField):
read_only = False
def to_native(self, data):
new_data = copy.deepcopy(data)
try:
user = users_models.User.objects.get(pk=new_data["user"]["id"])
new_data["user"]["email"] = user.email
del new_data["user"]["id"]
except users_models.User.DoesNotExist:
pass
return new_data
def from_native(self, data):
new_data = copy.deepcopy(data)
try:
user = users_models.User.objects.get(email=new_data["user"]["email"])
new_data["user"]["id"] = user.id
del new_data["user"]["email"]
except users_models.User.DoesNotExist:
pass
return new_data
class TimelineExportSerializer(serializers.ModelSerializer):
data = TimelineDataField()
class Meta:
model = timeline_models.Timeline
exclude = ('id', 'project', 'namespace', 'object_id')
class ProjectExportSerializer(serializers.ModelSerializer): class ProjectExportSerializer(serializers.ModelSerializer):
owner = UserRelatedField(required=False) owner = UserRelatedField(required=False)
default_points = serializers.SlugRelatedField(slug_field="name", required=False) default_points = serializers.SlugRelatedField(slug_field="name", required=False)
@ -579,7 +615,12 @@ class ProjectExportSerializer(serializers.ModelSerializer):
anon_permissions = PgArrayField(required=False) anon_permissions = PgArrayField(required=False)
public_permissions = PgArrayField(required=False) public_permissions = PgArrayField(required=False)
modified_date = serializers.DateTimeField(required=False) modified_date = serializers.DateTimeField(required=False)
timeline = serializers.SerializerMethodField("get_timeline")
class Meta: class Meta:
model = projects_models.Project model = projects_models.Project
exclude = ('id', 'creation_template', 'members') exclude = ('id', 'creation_template', 'members')
def get_timeline(self, obj):
timeline_qs = timeline_service.get_project_timeline(obj)
return TimelineExportSerializer(timeline_qs, many=True).data

View File

@ -23,6 +23,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from taiga.projects.history.services import make_key_from_model_object from taiga.projects.history.services import make_key_from_model_object
from taiga.timeline.service import build_project_namespace
from taiga.projects.references import sequences as seq from taiga.projects.references import sequences as seq
from taiga.projects.references import models as refs from taiga.projects.references import models as refs
from taiga.projects.services import find_invited_user from taiga.projects.services import find_invited_user
@ -275,6 +276,19 @@ def store_attachment(project, obj, attachment):
return serialized return serialized
def store_timeline_entry(project, timeline):
serialized = serializers.TimelineExportSerializer(data=timeline, context={"project": project})
if serialized.is_valid():
serialized.object.project = project
serialized.object.namespace = build_project_namespace(project)
serialized.object.object_id = project.id
serialized.object._importing = True
serialized.save()
return serialized
add_errors("timeline", serialized.errors)
return serialized
def store_history(project, obj, history): def store_history(project, obj, history):
serialized = serializers.HistoryExportSerializer(data=history, context={"project": project}) serialized = serializers.HistoryExportSerializer(data=history, context={"project": project})
if serialized.is_valid(): if serialized.is_valid():

View File

@ -76,6 +76,8 @@ class HistoryEntry(models.Model):
# snapshot. The rest are partial snapshot. # snapshot. The rest are partial snapshot.
is_snapshot = models.BooleanField(default=False) is_snapshot = models.BooleanField(default=False)
_importing = None
@cached_property @cached_property
def is_change(self): def is_change(self):
return self.type == HistoryType.change return self.type == HistoryType.change

View File

@ -29,8 +29,8 @@ class Timeline(models.Model):
content_type = models.ForeignKey(ContentType, related_name="content_type_timelines") content_type = models.ForeignKey(ContentType, related_name="content_type_timelines")
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id') content_object = GenericForeignKey('content_type', 'object_id')
namespace = models.SlugField(default="default") namespace = models.CharField(max_length=250, default="default", db_index=True)
event_type = models.SlugField() event_type = models.CharField(max_length=250, db_index=True)
project = models.ForeignKey(Project) project = models.ForeignKey(Project)
data = JsonField() data = JsonField()
data_content_type = models.ForeignKey(ContentType, related_name="data_timelines") data_content_type = models.ForeignKey(ContentType, related_name="data_timelines")

View File

@ -71,6 +71,9 @@ def _push_to_timelines(project, user, obj, event_type, extra_data={}):
def on_new_history_entry(sender, instance, created, **kwargs): def on_new_history_entry(sender, instance, created, **kwargs):
if instance._importing:
return
if instance.is_hidden: if instance.is_hidden:
return None return None