Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 830652de

Přidáno uživatelem Vojtěch Bartička před asi 2 roky(ů)

Export in BE

  1. Conflicts:
  2. Backend/Core/Services/AnnotationService/AnnotationServiceEF.cs
  3. Backend/Core/Services/AnnotationService/IAnnotationService.cs

Zobrazit rozdíly:

Backend/Backend/Controllers/DocumentController.cs
208 208
            throw new BadRequestException(e.Message);
209 209
        }
210 210
    }
211

  
212
    [HttpPost("/documents/export")]
213
    [Authorize(Models.Enums.ERole.ADMINISTRATOR)]
214
    [ProducesResponseType((int)HttpStatusCode.OK)]
215
    [ProducesResponseType((int)HttpStatusCode.Forbidden)]
216
    public ActionResult<ExportResponse> ExportDocuments([FromServices] ClientInfo clientInfo, [FromBody] ExportRequest request)
217
    {
218
        if (clientInfo.LoggedUser == null)
219
        {
220
            logger.Warning("ClientInfo has null LoggerUser in [Authorized] controller");
221
            return Problem();
222
        }
223

  
224
        try
225
        {
226
            var outputStream = annotationService.Export(request);
227

  
228
            var cd = new System.Net.Mime.ContentDisposition()
229
            {
230
                FileName = "export.zip",
231
                Inline = false,
232
            };
233

  
234
            Response.Headers.Add("Content-Disposition", cd.ToString());
235
            return File(outputStream, "application/zip");
236
        }
237
        catch (InvalidOperationException e)
238
        {
239
            throw new BadRequestException(e.Message);
240
        }
241
    }
211 242
}
212 243

  
Backend/Core/Services/AnnotationService/AnnotationServiceEF.cs
16 16
using System.Text.RegularExpressions;
17 17
using Newtonsoft.Json;
18 18
using Core.GraphUtils;
19
using Models.Documents;
19 20

  
20 21
namespace Core.Services.AnnotationService
21 22
{
......
775 776

  
776 777
            return true;
777 778
        }
778

  
779
        
779 780
        public void SetTagIsFinal(Guid annotationId, Guid occurenceId, bool isFinal)
780 781
        {
781 782
            Annotation annotation;
......
802 803

  
803 804
            context.SaveChanges();
804 805
        }
806

  
807
        public MemoryStream Export(ExportRequest request)
808
        {
809
            if (request.ExportAllDone && request.DocumentIds == null)
810
            {
811
                throw new InvalidOperationException("No documents specified");
812
            }
813

  
814
            // Get documents
815
            IEnumerable<Document> documentsToExport = null;
816
            if (request.ExportAllDone)
817
            {
818
                documentsToExport = context.Documents
819
                    .Include(d => d.Content);
820
            }
821
            else
822
            {
823
                documentsToExport = context.Documents
824
                    .Include(d => d.Content)
825
                    .Where(d => request.DocumentIds.Contains(d.Id));
826
            }
827

  
828
            // Get annotations
829
            Dictionary<Document, List<Annotation>> annotationsToExport = new();
830
            foreach (var document in documentsToExport)
831
            {
832
                annotationsToExport[document] = context.Annotations
833
                    .Where(a => a.Document == document && a.State == EState.DONE)
834
                    .Include(a => a.Document)
835
                    .Include(a => a.User)
836
                    .ToList();
837
            }
838

  
839
            // Get final annotations
840
            Dictionary<Document, FinalAnnotation> finalAnnotationsToExport = new();
841
            foreach (var document in documentsToExport)
842
            {
843
                if (!context.FinalAnnotations.Any(fa => fa.Document == document))
844
                {
845
                    finalAnnotationsToExport[document] = null;
846
                }
847
                else
848
                {
849
                    finalAnnotationsToExport[document] = context.FinalAnnotations
850
                        .Single(fa => fa.Document == document);
851
                }
852
            }
853

  
854
            // Get tags for each annotation
855
            Dictionary<Annotation, List<AnnotationTag>> tagsToExport = new();
856
            foreach (var document in annotationsToExport.Keys)
857
            {
858
                foreach (var annotation in annotationsToExport[document])
859
                {
860
                    tagsToExport[annotation] = context.AnnotationTags
861
                        .Include(at => at.Annotation)
862
                        .Include(at => at.Tag).ThenInclude(t => t.Category)
863
                        .Include(at => at.SubTag)
864
                        .Where(at => at.Annotation == annotation)
865
                        .ToList();
866
                }
867
            }
868

  
869
            // Get tags for each final annotation
870
            Dictionary<FinalAnnotation, List<FinalAnnotationTag>> finalTagsToExport = new();
871
            foreach (var document in finalAnnotationsToExport.Keys)
872
            {
873
                var finalAnnotation = finalAnnotationsToExport[document];
874
                finalTagsToExport[finalAnnotation] = context.FinalAnnotationTags
875
                    .Include(at => at.Annotation)
876
                    .Include(at => at.Tag).ThenInclude(t => t.Category)
877
                    .Include(at => at.SubTag)
878
                    .Where(at => at.Annotation == finalAnnotation)
879
                    .ToList();
880
            }
881

  
882
            MemoryStream output = ZipUtils.Export.FullExport(documentsToExport.ToList(), annotationsToExport, finalAnnotationsToExport, tagsToExport, finalTagsToExport);
883
            return output;
884
        }
