Projekt

Obecné

Profil

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

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

    
11
namespace ServerApp.Parser.Parsers
12
{
13
    /// <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
    /// <author>A. Konig</author>
18
    class LogInParser
19
    {
20
        /// <summary> Datafile loader  </summary>
21
        IDataLoader loader;
22

    
23
        /// <summary>
24
        /// Constructor
25
        /// </summary>
26
        /// <param name="loader">Datafile loader</param>
27
        public LogInParser(IDataLoader loader)
28
        {
29
            this.loader = loader;
30
        }
31

    
32
        /// <summary>
33
        /// Parses login data to ActivityInfo instances
34
        /// Data parsed from 7am (included) to 18pm (included)
35
        /// </summary>
36
        /// <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
        /// <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
        public List<ActivityInfo> ParseLogInData(List<string> loginFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
43
        {
44
            List<ActivityInfo> list = new List<ActivityInfo>();
45

    
46
            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
            {
52
                if (!File.Exists(fileName))
53
                    continue;
54
                
55
                // parse as one instance per day
56
                List<ActivityInfo> loadedData = null;
57
                if (wholeDay)
58
                    loadedData = ProcessOneLogInFileAsDays(fileName, startTime, endTime);
59
                // parse by interval length
60
                else
61
                    loadedData = ProcessOneLoginFileAsIntervals(fileName, interval, startTime, endTime);
62

    
63
                list.AddRange(loadedData);
64
            }
65

    
66
            return list;
67
        }
68

    
69
        /// <summary>
70
        /// Parses data from one data file as one instance per day
71
        /// </summary>
72
        /// <param name="path">Path ti file</param>
73
        /// <param name="endTime">End time of related data</param>
74
        /// <param name="startTime">Start time of related data</param>
75
        /// <returns>List with ActivityInfo instances</returns>
76
        private List<ActivityInfo> ProcessOneLogInFileAsDays(string path, DateTime startTime, DateTime endTime)
77
        {
78
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
79

    
80
            if (!File.Exists(path))
81
                return loginInfo;
82

    
83
            List<LogInInstance> list = loader.LoadLoginFile(path);
84

    
85
            // data for each faculty
86
            int[] recordedAmount = new int[TagInfo.buildings.Length];
87
            // min/max hour taken into account
88
            int[] minmaxHour = new int[] { 7, 18 };
89
            // interval length
90
            int range = minmaxHour[1] - minmaxHour[0];
91

    
92
            // first day
93
            DateTime lastStartDay = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
94
            for (int i = 0; i < list.Count; i++)
95
            {
96
                int currHour = list[i].lessonStart.Hour;
97
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
98
                    continue;
99

    
100
                // start of the day -> make an instance
101
                string place = list[i].building;
102
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, minmaxHour[0], 0, 0);
103
                if (!date.Equals(lastStartDay))
104
                {
105
                    // data for each faculty separate
106
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
107
                    {
108
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range); 
109
                        loginInfo.Add(dayInfo);
110
                    }
111

    
112
                    recordedAmount = new int[TagInfo.buildings.Length];
113
                    lastStartDay = date;
114
                }
115

    
116
                // if not in allowed time window -> discard
117
                if (list[i].date < startTime || list[i].date > endTime)
118
                    continue;
119

    
120
                // aggregate data
121
                if (TagInfo.buildingTags.ContainsKey(place))
122
                {
123
                    int index = TagInfo.buildingTags[place];
124
                    //Console.WriteLine(place + " " + index);
125

    
126
                    // to all
127
                    if (index == -1)
128
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
129
                            recordedAmount[l] += list[i].amount;
130
                    else
131
                        recordedAmount[index] += list[i].amount;
132

    
133
                }
134
                else
135
                {
136
                    // TODO uknown code handling -> to file?
137
                    // Console.WriteLine("Unknown code " + list[i].building);
138
                }
139

    
140
            }
141

    
142
            // last day
143
            for (int k = 0; k < TagInfo.buildings.Length; k++)
144
            {
145
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range);
146
                loginInfo.Add(dayInfo);
147
            }
148

    
149
            return loginInfo;
150
        }
