Projekt

Obecné

Profil

Stáhnout (5.54 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

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

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

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

    
43
            foreach (var documentInfo in request.Documents)
44
            {
45
                if (documentInfo.Format == Models.Enums.EAddDocumentFormat.PLAINTEXT)
46
                {
47
                    SaveDocument(documentInfo.Content, user, documentInfo.Name);
48
                }
49
                else if (documentInfo.Format == Models.Enums.EAddDocumentFormat.BASE64)
50
                {
51
                    var (names, contents) = UnzipDocuments(documentInfo.Content);
52
                    for (int i = 0; i < names.Count; i++)
53
                    {
54
                        SaveDocument(contents[i], user, names[i]);
55
                    }
56
                }
57
            }
58
        }
59

    
60
        /// <summary>
61
        /// 
62
        /// </summary>
63
        /// <param name="base64encoded"></param>
64
        /// <returns></returns>
65
        private (List<string> Names, List<string> Contents) UnzipDocuments(string base64encoded)
66
        {
67
            List<string> names = new();
68
            List<string> contents = new();
69

    
70
            byte[] decoded = Convert.FromBase64String(base64encoded);
71

    
72
            using (var zipStream = new MemoryStream(decoded))
73
            using (var zipArchive = new ZipArchive(zipStream))
74
            {
75
                foreach (var entry in zipArchive.Entries)
76
                {
77
                    names.Add(entry.Name);
78
                    using (var streamReader = new StreamReader(entry.Open()))
79
                    {
80
                        string text = streamReader.ReadToEnd();
81
                        contents.Add(text);
82
                    }
83
                }
84
            }
85

    
86
            return (names, contents);
87
        }
88

    
89
        private void SaveDocument(string content, User userAdded, string documentName)
90
        {
91
            DocumentContent documentContent = new DocumentContent()
92
            {
93
                Content = content
94
            };
95

    
96
            Document document = new Document()
97
            {
98
                DateAdded = DateTime.Now,
99
                Content = documentContent,
100
                UserAdded = userAdded,
101
                Name = documentName,
102
                Length = documentContent.Content.Length,
103
                RequiredAnnotations = 3                     // TODO this is only for beta testing purposes
104
            };
105

    
106
            databaseContext.DocumentContents.Add(documentContent);
107
            databaseContext.Documents.Add(document);
108
            databaseContext.SaveChanges();                  // Maybe do this after all the documents are added
109
        }
110

    
111
        public DocumentListResponse GetDocuments(DocumentListRequest request)
112
        {
113
            var firstIndex = request.PageIndex * request.PageSize;
114
            var documents = databaseContext.Documents.Select(d => d).ToList();
115
            var totalCount = documents.Count;
116
            var pageCount = totalCount / request.PageSize;
117
            if (pageCount == 0 && totalCount > 0)
118
            {
119
                pageCount = 1;
120
            }
121

    
122
            if (firstIndex > documents.Count - 1)
123
            {
124
                throw new Exception("Page index or page size too large");
125
            }
126

    
127
            if (firstIndex + request.PageSize > documents.Count - 1)
128
            {
129
                request.PageSize = documents.Count - firstIndex;
130
            }
131

    
132
            List<DocumentListInfo> documentInfos = new List<DocumentListInfo>();
133
            foreach (var document in documents.GetRange(firstIndex, request.PageSize))
134
            {
135
                var annotatingUsers = databaseContext.Annotations.Where(a => a.Document == document).Select(a => a.User).ToList();
136
                List<UserInfo> annotatingUsersDto = annotatingUsers.Select(a => mapper.Map<UserInfo>(a)).ToList();
137

    
138
                DocumentListInfo dai = mapper.Map<DocumentListInfo>(document);
139
                dai.AnnotatingUsers = annotatingUsersDto;
140
                documentInfos.Add(dai);
141
            }
142

    
143
            return new DocumentListResponse()
144
            {
145
                PageCount = pageCount,
146
                PageIndex = request.PageIndex,
147
                TotalCount = totalCount,
148
                Documents = documentInfos
149
            };
150
        }
151

    
152
    }
153
}
(1-1/2)