Разработка сайта радиостанции "DJ843" с формой заказа песни

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

http: ///

http: ///

СОДЕРЖАНИЕ

  • ЗАДАНИЕ
  • ВВЕДЕНИЕ
  • 1. ВЫЯВЛЕНИЕ НЕОБХОДИМОЙ ФУНКЦИОНАЛЬНОСТИ
  • 2. КРАТКИЙ ОБЗОР ИНФОРМАЦИОННОЙ СИСТЕМЫ
    • 2.1 Серверная часть информационной системы
    • 2. 2 Клиентская часть информационной системы
  • 3. РАЗРАБОТКА САЙТА РАДИОСТАНЦИИ
    • 3.1 Интернет-страница радиостанции с формой заявок
    • 3.2 Обработка ввода пользователя
    • 3.3 Выбор хостинг-провайдера
  • 4. УЛУЧШЕНИЕ КЛИЕНТСКОЙ ЧАСТИ ИНФОРМАЦИОННОЙ СИСТЕМЫ
    • 4.1 Взаимодействие клиентской программы с БД
    • 4.2 Организация работы с электронной почтой в клиентской программе
    • 4.3 Разработка действий приложения по истечению таймера
  • 5. ПРИМЕР ПОЛУЧЕНИЯ ЗАЯВКИ ПО ЭЛЕКТРОННОЙ ПОЧТЕ
  • ЗАКЛЮЧЕНИЕ
  • ПРИЛОЖЕНИЯ

ЗАДАНИЕ

1. Разработать одностраничный сайт радиостанции «DJ843"с формой заказа песни.

2. Реализовать отправку заявок с сайта по электронной почте.

3. Добавить в информационную систему с клиент-серверной архитектурой «Песни и исполнители» возможность автоматического получения заявок на воспроизведение песен по электронной почте, отправленной с сайта.

ВВЕДЕНИЕ

В рамках данного курсового проекта необходимо расширить функциональность информационной системы с клиент-серверной архитектурой «Песни и исполнители».

Данная система предназначена для диджеев на радиостанции. Она организовывает список песен, которые будут проигрываться в эфире. Система носит также информационный характер: в базе данных хранятся песни и данные об исполнителях, возможных концертах, альбомах и их содержании, музыкантах, входящих в группы, и наличии самих файлов с песнями на радиостанции. Эти данные также помогут радиооператору и с организацией списка воспроизведения, и с информированием слушателей.

Программа имеет возможность хранить заявки радиослушателей и формировать отчет по списку запланированных для воспроизведения песен. В ходе выполнения данного курсового проекта необходимо добавить в программу возможность автоматического занесения в базу данных заявок на воспроизведение песен, пришедших по электронной почте, отправленной с сайта радиостанции. Такая функциональность обязательна для современных радиостанций: заказывать песню через интернет быстрее и проще, чем, например, по телефону.

Для выполнения поставленной задачи будет использоваться следующие технологии и программное обеспечение:

• СУБД: MS SQL Server 2012;

• среда программирования: MS VisualStudio 2012и язык программирования C#;

• язык разметки документовHTMLи язык программирования PHP;

• компилятор установочных файлов: ExcelsiorInstaller 2.2.

1. ВЫЯВЛЕНИЕ НЕОБХОДИМОЙ ФУНКЦИОНАЛЬНОСТИ

Сайт радиостанции, позволяющий заказать песню для исполнения в эфире, должен быть расположен в свободном доступе в сети Интернет.

Форма приема заявок должна содержать семь полей для ввода имени и адреса электронной почты радиослушателя, названия и исполнителя песни, желаемых даты и времени воспроизведения песни, а также произвольного комментария. Кнопка «Отправить» должна запускать PHP-скрипт. Его задача -- проверка корректности введенных данных и отправка письма с данными на определенный электронный почтовый ящик в определенном формате.

Клиентское приложение информационной системы «Песни и исполнители» должно автоматически один раз в три минуты проверять наличие новых писем в электронном почтовом ящике, на который отправляет письма PHP-скрипт. Если письмо получено и имеет правильный формат, необходимо проверить наличие запрошенной песни в базе данных информационной системы. Если такая песня действительно существует, она добавляется в список заявок на воспроизведение в эфире.

2. КРАТКИЙ ОБЗОР ИНФОРМАЦИОННОЙ СИСТЕМЫ

2.1 Серверная часть информационной системы

В информационной системе используется клиент-серверная архитектура с применением двухзвенной модели DBS (DateBaseServer — сервер баз данных). Для этой модели характерно, что функции компьютера клиента ограничиваются функциями представления информации, в то время как прикладные функции обеспечиваются приложением, находящемся на компьютере сервере. При этом приложения реализуются в виде хранимых процедур.

Концептуальная модель данных, построенная для информационной системы «Песни и исполнители» представлена на рисунке 2.1.

Рисунок2. 1- Концептуальная модель данных для предметной области «Песни и исполнители».

Логическая модель данных для информационной системы «Песни и исполнители» показана на рисунке 2.2.

Рисунок 2. 2- Логическая модель данных для предметной области «Песни и исполнители»

Физическая модель приведена на рисунке 2.3. На рисунке 2.4 приведена физическая модель данных с именами сущностей и атрибутов, которые используются в коде.

