Projekt

Obecné

Profil

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

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

    
11
namespace ServerApp.Parser.Parsers
12
{
13
    /// <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
    /// <author>A. Konig</author>
18
    public class JisParser
19
    {
20

    
21
        /// <summary> Datafile loader  </summary>
22
        IDataLoader loader;
23

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

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

    
47
            if (jisFiles == null || startTime == null || endTime == null || interval <= 0)
48
                return list;
49

    
50
            // parse all files
51
            foreach (string fileName in jisFiles)
52
            {
53
                if (!File.Exists(fileName))
54
                    continue;
55
                
56
                // parse as one instance per day
57
                List<ActivityInfo> loadedData = null;
58
                if (wholeDay)
59
                    loadedData = ProcessOneJisFileAsDays(fileName, startTime, endTime);
60
                // parse by interval length
61
                else
62
                    loadedData = ProcessOneJisFileAsIntervals(fileName, interval, startTime, endTime);
63

    
64
                list.AddRange(loadedData);
65
            }
66

    
67
            return list;
68
        }
69

    
70
        /// <summary>
71
        /// Parses data from one data file as one instance per day
72
        /// </summary>
73
        /// <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
        /// <returns>List with ActivityInfo instances</returns>
77
        private List<ActivityInfo> ProcessOneJisFileAsDays(string path, DateTime startTime, DateTime endTime)
78
        {
79
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
80
            
81
            List<JisInstance> list =  loader.LoadJisFile(path);
82
            if (list == null)
83
                return jisInfo;
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 lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
94
            for (int i = 0; i < list.Count; i++)
95
            {
96
                int currHour = list[i].dateTime.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].placeTag;
102
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
103
                if (!date.Equals(lastStartTime)) 
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], lastStartTime, range);
109
                        if (recordedAmount[k] != 0)
110
                            jisInfo.Add(dayInfo);
111
                    }
112

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

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

    
121
                // aggregate data
122
                if (TagInfo.jisPlaces.ContainsKey(place))
123
                {
124
                    int index = TagInfo.jisPlaces[place];
125
                    if (index == -1)
126
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
127
                            recordedAmount[l] += list[i].amount;
128
                    else
129
                        recordedAmount[index] += list[i].amount;
130

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

    
138
            }
139

    
140
            // last day
141
            for (int k = 0; k < TagInfo.buildings.Length; k++)
142
            {
143
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartTime, range);
144
                if (recordedAmount[k] != 0)
145
                    jisInfo.Add(dayInfo);
146
            }
147

    
148
            return jisInfo;
149
        }
150

    
151
        /// <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
        /// <param name="endTime">End time of related data</param>
157
        /// <param name="startTime">Start time of related data</param>
158
        /// <returns>List with ActivityInfo instances</returns>
159
        private List<ActivityInfo> ProcessOneJisFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
160
        {
161
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
162

    
163
            List<JisInstance> list = loader.LoadJisFile(path);
164
            if (list == null)
165
                return jisInfo;
166

    
167
            // data for each faculty
168
            int[] recordedAmount = new int[TagInfo.buildings.Length];
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
            for (int i = 0; i < to.Length; i++) 
179
                to[i] = minmaxHour[0] + interval * (i+1);
180

    
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
            int endtime = to[0];
184
            int startingTime = minmaxHour[0];
185
            int index = 0;
186
            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

    
197
                // end of the day
198
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
199
                {
200
                    trigger = true;
201
                    index = 0;
202
                }
203

    
204
                // end of interval period
205
                if ( date.Hour >= endtime || trigger) 
206
                {
207
                    // start time of last interval
208
                    DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
209

    
210
                    // TODO zjistit kolik se vynechalo a přidat tolik nul?
211

    
212
                    // find end and start time
213
                    if (!trigger)
214
                        index++;
215
                    while (date.Hour >= to[index])
216
                        index++;
217

    
218
                    endtime = to[index];
219
                    if (index == 0)
220
                        startingTime = minmaxHour[0];
221
                    else
222
                        startingTime = to[index - 1];
223

    
224
                    // data for each faculty separate
225
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
226
                    {
227
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], stTime, interval);
228
                        if (recordedAmount[k] != 0)
229
                            jisInfo.Add(dayInfo);
230
                    }
231

    
232
                    recordedAmount = new int[TagInfo.buildings.Length];
233
                    lastStartTime = date;
234
                }
235

    
236
                // if not in allowed time window -> discard
237
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
238
                    continue;
239

    
240
                // aggregate data
241
                if (TagInfo.jisPlaces.ContainsKey(place))
242
                {
243
                    int faculty = TagInfo.jisPlaces[place];
244
                    if (faculty == -1)
245
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
246
                            recordedAmount[l] += list[i].amount;
247
                    else
248
                        recordedAmount[faculty] += list[i].amount;
249

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

    
257
            }
258

    
259
            // last day
260
            DateTime startT = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
261
            for (int k = 0; k < TagInfo.buildings.Length; k++)
262
            {
263
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], startT, interval);
264
                if (recordedAmount[k] != 0)
265
                    jisInfo.Add(dayInfo);
266
            }
267

    
268
            return jisInfo;
269
        }
270
    }
271
}
(3-3/6)