Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 8ca80c9a

Přidáno uživatelem Vojtěch Bartička před téměř 3 roky(ů)

  • ID 8ca80c9a66e28fc1caecfea278568d514e98bcb2
  • Rodič a49028dd

Export in BE

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
{
......
154 155
            }
155 156

  
156 157
            var docToRender = "";
157
            HTMLService.CachedInfo cachedInfoToReturn = new(); 
158
            HTMLService.CachedInfo cachedInfoToReturn = new();
158 159
            if (annotation.CachedDocumentHTML == "")
159 160
            {
160 161
                var result = htmlService.FullPreprocessHTML(documentContent.Content, tags);
......
181 182
                    TagClosingLengths = JsonConvert.DeserializeObject<List<int>>(annotation.CachedClosingLengths),
182 183
                    TagInstanceCSS = JsonConvert.DeserializeObject<List<TagInstanceCSSInfo>>(annotation.CachedCSS)
183 184
                };
184
                
185

  
185 186
                // The annotation has been modified and we need to either add the new tag or remove the tag
186 187
                if (annotation.ModifiedType != EModified.NONE)
187 188
                {
......
608 609

  
609 610
            return true;
610 611
        }
612

  
613
        public MemoryStream Export(ExportRequest request)
614
        {
615
            if (request.ExportAllDone && request.DocumentIds == null)
616
            {
617
                throw new InvalidOperationException("No documents specified");
618
            }
619

  
620
            // Get documents
621
            IEnumerable<Document> documentsToExport = null;
622
            if (request.ExportAllDone)
623
            {
624
                documentsToExport = context.Documents
625
                    .Include(d => d.Content);
626
            }
627
            else
628
            {
629
                documentsToExport = context.Documents
630
                    .Include(d => d.Content)
631
                    .Where(d => request.DocumentIds.Contains(d.Id));
632
            }
633

  
634
            // Get annotations
635
            Dictionary<Document, List<Annotation>> annotationsToExport = new();
636
            foreach (var document in documentsToExport)
637
            {
638
                annotationsToExport[document] = context.Annotations
639
                    .Where(a => a.Document == document && a.State == EState.DONE)
640
                    .Include(a => a.Document)
641
                    .Include(a => a.User)
642
                    .ToList();
643
            }
644

  
645
            // Get final annotations
646
            Dictionary<Document, FinalAnnotation> finalAnnotationsToExport = new();
647
            foreach (var document in documentsToExport)
648
            {
649
                if (!context.FinalAnnotations.Any(fa => fa.Document == document))
650
                {
651
                    finalAnnotationsToExport[document] = null;
652
                }
653
                else
654
                {
655
                    finalAnnotationsToExport[document] = context.FinalAnnotations
656
                        .Single(fa => fa.Document == document);
657
                }
658
            }
659

  
660
            // Get tags for each annotation
661
            Dictionary<Annotation, List<AnnotationTag>> tagsToExport = new();
662
            foreach (var document in annotationsToExport.Keys)
663
            {
664
                foreach (var annotation in annotationsToExport[document])
665
                {
666
                    tagsToExport[annotation] = context.AnnotationTags
667
                        .Include(at => at.Annotation)
668
                        .Include(at => at.Tag).ThenInclude(t => t.Category)
669
                        .Include(at => at.SubTag)
670
                        .Where(at => at.Annotation == annotation)
671
                        .ToList();
672
                }
673
            }
674

  
675
            // Get tags for each final annotation
676
            Dictionary<FinalAnnotation, List<FinalAnnotationTag>> finalTagsToExport = new();
677
            foreach (var document in finalAnnotationsToExport.Keys)
678
            {
679
                var finalAnnotation = finalAnnotationsToExport[document];
680
                finalTagsToExport[finalAnnotation] = context.FinalAnnotationTags
681
                    .Include(at => at.Annotation)
682
                    .Include(at => at.Tag).ThenInclude(t => t.Category)
683
                    .Include(at => at.SubTag)
684
                    .Where(at => at.Annotation == finalAnnotation)
685
                    .ToList();
686
            }
687

  
688
            MemoryStream output = ZipUtils.Export.FullExport(documentsToExport.ToList(), annotationsToExport, finalAnnotationsToExport, tagsToExport, finalTagsToExport);
689
            return output;
690
        }
611 691
    }
612 692
}
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);
20 21
        public void MarkAnnotationAsDone(Guid annotationId, Guid userId, ERole userRole, bool done);
21 22
        public Guid CreateFinalAnnotation(Guid documentId, Guid userId);
23
        public MemoryStream Export(ExportRequest request);
22 24
    }
23 25
}
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