Новые возможности информационной системы, добавляемые в рамках данного курсового проекта, требуют хранения в базе данных списка песен и их исполнителей, списка заявок на воспроизведение песен в эфире радиостанции. Так как эта информация уже содержится в разработанной базе данных, никаких изменений в серверной части информационной системы не требуется.

Рисунок 2. 3- Физическая модель данных для предметной области «Песни и исполнители»

Рисунок 2. 4- Физическая модель данных с именами сущностей и атрибутов, которые используются в коде.

1. 2 Клиентская часть информационной системы

Для доступа к базе данных используется технология ADO. NET. Взаимодействие клиентской программы с базой данных осуществляется через хранимые процедуры, осуществляющие выборку, вставку, обновление и удаление из таблиц соответствующих записей.

Программа «ДиДжей» разработана на языке C# и состоит из главной формы и 17вспомогательных.

Форма FormMain — главная форма приложения. Интерфейс главной формы состоит из 8 вкладок: Режим, Песни, Исполнители, Альбомы, Концерты, Заявки, План и Отчет.

Вкладка «Заявки» показана на рисунке 2. 5:

Рисунок 2.5 — Вкладка «Заявки»

Здесь отображается информация о заявках радиослушателей. Её редактирование может осуществляться во всех режимах работы программы.

В блоке «Принятые заявки радиослушателей» доступна возможность перемещения по таблице с заявками, фильтрации, добавления, изменения и удаления заявки из базы данных. Соответствующий диалог показан на рисунке 2.6. Также есть возможность перейти в соответствующей песне на вкладке «Песни», удалить устаревшие заявки и поместить песню из заявки в запланированный список воспроизведения (рисунок 2. 7), причём комментарий к заявке будет помещен в комментарий для запланированного воспроизведения.

Таким образом, клиентское приложение информационной системы уже содержит пользовательский инструментарий работы с заявками радиослушателей. В ходе выполнения курсового проекта необходимо добавить возможность приема заявок, отправленных по электронной почте и их автоматическое добавление в базу данных и в список заявок клиентского приложения.

Рисунок2.6 — Диалог изменения информации о заявке

Рисунок 2.7 — Вкладка «План»

3. РАЗРАБОТКА САЙТА РАДИОСТАНЦИИ

3.1 Интернет-страница радиостанции с формой заявок

Интернет-страница радиостанции «DJ843"созданав текстовом редакторе с помощью языка разметки HTML. В заголовке страницы отображено название радиостанции, затем следует форма заказа песни, состоящая из шести однострочных полей ввода (имя и электронный адрес радиослушателя, название песни и имя исполнителя, дата и время) и многострочное поле для комментария.

В нижней части страницы расположена кнопка «Отправить», нажатие которой должно вызывать отправку письма с информацией из всех вышеперечисленных полей ввода.

В качестве фона для сайта выбрано фоновое изображение из клиентского приложения, чтобы подчеркнуть связь разработанного сайта с информационной системой «Песни и исполнители».

На рисунке 3.1 приведен снимок экрана браузера, в котором открыта разработанная интернет-страница.

3.2 Обработка ввода пользователя

Данные, введенные пользователем на сайте радиостанции, необходимо обработать: проверить на корректность и отправить по электронной почте. Для этого решено применить web-ориентированный язык PHP.

После нажатия кнопки отправки формы происходит передача значений всех полей формы ее обработчику. Отправка осуществляется методом POST.

Проверяется, что каждое поле ввода не является пустым и содержит текстовые данные. Для полей ввода адреса электронной почты, даты и времени, введенные значения дополнительно проверяются с помощью регулярных выражений и стандартной функции PHP (checkdate) на соответствие правильному формату.

Если какое-либо поле ввода оказалось пустым или имеет неправильный формат, выводится соответствующая ошибка. Пример показан на рисунке 3.2.

Если никаких ошибок нет, составляется письмо и отправляется с помощью функции mailна почтовый адрес dj843@yandex. ru, зарегистрированный для данной курсовой работы.

Письмо с темой «DJ843» имеет следующий формат:

· < Имя исполнителя песни> ;

· < Название песни> ;

· < Дата>;

· < Время>;

· < Имя радиослушателя> ;

· < Адрес электронной почты> ;

· < Дополнительный комментарий>.

Вместо каждой строки подставляется значение соответствующего текстового поля, очищенного от предваряющих и замыкающих пробелов.

Исходный код PHP-скрипта приведен в Приложении 2.

3.3 Выбор хостинг-провайдера

Для размещения разработанного сайта в сети Интернет требовался хостинг, поддерживающий PHPи разрешающий отправку электронной почты.

В итоге был выбран бесплатный тарифный план хостинг-провайдераhostinger. ru, отвечающий приведенным требованиям. Сайт размещен по адресу dj843. 16mb. com.

Рисунок 3.1 — Сайт радиостанции

Рисунок 3.2 — Пример сообщения об ошибке

4. УЛУЧШЕНИЕКЛИЕНТСКОЙ ЧАСТИ ИНФОРМАЦИОННОЙ СИСТЕМЫ

4.1 Взаимодействие клиентской программы с БД

Взаимодействие клиентской программы с базой данных в информационной системе осуществляется через хранимые процедуры.

Для реализации новых возможностей информационной системы, добавляемых в рамках данного курсового проекта, необходимо получение номера песни и номера исполнителя по названию песни и имени исполнителя, если они существуют в базе данных. Для этого была разработана следующая процедура:

CREATEPROC[FindSongSelect]

@Song_Namenvarchar (64),

@Artist_Namenvarchar (64)

AS

SELECT[Song]

FROM[SongArtist]

WHERE[Song]in (SELECT[N_Song]

FROM[SONG]

WHERE[Song_Name]=@Song_Name)

AND[Artist]in (SELECT[N_Artist]

FROM[Artist]

WHERE[Artist_Name]=@Artist_Name)

Хранимая процедура для добавления новой заявки в базу данных уже реализована:

CREATEPROC[RequestInsert]

@Songint,

@Playback_Timedatetime,

@Request_Texttext

AS

INSERTINTO[Request]([Song],[Playback_Time],[Request_Text])

SELECT@Song,@Playback_Time,@Request_Text

4.2 Организация работы с электронной почтой в клиентской программе

В языке C# нет встроенных средств для получения электронной почты в клиентском приложении. Поэтому требовалось разработать классы для получения электронной почты по протоколу Pop3.

Для работы с протоколом Pop3 в данной курсовой работе разработаны 4 класса. Они представлены в таблице 4.1.

Таблица 4.1. Классы для получения электронной почты

Класс

Назначение

MailItem

Класс для писем и частей писем.

Содержит методы для декодирования письма и получения текстовой информации.

Parameters

Класс для обработки параметров в значениях MIME-заголовков (заголовков электронных писем).

Pop3Client

Основной класс для работы с протоколом Pop3.

Он содержит методы для подключения к почтовому серверу, завершения сеанса связи с сервером, получения следующего письма, удаления текущего письма, передачи команды почтовому серверу и чтению строк из ответа сервера.

Pop3Result

Универсальный обработчик ответов почтового сервера.

Содержит методы для получения из ответа сервера информации о количестве писем и их размере, а также передачи обработанного письма на основе данных, полученных от почтового сервера

Исходный код этих классов приведен в Приложении 3.

4.3 Разработка действий приложения по истечению таймера

Для того чтобы приложение каждые три минуты проверяло поступление почты, необходимо добавить на главную форму клиентского приложения компонент-таймер timer Mail (объект класса System. Windows. Forms. Timer). Интервал времени срабатывания таймера устанавливается в 3000мс, по умолчанию таймер должен быть выключен. Его необходимо включить только после успешного подключения программы к базе данных.

В обработчике события Tick таймера timer Mail необходимо создать объект класса Pop3Client и подключить его к серверу электронной почты. Так как в данной работе используется почтовый ящик, зарегистрированный на сайте yandex. ru, то необходимо использовать серверpop. yandex. ru.

Если метод NextMail объекта классаPop3Client показал, что получено одно или несколько писем, необходимо начать их обработку.

Первым делом проверяется тема письма. Если она отличается от должной (DJ843), письмо удаляется. В противном случае проверяется содержание. Письма, состоящие менее чем из семи строк, также удаляются.

Далее вызывается хранимая процедура FindSongSelect, которой в качестве параметров передаются вторая (название песни) и первая (исполнитель) строки письма. Если в результате выполнения хранимой процедуры получен непустой список номеров песен, значит, запрошенная песня содержится в базе данных в одном или нескольких вариантах, и ее можно добавлять в список полученных заявок.

Информация из всех строк письма, начиная с пятой, объединяется в одной текстовой переменой. Таким образом, данные о радиослушателе, заказавшем песню, присоединяются к текстовому комментарию.

На основе третьей и четвертой строк письма составляется переменная типа SqlDbType. DateTime, понятного SQL.

Наконец, вызывается хранимая процедура RequestInsert, в которую передаются номер песен (если процедура FindSongSelect вернула целый список песен, берется первая из них) и переменные, содержащие время исполнения песни и текстовый комментарий.

После обработки письмо удаляется из почтового ящика.

Исходный код обработчика таймера приведен в Приложении 4.

5. ПРИМЕР ПОЛУЧЕНИЯ ЗАЯВКИ ПО ЭЛЕКТРОННОЙ ПОЧТЕ

Закажем для воспроизведения по радио песню «Маяк» группы Сплин. Для этого откроем сайт dj843. 16mb. com и введем данные, как показано на рисунке 5. 1:

Рисунок 5.1 — Форма заказа песни «Маяк» группы Сплин

электронный радиостанция заявка провайдер

После нажатия кнопки «Отправить», на сайте появилось сообщение, показанное на рисунке 5. 2:

Рисунок 5.2 — Сообщение об отправке письма

Теперь закроем браузер, запустим клиентское приложение информационной системы.

Спустя три минуты после подключения приложения к базе данных, запрошенная нами заявка появилась в списке заявок, показанном на рисунке 5. 3:

Рисунок 5.3 — Новая заявка в списке заявок информационной системы

С другими исходными данными результат аналогичен. Можно сделать вывод, что сайт и обновленная информационная система работают верно.

ЗАКЛЮЧЕНИЕ

В ходе работы над курсовым проектом был разработан сайт радиостанции с возможностью оправки по электронной почте заявок на воспроизведение песен. В клиентское приложение информационной системы добавлена возможность получения заявок по электронной почте и автоматическое добавление их в базу данных и в список заявок, отображаемый в приложении.

Выполненная работа полностью удовлетворяет поставленной задаче.

