/// <summary>
        /// get the featured timetable events
        /// </summary>
        /// <param name="contentItem"></param>
        /// <param name="multilistFieldID"></param>
        /// <returns></returns>
        private List <TimetableEvent> GetTimetableEvents(Item contentItem, ID multilistFieldID)
        {
            List <TimetableEvent> timetableEvents = null;

            //get the list of items selected in the multilist field
            IList <Item> featuredItems = SitecoreUtility.GetSelectedItemsInMultilistField(contentItem, multilistFieldID);

            //check for each item if it is of valid template and active.If yes, then add it to the list
            if (featuredItems != null && featuredItems.Count > 0)
            {
                timetableEvents = new List <TimetableEvent>();

                foreach (Item featuredItem in featuredItems)
                {
                    if (featuredItem.TemplateID == References.Templates.TimetableEvent.ID)
                    {
                        TimetableEvent timetableEventItem = new TimetableEvent(featuredItem);

                        if (timetableEventItem != null && timetableEventItem.IsActive)
                        {
                            timetableEventItem.Instructor = GetInstructor(timetableEventItem.SelectedInstructorItemID);
                            timetableEvents.Add(timetableEventItem);
                        }
                    }
                }
            }

            return(timetableEvents);
        }
Exemple #2
0
        public async Task <IActionResult> ImportTimetableData()
        {
            try
            {
                // Create a list to store the events from the CSV file.
                List <TimetableEventFromExtract> inputEvents;

                // Read extracted data from a CSV file.
                using (var reader = new StreamReader("E:/OneDrive - University of Lincoln/PROJECT/Dev/timetableExtract.csv"))
                {
                    using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
                    {
                        csvReader.Configuration.Delimiter = ";";
                        inputEvents = csvReader.GetRecords <TimetableEventFromExtract>().ToList();
                    }
                }

                // Get the allowed rooms to avoid creating events for rooms that don't exist.
                HashSet <string> possibleRooms = (await DissDatabaseContext.Nodes
                                                  .Where(node => node.Type == NodeType.Room)
                                                  .Select(node => node.NodeId)
                                                  .ToArrayAsync()).ToHashSet();

                // Create the output list.
                List <TimetableEvent> outputEvents = new List <TimetableEvent>(inputEvents.Count);

                // Convert each input to an output type.
                foreach (TimetableEventFromExtract input in inputEvents)
                {
                    TimetableEvent output = input.MapToTimetableEvent(possibleRooms);
                    if (output != default)
                    {
                        outputEvents.Add(output);
                    }
                }

                // Remove entire content of events table.
                DissDatabaseContext.TimetableEvents.RemoveRange(DissDatabaseContext.TimetableEvents);

                await DissDatabaseContext.SaveChangesAsync();

                // Insert the new data.
                DissDatabaseContext.TimetableEvents.AddRange(outputEvents);

                await DissDatabaseContext.SaveChangesAsync();

                return(Created("", ""));
            }
            catch (Exception e)
            {
                return(StatusCode(500, e.Message));
            }
        }
        public TimetableEvent MapToTimetableEvent(HashSet <string> possibleRooms)
        {
            TimetableEvent output = new TimetableEvent
            {
                EventDate = EventDate,
                StartTime = StartTime,
                EndTime   = EndTime,
                StudentId = StudentId
            };

            // Ignore any extra rooms, use the first one.
            string[] rooms = LocationId.Split(",");

            int indexOfFirstDigit = rooms[0].IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });

            if (indexOfFirstDigit < 0)
            {
                return(default);
Exemple #4
0
 public Task HandleTimetableEvent(TimetableEvent @event, IOutput outputSettings)
 {
     return(HandleTimetableEvent(@event, CastSettings(outputSettings)));
 }
Exemple #5
0
 protected abstract Task HandleTimetableEvent(TimetableEvent @event, T outputSettings);
 private void HandleTimetableEvent(TimetableEvent obj)
 {
     Handle("timetable", (handler, settings) => handler.HandleTimetableEvent(obj, settings));
 }
Exemple #7
0
        public static void SaveEventToFile(TimetableEvent e, DateTime date, string folderName, out string fileSavedName)
        {
            string mode = e.Mode, fieldOfStudy = e.FieldOfStudy, type = e.Type;

            if (Dictionaries.ModesDictionary2.ContainsKey(mode))
            {
                Dictionaries.ModesDictionary2.TryGetValue(mode, out mode);
            }
            if (Dictionaries.FieldsDictionary2.ContainsKey(fieldOfStudy))
            {
                Dictionaries.FieldsDictionary2.TryGetValue(fieldOfStudy, out fieldOfStudy);
            }
            if (Dictionaries.TypesOfEventDictionary2.ContainsKey(type))
            {
                Dictionaries.TypesOfEventDictionary2.TryGetValue(type, out type);
            }


            string fileName = folderName + "/" + e.Department + "_2019_J_" + mode + "_" + fieldOfStudy + "_" + e.Degree + "_R" + e.Year + "S" + e.Semester + "_";

            if (e.Specialization != "")
            {
                fileName += e.Specialization;
            }
            else
            {
                fileName += "gr" + e.Group;
            }
            fileName += ".txt";

            fileSavedName = fileName;
            bool alreadyExists = File.Exists(fileName);

            if (!alreadyExists)
            {
                File.CreateText(fileName).Close();
            }

            //count lines
            int          linesCount   = 0;
            StreamReader streamReader = new StreamReader(fileName);

            while (!streamReader.EndOfStream)
            {
                streamReader.ReadLine(); linesCount++;
            }
            streamReader.Close();

            StreamWriter streamWriter = new StreamWriter(fileName, true);

            if (!alreadyExists)
            {
                string formatedDate = date.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture).Replace('/', '.');
                streamWriter.WriteLine(formatedDate);
                string formatedInfo = string.Format(e.Department + ", 2019, J, " + mode + ", " + fieldOfStudy + ", " + e.Degree + ", R" + e.Year + ", S" + e.Semester + ", gr" + e.Group + (e.Specialization != "" ? ", " + e.Specialization + ";" : ";"));
                streamWriter.WriteLine(formatedInfo);
                streamWriter.WriteLine("------------------------------------------------");
            }
            if (linesCount > 9)
            {
                linesCount -= 2;
            }
            string eventIndex = "ZJ_" + (linesCount / 7 + 1).ToString().PadLeft(2, '0');

            streamWriter.WriteLine(eventIndex);
            streamWriter.WriteLine(e.Name + " [" + type + "]");
            streamWriter.WriteLine("d" + Dictionaries.DaysOfWeekDictionary2[e.DayOfWeek] + ", " + e.StartTime + "-" + e.EndTime);
            streamWriter.WriteLine(e.Room + (e.Building != "34" ? ", " + e.Building : ""));
            string lecturers = "";

            for (int i = 0; i < e.Lecturers.Length; i++)
            {
                lecturers += e.Lecturers[i];
                if (i != e.Lecturers.Length - 1)
                {
                    lecturers += ", ";
                }
            }
            streamWriter.WriteLine(lecturers);
            streamWriter.WriteLine("U: " + e.Remarks);
            streamWriter.WriteLine("------------------------------------------------");

            streamWriter.Close();
        }
