Projekt

Obecné

Profil

Stáhnout (11.4 KB) Statistiky
| Větev: | Tag: | Revize:
1 cdf3c217 A-Konig
//
2
// Author: A. Konig
3
//
4
5 f9dd116f A-Konig
using log4net;
6 cdf3c217 A-Konig
using ServerApp.Parser.InputData;
7 734533a8 A-Konig
using ServerApp.Parser.OutputInfo;
8 0da0ac88 A-Konig
using System;
9 5d9a5bd9 A-Konig
using System.Collections.Generic;
10 0da0ac88 A-Konig
using System.IO;
11 5d9a5bd9 A-Konig
12 734533a8 A-Konig
namespace ServerApp.Parser.Parsers
13 5d9a5bd9 A-Konig
{
14 734533a8 A-Konig
    /// <summary>
15
    /// Class parsing login files into instances of ActivityInfo divided by given time interval
16
    /// Data parsed from 7am (included) to 18pm (included)
17
    /// </summary>
18 cdf3c217 A-Konig
    /// <author>A. Konig</author>
19 4b847de5 A-Konig
    public class LogInParser
20 5d9a5bd9 A-Konig
    {
21 f9dd116f A-Konig
        /// <summary> Logger </summary>
22
        private static readonly ILog _log = LogManager.GetLogger(typeof(LogInParser));
23
24 98b568bc A-Konig
        /// <summary> Datafile loader  </summary>
25 cdf3c217 A-Konig
        IDataLoader loader;
26 98b568bc A-Konig
27
        /// <summary>
28
        /// Constructor
29
        /// </summary>
30
        /// <param name="loader">Datafile loader</param>
31 cdf3c217 A-Konig
        public LogInParser(IDataLoader loader)
32 98b568bc A-Konig
        {
33
            this.loader = loader;
34
        }
35
36 734533a8 A-Konig
        /// <summary>
37
        /// Parses login data to ActivityInfo instances
38
        /// Data parsed from 7am (included) to 18pm (included)
39
        /// </summary>
40 cdf3c217 A-Konig
        /// <param name="loginFiles">Paths to files with login data files</param>
41
        /// <param name="endTime">End time of related data</param>
42
        /// <param name="startTime">Start time of related data</param>
43 734533a8 A-Konig
        /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
44
        /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
45
        /// <returns></returns>
46 cdf3c217 A-Konig
        public List<ActivityInfo> ParseLogInData(List<string> loginFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
47 0da0ac88 A-Konig
        {
48 734533a8 A-Konig
            List<ActivityInfo> list = new List<ActivityInfo>();
49 0da0ac88 A-Konig
50 23e8ae04 A-Konig
            if (loginFiles == null || interval <= 0)
51 cdf3c217 A-Konig
                return list;
52
53 23e8ae04 A-Konig
            string current = "";
54
            try
55 0da0ac88 A-Konig
            {
56 23e8ae04 A-Konig
                // for all files in folder
57
                foreach (string fileName in loginFiles)
58
                {
59
                    current = fileName;
60 0da0ac88 A-Konig
61 23e8ae04 A-Konig
                    if (!File.Exists(fileName))
62
                        continue;
63
64
                    // parse as one instance per day
65
                    List<ActivityInfo> loadedData = null;
66
                    if (wholeDay)
67
                        loadedData = ProcessOneLogInFileAsDays(fileName, startTime, endTime);
68
                    // parse by interval length
69
                    else
70
                        loadedData = ProcessOneLoginFileAsIntervals(fileName, interval, startTime, endTime);
71
72
                    list.AddRange(loadedData);
73
                }
74
            } catch
75
            {
76 f9dd116f A-Konig
                _log.Error("Incorrect Login input file " + current);
77 0da0ac88 A-Konig
            }
78
79
            return list;
80
        }
81
82 734533a8 A-Konig
        /// <summary>
83
        /// Parses data from one data file as one instance per day
84
        /// </summary>
85
        /// <param name="path">Path ti file</param>
86 cdf3c217 A-Konig
        /// <param name="endTime">End time of related data</param>
87
        /// <param name="startTime">Start time of related data</param>
88 734533a8 A-Konig
        /// <returns>List with ActivityInfo instances</returns>
89 cdf3c217 A-Konig
        private List<ActivityInfo> ProcessOneLogInFileAsDays(string path, DateTime startTime, DateTime endTime)
90 0da0ac88 A-Konig
        {
91 cdf3c217 A-Konig
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
92
93 98b568bc A-Konig
            List<LogInInstance> list = loader.LoadLoginFile(path);
94 3729dcae A-Konig
            if (list == null || list.Count == 0)
95 a53b1de8 A-Konig
                return loginInfo;
96 0da0ac88 A-Konig
97 734533a8 A-Konig
            // data for each faculty
98 d39750f3 A-Konig
            int[] recordedAmount = new int[TagInfo.buildings.Length];
99 734533a8 A-Konig
            // min/max hour taken into account
100 0da0ac88 A-Konig
            int[] minmaxHour = new int[] { 7, 18 };
101 734533a8 A-Konig
            // interval length
102 0da0ac88 A-Konig
            int range = minmaxHour[1] - minmaxHour[0];
103
104 734533a8 A-Konig
            // first day
105
            DateTime lastStartDay = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
106 0da0ac88 A-Konig
            for (int i = 0; i < list.Count; i++)
107
            {
108 93452c41 A-Konig
                int currHour = list[i].lessonStart.Hour;
109 0da0ac88 A-Konig
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
110
                    continue;
111
112 734533a8 A-Konig
                // start of the day -> make an instance
113 0da0ac88 A-Konig
                string place = list[i].building;
114 734533a8 A-Konig
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, minmaxHour[0], 0, 0);
115 4b847de5 A-Konig
                DateTime dateOfLessonStart = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, list[i].lessonStart.Minute, list[i].lessonStart.Second);
116 0da0ac88 A-Konig
                if (!date.Equals(lastStartDay))
117
                {
118 734533a8 A-Konig
                    // data for each faculty separate
119 d39750f3 A-Konig
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
120 0da0ac88 A-Konig
                    {
121 d39750f3 A-Konig
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range); 
122 4b847de5 A-Konig
                        if (recordedAmount[k] != 0)
123
                            loginInfo.Add(dayInfo);
124 0da0ac88 A-Konig
                    }
125
126 d39750f3 A-Konig
                    recordedAmount = new int[TagInfo.buildings.Length];
127 0da0ac88 A-Konig
                    lastStartDay = date;
128
                }
129
130 cdf3c217 A-Konig
                // if not in allowed time window -> discard
131 4b847de5 A-Konig
                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
132 cdf3c217 A-Konig
                    continue;
133
134 734533a8 A-Konig
                // aggregate data
135 0da0ac88 A-Konig
                if (TagInfo.buildingTags.ContainsKey(place))
136
                {
137
                    int index = TagInfo.buildingTags[place];
138 d39750f3 A-Konig
139 734533a8 A-Konig
                    // to all
140 0da0ac88 A-Konig
                    if (index == -1)
141 d39750f3 A-Konig
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
142 0da0ac88 A-Konig
                            recordedAmount[l] += list[i].amount;
143
                    else
144
                        recordedAmount[index] += list[i].amount;
145
146
                }
147
                else
148
                {
149 f9dd116f A-Konig
                    _log.Warn("Unknown code " + list[i].building);
150 0da0ac88 A-Konig
                }
151
152
            }
153
154 734533a8 A-Konig
            // last day
155 d39750f3 A-Konig
            for (int k = 0; k < TagInfo.buildings.Length; k++)
156 0da0ac88 A-Konig
            {
157 d39750f3 A-Konig
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range);
158 4b847de5 A-Konig
                if (recordedAmount[k] != 0)
159
                    loginInfo.Add(dayInfo);
160 0da0ac88 A-Konig
            }
