Как стать автором
Обновить

Создание WEB календаря с HTML страницы

Учеба с работой это очень напряжённый график. И мне и мой друзьям захотелось сделать так чтоб все расписание было в календаре(например gmail или outlook). Обращение в учебное заведение не дало ответа, точнее ответ был стандартный «Мы подумай над этим».

Тогда решил сам написать WEB сервис который будет делать синхронизацию между колледжем и чем угодно с помощью файла .ICS. То есть при обращение клиент получить файл ICS который создан только что для него со всеми свежими данными(есть лекция или ее перенесли и так далее).

Так как доступ к базе данных учебного заведения мне не кто не даст, потому что я случайно по ошибки могу стать отличником за 5 минут. Значит надо брать HTML и от туда вырезать что надо.

Разделил проект на этапы:
1. Сделать Login с помощью HttpWebRequest на сайт учебного заведения

2. Сделать запрос на нужную страницу где есть список лекции. В моем случае это выглядело как обычная таблица HTML. Взять ее как стринг и резать пока не останется только таблица с нужными данными.
public string getTableLessons()
        {
            if (this.id.IndexOf("error login") != -1) { return "<p>יש שגיע אנא בדוק פרטים</p>"; }
            //string myParamters = "prgname=MonthlyStudentTimes&arguments=-N" + this.username + ",-N" + this.id + ",-N0080,";
            string myParamters = "APPNAME=&prgname=MonthlyStudentTimes&arguments=-N"+this.username+"%2C-N"+this.id+"%2C-A%EB%2CR1C1%2CR1C2&R1C1=23/09/2012&R1C2=03/03/2013";
            string HtmlResult = Postto(myParamters);
            try
            {
                string tmp = HtmlResult;
                ThreadStart starter = delegate { insert(tmp); };
                new Thread(starter).Start();
            }
            finally
            {
                try
                {
                    HtmlResult = HtmlResult.Substring(HtmlResult.IndexOf("<table style=\"text-align"));
                    HtmlResult = HtmlResult.Substring(0, HtmlResult.IndexOf("<table style=\"width: 100%;"));
                    HtmlResult = HtmlResult.Replace("TD", "td");
                    HtmlResult = HtmlResult.Replace("TR", "tr");
                    HtmlResult = HtmlResult.Replace("TH", "th");
                    HtmlResult = HtmlResult.Replace("<th> ", "<th>");
                    HtmlResult = HtmlResult.Replace(" </th>", "</th>");
                    HtmlResult = HtmlResult.Replace(" <th> ", "<th>");
                    HtmlResult = HtmlResult.Replace("\t", "");
                    HtmlResult = HtmlResult.Replace("\r", "");
                    HtmlResult = HtmlResult.Replace("\n", "");
                    HtmlResult = HtmlResult.Replace(" ", "");
                    HtmlResult = HtmlResult.Replace("סיווג", "status");
                    HtmlResult = HtmlResult.Replace("נושא", "kurs");
                    HtmlResult = HtmlResult.Replace("תאריך", "date");
                    HtmlResult = HtmlResult.Replace("מ-שעה", "from");
                    HtmlResult = HtmlResult.Replace("עד-שעה", "to");
                    HtmlResult = HtmlResult.Replace("חדר לימוד", "place");
                    HtmlResult = HtmlResult.Replace("סוג מקצוע", "type");
                    HtmlResult = HtmlResult.Replace("רשומה ", "");

                }
                catch
                {
                    HtmlResult += "<p>יש שגיעה אנא בדוק פרטים</p>";
                }
            }
            return HtmlResult;
        }

3. Перевести данные в какой нибуть удобный объект. Для этого я нашёл класс который как раз делает то что мне надо, берет HTML таблицу и дает DataTable
 DataTable t1 = HtmlTableParser.ParseTable(html1);


4. Потом надо было найти какой нибуть объект который умеет собирать файл ICS. Тут было тяжело, обыскал много страниц в гугле пока не нашёл пулу готовый проект. Я его доделал для себя.
public static string CreatIcs(DataTable d)
        {
            var eventos = new EventCollection();
            var calendar = new Calendar(MethodNames.Request) { ProductId = "-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN" };
            List<dynamic> l = new List<dynamic>();
            for (int i = 0; i < d.Rows.Count; i++)
            {
                var evento = new Event(d.Rows[i]["status"].ToString() + " " + d.Rows[i]["kurs"].ToString(), DateTime.ParseExact(d.Rows[i]["date"].ToString() + " " + d.Rows[i]["from"].ToString(), "dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture),
                                       DateTime.ParseExact(d.Rows[i]["date"].ToString() + " " + d.Rows[i]["to"].ToString(), "dd/MM/yyyy HH:mm",                      CultureInfo.InvariantCulture))
                                 {
                                     Location = d.Rows[i]["place"].ToString(),
                                     Description = d.Rows[i]["type"].ToString(),
                                     Organizer =
                                         new Organizer(new MailAddress("test@afeka.co.il", "Afeka"),
                                                       new MailAddress("test@afeka.co.il", "Afeka")),
                                     Geo = new Geo(-32.122617f, -145.19346f),
                                     Status = EventStatusValue.Confirmed,
                                     Transparent = false,
                                     RecurrenceId = new RecurrenceId(DateTime.Now) { Range = Range.ThisAndFuture },
                                     EventId = new UniqueIdentifier()

                                 };
                                    var trigger = new Duration() { Minute = 60, TimeLine = TimeLine.Before };
                                  evento.Alarms.Add(new Alarm(ActionValue.Display, trigger)
                                  {
                                      Duration = new Duration(DurationType.Time) { Day = 5, Minute = 4, TimeLine = TimeLine.After },
                                      Description = "Reminder",
                                      TriggerRelationship = TriggerRelationship.End
                                  });
                l.Add(evento);
                eventos.Add(l[i]);
            }
            calendar.Events = eventos;

            string isc = ISC.CreatIcs(t1);
            var byteArray = Encoding.UTF8.GetBytes(isc);
            Response.AddHeader("Content-Disposition", "attachment; filename=" + "afeka.ics");
            Response.ContentType = "text/calendar";
            Response.Charset = "utf-8";
            Response.HeaderEncoding = UnicodeEncoding.UTF8;
            Response.ContentEncoding = UnicodeEncoding.UTF8;
            Response.BinaryWrite(byteArray);
            Response.End();


5. Маленькая простая страница html что люди там писали свой имя пользователя и пароль и получит линк для его файла который можно поставить в gmail или в outlook как интернет каледарь.

Все готово!

Секунду…. Не прикольно давать линк такого типа www.asd.com/index?user=XXXXpass=YYYYY. Тогда я сделал чтоб пароль и имя пользователя кодировалось в что то такое H/R5ptopXwb4qcLIweMeH2+NCihXmsR1oeGOTDIi8/K9/lIA1rHFkDelXeC8
Еще поставил ссылку с объяснением как пользоваться…
И все есть уже 20 пользователей…
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.