Projekt

Obecné

Profil

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