1 /*
2 * %kadu copyright begin%
3 * Copyright 2015 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
4 * %kadu copyright end%
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "gadu-outgoing-file-transfer-handler.h"
21
22 #include "services/drive/gadu-drive-put-transfer.h"
23 #include "services/drive/gadu-drive-send-status-update-request.h"
24 #include "services/drive/gadu-drive-send-ticket-ack-status.h"
25 #include "services/drive/gadu-drive-send-ticket-request.h"
26 #include "services/drive/gadu-drive-send-ticket-status.h"
27 #include "services/drive/gadu-drive-service.h"
28 #include "gadu-protocol.h"
29
30 #include "file-transfer/file-transfer-status.h"
31
32 #include <QtCore/QTimer>
33
GaduOutgoingFileTransferHandler(GaduProtocol * protocol,FileTransfer fileTransfer)34 GaduOutgoingFileTransferHandler::GaduOutgoingFileTransferHandler(GaduProtocol *protocol, FileTransfer fileTransfer) :
35 OutgoingFileTransferHandler{fileTransfer},
36 m_protocol{protocol}
37 {
38 }
39
~GaduOutgoingFileTransferHandler()40 GaduOutgoingFileTransferHandler::~GaduOutgoingFileTransferHandler()
41 {
42 clenaup();
43 }
44
clenaup()45 void GaduOutgoingFileTransferHandler::clenaup()
46 {
47 if (m_source)
48 {
49 m_source->close();
50 m_source->deleteLater();
51 m_source = nullptr;
52 }
53
54 if (m_putTransfer)
55 {
56 m_putTransfer->deleteLater();
57 m_putTransfer = nullptr;
58 }
59 }
60
send(QIODevice * source)61 void GaduOutgoingFileTransferHandler::send(QIODevice *source)
62 {
63 m_source = source;
64
65 if (!m_protocol)
66 {
67 transfer().setTransferStatus(FileTransferStatus::NotConnected);
68 return;
69 }
70
71 auto contact = transfer().peer();
72 auto driveService = m_protocol->driveService();
73 auto sendTicketRequest = driveService->requestSendTicket(contact.id(), transfer().remoteFileName(), transfer().fileSize());
74 connect(sendTicketRequest, SIGNAL(sendTickedReceived(GaduDriveSendTicket)), this, SLOT(initialStatusUpdateReceived(GaduDriveSendTicket)));
75
76 transfer().setTransferStatus(FileTransferStatus::WaitingForConnection);
77 }
78
initialStatusUpdateReceived(GaduDriveSendTicket ticket)79 void GaduOutgoingFileTransferHandler::initialStatusUpdateReceived(GaduDriveSendTicket ticket)
80 {
81 m_ticket = std::move(ticket);
82 updateStatus();
83 }
84
statusUpdateReceived(GaduDriveSendTicket ticket)85 void GaduOutgoingFileTransferHandler::statusUpdateReceived(GaduDriveSendTicket ticket)
86 {
87 m_ticket = std::move(ticket);
88 updateStatus();
89 }
90
updateStatus()91 void GaduOutgoingFileTransferHandler::updateStatus()
92 {
93 if (!m_ticket.isValid())
94 {
95 transfer().setError(tr("Valid GG Drive ticket not available"));
96 transfer().setTransferStatus(FileTransferStatus::NotConnected);
97 clenaup();
98 return;
99 }
100
101 transfer().setFileSize(m_ticket.fileSize());
102 transfer().setTransferredSize(m_ticket.progress() * m_ticket.fileSize());
103
104 if (m_ticket.status() == GaduDriveSendTicketStatus::Completed)
105 {
106 transfer().setTransferStatus(FileTransferStatus::Finished);
107 transfer().setTransferredSize(m_ticket.fileSize());
108 clenaup();
109 return;
110 }
111
112 if (m_ticket.ackStatus() != GaduDriveSendTicketAckStatus::Allowed)
113 {
114 transfer().setTransferStatus(FileTransferStatus::WaitingForAccept);
115 transfer().setTransferredSize(0);
116 }
117 else
118 {
119 startOutgoingTransferIfNotStarted();
120 transfer().setTransferStatus(FileTransferStatus::Transfer);
121 }
122
123 if (m_putTransfer)
124 QTimer::singleShot(1000, this, SLOT(requestSendStatusUpdate()));
125 }
126
startOutgoingTransferIfNotStarted()127 void GaduOutgoingFileTransferHandler::startOutgoingTransferIfNotStarted()
128 {
129 if (m_putTransfer)
130 return;
131
132 auto driveService = m_protocol->driveService();
133 m_putTransfer = driveService->putInOutbox(m_ticket, transfer().remoteFileName(), m_source);
134 connect(m_putTransfer, &GaduDrivePutTransfer::finished, this, &GaduOutgoingFileTransferHandler::requestSendStatusUpdate);
135 }
136
requestSendStatusUpdate()137 void GaduOutgoingFileTransferHandler::requestSendStatusUpdate()
138 {
139 auto driveService = m_protocol->driveService();
140 auto updateSendStatusRequest = driveService->requestSendStatusUpdate(m_ticket.ticketId());
141
142 connect(updateSendStatusRequest, SIGNAL(statusUpdateReceived(GaduDriveSendTicket)),
143 this, SLOT(statusUpdateReceived(GaduDriveSendTicket)));
144 }
145
stop()146 void GaduOutgoingFileTransferHandler::stop()
147 {
148 clenaup();
149 transfer().setTransferStatus(FileTransferStatus::NotConnected);
150 }
151
152 #include "moc_gadu-outgoing-file-transfer-handler.cpp"
153