805 885
    }
806 886
}
Backend/Core/Services/AnnotationService/IAnnotationService.cs
1 1
using Models.Annotations;
2
using Models.Documents;
2 3
using Models.Enums;
3 4
using System;
4 5
using System.Collections.Generic;
......
19 20
        public void SetTagInstanceSentiment(Guid annotationId, Guid instanceId, Guid userId, ERole userRole, ETagSentiment sentiment, bool isFinal);
20 21
        public void MarkAnnotationAsDone(Guid annotationId, Guid userId, ERole userRole, bool done, bool isFinal);
21 22
        public Guid CreateFinalAnnotation(Guid documentId, Guid userId);
23
        public MemoryStream Export(ExportRequest request);
22 24
        public void SetTagIsFinal(Guid annotationId, Guid occurenceId, bool isFinal);
23 25
    }
24 26
}
Backend/Core/ZipUtils/Export.cs
1
using Core.Entities;
2
using Models.Enums;
3
using Newtonsoft.Json;
4
using System;
5
using System.Collections.Generic;
6
using System.IO.Compression;
7
using System.Linq;
8
using System.Text;
9
using System.Threading.Tasks;
10

  
11
namespace Core.ZipUtils
12
{
13
    public class Export
14
    {
15
        public static MemoryStream FullExport(List<Document> documents, Dictionary<Document, List<Annotation>> documentAnnotations, Dictionary<Document, FinalAnnotation> documentFinalAnnotations,
16
            Dictionary<Annotation, List<AnnotationTag>> annotationTags, Dictionary<FinalAnnotation, List<FinalAnnotationTag>> finalAnnotationTags)
17
        {
18
            MemoryStream ms = new MemoryStream();
19
            var archive = new ZipArchive(ms);
20

  
21
            for (int docIndex = 0; docIndex < documents.Count; docIndex++)
22
            {
23
                var document = documents[docIndex];
24
                string documentDir = $"{docIndex:00000}";
25

  
26
                // Write document content and name into a JSON file
27
                string documentInfoJson = DumpDocument(document);
28
                CreateFile(documentDir + "/document.json", documentInfoJson, archive);
29

  
30
                // Deal with annotations
31
                var annotations = documentAnnotations[document];
32
                for (int annotationIndex = 0; annotationIndex < annotations.Count; annotationIndex++)
33
                {
34
                    var annotation = annotations[annotationIndex];
35
                    var tags = annotationTags[annotation].Select(at => at as AnnotationTagGeneric).ToList();
36
                    string annotationInfoJson = DumpAnnotation(annotation, tags, document.Id);
37
                    CreateFile(documentDir + $"/annotation_{annotationIndex:00000}.json", annotationInfoJson, archive);
38
                }
39

  
40
                var finalAnnotation = documentFinalAnnotations[document];
41
                var finalTags = finalAnnotationTags[finalAnnotation].Select(ft => ft as AnnotationTagGeneric).ToList();
42
                string finalAnnotationInfoJson = DumpAnnotation(finalAnnotation, finalTags, document.Id);
43
                CreateFile(documentDir + "/final.json", finalAnnotationInfoJson, archive);
44
            }
45

  
46
            archive.Dispose();
47
            ms.Position = 0;
48

  
49
            return ms;
50
        }
51

  
52
        private static void CreateFile(string path, string fileContent, ZipArchive archive)
53
        {
54
            var entry = archive.CreateEntry(path);
55
            var entryStream = entry.Open();
56
            entryStream.Write(Encoding.UTF8.GetBytes(fileContent));
57
            entryStream.Close();
58
        }
59

  
60
        private static string DumpDocument(Document document)
61
        {
62
            ExportDocumentInfo documentInfo = new();
63
            documentInfo.Name = document.Name;
64
            documentInfo.Content = document.Content.Content;
65
            documentInfo.DocumentId = document.Id;
66

  
67
            return JsonConvert.SerializeObject(documentInfo);
68
        }
69

  
70
        private static string DumpAnnotation(Annotation annotation, List<AnnotationTagGeneric> tags, Guid documentId)
71
        {
72
            ExportAnnotationInfo annotationInfo = new();
73
            annotationInfo.AnnotatorId = annotation.User.Id;
74
            annotationInfo.DocumentId = documentId;
75

  
76
            foreach (var tag in tags)
77
            {
78
                ExportTagInstanceInfo tagInfo = new()
79
                {
80

  
81
                    Category = tag.Tag.Category.Name,
82
                    TagName = tag.Tag.Name,
83
                    InstanceId = tag.Instance,
84
                    FirstCharPosition = tag.Position,
85
                    Length = tag.Length,
86
                };
87

  
88
                if (tag.Tag.SentimentEnabled && tagInfo.Sentiment != null)
89
                {
90
                    tagInfo.Sentiment = tag.Sentiment.ToString().ToLower();
91
                }
92

  
93
                if (tag.SubTag != null)
94
                {
95
                    tagInfo.SubTagName = tag.SubTag.Name;
96
                }
97

  
98
                annotationInfo.Tags.Add(tagInfo);
99
            }
100

  
101
            return JsonConvert.SerializeObject(annotationInfo);
102
        }
103
    }
104

  
105
    public class ExportDocumentInfo
106
    {
107
        public string Name { get; set; }
108
        public string Content { get; set; }
109
        public Guid DocumentId { get; set; }
110
    }
111

  
112
    public class ExportAnnotationInfo
113
    {
114
        public Guid AnnotatorId { get; set; }
115
        public Guid DocumentId { get; set; }
116
        public List<ExportTagInstanceInfo> Tags { get; set; } = new();
117
    }
118

  
119
    public class ExportTagInstanceInfo
120
    {
121
        public string Category { get; set; }
122
        public string TagName { get; set; }
123
        public string? SubTagName { get; set; }
124
        public Guid InstanceId { get; set; }
125
        public int FirstCharPosition { get; set; }
126
        public int Length { get; set; }
127
        public string? Sentiment { get; set; }
128
    }
129
}
Backend/Models/Documents/ExportRequest.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6

  
7
namespace Models.Documents
8
{
9
    public class ExportRequest
10
    {
11
        public List<Guid>? DocumentIds { get; set; }
12
        public bool ExportAllDone { get; set; }
13
    }
14
}
Backend/Models/Documents/ExportResponse.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6

  
7
namespace Models.Documents
8
{
9
    public class ExportResponse
10
    {
11

  
12
    }
13
}

Také k dispozici: Unified diff