Exemple #8
0
        public static Timetable ParseTimetableFile(string filepath)
        {
            StreamReader sr = new StreamReader(filepath);

            string[] lines = Regex.Split(sr.ReadToEnd(), Environment.NewLine);
            sr.Close();

            var events = new List <TimetableEvent>();
            var date   = new DateTime();
            var i      = 0;

            string BuildErrorMsg(string msg)
            {
                return(string.Format("{0}\nw linii: {1}\nPlik: {2}", msg, i, filepath));
            }

            DateTime dateFromFile;

            try
            {
                // get info about current group timetable
                dateFromFile = DateTime.ParseExact(lines[i], new[] { "dd.MM.yyyy HH:mm", "d.MM.yyyy HH:mm", "dd.M.yyyy HH:mm", "d.M.yyyy HH:mm",
                                                                     "dd.MM.yyyy H:mm", "d.MM.yyyy H:mm", "dd.M.yyyy H:mm", "d.M.yyyy H:mm" }, null, DateTimeStyles.AllowWhiteSpaces);
            }
            catch (Exception ex)
            {
                string errMsg = BuildErrorMsg("Niepoprawna data: " + lines[i]);
                Console.WriteLine(errMsg);
                throw new Exception(errMsg);
            }

            date = dateFromFile > date ? dateFromFile : date; // get the most recent date from files
            i++;                                              // next line

            var info = lines[i].Split(',');

            // checks
            if (info.Length < 9)
            {
                string errMsg = BuildErrorMsg("Spodziewano się min 9 wartości w drugiej linii pliku, a otrzymano " + info.Length);
                Console.WriteLine(errMsg);
                throw new Exception(errMsg);
            }
            if (info[6].Length < 1 || !char.IsDigit(info[6].Trim()[1]))
            {
                string errMsg = BuildErrorMsg("Rok studiów w złym formacie " + info[6]);
                Console.WriteLine(errMsg);
                throw new Exception(errMsg);
            }
            if (info[7].Length < 1 || !char.IsDigit(info[7].Trim()[1]))
            {
                string errMsg = BuildErrorMsg("Semestr studiów w złym formacie " + info[7]);
                Console.WriteLine(errMsg);
                throw new Exception(errMsg);
            }
            if (info[8].Length < 2 || !char.IsDigit(info[8].Trim()[2]))
            {
                string errMsg = BuildErrorMsg("Grupa w złym formacie " + info[8]);
                Console.WriteLine(errMsg);
                throw new Exception(errMsg);
            }

            var department   = info[0];
            var isFieldKnown = Dictionaries.FieldsDictionary.TryGetValue(info[4].Trim().ToUpper(), out var fieldOfStudy);
            var mode         = Dictionaries.ModesDictionary.ContainsKey(info[3].Trim().ToUpper())
                ? Dictionaries.ModesDictionary[info[3].Trim().ToUpper()]
                : info[3].Trim();
            //var fieldOfStudy = Dictionaries.FieldsDictionary[info[4].Trim().ToUpper()];
            var degree   = Dictionaries.DegreesDictionary2.ContainsKey(info[5].Trim().ToUpper()) ? Dictionaries.DegreesDictionary2[info[5].Trim().ToUpper()] : info[5].Trim();
            var year     = info[6].Trim().Substring(1).ToString();
            var semester = info[7].Trim().Substring(1).ToString();

            // szybki fix grup (jesli grupy sa brane pod uwage to powinno byc ok, jesli specka jest brana ta wartosc mozliwe ze bedzie spierdolona)
            info[8] = info[8].Trim();
            int groupLastCharIndex = info[8].Length;

            if (info[8].IndexOf(';') != -1)
            {
                groupLastCharIndex = info[8].IndexOf(';');
            }
            if (info[8].IndexOf(' ') != -1)
            {
                if (info[8].IndexOf(' ') < groupLastCharIndex)
                {
                    groupLastCharIndex = info[8].IndexOf(' ');
                }
            }

            var group          = info[8].Trim().Substring(2, groupLastCharIndex - 2).ToString();
            var specialization = info.Length == 10 ? string.Concat(info[9].Take(info[9].Length - 1)).Trim() : "";

            int.TryParse(info[1], out int creationYear);
            var academicYear = info[2].ToLower().Trim() == "jesień" || info[2].ToLower().Trim() == "j"
                ? $"{creationYear}/{creationYear + 1}"
                : $"{creationYear - 1}/{creationYear}";

            while (true)
            {
                var endOfFile = false;
                while (!lines[i].Contains("ZJ"))
                {
                    i++;
                    if (!lines[i].Contains("end."))
                    {
                        continue;
                    }
                    endOfFile = true;
                    break;
                }

                if (endOfFile)
                {
                    break;
                }
                //check lines amount
                if (i + 5 >= lines.Length)
                {
                    string errMsg = BuildErrorMsg("Ilość linii w pliku nie jest prawidłowa");
                    Console.WriteLine(errMsg);
                    throw new Exception(errMsg);
                }

                var room     = lines[i + 3].Split(',')[0].Trim();
                var building = lines[i + 3].Split(',').ElementAtOrDefault(1);
                if (string.IsNullOrEmpty(building))
                {
                    building = "";
                }
                string day = "";

                try
                {
                    Dictionaries.DaysOfWeekDictionary.TryGetValue(lines[i + 2][1].ToString().ToUpper(), out day);
                }
                catch (Exception ex)
                {
                    string errMsg = BuildErrorMsg("Podano niepoprawny dzień tygodnia " + lines[i + 2][1]);
                    Console.WriteLine(errMsg);
                    throw new Exception(errMsg);
                }
                var lecturers      = lines[i + 4].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()).ToArray();
                var timetableEvent =
                    new TimetableEvent
                {
                    Name      = string.Concat(lines[i + 1].TakeWhile(c => c != '[')).Trim(),
                    DayOfWeek = day,
                    StartTime = string.Concat(lines[i + 2].SkipWhile(c => c != ',').Skip(1).TakeWhile(c => c != '-')).Trim(),
                    EndTime   = string.Concat(lines[i + 2].SkipWhile(c => c != '-').Skip(1)).Trim(),
                    Room      = room,
                    //Building = lines[i + 3].Split(',').ElementAtOrDefault(1)?.Trim() ?? (department.Equals("WZIM") && !string.IsNullOrWhiteSpace(room) ? "34" : null),
                    Building       = building,
                    Lecturers      = lecturers,
                    Remarks        = string.Concat(lines[i + 5].SkipWhile(c => c != ':').Skip(1)).Trim(),
                    Department     = department,
                    Mode           = mode,
                    Degree         = degree,
                    Year           = year,
                    Semester       = semester,
                    Group          = group,
                    Specialization = specialization,
                    FieldOfStudy   = isFieldKnown ? fieldOfStudy : info[4].Trim(),
                    AcademicYear   = academicYear,
                    IsFaculty      = lines[i + 1].Contains("(Faq)") || lines[i + 1].Contains("(faq)") || lines[i + 1].Contains("(f)") || lines[i + 1].Contains("(F)"),
                    FacultyGroup   = string.Concat(lines[i + 1].SkipWhile(c => c != ')').Skip(1).SkipWhile(c => c != ')').SkipWhile(c => c != '(').Skip(1).TakeWhile(c => c != ')')).Trim()
                };

                var type = string.Concat(lines[i + 1]
                                         .SkipWhile(c => c != '[')
                                         .Skip(1)
                                         .TakeWhile(c => c != ']'))
                           .Trim()
                           .ToUpper();
                timetableEvent.Type = Dictionaries.TypesOfEventDictionary.ContainsKey(type)
                    ? Dictionaries.TypesOfEventDictionary[type]
                    : type;

                events.Add(timetableEvent);
                i++;
            }
            return(new Timetable {
                Date = date, Events = events
            });
        }
        protected override async Task HandleTimetableEvent(TimetableEvent @event, IIccOutput outputSettings)
        {
            Configure(outputSettings);
            tuitionResolver.Initialize();

            if (outputSettings.TimetablePeriodMapping == null)
            {
                logger.LogError("TimetablePeriodMapping is null. Do not upload timetable.");
                return;
            }

            var period = outputSettings.TimetablePeriodMapping.ContainsKey(@event.Period) ? outputSettings.TimetablePeriodMapping[@event.Period] : null;

            if (period == null)
            {
                logger.LogDebug($"Cannot resolve period {@event.Period}. Skip upload.");
                return;
            }

            var lessons = new List <TimetableLessonData>();

            try
            {
                logger.LogDebug("Group lessons by week, lesson, room, subject and teacher...");

                var groups = @event.Lessons.GroupBy(l => new { Weeks = string.Join(',', l.Weeks), l.Day, l.LessonStart, l.LessonEnd, l.Subject, l.Room });

                foreach (var group in groups)
                {
                    var teachers = new List <string>();
                    var tuitions = new Dictionary <string, string>();
                    var grades   = new List <string>();

                    foreach (var lesson in group)
                    {
                        if (!teachers.Contains(lesson.Teacher))
                        {
                            teachers.Add(lesson.Teacher);
                        }

                        if (!string.IsNullOrEmpty(lesson.Grade) && !grades.Contains(lesson.Grade))
                        {
                            grades.Add(lesson.Grade);
                            var resolvedTuition = tuitionResolver.ResolveTuition(lesson.Grade, lesson.Subject, lesson.Teacher);

                            if (resolvedTuition != null)
                            {
                                tuitions.Add(lesson.Grade, resolvedTuition);
                            }
                        }
                    }

                    var distinctTuitions = tuitions.Select(x => x.Value).Distinct().ToList();

                    if (distinctTuitions.Count > 1)
                    {
                        logger.LogDebug($"Found more than one tuition for lesson (day: {group.Key.Day}, weeks: {string.Join(',', group.Key.Weeks)}, lesson: {group.Key.LessonStart}, subject: {group.Key.Subject}, room: {group.Key.Room}, grades: { string.Join(',', grades)}.");
                    }

                    if (distinctTuitions.Count == 0)
                    {
                        logger.LogDebug($"Found no tuition for lesson (day: {group.Key.Day}, weeks: {string.Join(',', group.Key.Weeks)}, lesson: {group.Key.LessonStart}, subject: {group.Key.Subject}, room: {group.Key.Room}, grades: { string.Join(',', grades)}.");
                    }

                    var subject  = group.Key.Subject;
                    var duration = group.Key.LessonEnd - group.Key.LessonStart + 1;

                    foreach (var week in group.Key.Weeks.Split(','))
                    {
                        for (int i = 0; i < duration; i += 2)
                        {
                            var lessonStart = group.Key.LessonStart + i;
                            var lessonEnd   = Math.Min(lessonStart + 1, group.Key.LessonEnd);

                            if (distinctTuitions.Count > 1)
                            {
                                foreach (var kv in tuitions)
                                {
                                    lessons.Add(CreateTimetableLessonData(kv.Value, new List <string> {
                                        kv.Key
                                    }, teachers, lessonStart, lessonEnd, group.Key.Room, group.Key.Day, week, null));
                                }
                            }
                            else if (distinctTuitions.Count == 1)
                            {
                                lessons.Add(CreateTimetableLessonData(distinctTuitions.First(), grades, teachers, lessonStart, lessonEnd, group.Key.Room, group.Key.Day, week, null));
                            }
                            else
                            {
                                lessons.Add(CreateTimetableLessonData(null, grades, teachers, lessonStart, lessonEnd, group.Key.Room, group.Key.Day, week, subject));
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogError(e, "Something went wrong while constructing all timetable lessons.");
                return;
            }

            var response = await iccImporter.ImportTimetableLessonsAsync(period, lessons);

            await HandleResponseAsync(response);
        }
Exemple #10
0
 protected override Task HandleTimetableEvent(TimetableEvent @event, IFileOutput outputSettings)
 {
     return(WriteJson(@event.Lessons, outputSettings, "lessons.json"));
 }
Exemple #11
0
        public static Timetable MergeToTimetable(Timetable t, TimetableAcademicYear d)
        {
            //adding event to the timetable tree
            if (t.AcademicYears.Exists(e => e.AcademicYear == d.AcademicYear))
            {
                TimetableAcademicYear nextLayerTimetable = t[d.AcademicYear].First();
                TimetableDepartment   nextLayerK0        = d.Departments[0];
                if (nextLayerTimetable.Departments.Exists(e => e.Department == nextLayerK0.Department))
                {
                    TimetableDepartment nextLayerTimetable1 = nextLayerTimetable[nextLayerK0.Department].First();
                    TimetableMode       nextLayerK1         = nextLayerK0.Modes[0];
                    if (nextLayerTimetable1.Modes.Exists(e => e.Mode == nextLayerK1.Mode))
                    {
                        TimetableMode  nextLayerTimetable2 = nextLayerTimetable1[nextLayerK1.Mode].First();
                        TimetableField nextLayerK2         = nextLayerK1.Fields[0];
                        if (nextLayerTimetable2.Fields.Exists(e => e.FieldOfStudy == nextLayerK2.FieldOfStudy))
                        {
                            TimetableField    nextLayerTimetable3 = nextLayerTimetable2[nextLayerK2.FieldOfStudy].First();
                            TimetableSemester nextLayerK3         = nextLayerK2.Semesters[0];
                            if (nextLayerTimetable3.Semesters.Exists(e => e.Semester == nextLayerK3.Semester && e.Degree == nextLayerK3.Degree))
                            {
                                TimetableSemester nextLayerTimetable4 = nextLayerTimetable3[nextLayerK3.Semester, nextLayerK3.Degree, nextLayerK3.Year].First();
                                TimetableDay      nextLayerK4         = nextLayerK3.Days[0];
                                if (nextLayerTimetable4.Days.Exists(e => e.DayOfWeek == nextLayerK4.DayOfWeek))
                                {
                                    //TimetableDay nextLayerTimetable5 = nextLayerTimetable4[nextLayerK4.DayOfWeek].First();
                                    //nextLayerTimetable5.Events.AddRange(nextLayerK4.Events);
                                    TimetableDay   nextLayerTimetable5 = nextLayerTimetable4[nextLayerK4.DayOfWeek].First();
                                    TimetableEvent nextLayerK5         = nextLayerK4.Events[0];
                                    if (nextLayerTimetable5.Events.Any(e => e.EqualsExceptGroups(nextLayerK5)))
                                    {
                                        TimetableEvent nextLayerTimetable6 = nextLayerTimetable5.Events.Find(e => e.EqualsExceptGroups(nextLayerK5));
                                        nextLayerTimetable6.Groups        = nextLayerTimetable6.Groups.Union(nextLayerK5.Groups).ToList();
                                        nextLayerTimetable6.FacultyGroups = nextLayerTimetable6.FacultyGroups.Union(nextLayerK5.FacultyGroups).ToList();
                                    }
                                    else
                                    {
                                        nextLayerTimetable5.Events.Add(nextLayerK5);
                                    }
                                }
                                else
                                {
                                    nextLayerTimetable4.Days.Add(nextLayerK4);
                                }
                            }
                            else
                            {
                                nextLayerTimetable3.Semesters.Add(nextLayerK3);
                            }
                        }
                        else
                        {
                            nextLayerTimetable2.Fields.Add(nextLayerK2);
                        }
                    }
                    else
                    {
                        nextLayerTimetable1.Modes.Add(nextLayerK1);
                    }
                }
                else
                {
                    nextLayerTimetable.Departments.Add(nextLayerK0);
                }
            }
            else
            {
                t.AcademicYears.Add(d);
            }

            return(t);
        }
Exemple #12
0
 public static TimetableAcademicYear MakeTimetableAcademicYear(string academicYear, string department, string mode, string field, int semester, string degree, int year, DayOfWeek dayOfWeek, TimetableEvent e)
 {
     return(new TimetableAcademicYear()
     {
         AcademicYear = academicYear,
         Departments = new List <TimetableDepartment>()
         {
             new TimetableDepartment()
             {
                 Department = department,
                 Modes = new List <TimetableMode>()
                 {
                     new TimetableMode()
                     {
                         Mode = mode,
                         Fields = new List <TimetableField>()
                         {
                             new TimetableField()
                             {
                                 FieldOfStudy = field,
                                 Semesters = new List <TimetableSemester>()
                                 {
                                     new TimetableSemester()
                                     {
                                         Semester = semester,
                                         Degree = degree,
                                         Year = year,
                                         Days = new List <TimetableDay>()
                                         {
                                             new TimetableDay()
                                             {
                                                 DayOfWeek = dayOfWeek,
                                                 Events = new List <TimetableEvent>()
                                                 {
                                                     e
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     });
 }
Exemple #13
0
        public static Timetable ParseTimetableFiles(IEnumerable <string> filesContents, DateTime date)
        {
            string[]  dni       = { "PN", "WT", "ŚR", "CZW", "PT", "SO", "NIE" };
            Timetable timetable = new Timetable()
            {
                Date = date
            };

            foreach (var content in filesContents)
            {
                var lines = Regex.Split(content, Environment.NewLine);
                Dictionary <string, string> groups  = new Dictionary <string, string>();
                Dictionary <string, string> degrees = TimetableOLD.Models.Dictionaries.DegreesDictionary2;
                TimetableInfo currentInfo           = new TimetableInfo();
                for (int i = 0; i < lines.Length; i++)
                {
                    if (lines[i].ToUpper().Trim() == "GROUPS")
                    {
                        string[] grs = lines.Skip(i + 1).TakeWhile(l => l.ToLower().Trim() != "end_groups.").ToArray();
                        foreach (var gr in grs)
                        {
                            string[] g = gr.Split(';');
                            if (!groups.ContainsKey(g[0].Trim()))
                            {
                                groups.Add(g[0].Trim(), g.Length > 1 ? g[1].Trim() : "");
                            }
                        }
                        i += grs.Length + 1;
                    }
                    else if (lines[i].ToUpper().Trim() == "INFO")
                    {
                        string[] infoLines = lines.Skip(i + 1).TakeWhile(l => l.ToLower().Trim() != "end_info.").ToArray();
                        string[] infos     = infoLines[0].Split(';');
                        currentInfo = new TimetableInfo()
                        {
                            AcademicYear = infos[0].Trim(),
                            Department   = infos[1].Trim(),
                            Mode         = infos[2].Trim(),
                            Field        = infos[3].Trim(),
                            Degree       = degrees.ContainsKey(infos[4].Trim().ToUpper()) ? degrees[infos[4].Trim().ToUpper()] : infos[4].Trim(),
                            Semester     = Convert.ToInt32(infos[5].Trim()),
                            Year         = Convert.ToInt32(infos[6].Trim()),
                        };
                        i += infoLines.Length + 1;
                    }
                    else if (dni.Contains(lines[i].ToUpper().Trim()))
                    {
                        DayOfWeek day = 0;
                        for (int j = 0; j < dni.Length; j++)
                        {
                            if (lines[i].ToUpper().Trim() == dni[j])
                            {
                                day = (DayOfWeek)j;
                            }
                        }

                        string[] dayLines = lines.Skip(i + 1).TakeWhile(l => l.ToLower().Trim() != "end_day.").ToArray();
                        for (int j = 0; j < dayLines.Length;)
                        {
                            string[]      eventLines = lines.Skip(i + j + 1).TakeWhile(l => l.ToLower().Trim() != "end_event.").ToArray();
                            string        name, type, room, building, remarks;
                            List <string> lecturers = new List <string>(), facultyGroups = new List <string>();
                            List <string> groupsNrs = new List <string>();
                            DateTime      startTime, endTime;
                            name = eventLines[0].Split(';')[0].Trim();
                            try
                            {
                                type = eventLines[0].Split(';')[1].Trim();
                            }
                            catch (Exception ex)
                            {
                                type = "?";
                            }
                            //TODO: add facultygroups
                            foreach (string s in eventLines[1].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                groupsNrs.Add(s.Trim());
                            }
                            List <TimetableGroup> eventGroups = new List <TimetableGroup>();
                            foreach (var item in groupsNrs)
                            {
                                eventGroups.Add(new TimetableGroup()
                                {
                                    Group = item, Specialization = groups.ContainsKey(item) ? groups[item] : ""
                                });
                            }

                            startTime = DateTime.ParseExact(eventLines[2].Split('-')[0], new[] { "HH:mm", "H:mm" }, null, DateTimeStyles.AllowWhiteSpaces);
                            endTime   = DateTime.ParseExact(eventLines[2].Split('-')[1], new[] { "HH:mm", "H:mm" }, null, DateTimeStyles.AllowWhiteSpaces);

                            string[] where = eventLines[3].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                            room           = where.Length > 0 ? where[0].Trim() : "";
                            building       = where.Length > 1 ? where[1].Trim() : "";

                            foreach (string l in eventLines[4].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                lecturers.Add(l.Trim());
                            }

                            remarks = eventLines[5].Trim();

                            TimetableEvent ev = new TimetableEvent()
                            {
                                Name          = name,
                                Type          = type,
                                Groups        = eventGroups,
                                FacultyGroups = new List <string>(),
                                StartTime     = startTime,
                                EndTime       = endTime,
                                Room          = room,
                                Building      = building,
                                Lecturers     = lecturers,
                                Remarks       = remarks
                            };

                            TimetableAcademicYear k = MakeTimetableAcademicYear(currentInfo.AcademicYear, currentInfo.Department, currentInfo.Mode, currentInfo.Field, currentInfo.Semester, currentInfo.Degree, currentInfo.Year, day, ev);

                            MergeToTimetable(timetable, k);


                            j += eventLines.Length + 1;
                        }
                    }
                }
            }

            //sorting all events
            SortTimetable(timetable);

            return(timetable);
        }