В качестве дальнейшего развития информационной системы возможно расширение функциональности сайта радиостанции, заполнение его различной информацией о самой радиостанции, о песнях и исполнителях.

ПРИЛОЖЕНИЯ

ПРИЛОЖЕНИЕ 1

HTML-код страницы радиостанции

< !DOCTYPE html PUBLIC «-//W3C//DTD HTML 4. 01 Transitional//EN">

< html>

< head>

< meta content="text/html; charset=Windows-1251″ http-equiv="content-type">

< title>DJ843</title>

< style> body { background: url («note. png»); }

< /style>

< /head>

< body>

< div style="text-align:center;«>

<h1>Радиостанция DJ843</h1>

<h2>Форма заказа песни</h2>

<form action="form_processing. php" method="post">

< p>Ваше имя: <br>

< input size="60″ name="your_name"> </p>

< p>E-mail:<br>

< input size="60″ name="email"> </p>

< p>Исполнитель или группа: <br>

< input size="60″ name="artist"> </p>

< p>Название песни: <br>

< input size="60″ name="song"> </p>

< p>Желаемое время (ЧЧ: ММ, ЧЧ. ММ):<br>

< input size="60″ name="time"> </p>

< p>Желаемая дата (ДД. ММ. ГГГГ):<br>

< input size="60″ name="date"> </p>

< p>Комментарий:<br>

< textarea name="message" rows="5″ cols="50"> </textarea></p>

< p><input value="Отправить" type="submit"> </p>

< /form>

< /div>

< /body>

< /html>

ПРИЛОЖЕНИЕ 2

Код PHP-скрипта для страницы радиостанции

< ?php

/* Осуществляем проверку вводимых данных и их защиту от враждебных

скриптов */

$your_name = htmlspecialchars ($_POST["your_name"]);

$email = htmlspecialchars ($_POST["email"]);

$artist = htmlspecialchars ($_POST["artist"]);

$song = htmlspecialchars ($_POST["song"]);

$time = htmlspecialchars ($_POST["time"]);

$date = htmlspecialchars ($_POST["date"]);

$message = htmlspecialchars ($_POST["messages"]);

/* Устанавливаем e-mail адресата */

$myemail = «dj843@yandex. ru»;

/* Проверяем заполнены ли обязательные поля ввода, используя check_input

функцию */

$your_name = check_input ($_POST["your_name"], «Введите ваше имя!»);

$email = check_input ($_POST["email"], «Введите ваш e-mail!»);

if (!checkEmail ($email))

{

show_error («Е-mail адрес не существует»);

}

$artist = check_input ($_POST["artist"], «Укажите исполнителя песни!»);

$song = check_input ($_POST["song"], «Выберите название песни!»);

$time = check_input ($_POST["time"], «Укажите желаемое время!»);

if (!checkTime ($time))

{

show_error («Формат ввода времени не верен. Следует вводить „ЧЧ: ММ“, „Ч: ММ“, „Ч. ММ“ или „ЧЧ. ММ“»);

}

$date = check_input ($_POST["date"], «Укажите желаемую дату!»);

if (!checkStringDate ($date))

{

show_error («Формат ввода даты не верен. Следует вводить „ДД. ММ. ГГГГ“»);

}

$message = check_input ($_POST["message"], «Вы забыли написать комментарий!»);

/* Создаем новую переменную, присвоив ей значение */

$message_to_myemail = «$artist

$song

$date

$time

$your_name

$email

$message";

/* Отправляем сообщение, используя mail () функцию */

$from = «From: $your_name < $email> rn Reply-To: $email rn»;

mail ($myemail, «DJ843», $message_to_myemail, $from);

?>

< p>Ваше сообщение было успешно отправлено!< /p>

< p><a href="index. html">Вернуться назад< /a></p>

< ?php

/* Если при заполнении формы были допущены ошибки, сработает

следующий код: */

function check_input ($data, $problem = ««)

{

$data = trim ($data);

$data = stripslashes ($data);

$data = htmlspecialchars ($data);

if ($problem & & strlen ($data) == 0)

{

show_error ($problem);

}

return $data;

}

function checkTime ($time)

.)[0−5][0−9]$/', $time);

function checkStringDate ($date)

{

$stamp = strtotime ($date);

if (!is_numeric ($stamp))

{

return FALSE;

}

$month = date ('m', $stamp);

$day = date ('d', $stamp);

$year = date ('Y', $stamp);

if (checkdate ($month, $day, $year))

{

return TRUE;

}

return FALSE;

}

function checkEmail ($email)

{

return preg_match («|^[-0−9a-z_. ]+@[-0−9a-z_^. ]+. a-z]{2,6}$|i», $email);

}

function show_error ($myError)

{

?>

< html>

< body>

< p>Исправьте, пожалуйста, следующую ошибку: </p>

< ?php echo $myError; ?>

< /body>

< /html>

< ?php

exit ();

}

?>

ПРИЛОЖЕНИЕ 3

Исходный текст классов для получения почты

ФайлMailItem. cs

using System;

usingSystem. Collections;

usingSystem. Collections. Generic;

usingSystem. Globalization;

usingSystem. Net. Mail;

usingSystem. Text;

usingSystem. Text. RegularExpressions;

namespace IS_DJ

