Projekt

Obecné

Profil

Stáhnout (10.9 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 || interval <= 0)
48
                return list;
49

    
50
            string current = "";
51
            try
52
            {
53
                // parse all files
54
                foreach (string fileName in jisFiles)
55
                {
56
                    current = fileName;
57

    
58
                    if (!File.Exists(fileName))
59
                        continue;
60

    
61
                    // parse as one instance per day
62
                    List<ActivityInfo> loadedData = null;
63
                    if (wholeDay)
64
                        loadedData = ProcessOneJisFileAsDays(fileName, startTime, endTime);
65
                    // parse by interval length
66
                    else
67
                        loadedData = ProcessOneJisFileAsIntervals(fileName, interval, startTime, endTime);
68

    
69
                    list.AddRange(loadedData);
70
                }
71
            }
72
            catch
73
            {
74
                Console.WriteLine("Incorrect jis input file " + current);
75
            }
76

    
77
            return list;
78
        }
79

    
80
        /// <summary>
81
        /// Parses data from one data file as one instance per day
82
        /// </summary>
83
        /// <param name="path">Path to file</param>
84
        /// <param name="endTime">End time of related data</param>
85
        /// <param name="startTime">Start time of related data</param>
86
        /// <returns>List with ActivityInfo instances</returns>
87
        private List<ActivityInfo> ProcessOneJisFileAsDays(string path, DateTime startTime, DateTime endTime)
88
        {
89
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
90
            
91
            List<JisInstance> list =  loader.LoadJisFile(path);
92
            if (list == null || list.Count == 0)
93
                return jisInfo;
94

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

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

    
110
                // start of the day -> make an instance
111
                string place = list[i].placeTag;
112
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
113
                if (!date.Equals(lastStartTime)) 
114
                {
115
                    // data for each faculty separate
116
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
117
                    {
118
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartTime, range);
119
                        if (recordedAmount[k] != 0)
120
                            jisInfo.Add(dayInfo);
121
                    }
122

    
123
                    recordedAmount = new int[TagInfo.buildings.Length];
124
                    lastStartTime = date;
125
                }
126

    
127
                // if not in allowed time window -> discard
128
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
129
                    continue;
130

    
131
                // aggregate data
132
                if (TagInfo.jisPlaces.ContainsKey(place))
133
                {
134
                    int index = TagInfo.jisPlaces[place];
135
                    if (index == -1)
136
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
137
                            recordedAmount[l] += list[i].amount;
138
                    else
139
                        recordedAmount[index] += list[i].amount;
140

    
141
                }
142
                else
143
                {
144
                    // TODO uknown code handling -> to file?
145
                    // Console.WriteLine("Unknown code " + list[i].placeTag);
146
                }
147

    
148
            }
149

    
150
            // last day
151
            for (int k = 0; k < TagInfo.buildings.Length; k++)
152
            {
153
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartTime, range);
154
                if (recordedAmount[k] != 0)
155
                    jisInfo.Add(dayInfo);
156
            }
157

    
158
            return jisInfo;
159
        }
160

    
161
        /// <summary>
162
        /// Parses data from one data file as instance per interval length in a day
163
        /// </summary>
164
        /// <param name="path">Path ti file</param>
165
        /// <param name="interval">Interval length</param>
166
        /// <param name="endTime">End time of related data</param>
167
        /// <param name="startTime">Start time of related data</param>
168
        /// <returns>List with ActivityInfo instances</returns>
169
        private List<ActivityInfo> ProcessOneJisFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
170
        {
171
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
172

    
173
            List<JisInstance> list = loader.LoadJisFile(path);
174
            if (list == null || list.Count == 0)
175
                return jisInfo;
176

    
177
            // data for each faculty
178
            int[] recordedAmount = new int[TagInfo.buildings.Length];
179
            // min/max hour taken into account
180
            int[] minmaxHour = new int[] { 7, 18 };
181
            int range = minmaxHour[1] - minmaxHour[0];
182

    
183
            if (interval > range)
184
                return null;
185

    
186
            int indices = (int) Math.Ceiling(range / (double)interval);
187
            int[] to = new int[indices];
188
            for (int i = 0; i < to.Length; i++) 
189
                to[i] = minmaxHour[0] + interval * (i+1);
190

    
191
            // first day
192
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
193
            int endtime = to[0];
194
            int startingTime = minmaxHour[0];
195
            int index = 0;
196
            for (int i = 0; i < list.Count; i++)
197
            {
198
                int currHour = list[i].dateTime.Hour;
199
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
200
                    continue;
201

    
202
                // start of the day -> make an instance
203
                string place = list[i].placeTag;
204
                bool trigger = false;
205
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, list[i].dateTime.Hour, 0, 0);
206

    
207
                // end of the day
208
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
209
                {
210
                    trigger = true;
211
                    index = 0;
212
                }
213

    
214
                // end of interval period
215
                if ( date.Hour >= endtime || trigger) 
216
                {
217
                    // start time of last interval
218
                    DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
219

    
220
                    // TODO zjistit kolik se vynechalo a přidat tolik nul?
221

    
222
                    // find end and start time
223
                    if (!trigger)
224
                        index++;
225
                    while (date.Hour >= to[index])
226
                        index++;
227

    
228
                    endtime = to[index];
229
                    if (index == 0)
230
                        startingTime = minmaxHour[0];
231
                    else
232
                        startingTime = to[index - 1];
233

    
234
                    // data for each faculty separate
235
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
236
                    {
237
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], stTime, interval);
238
                        if (recordedAmount[k] != 0)
239
                            jisInfo.Add(dayInfo);
240
                    }
241

    
242
                    recordedAmount = new int[TagInfo.buildings.Length];
243
                    lastStartTime = date;
244
                }
245

    
246
                // if not in allowed time window -> discard
247
                if (list[i].dateTime < startTime || list[i].dateTime > endTime)
248
                    continue;
249

    
250
                // aggregate data
251
                if (TagInfo.jisPlaces.ContainsKey(place))
252
                {
253
                    int faculty = TagInfo.jisPlaces[place];
254
                    if (faculty == -1)
255
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
256
                            recordedAmount[l] += list[i].amount;
257
                    else
258
                        recordedAmount[faculty] += list[i].amount;
259

    
260
                }
261
                else
262
                {
263
                    // TODO uknown code handling -> to file?
264
                    // Console.WriteLine("Unknown code " + list[i].placeTag);
265
                }
266

    
267
            }
268

    
269
            // last day
270
            DateTime startT = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startingTime, 0, 0);
271
            for (int k = 0; k < TagInfo.buildings.Length; k++)
272
            {
273
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], startT, interval);
274
                if (recordedAmount[k] != 0)
275
                    jisInfo.Add(dayInfo);
276
            }
277

    
278
            return jisInfo;
279
        }
280
    }
281
}
(3-3/6)