rcbuildtask.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include <QDir>
  2. #include <QNetworkReply>
  3. // from WccApi
  4. #include "wccapi/wccbuild.h"
  5. #include "wccapi/wccdownloadbinaryrequest.h"
  6. #include "wccapi/wccnetworkaccessmanager.h"
  7. #include "wccapi/wccnetworkrequestbase.h"
  8. #include "wccapi/wccpostfilerequest.h"
  9. #include "generatoroutputview.h"
  10. #include "rcbuildtask.h"
  11. #include "rcsession.h"
  12. #include "common/fstraverseiterator.h"
  13. namespace
  14. {
  15. const int UPLOAD_TIMEOUT_MSEC = 30000;
  16. // 60 min (server should handle the timeout)
  17. const int BUILD_TIMEOUT_MSEC = 3600000;
  18. }
  19. RcBuildTask::RcBuildTask(GeneratorOutputView & generatorOutput,
  20. RcSession & session,
  21. const QString & projectName,
  22. const QString & projectDir,
  23. QObject * parent)
  24. : QObject(parent)
  25. , m_generatorOutput(generatorOutput)
  26. , m_session(session)
  27. , m_projectName(projectName)
  28. , m_projectDir(projectDir)
  29. , m_build(NULL)
  30. {
  31. traverseProjectDir();
  32. }
  33. #include <stdlib.h>
  34. void RcBuildTask::startBuilding(const QString & wccParams,
  35. const QString & downloadDir)
  36. {
  37. m_wccParams = wccParams;
  38. m_downloadDir = downloadDir;
  39. emit zipping();
  40. QString
  41. msg = QString("Starting build process for %1 in %2 for %3").arg(m_projectName,
  42. m_projectDir,
  43. m_wccParams);
  44. m_generatorOutput.printOutput(msg);
  45. QString
  46. requestUrl = RcSession::makeRequestUrl(QString("build?") + wccParams);
  47. m_build = new WccApi::WccBuild(requestUrl);
  48. connect(m_build,
  49. SIGNAL(processFinished(QString,QString)),
  50. this,
  51. SLOT(zipProcessSucceedSlot(QString,QString)));
  52. connect(m_build,
  53. SIGNAL(processFailed(QString)),
  54. this,
  55. SLOT(zipProcessFailedSlot(QString)));
  56. m_generatorOutput.printOutput(" - project dir: " + m_projectDir);
  57. m_generatorOutput.printOutput(" - project name: " + m_projectName);
  58. m_generatorOutput.printOutput(" - zipping ...");
  59. QDir zipTargetDir(m_projectDir);
  60. zipTargetDir.mkdir("foobar");
  61. //zipTargetDir.cdUp();
  62. foreach (QString fileName, m_projectFiles) {
  63. m_generatorOutput.printOutput(" - zipping file: " + fileName);
  64. }
  65. m_savedPath = QDir::currentPath();
  66. QDir::setCurrent(zipTargetDir.absolutePath());
  67. m_build->startProcess(zipTargetDir.absolutePath(),
  68. m_projectName,
  69. m_projectFiles);
  70. }
  71. void RcBuildTask::zipProcessSucceedSlot(const QString & buildUrl,
  72. const QString & zipFileName)
  73. {
  74. QDir::setCurrent(m_savedPath);
  75. emit uploadingAndWaiting();
  76. int
  77. id = m_session.nextReqId();
  78. WccApi::WccNetworkAccessManager
  79. * netAccessManager = m_session.networkAccessManager();
  80. m_generatorOutput.printOutput(QString(" - zipping succeeded: %1").arg(zipFileName));
  81. m_generatorOutput.printOutput(" - uploading ...");
  82. netAccessManager->sendZipToRemoteCompiler(id,
  83. buildUrl,
  84. zipFileName);
  85. WccApi::WccPostFileRequest
  86. * req = qobject_cast<WccApi::WccPostFileRequest*> (netAccessManager->requestById(id));
  87. if (!req)
  88. {
  89. m_generatorOutput.printOutput("Could not get post request");
  90. emit buildCompleted(false,
  91. "");
  92. return;
  93. }
  94. QNetworkReply
  95. * reply = req->reply();
  96. connect(reply,
  97. SIGNAL(uploadProgress(qint64,qint64)),
  98. this,
  99. SLOT(uploadedSlot(qint64,qint64)));
  100. connect(req,
  101. SIGNAL(finished()),
  102. this,
  103. SLOT(sendZipOkSlot()));
  104. m_timeout.setSingleShot(true);
  105. connect(&m_timeout,
  106. SIGNAL(timeout()),
  107. this,
  108. SLOT(operationTimedOutSlot()));
  109. m_timeout.start(UPLOAD_TIMEOUT_MSEC);
  110. }
  111. void RcBuildTask::zipProcessFailedSlot(const QString & eMsg)
  112. {
  113. QDir::setCurrent(m_savedPath);
  114. m_generatorOutput.printOutput("zipping failed.");
  115. emit buildCompleted(false,
  116. "");
  117. }
  118. void RcBuildTask::sendZipOkSlot()
  119. {
  120. emit downloading();
  121. m_generatorOutput.printOutput("waiting for remote build");
  122. m_timeout.stop();
  123. int
  124. id = m_session.nextReqId();
  125. QObject
  126. *oreq = sender();
  127. WccApi::WccPostFileRequest
  128. * req = qobject_cast<WccApi::WccPostFileRequest*>(oreq);
  129. if (!req)
  130. {
  131. m_generatorOutput.printOutput("Could not get post request");
  132. emit buildCompleted(false,
  133. "");
  134. return;
  135. }
  136. WccApi::WccResponse
  137. *resp = req->response();
  138. QString
  139. msg = resp->message();
  140. QString
  141. prj,
  142. log,
  143. status;
  144. WccApi::WccNetworkAccessManager
  145. * netAccessManager = m_session.networkAccessManager();
  146. netAccessManager->parsePostFileReply(msg,
  147. prj,
  148. log,
  149. status);
  150. parseBuildLog(log);
  151. m_generatorOutput.printOutput(log);
  152. m_generatorOutput.printOutput(QString("build status: \"%1\"").arg(status));
  153. if (status == "fail") {
  154. m_generatorOutput.printOutput("build failed.");
  155. emit buildCompleted(false,
  156. "");
  157. return;
  158. }
  159. //NOTE: download doesn't yet support pSet arguments
  160. QString
  161. request = m_wccParams;
  162. request = request.replace("pSet[os]", "os");
  163. request = request.replace("pSet[qt]", "qt");
  164. request = QString("download?installer=1&%1&project=%2").arg(request, prj);
  165. QString
  166. url = RcSession::makeRequestUrl(request);
  167. QString
  168. dlpath = m_downloadDir;
  169. netAccessManager->downloadBinary(id,
  170. url,
  171. dlpath);
  172. WccApi::WccNetworkRequestBase
  173. *b = netAccessManager->requestById(id);
  174. connect(b,
  175. SIGNAL(finished()),
  176. this,
  177. SLOT(downloadFinishedSlot()));
  178. }
  179. void RcBuildTask::uploadedSlot(qint64 sent,
  180. qint64 total)
  181. {
  182. QString upl = QString("Uploaded: %1/%2 kb").arg(sent/1024).arg(total/1024);
  183. m_generatorOutput.printOutput(upl);
  184. if (total == sent) {
  185. m_timeout.start(BUILD_TIMEOUT_MSEC);
  186. m_generatorOutput.printOutput(" - waiting for remote build to complete");
  187. }
  188. }
  189. void RcBuildTask::operationTimedOutSlot()
  190. {
  191. m_generatorOutput.printOutput("Operation timed out.");
  192. emit buildCompleted(false,
  193. "");
  194. }
  195. void RcBuildTask::downloadFinishedSlot()
  196. {
  197. QObject
  198. *oreq = sender();
  199. WccApi::WccDownloadBinaryRequest
  200. * req = qobject_cast<WccApi::WccDownloadBinaryRequest*>(oreq);
  201. if (!req)
  202. {
  203. m_generatorOutput.printOutput("Could not get download request");
  204. emit buildCompleted(false,
  205. "");
  206. return;
  207. }
  208. QString
  209. file = req->response()->message();
  210. file.remove('"');
  211. QString msg = QString("Binary downloaded to: ") + file;
  212. m_generatorOutput.printOutput(msg);
  213. emit buildCompleted(true,
  214. file);
  215. }
  216. void RcBuildTask::traverseProjectDir()
  217. {
  218. FSTraverseIterator
  219. it(m_projectDir,
  220. FSTraverseIterator::Files),
  221. end;
  222. QDir projectDir(m_projectDir);
  223. m_generatorOutput.printOutput(" - Creating source directory for zip");
  224. for (; it != end; ++it)
  225. m_projectFiles << projectDir.relativeFilePath(it->filePath());
  226. }
  227. void RcBuildTask::parseBuildLog(const QString & fullLog)
  228. {
  229. ; // TODO - necessary? probably not
  230. }