161
162
            return loginInfo;
163
        }
164
165 98b568bc A-Konig
        /// <summary>
166
        /// Parses data from one data file as one instance per interval length
167
        /// </summary>
168
        /// <param name="path">Path to file</param>
169
        /// <param name="interval">Interval length</param>
170 cdf3c217 A-Konig
        /// <param name="endTime">End time of related data</param>
171
        /// <param name="startTime">Start time of related data</param>
172 98b568bc A-Konig
        /// <returns>List with ActivityInfo instances</returns>
173 cdf3c217 A-Konig
        private List<ActivityInfo> ProcessOneLoginFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
174 0da0ac88 A-Konig
        {
175 cdf3c217 A-Konig
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
176
            
177 98b568bc A-Konig
            List<LogInInstance> list = loader.LoadLoginFile(path);
178 3729dcae A-Konig
            if (list == null || list.Count == 0)
179 a53b1de8 A-Konig
                return loginInfo;
180 54fb2bde A-Konig
181
            // min/max hour taken into account
182
            int[] minmaxHour = new int[] { 7, 18 };
183
            int range = minmaxHour[1] - minmaxHour[0];
184
185
            if (interval > range)
186
                return null;
187
188
            int indices = (int)Math.Ceiling(range / (double)interval);
189
            int[] to = new int[indices];
190
            int[][] data = new int[indices][];
191
            for (int i = 0; i < to.Length; i++)
192
            {
193
                to[i] = minmaxHour[0] + interval * (i + 1);
194 d39750f3 A-Konig
                data[i] = new int[TagInfo.buildings.Length];
195 54fb2bde A-Konig
            }
196
            
197
            // first day
198
            DateTime lastStartTime = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
199
            int index = 0;
200
            for (int i = 0; i < list.Count; i++)
201
            {
202
                int currHour = list[i].lessonStart.Hour;
203
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
204
                    continue;
205
206
                // start of the day -> make an instance
207
                string place = list[i].building;
208
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, 0, 0);
209 4b847de5 A-Konig
                DateTime dateOfLessonStart = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, list[i].lessonStart.Minute, list[i].lessonStart.Second);
