
8 семестр / Готовая курсовая работа / ММиВА. Курсовая работа
.pdf17// getters
18std::string get_server_address() const;
19int get_server_port() const;
20std::string get_login() const;
21std::string get_password() const;
22std::string get_name() const;
23mailio::smtps::auth_method_t get_auth_method() const;
25private:
26std::string server_address, login, password, name;
27int server_port;
28mailio::smtps::auth_method_t auth_method;
29};
30
31 #endif // SMTPSETTINGS_H
Модуль «smtp_settings.cpp»
1 #include "smtp_settings.h"
2
3 SmtpSettings::SmtpSettings()
4{
5}
7// setters
8void SmtpSettings::set_server_address(const std::string &server_address)
9{
10this->server_address = server_address;
11}
12void SmtpSettings::set_server_port(int server_port)
13{
14this->server_port = server_port;
15}
16void SmtpSettings::set_login(const std::string &login)
17{
18this->login = login;
19}
20void SmtpSettings::set_password(std::string password)
21{
22for (size_t i = 0, n = password.length(); i < n; ++i)
23{
24password[i] ^= 0x10100110 ^ i;
25}
26this->password = password;
27}
28void SmtpSettings::set_name(const std::string &name)
29{
30this->name = name;
31}
32void SmtpSettings::set_auth_method(const mailio::smtps::auth_method_t &auth_method)
33{
34this->auth_method = auth_method;
35}
36
37// getters
38std::string SmtpSettings::get_server_address() const
39{
40return this->server_address;
41}
42int SmtpSettings::get_server_port() const
43{
44return this->server_port;
45}
46std::string SmtpSettings::get_login() const
47{
48return this->login;
49}
50std::string SmtpSettings::get_password() const
51{
41
52std::string decoded_password(password);
53for (size_t i = 0, n = decoded_password.length(); i < n; ++i)
54{
55decoded_password[i] ^= 0x10100110 ^ i;
56}
57return decoded_password;
58}
59std::string SmtpSettings::get_name() const
60{
61return this->name;
62}
63mailio::smtps::auth_method_t SmtpSettings::get_auth_method() const
64{
65return this->auth_method;
66}
Модуль «tools.h»
1#ifndef TOOLS_H
2#define TOOLS_H
4#include <QList>
5#include <QString>
6#include <QStringConverter>
8QString utf7encode(QString str)
9{
10auto toUtf16be = QStringEncoder(QStringConverter::Utf16BE);
11QString unipart, out;
12str.replace("&", "&-");
13for (QChar ch : str)
14{
15uint16_t i16 = ch.unicode();
16if (0x20 <= i16 && i16 <= 0x7f)
17{
18 |
if (!unipart.isEmpty()) |
19 |
{ |
20 |
QByteArray unipart16be_bytes = (QByteArray)toUtf16be(unipart); |
21 |
QString encoded_string(unipart16be_bytes.toBase64( |
22 |
QByteArray::Base64Option::Base64Encoding | |
|
QByteArray::Base64Option::OmitTrailingEquals | |
23 |
QByteArray::Base64Option::IgnoreBase64DecodingErrors)); |
24 |
out += '&' + encoded_string.replace('/', ',') + '-'; |
25 |
unipart.clear(); |
26 |
} |
27 |
out += ch; |
28}
29else
30{
31 |
unipart += ch; |
32}
33}
34if (!unipart.isEmpty())
35{
36QByteArray unipart16be_bytes = (QByteArray)toUtf16be(unipart);
37QString
encoded_string(unipart16be_bytes.toBase64(QByteArray::Base64Option::Base64Encoding |
38
QByteArray::Base64Option::OmitTrailingEquals |
39
QByteArray::Base64Option::IgnoreBase64DecodingErrors));
40out += '&' + encoded_string.replace('/', ',') + '-';
41unipart.clear();
42}
43return out;
44}
45
46QString utf7decode(const QString &str)
47{
42
48auto fromUtf16be = QStringDecoder(QStringConverter::Utf16BE);
49QList<QString> parts = str.split('&', Qt::KeepEmptyParts);
50if (parts.empty())
51{
52return QString();
53}
54QString out = parts[0];
55for (qsizetype i = 1, n = parts.size(); i < n; ++i)
56{
57QString part = parts[i], first, last;
58qsizetype pos = part.indexOf('-');
59if (pos != -1)
60{
61 |
first = part.left(pos); |
62 |
last = part.right(part.size() - pos - 1); |
63}
64else
65{
66 |
first = part; |
67}
68if (first.isEmpty())
69{
70 |
out += '&'; |
71}
72else
73{
74 |
first = first.replace(',', '/'); |
75 |
QByteArray decoded_bytes = |
76 |
QByteArray::fromBase64(first.toUtf8(), |
|
QByteArray::Base64Option::Base64Encoding | |
77 |
|
|
QByteArray::Base64Option::OmitTrailingEquals | |
78 |
|
|
QByteArray::Base64Option::IgnoreBase64DecodingErrors); |
79 |
out += fromUtf16be(decoded_bytes); |
80}
81out += last;
82}
83return out;
84}
85
86 #endif // TOOLS_H
Модуль «send_message_dialog.h»
1#ifndef SEND_MESSAGE_DIALOG_H
2#define SEND_MESSAGE_DIALOG_H
4#include <QCloseEvent>
5#include <QDialog>
7#include <mailio/message.hpp>
9namespace Ui
10{
11class SendMessageDialog;
12}
13
14class SendMessageDialog : public QDialog
15{
16Q_OBJECT
17
18public:
19explicit SendMessageDialog(QWidget *parent = nullptr);
20mailio::message get_message();
21~SendMessageDialog() override;
22
23private slots:
24void on_add_attachment_clicked();
43
25 void on_remove_attachment_clicked();
26
27private:
28void closeEvent(QCloseEvent *event) override;
30Ui::SendMessageDialog *ui;
31std::list<std::tuple<std::shared_ptr<std::stringstream>, std::string, mailio::message::content_type_t>> attachments;
32 |
}; |
33 |
|
34 |
#endif // SEND_MESSAGE_DIALOG_H |
Модуль «send_message_dialog.cpp»
1#include <QFileDialog>
2#include <QMessageBox>
4#include "send_message_dialog.h"
5#include "ui_send_message_dialog.h"
7SendMessageDialog::SendMessageDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SendMessageDialog)
8{
9ui->setupUi(this);
10ui->attachments_table->setSortingEnabled(false);
11ui->attachments_table->horizontalHeader()- >resizeSections(QHeaderView::ResizeMode::ResizeToContents);
12}
13
14SendMessageDialog::~SendMessageDialog()
15{
16delete ui;
17}
18
19mailio::message SendMessageDialog::get_message()
20{
21QRegularExpression delim("[,;\t ]+");
22mailio::message message;
23QString subject = ui->subject_line_edit->text();
24QStringList recipients = ui->recipients_line_edit->text().split(delim, Qt::SkipEmptyParts);
25QStringList cc_recipients = ui->cc_recipients_line_edit->text().split(delim, Qt::SkipEmptyParts);
26QStringList bcc_recipients = ui->bcc_recipients_line_edit->text().split(delim, Qt::SkipEmptyParts);
27QString content = ui->content_text_edit->toPlainText();
28message.subject(subject.toStdString());
29for (auto recipient : recipients)
30{
31auto recipient_s = recipient.simplified().toStdString();
32message.add_recipient(mailio::mail_address(recipient_s, recipient_s));
33}
34for (auto recipient : cc_recipients)
35{
36auto recipient_s = recipient.simplified().toStdString();
37message.add_cc_recipient(mailio::mail_address(recipient_s, recipient_s));
38}
39for (auto recipient : bcc_recipients)
40{
41auto recipient_s = recipient.simplified().toStdString();
42message.add_bcc_recipient(mailio::mail_address(recipient_s, recipient_s));
43}
44
message.content_transfer_encoding(mailio::mime::content_transfer_encoding_t::BASE_64);
45message.content_type(mailio::message::media_type_t::TEXT, "plain", "utf-8");
46message.content(content.toStdString());
47if (!attachments.empty())
48{
44
49std::list<std::tuple<std::istream &, std::string, mailio::message::content_type_t>> attachments_tlist;
50for (auto attachment : attachments)
51{
52 |
std::shared_ptr<std::stringstream> ss; |
53 |
std::string filename; |
54 |
mailio::message::content_type_t content_type; |
55 |
std::tie(ss, filename, content_type) = attachment; |
56 |
attachments_tlist.emplace_back( |
57 |
std::tuple<std::istream &, std::string, |
mailio::message::content_type_t>(*ss, filename, content_type));
58}
59message.attach(attachments_tlist);
60}
61return message;
62}
63
64void SendMessageDialog::on_add_attachment_clicked()
65{
66try
67{
68QString filename = QFileDialog::getOpenFileName(this, "Добавить вложение", "", "All files (*.*)");
69if (filename.isEmpty())
70{
71 |
return; |
72}
73std::fstream file_stream(filename.toStdWString().c_str(), std::ios::in | std::ios::binary);
74if (!file_stream.is_open())
75{
76 |
QMessageBox::warning(this, "Внимание", "Файл недоступен для чтения"); |
77 |
return; |
78}
79file_stream.seekg(0, file_stream.end);
80std::basic_istream<char>::pos_type size = file_stream.tellg();
81file_stream.seekg(0, file_stream.beg);
82std::string attachment_size;
83constexpr size_t kb = 1 << 10, mb = kb << 10, gb = mb << 10;
84if (size >= gb)
85{
86 |
size = size * 100 |
/ gb; |
87 |
attachment_size = |
std::to_string(size / 100) + "." + std::to_string(size % |
|
100) + " ГиБ"; |
|
88}
89else if (size >= mb)
90{
91 |
size = size * 100 |
/ mb; |
92 |
attachment_size = |
std::to_string(size / 100) + "." + std::to_string(size % |
|
100) + " МиБ"; |
|
93}
94else if (size >= kb)
95{
96 |
size = size * 100 / kb; |
97 |
attachment_size = std::to_string(size / 100) + "." + std::to_string(size % |
|
100) + " КиБ"; |
98}
99else
100{
101 |
attachment_size = std::to_string(size) + " Б"; |
102}
103std::shared_ptr<std::stringstream> ss = std::make_shared<std::stringstream>();
104std::ostream &os = *ss;
105os << ((std::istream &)file_stream).rdbuf();
106ss->seekg(0, ss->beg);
107file_stream.close();
108std::string filename_s = filename.toStdString();
109std::string base_filename = filename_s.substr(filename_s.find_last_of("/\\") +
1);
110int new_last_index = ui->attachments_table->rowCount();
111attachments.emplace_back(
45
112 |
std::tuple<std::shared_ptr<std::stringstream>, std::string, |
|
mailio::message::content_type_t>( |
113 |
ss, base_filename, |
mailio::message::content_type_t(mailio::message::media_type_t::MULTIPART, "mixed")));
114ui->attachments_table->setRowCount(new_last_index + 1);
115ui->attachments_table->setItem(new_last_index, 0, new QTableWidgetItem(QString::fromStdString(base_filename)));
116ui->attachments_table->setItem(new_last_index, 1,
117 new QTableWidgetItem(QString::fromStdString(attachment_size)));
118ui->attachments_table->setItem(new_last_index, 2, new QTableWidgetItem(filename));
119ui->attachments_table->horizontalHeader()- >resizeSections(QHeaderView::ResizeMode::ResizeToContents);
120}
121catch (const std::exception &exc)
122{
123QMessageBox::critical(this, "Внимание", "Ошибка добавления вложения");
124}
125}
126 |
|
127 |
void SendMessageDialog::on_remove_attachment_clicked() |
128 |
{ |
129 |
try |
130 |
{ |
131 |
if (ui->attachments_table->currentItem() != nullptr) |
132 |
{ |
133 |
int current_row = ui->attachments_table->currentRow(); |
134 |
auto it = attachments.begin(); |
135 |
std::advance(it, current_row); |
136 |
attachments.erase(it); |
137 |
ui->attachments_table->removeRow(current_row); |
138 |
ui->attachments_table->horizontalHeader()- |
|
>resizeSections(QHeaderView::ResizeMode::ResizeToContents); |
139}
140}
141catch (const std::exception &exc)
142{
143QMessageBox::critical(this, "Внимание", "Ошибка удаления вложения");
144}
145}
146
147void SendMessageDialog::closeEvent(QCloseEvent *event)
148{
149if (QMessageBox::question(this, "Внимание", "Сообщение не будет отправлено и/или сохранено. Продолжить?",
150 |
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == |
|
QMessageBox::Yes) |
151{
152event->accept();
153}
154else
155{
156event->ignore();
157}
158}
Модуль «settings_dialog.h»
1#ifndef SETTINGS_DIALOG_H
2#define SETTINGS_DIALOG_H
4#include <QCloseEvent>
5#include <QDialog>
7#include "imap_settings.h"
8#include "smtp_settings.h"
10namespace Ui
46
11{
12class SettingsDialog;
13}
14
15class SettingsDialog : public QDialog
16{
17Q_OBJECT
18
19public:
20explicit SettingsDialog(QWidget *parent = nullptr);
21void set_imap_settings(const ImapSettings &arg_imap_settings);
22void set_smtp_settings(const SmtpSettings &arg_smtp_settings);
23ImapSettings get_imap_settings() const;
24SmtpSettings get_smtp_settings() const;
25~SettingsDialog() override;
26
27private slots:
28void on_mail_server_combo_box_textActivated(const QString &text);
29void on_smtp_login_line_edit_textEdited(const QString &arg1);
30
31private:
32void closeEvent(QCloseEvent *event) override;
34Ui::SettingsDialog *ui;
35 |
}; |
36 |
|
37 |
#endif // SETTINGS_DIALOG_H |
Модуль «settings_dialog.cpp»
1 #include <QMessageBox>
2
3#include "settings_dialog.h"
4#include "ui_settings_dialog.h"
6SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new
Ui::SettingsDialog)
7{
8ui->setupUi(this);
9this->setFixedSize(QSize(540, 360));
10}
11
12SettingsDialog::~SettingsDialog()
13{
14delete ui;
15}
16
17void SettingsDialog::set_imap_settings(const ImapSettings &arg_imap_settings)
18{
19ui->imap_server_line_edit-
>setText(QString::fromStdString(arg_imap_settings.get_server_address()));
20ui->imap_port_spin_box->setValue(arg_imap_settings.get_server_port());
21ui->imap_login_line_edit-
>setText(QString::fromStdString(arg_imap_settings.get_login()));
22ui->imap_password_line_edit- >setText(QString::fromStdString(arg_imap_settings.get_password()));
23ui->autoupdate_check_box->setChecked(arg_imap_settings.get_autoupdate());
24ui->autoupdate_spin_box->setValue(arg_imap_settings.get_autoupdate_interval());
25mailio::imaps::auth_method_t method = arg_imap_settings.get_auth_method();
26if (method == mailio::imaps::auth_method_t::LOGIN)
27{
28ui->imap_auth_combo_box->setCurrentText("LOGIN");
29}
30else if (method == mailio::imaps::auth_method_t::START_TLS)
31{
32ui->imap_auth_combo_box->setCurrentText("START_TLS");
33}
34else
35{
47
36ui->imap_auth_combo_box->setCurrentText("");
37}
38if (ui->imap_server_line_edit->text().contains("yandex", Qt::CaseInsensitive))
39{
40ui->mail_server_combo_box->setCurrentText("Yandex");
41}
42else if (ui->imap_server_line_edit->text().contains("gmail", Qt::CaseInsensitive))
43{
44ui->mail_server_combo_box->setCurrentText("Gmail");
45}
46else if (ui->imap_server_line_edit->text().contains("mail.ru", Qt::CaseInsensitive))
47{
48ui->mail_server_combo_box->setCurrentText("Mail.ru");
49}
50else
51{
52ui->mail_server_combo_box->clearEditText();
53}
54}
55
56void SettingsDialog::set_smtp_settings(const SmtpSettings &arg_smtp_settings)
57{
58ui->smtp_server_line_edit-
>setText(QString::fromStdString(arg_smtp_settings.get_server_address()));
59ui->smtp_port_spin_box->setValue(arg_smtp_settings.get_server_port());
60ui->smtp_login_line_edit-
>setText(QString::fromStdString(arg_smtp_settings.get_login()));
61ui->smtp_password_line_edit- >setText(QString::fromStdString(arg_smtp_settings.get_password()));
62ui->smtp_name_line_edit-
>setText(QString::fromStdString(arg_smtp_settings.get_name()));
63mailio::smtps::auth_method_t method = arg_smtp_settings.get_auth_method();
64if (method == mailio::smtps::auth_method_t::LOGIN)
65{
66ui->smtp_auth_combo_box->setCurrentText("LOGIN");
67}
68else if (method == mailio::smtps::auth_method_t::START_TLS)
69{
70ui->smtp_auth_combo_box->setCurrentText("START_TLS");
71}
72else if (method == mailio::smtps::auth_method_t::NONE)
73{
74ui->smtp_auth_combo_box->setCurrentText("NONE");
75}
76else
77{
78ui->smtp_auth_combo_box->setCurrentText("");
79}
80if (ui->mail_server_combo_box->currentText().isEmpty())
81{
82if (ui->smtp_server_line_edit->text().contains("yandex", Qt::CaseInsensitive))
83{
84 |
ui->mail_server_combo_box->setCurrentText("Yandex"); |
85}
86else if (ui->smtp_server_line_edit->text().contains("gmail", Qt::CaseInsensitive))
87{
88 |
ui->mail_server_combo_box->setCurrentText("Gmail"); |
89}
90else if (ui->smtp_server_line_edit->text().contains("mail.ru", Qt::CaseInsensitive))
91{
92 |
ui->mail_server_combo_box->setCurrentText("Mail.ru"); |
93}
94}
95}
96
97ImapSettings SettingsDialog::get_imap_settings() const
98{
99ImapSettings new_imap_settings;
48
100new_imap_settings.set_server_address(ui->imap_server_line_edit- >text().toStdString());
101new_imap_settings.set_server_port(ui->imap_port_spin_box->value());
102new_imap_settings.set_login(ui->imap_login_line_edit->text().toStdString());
103new_imap_settings.set_password(ui->imap_password_line_edit->text().toStdString());
104new_imap_settings.set_autoupdate(ui->autoupdate_check_box->isChecked());
105new_imap_settings.set_autoupdate_interval(ui->autoupdate_spin_box->value());
106if (ui->imap_auth_combo_box->currentText() == "LOGIN")
107{
108new_imap_settings.set_auth_method(mailio::imaps::auth_method_t::LOGIN);
109}
110else if (ui->imap_auth_combo_box->currentText() == "START_TLS")
111{
112new_imap_settings.set_auth_method(mailio::imaps::auth_method_t::START_TLS);
113}
114else
115{
116new_imap_settings.set_auth_method(mailio::imaps::auth_method_t::LOGIN);
117}
118return new_imap_settings;
119}
120
121SmtpSettings SettingsDialog::get_smtp_settings() const
122{
123SmtpSettings new_smtp_settings;
124new_smtp_settings.set_server_address(ui->smtp_server_line_edit- >text().toStdString());
125new_smtp_settings.set_server_port(ui->smtp_port_spin_box->value());
126new_smtp_settings.set_login(ui->smtp_login_line_edit->text().toStdString());
127new_smtp_settings.set_password(ui->smtp_password_line_edit->text().toStdString());
128new_smtp_settings.set_name(ui->smtp_name_line_edit->text().toStdString());
129if (ui->smtp_auth_combo_box->currentText() == "LOGIN")
130{
131new_smtp_settings.set_auth_method(mailio::smtps::auth_method_t::LOGIN);
132}
133else if (ui->smtp_auth_combo_box->currentText() == "START_TLS")
134{
135new_smtp_settings.set_auth_method(mailio::smtps::auth_method_t::START_TLS);
136}
137else if (ui->smtp_auth_combo_box->currentText() == "NONE")
138{
139new_smtp_settings.set_auth_method(mailio::smtps::auth_method_t::NONE);
140}
141else
142{
143new_smtp_settings.set_auth_method(mailio::smtps::auth_method_t::LOGIN);
144}
145return new_smtp_settings;
146}
147
148void SettingsDialog::on_mail_server_combo_box_textActivated(const QString &text)
149{
150if (text == "Yandex")
151{
152// imap
153ui->imap_server_line_edit->setText("imap.yandex.ru");
154ui->imap_port_spin_box->setValue(993);
155std::string imap_login = ui->imap_login_line_edit->text().toStdString();
156imap_login = imap_login.substr(0, imap_login.find('@')) + "@yandex.ru";
157ui->imap_login_line_edit->setText(QString::fromStdString(imap_login));
158ui->imap_auth_combo_box->setCurrentText("LOGIN");
159// smtp
160ui->smtp_server_line_edit->setText("smtp.yandex.ru");
161ui->smtp_port_spin_box->setValue(465);
162std::string smtp_login = ui->smtp_login_line_edit->text().toStdString();
163smtp_login = smtp_login.substr(0, smtp_login.find('@')) + "@yandex.ru";
164ui->smtp_login_line_edit->setText(QString::fromStdString(smtp_login));
165ui->smtp_auth_combo_box->setCurrentText("LOGIN");
166}
167else if (text == "Gmail")
168{
49
169// imap
170ui->imap_server_line_edit->setText("imap.gmail.com");
171ui->imap_port_spin_box->setValue(993);
172std::string imap_login = ui->imap_login_line_edit->text().toStdString();
173imap_login = imap_login.substr(0, imap_login.find('@')) + "@gmail.com";
174ui->imap_login_line_edit->setText(QString::fromStdString(imap_login));
175ui->imap_auth_combo_box->setCurrentText("LOGIN");
176// smtp
177ui->smtp_server_line_edit->setText("smtp.gmail.com");
178ui->smtp_port_spin_box->setValue(465);
179std::string smtp_login = ui->smtp_login_line_edit->text().toStdString();
180smtp_login = smtp_login.substr(0, smtp_login.find('@')) + "@gmail.com";
181ui->smtp_login_line_edit->setText(QString::fromStdString(smtp_login));
182ui->smtp_auth_combo_box->setCurrentText("LOGIN");
183}
184else if (text == "Mail.ru")
185{
186// imap
187ui->imap_server_line_edit->setText("imap.mail.ru");
188ui->imap_port_spin_box->setValue(993);
189std::string imap_login = ui->imap_login_line_edit->text().toStdString();
190imap_login = imap_login.substr(0, imap_login.find('@')) + "@mail.ru";
191ui->imap_login_line_edit->setText(QString::fromStdString(imap_login));
192ui->imap_auth_combo_box->setCurrentText("LOGIN");
193// smtp
194ui->smtp_server_line_edit->setText("smtp.mail.ru");
195ui->smtp_port_spin_box->setValue(465);
196std::string smtp_login = ui->smtp_login_line_edit->text().toStdString();
197smtp_login = smtp_login.substr(0, smtp_login.find('@')) + "@mail.ru";
198ui->smtp_login_line_edit->setText(QString::fromStdString(smtp_login));
199ui->smtp_auth_combo_box->setCurrentText("LOGIN");
200}
201}
202
203void SettingsDialog::on_smtp_login_line_edit_textEdited(const QString &login)
204{
205std::string s = login.toStdString();
206s = s.substr(0, s.find('@'));
207ui->smtp_name_line_edit->setText(QString::fromStdString(s));
208}
209
210void SettingsDialog::closeEvent(QCloseEvent *event)
211{
212if (QMessageBox::question(this, "Внимание", "Настройки не будут сохранены.
|
Продолжить?", |
213 |
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == |
|
QMessageBox::Yes) |
214{
215event->accept();
216}
217else
218{
219event->ignore();
220}
221}
Модуль «mainwindow.h»
1#ifndef MAINWINDOW_H
2#define MAINWINDOW_H
4#include <mutex>
5#include <unordered_map>
6#include <unordered_set>
8#include <QCloseEvent>
9#include <QMainWindow>
10#include <QTableWidget>
11#include <QTextDocument>
50