Projekt

Obecné

Profil

Stáhnout (6.29 KB) Statistiky
| Větev: | Tag: | Revize:
1
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
using AutoMapper;
13
using Models.Users;
14
using Ganss.XSS;
15

    
16
namespace Core.Services.DocumentService
17
{
18
    public class DocumentServiceEF : IDocumentService
19
    {
20
        private readonly DatabaseContext databaseContext;
21
        private readonly ILogger logger;
22
        private readonly IMapper mapper;
23

    
24
        public DocumentServiceEF(DatabaseContext databaseContext, ILogger logger, IMapper mapper)
25
        {
26
            this.databaseContext = databaseContext;
27
            this.logger = logger;
28
            this.mapper = mapper;
29
        }
30

    
31
        /// <summary>
32
        /// Adds the documents in request to the database
33
        /// </summary>
34
        /// <param name="request">request</param>
35
        /// <param name="userId">GUID of the user</param>
36
        /// <exception cref="InvalidOperationException">No User with passed GUID</exception>
37
        /// <exception cref="FormatException">Error decoding BASE64 content</exception>
38
        /// <exception cref="InvalidDataException">Zip file has wrong format</exception>
39
        /// <exception cref="IOException">Error reading entries from the zip file</exception>
40
        public void AddDocuments(DocumentAddRequest request, Guid userId)
41
        {
42
            User user = databaseContext.Users.Single(u => u.Id == userId);
43

    
44
            var users = databaseContext.Users.Select(u => u).ToList();
45

    
46
            foreach (var documentInfo in request.Documents)
47
            {
48
                if (documentInfo.Format == Models.Enums.EAddDocumentFormat.TEXTFILE)
49
                {
50
                    // TODO hardcoded UTF-8 - maybe do something smarter
51
                    var documentContent = Encoding.UTF8.GetString(Convert.FromBase64String(documentInfo.Content));
52
                    SaveDocument(documentContent, user, documentInfo.Name, users);
53
                }
54
                else if (documentInfo.Format == Models.Enums.EAddDocumentFormat.ZIP)
55
                {
56
                    var (names, contents) = UnzipDocuments(documentInfo.Content);
57
                    for (int i = 0; i < names.Count; i++)
58
                    {
59
                        SaveDocument(contents[i], user, names[i], users);
60
                    }
61
                }
62
            }
63
        }
64

    
65
        /// <summary>
66
        /// 
67
        /// </summary>
68
        /// <param name="base64encoded"></param>
69
        /// <returns></returns>
70
        private (List<string> Names, List<string> Contents) UnzipDocuments(string base64encoded)
71
        {
72
            List<string> names = new();
73
            List<string> contents = new();
74

    
75
            byte[] decoded = Convert.FromBase64String(base64encoded);
76

    
77
            using (var zipStream = new MemoryStream(decoded))
78
            using (var zipArchive = new ZipArchive(zipStream))
79
            {
80
                foreach (var entry in zipArchive.Entries)
81
                {
82
                    names.Add(entry.Name);
83
                    using (var streamReader = new StreamReader(entry.Open()))
84
                    {
85
                        string text = streamReader.ReadToEnd();
86
                        contents.Add(text);
87
                    }
88
                }
89
            }
90

    
91
            return (names, contents);
92
        }
93

    
94
        private void SaveDocument(string content, User userAdded, string documentName, List<User> users)
95
        {
96
            DocumentContent documentContent = new DocumentContent()
97
            {
98
                Content = content
99
            };
100

    
101
            Document document = new Document()
102
            {
103
                DateAdded = DateTime.Now,
104
                Content = documentContent,
105
                UserAdded = userAdded,
106
                Name = documentName,
107
                Length = documentContent.Content.Length,
108
                RequiredAnnotations = 3                     // TODO this is only for testing purposes
109
            };
110

    
111
            /*foreach (var user in users)
112
            {
113
                Annotation annotation = new Annotation()
114
                {
115
                    User = user,
116
                    UserAssigned = userAdded,
117
                    State = Models.Enums.EState.NEW,
118
                    DateAssigned = DateTime.Now,
119
                    DateLastChanged = DateTime.Now,
120
                    Document = document,
121
                    Note = ""
122
                };
123
                databaseContext.Annotations.Add(annotation);
124
            }*/
125

    
126
            databaseContext.DocumentContents.Add(documentContent);
127
            databaseContext.Documents.Add(document);
128
            databaseContext.SaveChanges();                  // Maybe do this after all the documents are added
129
        }
130

    
131
        public DocumentListResponse GetDocuments(int pageIndex, int pageSize)
132
        {
133
            var firstIndex = pageIndex * pageSize;
134
            var documents = databaseContext.Documents.Select(d => d).ToList();
135
            var totalCount = documents.Count;
136
            var pageCount = totalCount / pageSize;
137
            if (pageCount == 0 && totalCount > 0)
138
            {
139
                pageCount = 1;
140
            }
141

    
142
            if (firstIndex > documents.Count - 1)
143
            {
144
                throw new Exception("Page index or page size too large");
145
            }
146

    
147
            if (firstIndex + pageSize > documents.Count - 1)
148
            {
149
                pageSize = documents.Count - firstIndex;
150
            }
151

    
152
            List<DocumentListInfo> documentInfos = new List<DocumentListInfo>();
153
            foreach (var document in documents.GetRange(firstIndex, pageSize))
154
            {
155
                var annotatingUsers = databaseContext.Annotations.Where(a => a.Document == document).Select(a => a.User).ToList();
156
                List<UserInfo> annotatingUsersDto = annotatingUsers.Select(a => mapper.Map<UserInfo>(a)).ToList();
157

    
158
                DocumentListInfo dai = mapper.Map<DocumentListInfo>(document);
159
                dai.AnnotatingUsers = annotatingUsersDto;
160
                documentInfos.Add(dai);
161
            }
162

    
163
            return new DocumentListResponse()
164
            {
165
                PageCount = pageCount,
166
                PageIndex = pageIndex,
167
                TotalCount = totalCount,
168
                Documents = documentInfos
169
            };
170
        }
171

    
172
    }
173
}
(1-1/2)