{

///< summary>

/// Класс для писем и частей писем

///< /summary>

publicclassMailItem

{

#regionНестатические поля

privatereadonlystring _ContentTransferEncoding = String. Empty;

privatereadonlyobject _Data;

privatereadonlyDictionary< string, object> _Headers;

privatereadonlystring _Source = String. Empty;

privateMailAddress _From;

privateMailAddress _ReturnPath;

privateMailAddress _To;

#endregion

#regionКонструкторы

///< summary>

///Конструктор класса

///< /summary>

publicMailItem ()

{

}

///< summary>

///Конструктор класса

///< /summary>

///< param name="source"> Исходный текст письма< /param>

publicMailItem (string source)

{

_Source = source;

// выделение заголовков (до первых двух переводов строк)

intheadersTail = source. IndexOf («rnrn»);

string h = headersTail == -1? source: source. Substring (0, headersTail);

_Headers = ParseHeaders (h);

if (headersTail == -1)

return; // если тела письма нет

// выделение тела с конца заголовков

string b = source. Substring (headersTail + 4,

source. Length — headersTail — 4); // 4 = «rnrn». Length

if (_Headers. ContainsKey («Content-Transfer-Encoding»))

{

_ContentTransferEncoding =

_Headers["Content-Transfer-Encoding"]. ToString (). ToLower ();

}

_Data = b;

}

#endregion

#regionМетоды

///< summary>

/// Разбор адреса электронной почты

///< /summary>

///< paramname="source">Строка, из которой нужно получить адрес< /param>

privateMailAddressParseMail (string source)

{

if (String. IsNullOrEmpty (source)) returnnull;

varmyReg =

newRegex (

@"(?< name>[^<]*?)[<]{0,1}(?<email>[A-Za-zА-Яа-яЁё0−9_-. ]+@[A-Za-zА-Яа-яЁё0−9_-. ]+)[>]{0,1}",

RegexOptions. IgnoreCase | RegexOptions. Multiline);

Match m = myReg. Match (source);

if (m == null || String. IsNullOrEmpty (m. Value)) returnnull;

string email = m. Groups["email"]. Value. Trim ();

if (String. IsNullOrEmpty (email)) returnnull;

string name = m. Groups["name"]. Value. Trim («» «. ToCharArray ());

returnnewMailAddress (email, name);

}

///< summary>

/// Разбор заголовков

///< /summary>

///< paramname="h">Источник, из которого нужно получить заголовки< /param>

privateDictionary< string, object> ParseHeaders (string h)

{

var result =

newDictionary< string, object> (

StringComparer. CurrentCultureIgnoreCase);

// декодирование текстовых данных в заголовках

h = Regex. Replace (h,

@"([x22]{0,1})=?(?< cp>[wd-]+)?(?<ct>[w]{1})?(?<value>[^x3f]+)?=([x22]{0,1})",

HeadersEncode,

RegexOptions. Multiline | RegexOptions. IgnoreCase);

// удаление лишних пробелов

h = Regex. Replace (h, @"([rn]+)^(s+)(. *)?$", «$ 3»,

RegexOptions. Multiline);

// разбор заголовков и занесение их в коллекцию

varmyReg = newRegex (@"^(?< key>[^x3A]+):s{1}(?<value>. +)$",

RegexOptions. Multiline);

MatchCollection mc = myReg. Matches (h);

foreach (Match m in mc)

{

string key = m. Groups["key"]. Value;

if (result. ContainsKey (key))

{

// если указанный ключ уже есть в коллекции,

// топроверяетсятипданных

if (result[key] isstring)

{

// тип данных — строка, преобразование в коллекцию

vararr = newArrayList ();

// добавление в коллекцию первого элемента

arr. Add (result[key]);

// добавление в коллекцию текущего элемента

arr. Add (m. Groups["value"]. Value);

// вставляем коллекцию элементов в найденный заголовок

result[key] = arr;

}

else

{

// тип данных — коллекция,

// добавление найденного элемента

((ArrayList)result[key]). Add (m. Groups["value"]. Value);

}

}

else

{

// такогоключанет

result. Add (key,

m. Groups["value"]. Value. TrimEnd («rn «. ToCharArray ()));

}

}

return result;

}

///< summary>

///Функция обратного вызова, обрабатывается в методе ParseHeaders,

/// производит декодирование данных в заголовках, в соответствии с

///найденными атрибутами.

///< /summary>

privatestringHeadersEncode (Match m)

{

string result = String. Empty;

Encodingcp = Encoding. GetEncoding (m. Groups["cp"]. Value);

switch (m. Groups["ct"]. Value. ToUpper ())

{

case"Q":

result = ParseQuotedPrintable (m. Groups["value"]. Value);

break;

case"B":

result =

cp. GetString (

Convert. FromBase64String (m. Groups["value"]. Value));

break;

default:

result = m. Groups["value"]. Value;

break;

}

return result;

}

///< summary>

///Декодирование Quoted-Printable.

///< /summary>

///< param name="source"> Текст для декодирования< /param>

privatestringParseQuotedPrintable (string source)

{

source = source. Replace («_», ««);

source = Regex. Replace (source, @"(=)([^dABCDEFabcdef]{2})", ««);

returnRegex. Replace (source, @"=(?< char>[dw]{2})",

QuotedPrintableEncode);

}

///< summary>

///Функция обратного вызова для ParseQuotedPrintable

///< /summary>

privatestringQuotedPrintableEncode (Match m)

{

return

((char)

int. Parse (m. Groups["char"]. Value,

NumberStyles. AllowHexSpecifier)). ToString ();

}

///< summary>

///Возврат текстовых данных текущей части письма

///< /summary>

publicstringGetText ()

{

return !IsText? String. Empty: _Data. ToString ();

}

#endregion

#regionСвойства

///< summary>

///Тема письма

///< /summary>

publicstring Subject

{

get

{

if (Headers. ContainsKey («Subject»))

return Headers["Subject"]. ToString ();

returnString. Empty;

}

}

///< summary>

///Получатель письма

///< /summary>

publicMailAddress To

{

get

{

if (_To == null)

{

if (!Headers. ContainsKey («To»)) returnnull;

_To = ParseMail (Headers["To"]. ToString ());

}

return _To;

}

}

///< summary>

///Кому писать ответ

///< /summary>

publicMailAddressReturnPath

{

get

{

if (_ReturnPath == null)

{

if (!Headers. ContainsKey («Return-Path»)) returnnull;

_ReturnPath = ParseMail (Headers["Return-Path"]. ToString ());

}

return _ReturnPath;

}

}

///< summary>

///Дата письма

///< /summary>

publicDateTime? Date

{

get

{

if (Headers. ContainsKey («Date»))

{

returnConvert. ToDateTime (Headers["Date"]);

}

returnnull;

}

}

///< summary>

///Отправитель письма

///< /summary>

publicMailAddress From

{

get

{

if (_From == null)

{

if (!Headers. ContainsKey («From»)) returnnull;

_From = ParseMail (Headers["From"]. ToString ());

}

return _From;

}

}

///< summary>

///Исходный текст письма (MIME)

///< /summary>

publicstring Source

{

get

{

return _Source;

}

}

///< summary>

///Коллекция MIME-заголовков

///< /summary>

publicDictionary< string, object> Headers

{

get

{

return _Headers;

}

}

///< summary>

///Тип кодирования содержимого

///< /summary>

publicstringContentTransferEncoding

{

get

{

return _ContentTransferEncoding;

}

}

///< summary>

///Содержимое

///< /summary>

publicobject Data

{

get

{

return _Data;

}

}

///< summary>

/// Возвращает true, если в текущей части письма нет никаких данных

///< /summary>

publicboolIsEmpty

{

get

return _Data == null

}

///< summary>

/// Возвращает true, если текущая часть письма содержит текстовые данные

///< /summary>

publicboolIsText

{

get

{

return _Data isstring;

}

}

#endregion

}

}

