Projekt

Obecné

Profil

Stáhnout (7.15 KB) Statistiky
| Větev: | Tag: | Revize:
1 24e1c89d Vojtěch Bartička
using Core.Contexts;
2
using Core.Entities;
3
using Models.Documents;
4
using Serilog;
5
using System;
6
using System.Collections.Generic;
7
using System.IO.Compression;
8
using System.Linq;
9
using System.Text;
10
using System.Threading.Tasks;
11
using System.Web;
12 5a08541d Vojtěch Bartička
using AutoMapper;
13
using Models.Users;
14 3c185841 Vojtěch Bartička
using Ganss.XSS;
15 42bb0025 Vojtěch Bartička
using Microsoft.EntityFrameworkCore;
16 24e1c89d Vojtěch Bartička
17
namespace Core.Services.DocumentService
18
{
19
    public class DocumentServiceEF : IDocumentService
20
    {
21
        private readonly DatabaseContext databaseContext;
22
        private readonly ILogger logger;
23 5a08541d Vojtěch Bartička
        private readonly IMapper mapper;
24 24e1c89d Vojtěch Bartička
25 5a08541d Vojtěch Bartička
        public DocumentServiceEF(DatabaseContext databaseContext, ILogger logger, IMapper mapper)
26 24e1c89d Vojtěch Bartička
        {
27
            this.databaseContext = databaseContext;
28
            this.logger = logger;
29 5a08541d Vojtěch Bartička
            this.mapper = mapper;
30 24e1c89d Vojtěch Bartička
        }
31
32
        /// <summary>
33
        /// Adds the documents in request to the database
34
        /// </summary>
35
        /// <param name="request">request</param>
36
        /// <param name="userId">GUID of the user</param>
37
        /// <exception cref="InvalidOperationException">No User with passed GUID</exception>
38
        /// <exception cref="FormatException">Error decoding BASE64 content</exception>
39
        /// <exception cref="InvalidDataException">Zip file has wrong format</exception>
40
        /// <exception cref="IOException">Error reading entries from the zip file</exception>
41
        public void AddDocuments(DocumentAddRequest request, Guid userId)
42
        {
43
            User user = databaseContext.Users.Single(u => u.Id == userId);
44
45 005202c6 Vojtěch Bartička
            var users = databaseContext.Users.Select(u => u).ToList();
46
47 24e1c89d Vojtěch Bartička
            foreach (var documentInfo in request.Documents)
48
            {
49 52fe46f9 Vojtěch Bartička
                if (documentInfo.Format == Models.Enums.EAddDocumentFormat.TEXTFILE)
50 24e1c89d Vojtěch Bartička
                {
51 7b2e66d3 Vojtěch Bartička
                    // TODO hardcoded UTF-8 - maybe do something smarter
52
                    var documentContent = Encoding.UTF8.GetString(Convert.FromBase64String(documentInfo.Content));
53 005202c6 Vojtěch Bartička
                    SaveDocument(documentContent, user, documentInfo.Name, users);
54 24e1c89d Vojtěch Bartička
                }
55 7b2e66d3 Vojtěch Bartička
                else if (documentInfo.Format == Models.Enums.EAddDocumentFormat.ZIP)
56 24e1c89d Vojtěch Bartička
                {
57
                    var (names, contents) = UnzipDocuments(documentInfo.Content);
58
                    for (int i = 0; i < names.Count; i++)
59
                    {
60 005202c6 Vojtěch Bartička
                        SaveDocument(contents[i], user, names[i], users);
61 24e1c89d Vojtěch Bartička
                    }
62
                }
63
            }
64
        }
65
66
        /// <summary>
67
        /// 
68
        /// </summary>
69
        /// <param name="base64encoded"></param>
70
        /// <returns></returns>
71
        private (List<string> Names, List<string> Contents) UnzipDocuments(string base64encoded)
72
        {
73
            List<string> names = new();
74
            List<string> contents = new();
75
76
            byte[] decoded = Convert.FromBase64String(base64encoded);
77
78
            using (var zipStream = new MemoryStream(decoded))
79
            using (var zipArchive = new ZipArchive(zipStream))
80
            {
81
                foreach (var entry in zipArchive.Entries)
82
                {
83
                    names.Add(entry.Name);
84
                    using (var streamReader = new StreamReader(entry.Open()))
85
                    {
86
                        string text = streamReader.ReadToEnd();
87
                        contents.Add(text);
88
                    }
89
                }
90
            }
91
92
            return (names, contents);
93
        }
94
95 005202c6 Vojtěch Bartička
        private void SaveDocument(string content, User userAdded, string documentName, List<User> users)
96 24e1c89d Vojtěch Bartička
        {
97
            DocumentContent documentContent = new DocumentContent()
98
            {
99
                Content = content
100
            };
101
102
            Document document = new Document()
103
            {
104
                DateAdded = DateTime.Now,
105
                Content = documentContent,
106
                UserAdded = userAdded,
107
                Name = documentName,
108
                Length = documentContent.Content.Length,
109 005202c6 Vojtěch Bartička
                RequiredAnnotations = 3                     // TODO this is only for testing purposes
110 24e1c89d Vojtěch Bartička
            };
111
112 11b41a50 Vojtěch Bartička
            /*foreach (var user in users)
113 005202c6 Vojtěch Bartička
            {
114
                Annotation annotation = new Annotation()
115
                {
116
                    User = user,
117
                    UserAssigned = userAdded,
118
                    State = Models.Enums.EState.NEW,
119
                    DateAssigned = DateTime.Now,
120
                    DateLastChanged = DateTime.Now,
121
                    Document = document,
122
                    Note = ""
123
                };
124
                databaseContext.Annotations.Add(annotation);
125 11b41a50 Vojtěch Bartička
            }*/
126 005202c6 Vojtěch Bartička
127 24e1c89d Vojtěch Bartička
            databaseContext.DocumentContents.Add(documentContent);
128
            databaseContext.Documents.Add(document);
129
            databaseContext.SaveChanges();                  // Maybe do this after all the documents are added
130
        }
131
132 42c654f6 Vojtěch Bartička
        public DocumentListResponse GetDocuments(int pageIndex, int pageSize)
133 24e1c89d Vojtěch Bartička
        {
134 42c654f6 Vojtěch Bartička
            var firstIndex = pageIndex * pageSize;
135 24e1c89d Vojtěch Bartička
            var documents = databaseContext.Documents.Select(d => d).ToList();
136
            var totalCount = documents.Count;
137 42c654f6 Vojtěch Bartička
            var pageCount = totalCount / pageSize;
138 24e1c89d Vojtěch Bartička
            if (pageCount == 0 && totalCount > 0)
139
            {
140
                pageCount = 1;
141
            }
142
143 7bbe8f15 Vojtěch Bartička
            if (firstIndex > documents.Count - 1)
144
            {
145
                throw new Exception("Page index or page size too large");
146
            }
147
148 42c654f6 Vojtěch Bartička
            if (firstIndex + pageSize > documents.Count - 1)
149 7bbe8f15 Vojtěch Bartička
            {
150 42c654f6 Vojtěch Bartička
                pageSize = documents.Count - firstIndex;
151 7bbe8f15 Vojtěch Bartička
            }
152
153 24e1c89d Vojtěch Bartička
            List<DocumentListInfo> documentInfos = new List<DocumentListInfo>();
154 42c654f6 Vojtěch Bartička
            foreach (var document in documents.GetRange(firstIndex, pageSize))
155 24e1c89d Vojtěch Bartička
            {
156 5a08541d Vojtěch Bartička
                var annotatingUsers = databaseContext.Annotations.Where(a => a.Document == document).Select(a => a.User).ToList();
157
                List<UserInfo> annotatingUsersDto = annotatingUsers.Select(a => mapper.Map<UserInfo>(a)).ToList();
158
159
                DocumentListInfo dai = mapper.Map<DocumentListInfo>(document);
160
                dai.AnnotatingUsers = annotatingUsersDto;
161 7bbe8f15 Vojtěch Bartička
                documentInfos.Add(dai);
162 24e1c89d Vojtěch Bartička
            }
163
164
            return new DocumentListResponse()
165
            {
166
                PageCount = pageCount,
167 42c654f6 Vojtěch Bartička
                PageIndex = pageIndex,
168 24e1c89d Vojtěch Bartička
                TotalCount = totalCount,
169
                Documents = documentInfos
170
            };
171
        }
172
173 42bb0025 Vojtěch Bartička
        public DocumentPreviewResponse GetDocumentPreview(Guid documentId)
174
        {
175
            try
176
            {
177
                var document = databaseContext.Documents.Include(d => d.Content).Single(d => d.Id == documentId);
178
                HtmlSanitizer sanitizer = new HtmlSanitizer();
179 343aa66b Vojtěch Bartička
                sanitizer.AllowedAttributes.Clear();
180
                if (sanitizer.AllowedTags.Contains("img"))
181
                {
182
                    sanitizer.AllowedTags.Remove("img");
183
                }
184 42bb0025 Vojtěch Bartička
                return new DocumentPreviewResponse()
185
                {
186
                    Content = sanitizer.Sanitize(document.Content.Content)
187
                };
188
            }
189
            catch (InvalidOperationException e)
190
            {
191
                throw new InvalidOperationException("Document not found");
192
            }
193
        }
194 24e1c89d Vojtěch Bartička
    }
195
}