151

    
152
        /// <summary>
153
        /// Parses data from one data file as one instance per interval length
154
        /// </summary>
155
        /// <param name="path">Path to file</param>
156
        /// <param name="interval">Interval length</param>
157
        /// <param name="endTime">End time of related data</param>
158
        /// <param name="startTime">Start time of related data</param>
159
        /// <returns>List with ActivityInfo instances</returns>
160
        private List<ActivityInfo> ProcessOneLoginFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
161
        {
162
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
163
            
164
            if (!File.Exists(path))
165
                return loginInfo;
166

    
167
            List<LogInInstance> list = loader.LoadLoginFile(path);
168

    
169
            // min/max hour taken into account
170
            int[] minmaxHour = new int[] { 7, 18 };
171
            int range = minmaxHour[1] - minmaxHour[0];
172

    
173
            if (interval > range)
174
                return null;
175

    
176
            int indices = (int)Math.Ceiling(range / (double)interval);
177
            int[] to = new int[indices];
178
            int[][] data = new int[indices][];
179
            for (int i = 0; i < to.Length; i++)
180
            {
181
                to[i] = minmaxHour[0] + interval * (i + 1);
182
                data[i] = new int[TagInfo.buildings.Length];
183
            }
184
            
185
            // first day
186
            DateTime lastStartTime = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
187
            int index = 0;
188
            for (int i = 0; i < list.Count; i++)
189
            {
190
                int currHour = list[i].lessonStart.Hour;
191
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
192
                    continue;
193

    
194
                // start of the day -> make an instance
195
                string place = list[i].building;
196
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, 0, 0);
197

    
198
                // end of the day
199
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
200
                {
201
                    // note down all aggregated data
202
                    for (int k = 0; k < to.Length; k++)
203
                    {
204
                        DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
205

    
206
                        // data for each faculty separate
207
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
208
                        {
209
                            ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
210
                            loginInfo.Add(dayInfo);
211
                        }
212

    
213
                        data[k] = new int[TagInfo.buildings.Length];
214
                    }
215
                    lastStartTime = date;
216
                }
217

    
218
                // if not in allowed time window -> discard
219
                if (list[i].date < startTime || list[i].date > endTime)
220
                    continue;
221

    
222
                // find index for current instance
223
                index = 0;
224
                for (int k = 1; k < to.Length; k++)
225
                {
226
                    if (to[k] > list[i].lessonStart.Hour && to[k - 1] <= list[i].lessonStart.Hour)
227
                    {
228
                        index = k;
229
                        break;
230
                    }
231
                }
232

    
233
                // aggregate data
234
                if (TagInfo.buildingTags.ContainsKey(place))
235
                {
236
                    int faculty = TagInfo.buildingTags[place];
237
                    // to all
238
                    if (faculty == -1)
239
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
240
                            data[index][l] += list[i].amount;
241
                    // to first two
242
                    else if (faculty == -2)
243
                    {
244
                        data[index][0] += list[i].amount;
245
                        data[index][1] += list[i].amount;
246
                    }
247
                    else
248
                        data[index][faculty] += list[i].amount;
249

    
250
                }
251
                else
252
                {
253
                    // TODO uknown code handling -> write to file?
254
                    // Console.WriteLine("Unknown code " + list[i].building);
255
                }
256

    
257
            }
258

    
259
            for (int k = 0; k < to.Length; k++)
260
            {
261
                DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
262

    
263
                // data for each faculty separate
264
                for (int l = 0; l < TagInfo.buildings.Length; l++)
265
                {
266
                    ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
267
                    loginInfo.Add(dayInfo);
268
                }
269
            }
270

    
271
            return loginInfo;
272
        }
273

    
274
    }
275
}
(4-4/6)