ФайлParameters. cs

using System;

using System. Collections. Generic;

using System. Text. RegularExpressions;

namespace IS_DJ

{

///< summary>

/// Класс для обработки параметров в значениях MIME-заголовков

///< /summary>

publicclassParameters

{

#regionНестатические поля

privatereadonlyDictionary< string, string> _Parameters;

privatereadonlystring _Source = String. Empty;

privatereadonlystring _Type = String. Empty;

#endregion

#region Конструкторы

///< summary>

/// Конструктор класса

///< /summary>

///< param name="source"> Параметр</param>

public Parameters (string source)

{

if (String. IsNullOrEmpty (source)) return;

_Source = source;

inttypeTail = source. IndexOf («;»);

if (typeTail == -1)

{

// все содержимое источника является информацией о типе

_Type = source;

return;

}

_Type = source. Substring (0, typeTail);

string p = source. Substring (typeTail + 1,

source. Length — typeTail — 1);

_Parameters =

newDictionary< string, string> (

String Comparer. CurrentCultureIgnoreCase);

varmyReg =

newRegex (

@"(?< key>. +?)=((«„(?<value>. +?)“»)|((?<value>[^;]+)))[;]{0,1}",

RegexOptions. Singleline);

MatchCollection mc = myReg. Matches (p);

foreach (Match m in mc)

{

if (!_Parameters. ContainsKey (m. Groups["key"]. Value))

{

_Parameters. Add (m. Groups["key"]. Value. Trim (),

m. Groups["value"]. Value);

}

}

}

#endregion

#regionСвойства

///< summary>

///Источник данных

///< /summary>

publicstring Source

{

get

{

return _Source;

}

}

///< summary>

///Тип

///< /summary>

publicstringType

{

get

{

return _Type;

}

}

///< summary>

/// Коллекция параметров

///< /summary>

Public Dictionary< string, string> ParametersDictionary

{

get

{

return _Parameters;

}

}

#endregion

}

}

ФайлPop3Client. cs

using System;

using System. Net;

usingSystem. Net. Sockets;

usingSystem. Text;

namespace IS_DJ

