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