210 54fb2bde A-Konig
211
                // end of the day
212
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
213
                {
214
                    // note down all aggregated data
215
                    for (int k = 0; k < to.Length; k++)
216
                    {
217
                        DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
218
219
                        // data for each faculty separate
220 d39750f3 A-Konig
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
221 54fb2bde A-Konig
                        {
222 d39750f3 A-Konig
                            ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
223 4b847de5 A-Konig
                            if (data[k][l] != 0)
224
                                loginInfo.Add(dayInfo);
225 54fb2bde A-Konig
                        }
226
227 d39750f3 A-Konig
                        data[k] = new int[TagInfo.buildings.Length];
228 54fb2bde A-Konig
                    }
229
                    lastStartTime = date;
230
                }
231
232 cdf3c217 A-Konig
                // if not in allowed time window -> discard
233 4b847de5 A-Konig
                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
234 cdf3c217 A-Konig
                    continue;
235
236 54fb2bde A-Konig
                // find index for current instance
237
                index = 0;
238
                for (int k = 1; k < to.Length; k++)
239
                {
240
                    if (to[k] > list[i].lessonStart.Hour && to[k - 1] <= list[i].lessonStart.Hour)
241
                    {
242
                        index = k;
243
                        break;
244
                    }
245
                }
246
247
                // aggregate data
248
                if (TagInfo.buildingTags.ContainsKey(place))
249
                {
250
                    int faculty = TagInfo.buildingTags[place];
251
                    // to all
252
                    if (faculty == -1)
253 d39750f3 A-Konig
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
254 54fb2bde A-Konig
                            data[index][l] += list[i].amount;
255
                    // to first two
256
                    else if (faculty == -2)
257
                    {
258
                        data[index][0] += list[i].amount;
259
                        data[index][1] += list[i].amount;
260
                    }
261
                    else
262
                        data[index][faculty] += list[i].amount;
263
264
                }
265
                else
266
                {
267 f9dd116f A-Konig
                    _log.Warn("Unknown code " + list[i].building);
268 54fb2bde A-Konig
                }
269
270
            }
271
272
            for (int k = 0; k < to.Length; k++)
273
            {
274
                DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
275
276
                // data for each faculty separate
277 d39750f3 A-Konig
                for (int l = 0; l < TagInfo.buildings.Length; l++)
278 54fb2bde A-Konig
                {
279 d39750f3 A-Konig
                    ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
280 4b847de5 A-Konig
                    if (data[k][l] != 0)
281
                        loginInfo.Add(dayInfo);
282 54fb2bde A-Konig
                }
283
            }
284
285 cdf3c217 A-Konig
            return loginInfo;
286 0da0ac88 A-Konig
        }
287
288 5d9a5bd9 A-Konig
    }
289 54fb2bde A-Konig
}