{

///< summary>

/// Основной класс для работы с протоколом Pop3

///< /summary>

publicclassPop3Client

{

#regionНестатические поля

privatereadonlyFormMain _FormMain;

privatereadonlystring _Host;

privatereadonlystring _Password;

privatereadonlyint _Port;

privatereadonlystring _UserName;

privateint _Index;

privatePop3Result _ServerResponse;

privateSocket _Socket;

publicintMessageCount;

publicintMessagesSize;

#endregion

#region Конструкторы

///< summary>

/// Конструктор класса

///< /summary>

///< param name="formMain"> Главная форма приложения< /param>

///< param name="host"> Имяхоста</param>

///< param name="userName"> Логин доступа< /param>

///< param name="password"> Пароль доступа< /param>

public Pop3Client (FormMainformMain, string host, stringuserName,

string password)

{

_Host = host;

_Password = password;

_Port = 110;

_UserName = userName;

_ServerResponse = newPop3Result ();

_FormMain = formMain;

Connect ();

}

#endregion

#regionМетоды

///< summary>

/// Подключение к почтовому серверу

///< /summary>

publicvoid Connect ()

{

// получение ip сервера

IPHostEntrymyIPHostEntry = Dns. GetHostEntry (_Host);

if (myIPHostEntry == null || myIPHostEntry. AddressList == null

|| myIPHostEntry. AddressList. Length<= 0)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

«Не удалось определить IP-адрес по хосту. «);

return;

}

// получение сетевой конечной точки

varmyIPEndPoint = newIPEndPoint (myIPHostEntry. AddressList[0],

_Port);

// инициализация сокета

_Socket = newSocket (AddressFamily. InterNetwork, SocketType. Stream,

ProtocolType. Tcp);

_Socket. ReceiveBufferSize = 512;

// размер приемного буфера в байтах

// соединение с сервером

_Socket. Connect (myIPEndPoint);

// получение ответа сервера

ReadLine ();

// выполнение авторизации

Command (String. Format («USER {0}», _UserName));

ReadLine ();

Command (String. Format («PASS {0}», _Password));

_ServerResponse = ReadLine ();

if (_ServerResponse. IsError)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

_ServerResponse. ServerMessage);

return;

}

// запрос статистики почтового ящика

Command («STAT»);

_ServerResponse = ReadLine ();

if (_ServerResponse. IsError)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

_ServerResponse. ServerMessage);

return;

}

_ServerResponse. ParseStat (outMessageCount, outMessagesSize);

}

///< summary>

/// Завершение сеанса связи с сервером

///< /summary>

publicvoid Close ()

{

if (_Socket == null)

{

return;

}

Command («QUIT»);

ReadLine ();

_Socket. Close ();

}

///< summary>

///Следующее письмо

///< /summary>

publicboolNextMail (outMailItem m)

{

m = null;

// следующее письмо

_Index++;

if (_Index > MessageCount) returnfalse;

Command (String. Format («RETR {0}», _Index));

_ServerResponse = ReadToEnd ();

if (_ServerResponse. IsError)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

_ServerResponse. ServerMessage);

returnfalse;

}

_ServerResponse. ParseMail (out m);

returntrue;

}

///< summary>

/// Удаление текущего письма

///< /summary>

publicvoid Delete ()

{

Delete (_Index);

}

///< summary>

/// Удаление письма по номеру

///< /summary>

///< param name="index"> Номер письма< /param>

publicvoid Delete (int index)

{

if (index > MessageCount)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

String. Format («Индекс должен быть от 1 и не больше{0}»,

MessageCount));

return;

}

Command (String. Format («DELE {0}», index));

_ServerResponse = ReadLine ();

if (_ServerResponse. IsError)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

_ServerResponse. ServerMessage);

}

}

///< summary>

/// Отправление команды почтовому серверу

///< /summary>

///< param name="cmd"> Команда</param>

publicvoid Command (stringcmd)

{

if (_Socket == null)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

«Соединение с сервером не установлено. Откройте соединение методом Connect. «);

return;

}

byte[] b = Encoding. ASCII. GetBytes (String. Format («{0}rn», cmd));

if (_Socket. Send (b, b. Length, SocketFlags. None) ≠ b. Length)

{

varformMessage = newFormMessage («Ошибка»);

formMessage. ShowMessage (_FormMain,

«При отправке данных удаленному серверу произошла ошибка. «);

}

}

///< summary>

/// Чтение первой строки ответа сервера из буфера

///< /summary>

publicstringReadLine ()

{

var b = newbyte[_Socket. ReceiveBufferSize];

var result = newStringBuilder (_Socket. ReceiveBufferSize);

int s;

while (_Socket. Poll (1 000 000, SelectMode. SelectRead)

& &

(s =

_Socket. Receive (b, _Socket. ReceiveBufferSize,

SocketFlags. None)) > 0)

{

result. Append (Encoding. ASCII. GetChars (b, 0, s));

}

returnresult. ToString (). TrimEnd («rn». ToCharArray ());

}

///< summary>

/// Получение содержимого ответа сервера из буфера

///< /summary>

publicstringReadToEnd ()

{

var b = newbyte[_Socket. ReceiveBufferSize];

var result = newStringBuilder (_Socket. ReceiveBufferSize);

int s;

while (_Socket. Poll (1 000 000, SelectMode. SelectRead)

& &

((s =

_Socket. Receive (b, _Socket. ReceiveBufferSize,

SocketFlags. None)) > 0))

{

result. Append (Encoding. GetEncoding («windows-1251»). GetChars (

b, 0, s));

}

returnresult. ToString ();

}

#endregion

}

}

ФайлPop3Result. cs

usingSystem. ComponentModel;

usingSystem. Text. RegularExpressions;

namespace IS_DJ

