Projekt

Obecné

Profil

Stáhnout (11.4 KB) Statistiky
| Větev: | Tag: | Revize:
1
//
2
// Author: A. Konig
3
//
4

    
5
using log4net;
6
using ServerApp.Parser.InputData;
7
using ServerApp.Parser.OutputInfo;
8
using System;
9
using System.Collections.Generic;
10
using System.IO;
11

    
12
namespace ServerApp.Parser.Parsers
13
{
14
    /// <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
    /// <author>A. Konig</author>
19
    public class LogInParser
20
    {
21
        /// <summary> Logger </summary>
22
        private static readonly ILog _log = LogManager.GetLogger(typeof(LogInParser));
23

    
24
        /// <summary> Datafile loader  </summary>
25
        IDataLoader loader;
26

    
27
        /// <summary>
28
        /// Constructor
29
        /// </summary>
30
        /// <param name="loader">Datafile loader</param>
31
        public LogInParser(IDataLoader loader)
32
        {
33
            this.loader = loader;
34
        }
35

    
36
        /// <summary>
37
        /// Parses login data to ActivityInfo instances
38
        /// Data parsed from 7am (included) to 18pm (included)
39
        /// </summary>
40
        /// <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
        /// <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
        public List<ActivityInfo> ParseLogInData(List<string> loginFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
47
        {
48
            List<ActivityInfo> list = new List<ActivityInfo>();
49

    
50
            if (loginFiles == null || interval <= 0)
51
                return list;
52

    
53
            string current = "";
54
            try
55
            {
56
                // for all files in folder
57
                foreach (string fileName in loginFiles)
58
                {
59
                    current = fileName;
60

    
61
                    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
                _log.Error("Incorrect Login input file " + current);
77
            }
78

    
79
            return list;
80
        }
81

    
82
        /// <summary>
83
        /// Parses data from one data file as one instance per day
84
        /// </summary>
85
        /// <param name="path">Path ti file</param>
86
        /// <param name="endTime">End time of related data</param>
87
        /// <param name="startTime">Start time of related data</param>
88
        /// <returns>List with ActivityInfo instances</returns>
89
        private List<ActivityInfo> ProcessOneLogInFileAsDays(string path, DateTime startTime, DateTime endTime)
90
        {
91
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
92

    
93
            List<LogInInstance> list = loader.LoadLoginFile(path);
94
            if (list == null || list.Count == 0)
95
                return loginInfo;
96

    
97
            // data for each faculty
98
            int[] recordedAmount = new int[TagInfo.buildings.Length];
99
            // min/max hour taken into account
100
            int[] minmaxHour = new int[] { 7, 18 };
101
            // interval length
102
            int range = minmaxHour[1] - minmaxHour[0];
103

    
104
            // first day
105
            DateTime lastStartDay = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
106
            for (int i = 0; i < list.Count; i++)
107
            {
108
                int currHour = list[i].lessonStart.Hour;
109
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
110
                    continue;
111

    
112
                // start of the day -> make an instance
113
                string place = list[i].building;
114
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, minmaxHour[0], 0, 0);
115
                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
                if (!date.Equals(lastStartDay))
117
                {
118
                    // data for each faculty separate
119
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
120
                    {
121
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range); 
122
                        if (recordedAmount[k] != 0)
123
                            loginInfo.Add(dayInfo);
124
                    }
125

    
126
                    recordedAmount = new int[TagInfo.buildings.Length];
127
                    lastStartDay = date;
128
                }
129

    
130
                // if not in allowed time window -> discard
131
                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
132
                    continue;
133

    
134
                // aggregate data
135
                if (TagInfo.buildingTags.ContainsKey(place))
136
                {
137
                    int index = TagInfo.buildingTags[place];
138

    
139
                    // to all
140
                    if (index == -1)
141
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
142
                            recordedAmount[l] += list[i].amount;
143
                    else
144
                        recordedAmount[index] += list[i].amount;
145

    
146
                }
147
                else
148
                {
149
                    _log.Warn("Unknown code " + list[i].building);
150
                }
151

    
152
            }
153

    
154
            // last day
155
            for (int k = 0; k < TagInfo.buildings.Length; k++)
156
            {
157
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range);
158
                if (recordedAmount[k] != 0)
159
                    loginInfo.Add(dayInfo);
160
            }
161

    
162
            return loginInfo;
163
        }
164

    
165
        /// <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
        /// <param name="endTime">End time of related data</param>
171
        /// <param name="startTime">Start time of related data</param>
172
        /// <returns>List with ActivityInfo instances</returns>
173
        private List<ActivityInfo> ProcessOneLoginFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
174
        {
175
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
176
            
177
            List<LogInInstance> list = loader.LoadLoginFile(path);
178
            if (list == null || list.Count == 0)
179
                return loginInfo;
180

    
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
                data[i] = new int[TagInfo.buildings.Length];
195
            }
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
                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

    
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
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
221
                        {
222
                            ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
223
                            if (data[k][l] != 0)
224
                                loginInfo.Add(dayInfo);
225
                        }
226

    
227
                        data[k] = new int[TagInfo.buildings.Length];
228
                    }
229
                    lastStartTime = date;
230
                }
231

    
232
                // if not in allowed time window -> discard
233
                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
234
                    continue;
235

    
236
                // 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
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
254
                            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
                    _log.Warn("Unknown code " + list[i].building);
268
                }
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
                for (int l = 0; l < TagInfo.buildings.Length; l++)
278
                {
279
                    ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
280
                    if (data[k][l] != 0)
281
                        loginInfo.Add(dayInfo);
282
                }
283
            }
284

    
285
            return loginInfo;
286
        }
287

    
288
    }
289
}
(4-4/6)