@ -30,9 +30,9 @@
@@ -30,9 +30,9 @@
# include <libtorrent/bdecode.hpp>
# include <libtorrent/bencode.hpp>
# include <libtorrent/create_torrent.hpp>
# include <libtorrent/entry.hpp>
# include <libtorrent/read_resume_data.hpp>
# include <libtorrent/torrent_info.hpp>
# include <libtorrent/write_resume_data.hpp>
# include <QByteArray>
@ -51,7 +51,6 @@
@@ -51,7 +51,6 @@
# include "base/utils/string.h"
# include "infohash.h"
# include "loadtorrentparams.h"
# include "torrentinfo.h"
namespace BitTorrent
{
@ -151,25 +150,36 @@ std::optional<BitTorrent::LoadTorrentParams> BitTorrent::BencodeResumeDataStorag
@@ -151,25 +150,36 @@ std::optional<BitTorrent::LoadTorrentParams> BitTorrent::BencodeResumeDataStorag
const QString fastresumePath = m_resumeDataDir . absoluteFilePath ( QString : : fromLatin1 ( " %1.fastresume " ) . arg ( idString ) ) ;
const QString torrentFilePath = m_resumeDataDir . absoluteFilePath ( QString : : fromLatin1 ( " %1.torrent " ) . arg ( idString ) ) ;
QFile f ile { fastresumePath } ;
if ( ! f ile. open ( QIODevice : : ReadOnly ) )
QFile resumeDataF ile { fastresumePath } ;
if ( ! resumeDataF ile. open ( QIODevice : : ReadOnly ) )
{
LogMsg ( tr ( " Cannot read file %1: %2 " ) . arg ( fastresumePath , f ile. errorString ( ) ) , Log : : WARNING ) ;
LogMsg ( tr ( " Cannot read file %1: %2 " ) . arg ( fastresumePath , resumeDataF ile. errorString ( ) ) , Log : : WARNING ) ;
return std : : nullopt ;
}
const QByteArray data = file . readAll ( ) ;
const TorrentInfo metadata = TorrentInfo : : loadFromFile ( torrentFilePath ) ;
QFile metadataFile { torrentFilePath } ;
if ( metadataFile . exists ( ) & & ! metadataFile . open ( QIODevice : : ReadOnly ) )
{
LogMsg ( tr ( " Cannot read file %1: %2 " ) . arg ( torrentFilePath , metadataFile . errorString ( ) ) , Log : : WARNING ) ;
return std : : nullopt ;
}
const QByteArray data = resumeDataFile . readAll ( ) ;
const QByteArray metadata = ( metadataFile . isOpen ( ) ? metadataFile . readAll ( ) : " " ) ;
return loadTorrentResumeData ( data , metadata ) ;
}
std : : optional < BitTorrent : : LoadTorrentParams > BitTorrent : : BencodeResumeDataStorage : : loadTorrentResumeData (
const QByteArray & data , const TorrentInfo & metadata ) const
const QByteArray & data , const QByteArray & metadata ) const
{
const QByteArray allData = ( ( metadata . isEmpty ( ) | | data . isEmpty ( ) )
? data : ( data . chopped ( 1 ) + metadata . mid ( 1 ) ) ) ;
lt : : error_code ec ;
const lt : : bdecode_node root = lt : : bdecode ( data , ec ) ;
if ( ec | | ( root . type ( ) ! = lt : : bdecode_node : : dict_t ) ) return std : : nullopt ;
const lt : : bdecode_node root = lt : : bdecode ( allData , ec ) ;
if ( ec | | ( root . type ( ) ! = lt : : bdecode_node : : dict_t ) )
return std : : nullopt ;
LoadTorrentParams torrentParams ;
torrentParams . restored = true ;
@ -220,8 +230,6 @@ std::optional<BitTorrent::LoadTorrentParams> BitTorrent::BencodeResumeDataStorag
@@ -220,8 +230,6 @@ std::optional<BitTorrent::LoadTorrentParams> BitTorrent::BencodeResumeDataStorag
p = lt : : read_resume_data ( root , ec ) ;
p . save_path = Profile : : instance ( ) - > fromPortablePath ( fromLTString ( p . save_path ) ) . toStdString ( ) ;
if ( metadata . isValid ( ) )
p . ti = metadata . nativeInfo ( ) ;
if ( p . flags & lt : : torrent_flags : : stop_when_ready )
{
@ -333,15 +341,22 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co
@@ -333,15 +341,22 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co
}
}
lt : : entry data = lt : : write_resume_data ( p ) ;
// metadata is stored in separate .torrent file
const std : : shared_ptr < lt : : torrent_info > torrentInfo = std : : move ( p . ti ) ;
if ( torrentInfo )
if ( p . ti )
{
lt : : entry : : dictionary_type & dataDict = data . dict ( ) ;
lt : : entry metadata { lt : : entry : : dictionary_t } ;
lt : : entry : : dictionary_type & metadataDict = metadata . dict ( ) ;
metadataDict . insert ( dataDict . extract ( " info " ) ) ;
metadataDict . insert ( dataDict . extract ( " creation date " ) ) ;
metadataDict . insert ( dataDict . extract ( " created by " ) ) ;
metadataDict . insert ( dataDict . extract ( " comment " ) ) ;
const QString torrentFilepath = m_resumeDataDir . absoluteFilePath ( QString : : fromLatin1 ( " %1.torrent " ) . arg ( id . toString ( ) ) ) ;
try
{
const auto torrentCreator = lt : : create_torrent ( * torrentInfo ) ;
const lt : : entry metadata = torrentCreator . generate ( ) ;
writeEntryToFile ( torrentFilepath , metadata ) ;
}
catch ( const RuntimeError & err )
@ -350,16 +365,8 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co
@@ -350,16 +365,8 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co
. arg ( torrentFilepath , err . message ( ) ) , Log : : CRITICAL ) ;
return ;
}
catch ( const std : : exception & err )
{
LogMsg ( tr ( " Couldn't save torrent metadata to '%1'. Error: %2. " )
. arg ( torrentFilepath , QString : : fromLocal8Bit ( err . what ( ) ) ) , Log : : CRITICAL ) ;
return ;
}
}
lt : : entry data = lt : : write_resume_data ( p ) ;
data [ " qBt-savePath " ] = Profile : : instance ( ) - > toPortablePath ( resumeData . savePath ) . toStdString ( ) ;
data [ " qBt-ratioLimit " ] = static_cast < int > ( resumeData . ratioLimit * 1000 ) ;
data [ " qBt-seedingTimeLimit " ] = resumeData . seedingTimeLimit ;