Logo Search packages:      
Sourcecode: fatrat-czshare version File versions  Download package

CzshareUpload.cpp

/*
FatRat download manager
http://fatrat.dolezel.info

Copyright (C) 2006-2008 Lubos Dolezel <lubos a dolezel.info>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "CzshareUpload.h"
#include <QFileInfo>
#include <QHttp>
#include <QRegExp>
#include <fatrat/fatrat.h>
#include <fatrat/RuntimeException.h>
#include <fatrat/Settings.h>
#include <fatrat/engines/CurlPoller.h>
#include <QString>
#include <QFileInfo>

static const char* DLINK_RE = "<!-dl->([^<]+)";
static const char* KLINK_RE = "<!-kl->([^<]+)";

CzshareUpload::CzshareUpload()
      : m_curl(0), m_probe(0), m_postData(0)
{
      m_mode = Upload;
      m_nPartnerID = getSettingsValue("czshare/partnerid").toInt();
}

CzshareUpload::~CzshareUpload()
{
      if(m_curl)
            curl_easy_cleanup(m_curl);
      if(m_postData)
            curl_formfree(m_postData);
}

void CzshareUpload::init(QString source, QString)
{
      if(!source.startsWith('/'))
            throw RuntimeException(tr("Invalid file location"));
      setObject(source);
}

void CzshareUpload::setObject(QString source)
{
      m_strSource = source;
      int p = source.lastIndexOf('/');
      if(p != -1)
            m_strName = source.mid(p + 1);
}

QString CzshareUpload::name() const
{
      return m_strName;
}

void CzshareUpload::load(const QDomNode& map)
{
      setObject( getXMLProperty(map, "source") );
      m_nPartnerID = getXMLProperty(map, "partnerid").toInt();
      m_proxy = getXMLProperty(map, "proxy");

      Transfer::load(map);
}

void CzshareUpload::save(QDomDocument& doc, QDomNode& map) const
{
      Transfer::save(doc, map);

      setXMLProperty(doc, map, "source", m_strSource);
      setXMLProperty(doc, map, "partnerid", QString::number(m_nPartnerID));
      setXMLProperty(doc, map, "proxy", m_proxy.toString());
}

void CzshareUpload::changeActive(bool bActive)
{
      if(!bActive)
      {
            resetStatistics();
            CurlPoller::instance()->removeTransfer(this);
            
            if(m_curl)
            {
                  curl_easy_cleanup(m_curl);
                  m_curl = 0;
            }
            if(m_postData)
            {
                  curl_formfree(m_postData);
                  m_postData = 0;
            }
            m_file.close();
      }
      else
      {
            // Max file size:
            // /program.php?otazka=maxfile
            m_strMessage = tr("Querying upload address");
            
            m_buffer.close();
            m_probe = new QHttp("czshare.com", 80, this);
            connect(m_probe, SIGNAL(done(bool)), this, SLOT(probeDone(bool)));
            m_probe->get("/upload_adress.php", &m_buffer);
      }
}

CURL* CzshareUpload::curlHandle()
{
      return m_curl;
}

int anti_crash_fun();

void CzshareUpload::probeDone(bool error)
{
      try
      {
            if(error)
                  throw tr("Failed to get the upload address");
            else if(isActive())
            {
                  char partnerid[50] = "";
                  curl_httppost* lastData = 0;
                  
                  if(m_postData)
                  {
                        curl_formfree(m_postData);
                        m_postData = 0;
                  }
                  
                  m_curl = curl_easy_init();
                  
                  curl_easy_setopt(m_curl, CURLOPT_USERAGENT, "FatRat/" VERSION);
                  curl_easy_setopt(m_curl, CURLOPT_ERRORBUFFER, m_errorBuffer);
                  curl_easy_setopt(m_curl, CURLOPT_SEEKFUNCTION, seek_function);
                  curl_easy_setopt(m_curl, CURLOPT_SEEKDATA, &m_file);
                  curl_easy_setopt(m_curl, CURLOPT_DEBUGDATA, this);
                  curl_easy_setopt(m_curl, CURLOPT_VERBOSE, true);
                  curl_easy_setopt(m_curl, CURLOPT_PROGRESSFUNCTION, anti_crash_fun);
                  curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, 10);
                  curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, write_function);
                  curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, static_cast<CurlUser*>(this));
                  curl_easy_setopt(m_curl, CURLOPT_READFUNCTION, read_function);
                  curl_easy_setopt(m_curl, CURLOPT_READDATA, static_cast<CurlUser*>(this));
                  curl_easy_setopt(m_curl, CURLOPT_AUTOREFERER, true);
                  curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, true);
                  
                  curl_easy_setopt(m_curl, CURLOPT_URL, m_buffer.data().constData());
                  
                  if(m_nPartnerID)
                        sprintf(partnerid, "%ld", m_nPartnerID);
                  
                  curl_formadd(&m_postData, &lastData, CURLFORM_PTRNAME, "partner_id", CURLFORM_COPYCONTENTS, partnerid, CURLFORM_END);
                  curl_formadd(&m_postData, &lastData, CURLFORM_PTRNAME, "prohlasuji", CURLFORM_PTRCONTENTS, "ano", CURLFORM_END);
                  curl_formadd(&m_postData, &lastData, CURLFORM_PTRNAME, "popis", CURLFORM_PTRCONTENTS, "", CURLFORM_END);
                  
                  curl_formadd(&m_postData, &lastData, CURLFORM_PTRNAME, "userfile",
                        CURLFORM_STREAM, static_cast<CurlUser*>(this),
                        CURLFORM_FILENAME, m_strName.toUtf8().constData(),
                        CURLFORM_CONTENTSLENGTH, long(total()), CURLFORM_END);
                  
                  curl_easy_setopt(m_curl, CURLOPT_HTTPPOST, m_postData);
                  
                  m_file.setFileName(m_strSource);
                  if(!m_file.open(QIODevice::ReadOnly))
                        throw tr("Can't open the file.");
                  
                  m_strMessage = tr("Sending data");
                  
                  m_buffer.close();
                  m_buffer.open(QIODevice::WriteOnly);
                  CurlPoller::instance()->addTransfer(this);
            }
      }
      catch(const QString& err)
      {
            setState(Failed);
            m_strMessage = err;
            qDebug() << "Failed 1:" << m_strMessage;
      }

      m_probe->deleteLater();
      m_probe = 0;
}

int CzshareUpload::seek_function(QFile* file, curl_off_t offset, int origin)
{
      qDebug() << "seek_function" << offset << origin;
      
      if(origin == SEEK_SET)
      {
            if(!file->seek(offset))
                  return -1;
      }
      else if(origin == SEEK_CUR)
      {
            if(!file->seek(file->pos() + offset))
                  return -1;
      }
      else
            return -1;
      return 0;
}

size_t CzshareUpload::readData(char* buffer, size_t maxData)
{
      return m_file.read(buffer, maxData);
}

bool CzshareUpload::writeData(const char* buffer, size_t bytes)
{
      m_buffer.write(buffer, bytes);
      return true;
}

void CzshareUpload::transferDone(CURLcode result)
{
      try
      {
            if(result != CURLE_OK)
                  throw QString(m_errorBuffer);
            else
            {
                  QRegExp re(DLINK_RE);
                  QString dl, kl;
                  
                  if(re.indexIn(m_buffer.data()) < 0)
                        throw tr("Failed to find the download link");
                  dl = re.cap(1);
                  
                  re.setPattern(KLINK_RE);
                  if(re.indexIn(m_buffer.data()) < 0)
                        throw tr("Failed to find the kill link");
                  kl = re.cap(1);
                  kl.replace("&amp;", "&");
                  
                  enterLogMessage(tr("Download link:") + ' ' + dl);
                  enterLogMessage(tr("Kill link:") + ' ' + kl);
                  
                  QString dlf, klf;
                  dlf = getSettingsValue("czshare/down_links").toString();
                  klf = getSettingsValue("czshare/kill_links").toString();
                  
                  if(!dlf.isEmpty())
                        saveLink(dlf, dl);
                  if(!klf.isEmpty())
                        saveLink(klf, kl);
            }
            setState(Completed);
      }
      catch(const QString& e)
      {
            m_strMessage = e;
            setState(Failed);
      }
}

void CzshareUpload::setSpeedLimits(int, int up)
{
      m_up.max = up;
}

void CzshareUpload::speeds(int& down, int& up) const
{
      up = 0;
      if(isActive())
            CurlUser::speeds(down, up);
      down = 0;
}

qulonglong CzshareUpload::total() const
{
      QFileInfo info(m_strSource);
      return info.size();
}

qulonglong CzshareUpload::done() const
{
      if(state() == Completed)
            return total();
      else
            return isActive() ? m_file.pos() : 0;
}

void CzshareUpload::saveLink(QString filename, QString link)
{
      QFile file(filename);
      if(!file.open(QIODevice::Append))
      {
            enterLogMessage(tr("Cannot append to file \"%1\"").arg(filename));
      }
      else
      {
            file.write( (link + '\n').toUtf8() );
      }
}


Generated by  Doxygen 1.6.0   Back to index