Projekt

Obecné

Profil

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