{

///< summary>

/// Универсальный обработчик ответов почтового сервера

///< /summary>

[DefaultProperty («Source»)]

publicclassPop3Result

{

#region Конструкторы

///< summary>

/// Конструктор класса

///< /summary>

///< param name="source"> </param>

public Pop3Result (string source)

{

Source = source;

IsError = source. StartsWith («-ERR»); // ошибка или нет

// сообщение о результате выполнения команды

varmyReg = newRegex (@"(+OK|-ERR)s{1}(?< msg>. *)?",

RegexOptions. Multiline | RegexOptions. IgnoreCase);

Server Message = myReg. Is Match (source)? myReg. Match (source). Groups["msg"]. Value: source;

if (source. IndexOf («rn») == -1) return;

Body = source. Substring (source. IndexOf («rn») + 2,

source. Length — source. IndexOf («rn») — 2);

if (Body. IndexOf («rnrn. rn») ≠ -1)

{

Body = Body. Substring (0, Body. IndexOf («rnrn. rn»));

}

}

public Pop3Result ()

{

}

#endregion

#regionМетоды

///< summary>

/// Реализация неявного оператора преобразования

///< /summary>

publicstaticimplicitoperatorPop3Result (string value)

{

returnnewPop3Result (value);

}

///< summary>

/// Получение из ответа сервера информации о количестве писем и их размере.

/// Используется только при команде STAT

///< /summary>

///< paramname="messagesCount">Количество сообщений (начиная с 1)< /param>

///< param name="messagesSize"> Общий размер сообщений< /param>

publicvoidParseStat (outintmessagesCount, outintmessagesSize)

{

varmyReg = newRegex (@"(?< count>d+)s+(?<size>d+)");

Match m = myReg. Match (Source);

int. TryParse (m. Groups["count"]. Value, outmessagesCount);

int. TryParse (m. Groups["size"]. Value, outmessagesSize);

}

///< summary>

/// Передача обработанного письма на основе данных, полученных от почтового сервера

///< /summary>

///< paramname="m">Переменная, в которую будет передано обработанное письмо< /param>

publicvoidParseMail (outMailItem m)

{

m = newMailItem (Body);

}

#endregion

#regionСвойства

///< summary>

///Исходные данные

///< /summary>

publicstring Source { get; set; }

///< summary>

/// Показатель ошибки в ответе сервера

///< /summary>

publicboolIsError { get; set; }

///< summary>

/// Сообщение сервера (первая строка)

///< /summary>

publicstringServerMessage { get; set; }

///< summary>

/// Тело ответа сервера, исключая код ответа и сообщение

///< /summary>

publicstring Body { get; set; }

#endregion

}

}

ПРИЛОЖЕНИЕ 4

Исходный текст метода обработки события таймера

Фрагмент файлаPop3Result. cs

///< summary>

/// Выполнение действий по таймеру

///< /summary>

///< param name="sender"> Отправитель</param>

///< param name="e"> Параметры</param>

privatevoidtimerMail_Tick (object sender, EventArgs e)

{

Pop3Client myPop3 = newPop3Client (this, «pop. yandex. ru», «dj843», «isdjisdj»);

MailItem m;

string[] separator = new[] { «rn» };

while (myPop3. NextMail (out m))

{

if (m. Subject == «DJ843»)

{

try

{

stringmessageText = m. GetText ();

string[] message = messageText. Split (separator,

StringSplitOptions. RemoveEmptyEntries);

if (message. Length>= 7)

{

try

{

string text = ««;

for (int i = 4; i < message. Length; i++)

{

text += message[i] + «rn»;

}

_Connection. Open ();

SqlCommand com = _Connection. CreateCommand ();

com. CommandText = «EXECUTE FindSongSelect @N1, @N2»;

com. Parameters. Add («@N1», SqlDbType. NVarChar). Value = message[1];

com. Parameters. Add («@N2», SqlDbType. NVarChar). Value = message[0];

SqlDataAdapterdataAdapter = newSqlDataAdapter (com);

DataTable songs = newDataTable ();

dataAdapter. Fill (songs);

_Connection. Close ();

if (message[3]. Length < 5)

message[3] = «0» + message[3];

if (songs. Rows. Count>0)

{

intnSong = (int)songs. Rows[0][0];

DateTime time = newDateTime (

int. Parse (message[2]. Substring (6, 4)),

int. Parse (message[2]. Substring (3, 2)),

int. Parse (message[2]. Substring (0, 2)),

int. Parse (message[3]. Substring (0, 2)),

int. Parse (message[3]. Substring (3, 2)),

0);

_Connection. Open ();

com = _Connection. CreateCommand ();

com. CommandText = «EXECUTE RequestInsert @N1, @N2, @N3»;

com. Parameters. Add («@N1», SqlDbType. Int). Value = nSong;

com. Parameters. Add («@N2», SqlDbType. DateTime). Value = time;

com. Parameters. Add («@N3», SqlDbType. Text). Value = text;

dataAdapter = newSqlDataAdapter (com);

dataAdapter. Fill (newDataTable ());

_Connection. Close ();

bindingSourceRequest. DataSource = RunSP («RequestSelect»);

}

}

catch (Exception)

{

_Connection. Close ();

}

}

}

catch { }

}

myPop3. Delete ();

}

myPop3. Close ();

}

///< summary>

///Включение таймера

///< /summary>

///< param name="sender"> Отправитель</param>

///< param name="e"> Параметры</param>

privatevoidFormMain_Shown (object sender, EventArgs e)

{

timerMail. Enabled = true;

}

ПоказатьСвернуть
Заполнить форму текущей работой