Merge pull request #2161 from csoler/v0.6-BugFixing_5

V0.6 bug fixing 5
This commit is contained in:
csoler 2020-12-15 20:50:14 +01:00 committed by GitHub
commit 733b059571
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 175 additions and 106 deletions

View file

@ -638,6 +638,23 @@ bool InternalFileHierarchyStorage::setTS(const DirectoryStorage::EntryIndex& ind
return true; return true;
} }
// Do a complete recursive sweep of directory hierarchy and update cumulative size of directories
uint64_t InternalFileHierarchyStorage::recursUpdateCumulatedSize(const DirectoryStorage::EntryIndex& dir_index)
{
DirEntry& d(*static_cast<DirEntry*>(mNodes[dir_index])) ;
uint64_t local_cumulative_size = 0;
for(uint32_t i=0;i<d.subfiles.size();++i)
local_cumulative_size += static_cast<FileEntry*>(mNodes[d.subfiles[i]])->file_size;
for(uint32_t i=0;i<d.subdirs.size();++i)
local_cumulative_size += recursUpdateCumulatedSize(d.subdirs[i]);
d.dir_cumulated_size = local_cumulative_size;
return local_cumulative_size;
}
// Do a complete recursive sweep over sub-directories and files, and update the lst modf TS. This could be also performed by a cleanup method. // Do a complete recursive sweep over sub-directories and files, and update the lst modf TS. This could be also performed by a cleanup method.
rstime_t InternalFileHierarchyStorage::recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index,bool& unfinished_files_present) rstime_t InternalFileHierarchyStorage::recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index,bool& unfinished_files_present)
@ -1199,6 +1216,8 @@ bool InternalFileHierarchyStorage::load(const std::string& fname)
if(!check(err_str)) if(!check(err_str))
std::cerr << "(EE) Error while loading file hierarchy " << fname << std::endl; std::cerr << "(EE) Error while loading file hierarchy " << fname << std::endl;
recursUpdateCumulatedSize(mRoot);
return true ; return true ;
} }
catch(read_error& e) catch(read_error& e)

View file

@ -63,7 +63,7 @@ public:
class DirEntry: public FileStorageNode class DirEntry: public FileStorageNode
{ {
public: public:
explicit DirEntry(const std::string& name) : dir_name(name), dir_modtime(0),dir_most_recent_time(0),dir_update_time(0) {} explicit DirEntry(const std::string& name) : dir_name(name), dir_cumulated_size(0), dir_modtime(0),dir_most_recent_time(0),dir_update_time(0) {}
virtual ~DirEntry() {} virtual ~DirEntry() {}
virtual uint32_t type() const { return FileStorageNode::TYPE_DIR ; } virtual uint32_t type() const { return FileStorageNode::TYPE_DIR ; }
@ -72,6 +72,7 @@ public:
std::string dir_name ; std::string dir_name ;
std::string dir_parent_path ; std::string dir_parent_path ;
RsFileHash dir_hash ; RsFileHash dir_hash ;
uint64_t dir_cumulated_size;
std::vector<DirectoryStorage::EntryIndex> subdirs ; std::vector<DirectoryStorage::EntryIndex> subdirs ;
std::vector<DirectoryStorage::EntryIndex> subfiles ; std::vector<DirectoryStorage::EntryIndex> subfiles ;
@ -108,6 +109,10 @@ public:
rstime_t recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index, bool &unfinished_files_present); rstime_t recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index, bool &unfinished_files_present);
// Do a complete recursive sweep over sub-directories and files, and update the cumulative size.
uint64_t recursUpdateCumulatedSize(const DirectoryStorage::EntryIndex& dir_index);
// hash stuff // hash stuff
bool getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const ; bool getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const ;

View file

@ -235,7 +235,7 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
d.type = DIR_TYPE_DIR; d.type = DIR_TYPE_DIR;
d.hash.clear() ; d.hash.clear() ;
d.count = dir_entry->subdirs.size() + dir_entry->subfiles.size(); d.size = dir_entry->dir_cumulated_size;//dir_entry->subdirs.size() + dir_entry->subfiles.size();
d.max_mtime = dir_entry->dir_most_recent_time ; d.max_mtime = dir_entry->dir_most_recent_time ;
d.mtime = dir_entry->dir_modtime ; d.mtime = dir_entry->dir_modtime ;
d.name = dir_entry->dir_name; d.name = dir_entry->dir_name;
@ -253,7 +253,7 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
const InternalFileHierarchyStorage::FileEntry *file_entry = mFileHierarchy->getFileEntry(indx) ; const InternalFileHierarchyStorage::FileEntry *file_entry = mFileHierarchy->getFileEntry(indx) ;
d.type = DIR_TYPE_FILE; d.type = DIR_TYPE_FILE;
d.count = file_entry->file_size; d.size = file_entry->file_size;
d.max_mtime = file_entry->file_modtime ; d.max_mtime = file_entry->file_modtime ;
d.name = file_entry->file_name; d.name = file_entry->file_name;
d.hash = file_entry->file_hash; d.hash = file_entry->file_hash;
@ -292,6 +292,8 @@ void DirectoryStorage::checkSave()
if(mChanged && mLastSavedTime + MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE < now) if(mChanged && mLastSavedTime + MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE < now)
{ {
mFileHierarchy->recursUpdateCumulatedSize(mFileHierarchy->mRoot);
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;
locked_check(); locked_check();
@ -585,7 +587,7 @@ bool LocalDirectoryStorage::getFileInfo(DirectoryStorage::EntryIndex i,FileInfo&
info.path = d.path + "/" + d.name; info.path = d.path + "/" + d.name;
info.fname = d.name; info.fname = d.name;
info.hash = d.hash; info.hash = d.hash;
info.size = d.count; info.size = d.size;
// all this stuff below is not useful in this case. // all this stuff below is not useful in this case.

View file

@ -224,7 +224,7 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p
{ {
some_files_not_ready = true ; some_files_not_ready = true ;
std::cerr << "(WW) file " << dirIt.file_fullpath() << " is probably being modified. Keeping it for later." << std::endl; std::cerr << "(WW) file " << dirIt.file_fullpath() << " is probably being written to. Keeping it for later." << std::endl;
} }
break; break;

View file

@ -138,7 +138,7 @@ void RsFileTree::recurs_buildFileTree(
{ {
FileData f ; FileData f ;
f.name = dd2.name ; f.name = dd2.name ;
f.size = dd2.count ; f.size = dd2.size ;
f.hash = dd2.hash ; f.hash = dd2.hash ;
ft.mDirs[index].subfiles.push_back(ft.mFiles.size()) ; ft.mDirs[index].subfiles.push_back(ft.mFiles.size()) ;
@ -186,7 +186,7 @@ std::unique_ptr<RsFileTree> RsFileTree::fromDirDetails(
if(dd.type == DIR_TYPE_FILE) if(dd.type == DIR_TYPE_FILE)
{ {
FileData fd; FileData fd;
fd.name = dd.name; fd.hash = dd.hash; fd.size = dd.count; fd.name = dd.name; fd.hash = dd.hash; fd.size = dd.size;
ft->mFiles.push_back(fd); ft->mFiles.push_back(fd);
ft->mTotalFiles = 1; ft->mTotalFiles = 1;
ft->mTotalSize = fd.size; ft->mTotalSize = fd.size;

View file

@ -1004,7 +1004,7 @@ void p3FileDatabase::getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIn
d.prow = 0;//fi-1 ; d.prow = 0;//fi-1 ;
d.type = DIR_TYPE_PERSON; d.type = DIR_TYPE_PERSON;
d.hash.clear() ; d.hash.clear() ;
d.count = mExtraFilesCache.size(); d.size = mExtraFilesCache.size();
d.max_mtime = time(NULL); d.max_mtime = time(NULL);
d.mtime = time(NULL); d.mtime = time(NULL);
d.name = "[Extra List]"; d.name = "[Extra List]";
@ -1029,7 +1029,7 @@ void p3FileDatabase::getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIn
FileInfo& f(mExtraFilesCache[(int)e-1]) ; FileInfo& f(mExtraFilesCache[(int)e-1]) ;
d.hash = f.hash; d.hash = f.hash;
d.count = f.size; d.size = f.size;
d.max_mtime = 0; // this is irrelevant d.max_mtime = 0; // this is irrelevant
d.mtime = 0; // this is irrelevant d.mtime = 0; // this is irrelevant
d.name = f.path; // so that the UI shows the complete path, since the parent directory is not really a directory. d.name = f.path; // so that the UI shows the complete path, since the parent directory is not really a directory.
@ -1116,7 +1116,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
d.children.push_back(stub); d.children.push_back(stub);
} }
d.count = d.children.size(); d.size = 0; // non documented
#ifdef DEBUG_FILE_HIERARCHY #ifdef DEBUG_FILE_HIERARCHY
P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl; P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl;

View file

@ -39,8 +39,23 @@
// - fast queue that is handled in highest priority. This one is used for e.g. updating while browsing. // - fast queue that is handled in highest priority. This one is used for e.g. updating while browsing.
// - slow queue that is handled slowly. Used in background update of shared directories. // - slow queue that is handled slowly. Used in background update of shared directories.
// //
// The file lists are not directry updated. A FileListWatcher class is responsible for this // The list of local shared files is maintained by FileListWatcher.
// in every case. //
// p3FileLists is organised as follows:
//
// p3FileDatabase
// |
// +---- HashStorage // Handles known hashes. Serves as a reference when new files are hashed.
// |
// +---- RemoteDirectoryStorage // Stores the list of shared files at friends
// | |
// | +---- InternalFileHierarchyStorage
// |
// +---- LocalDirectoryStorage // Stores the list of locally shared files
// | |
// | +---- InternalFileHierarchyStorage
// |
// +---- LocalDirectoryUpdater // Keeps the local lists up to date, by regularly crawling directories
// //
#pragma once #pragma once

View file

@ -2283,7 +2283,7 @@ std::error_condition ftServer::exportFileLink(
tDirDet.type = DIR_TYPE_FILE; tDirDet.type = DIR_TYPE_FILE;
tDirDet.name = fileName; tDirDet.name = fileName;
tDirDet.hash = fileHash; tDirDet.hash = fileHash;
tDirDet.count = fileSize; tDirDet.size = fileSize;
return dirDetailsToLink(link, tDirDet, fragSneak, baseUrl); return dirDetailsToLink(link, tDirDet, fragSneak, baseUrl);
} }
@ -2308,7 +2308,7 @@ std::error_condition ftServer::parseFilesLink(
dt.name = *tUrl.getQueryV("name"); dt.name = *tUrl.getQueryV("name");
try try
{ {
dt.count = std::stoull(*tUrl.getQueryV("size")); dt.size = std::stoull(*tUrl.getQueryV("size"));
std::unique_ptr<RsFileTree> ft; std::unique_ptr<RsFileTree> ft;
if( !dt.hash.isNull() && if( !dt.hash.isNull() &&
(ft = RsFileTree::fromDirDetails(dt, true)) ) (ft = RsFileTree::fromDirDetails(dt, true)) )

View file

@ -300,7 +300,7 @@ struct DirStub : RsSerializable
struct DirDetails : RsSerializable struct DirDetails : RsSerializable
{ {
DirDetails() : parent(nullptr), prow(0), ref(nullptr), DirDetails() : parent(nullptr), prow(0), ref(nullptr),
type(DIR_TYPE_UNKNOWN), count(0), mtime(0), max_mtime(0) {} type(DIR_TYPE_UNKNOWN), size(0), mtime(0), max_mtime(0) {}
/* G10h4ck do we still need to keep this as void* instead of uint64_t for /* G10h4ck do we still need to keep this as void* instead of uint64_t for
@ -318,7 +318,7 @@ struct DirDetails : RsSerializable
std::string name; std::string name;
RsFileHash hash; RsFileHash hash;
std::string path; // full path of the parent directory, when it is a file; full path of the dir otherwise. std::string path; // full path of the parent directory, when it is a file; full path of the dir otherwise.
uint64_t count; uint64_t size; // total size of directory, or size of the file.
uint32_t mtime; // file/directory modification time, according to what the system reports uint32_t mtime; // file/directory modification time, according to what the system reports
FileStorageFlags flags; FileStorageFlags flags;
uint32_t max_mtime ; // maximum modification time of the whole hierarchy below. uint32_t max_mtime ; // maximum modification time of the whole hierarchy below.
@ -347,7 +347,7 @@ struct DirDetails : RsSerializable
RS_SERIAL_PROCESS(name); RS_SERIAL_PROCESS(name);
RS_SERIAL_PROCESS(hash); RS_SERIAL_PROCESS(hash);
RS_SERIAL_PROCESS(path); RS_SERIAL_PROCESS(path);
RS_SERIAL_PROCESS(count); RS_SERIAL_PROCESS(size);
RS_SERIAL_PROCESS(mtime); RS_SERIAL_PROCESS(mtime);
RS_SERIAL_PROCESS(flags); RS_SERIAL_PROCESS(flags);
RS_SERIAL_PROCESS(max_mtime); RS_SERIAL_PROCESS(max_mtime);

View file

@ -1984,7 +1984,7 @@ void RsTurtleStringSearchRequestItem::search(std::list<TurtleFileInfo>& result)
TurtleFileInfo i ; TurtleFileInfo i ;
i.hash = it->hash ; i.hash = it->hash ;
i.size = it->count ; i.size = it->size ;
i.name = it->name ; i.name = it->name ;
result.push_back(i) ; result.push_back(i) ;
@ -2022,7 +2022,7 @@ void RsTurtleRegExpSearchRequestItem::search(std::list<TurtleFileInfo>& result)
} }
TurtleFileInfo i ; TurtleFileInfo i ;
i.hash = it->hash ; i.hash = it->hash ;
i.size = it->count ; i.size = it->size ;
i.name = it->name ; i.name = it->name ;
result.push_back(i) ; result.push_back(i) ;

View file

@ -479,7 +479,7 @@ void SearchDialog::collCreate()
DirDetails details; DirDetails details;
details.name = name; details.name = name;
details.hash = hash; details.hash = hash;
details.count = count; details.size = count;
details.type = DIR_TYPE_FILE; details.type = DIR_TYPE_FILE;
dirVec.push_back(details); dirVec.push_back(details);
@ -1010,8 +1010,8 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str())); child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str()));
child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString())); child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString()));
child->setText(SR_SIZE_COL, QString::number(dir.count)); child->setText(SR_SIZE_COL, QString::number(dir.size));
child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.count); child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.size);
child->setText(SR_AGE_COL, QString::number(dir.mtime)); child->setText(SR_AGE_COL, QString::number(dir.mtime));
child->setData(SR_AGE_COL, ROLE_SORT, dir.mtime); child->setData(SR_AGE_COL, ROLE_SORT, dir.mtime);
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
@ -1036,8 +1036,8 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
child->setIcon(SR_NAME_COL, QIcon(IMAGE_DIRECTORY)); child->setIcon(SR_NAME_COL, QIcon(IMAGE_DIRECTORY));
child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str())); child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str()));
child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString())); child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString()));
child->setText(SR_SIZE_COL, QString::number(dir.count)); child->setText(SR_SIZE_COL, QString::number(dir.size));
child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.count); child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.size);
child->setText(SR_AGE_COL, QString::number(dir.mtime)); child->setText(SR_AGE_COL, QString::number(dir.mtime));
child->setData(SR_AGE_COL, ROLE_SORT, dir.mtime); child->setData(SR_AGE_COL, ROLE_SORT, dir.mtime);
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
@ -1105,8 +1105,8 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
child->setIcon(SR_NAME_COL, QIcon(IMAGE_DIRECTORY)); child->setIcon(SR_NAME_COL, QIcon(IMAGE_DIRECTORY));
child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str())); child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str()));
child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString())); child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString()));
child->setText(SR_SIZE_COL, QString::number(dir.count)); child->setText(SR_SIZE_COL, QString::number(dir.size));
child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.count); child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.size);
child->setText(SR_AGE_COL, QString::number(dir.max_mtime)); child->setText(SR_AGE_COL, QString::number(dir.max_mtime));
child->setData(SR_AGE_COL, ROLE_SORT, dir.max_mtime); child->setData(SR_AGE_COL, ROLE_SORT, dir.max_mtime);
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
@ -1389,7 +1389,7 @@ void SearchDialog::resultsToTree(const QString& txt,qulonglong searchId, const s
fd.name = it->name; fd.name = it->name;
fd.hash = it->hash; fd.hash = it->hash;
fd.path = it->path; fd.path = it->path;
fd.size = it->count; fd.size = it->size;
fd.age = it->mtime; fd.age = it->mtime;
fd.rank = 0; fd.rank = 0;

View file

@ -655,7 +655,7 @@ void SharedFilesDialog::copyLinks(const QModelIndexList& lst, bool remote,QList<
} }
else else
name = QString::fromUtf8(details.name.c_str()); name = QString::fromUtf8(details.name.c_str());
RetroShareLink link = RetroShareLink::createFile(name, details.count, details.hash.toStdString().c_str()); RetroShareLink link = RetroShareLink::createFile(name, details.size, details.hash.toStdString().c_str());
if (link.valid()) { if (link.valid()) {
urls.push_back(link) ; urls.push_back(link) ;
} }

View file

@ -2468,7 +2468,7 @@ void TransfersDialog::collCreate()
DirDetails details; DirDetails details;
details.name = info.fname; details.name = info.fname;
details.hash = info.hash; details.hash = info.hash;
details.count = info.size; details.size = info.size;
details.type = DIR_TYPE_FILE; details.type = DIR_TYPE_FILE;
dirVec.push_back(details); dirVec.push_back(details);

View file

@ -203,10 +203,10 @@ bool TreeStyle_RDM::hasChildren(const QModelIndex &parent) const
} }
/* PERSON/DIR*/ /* PERSON/DIR*/
#ifdef RDM_DEBUG #ifdef RDM_DEBUG
std::cerr << "lookup PER/DIR #" << details.count; std::cerr << "lookup PER/DIR #" << details.size;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
return (details.count > 0); /* do we have children? */ return (details.children.size() > 0); /* do we have children? */
} }
bool FlatStyle_RDM::hasChildren(const QModelIndex &parent) const bool FlatStyle_RDM::hasChildren(const QModelIndex &parent) const
{ {
@ -262,7 +262,7 @@ int TreeStyle_RDM::rowCount(const QModelIndex &parent) const
/* else PERSON/DIR*/ /* else PERSON/DIR*/
#ifdef RDM_DEBUG #ifdef RDM_DEBUG
std::cerr << "lookup PER/DIR #" << details.count; std::cerr << "lookup PER/DIR #" << details.size;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
if ((details.type == DIR_TYPE_ROOT) && !_showEmpty && RemoteMode) if ((details.type == DIR_TYPE_ROOT) && !_showEmpty && RemoteMode)
@ -271,14 +271,14 @@ int TreeStyle_RDM::rowCount(const QModelIndex &parent) const
//Scan all children to know if they are empty. //Scan all children to know if they are empty.
//And save their real row index //And save their real row index
//Prefer do like that than modify requestDirDetails with a new flag (rsFiles->RequestDirDetails) //Prefer do like that than modify requestDirDetails with a new flag (rsFiles->RequestDirDetails)
for(uint64_t i = 0; i < details.count; ++i) for(uint64_t i = 0; i < details.children.size(); ++i)
{ {
if (requestDirDetails(details.children[i].ref, RemoteMode,childDetails) && (childDetails.count > 0)) if (requestDirDetails(details.children[i].ref, RemoteMode,childDetails) && (childDetails.children.size() > 0))
_parentRow.push_back(i); _parentRow.push_back(i);
} }
return _parentRow.size(); return _parentRow.size();
} }
return details.count; return details.children.size();
} }
int FlatStyle_RDM::rowCount(const QModelIndex &parent) const int FlatStyle_RDM::rowCount(const QModelIndex &parent) const
{ {
@ -505,7 +505,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
else if(details.id == rsPeers->getOwnId()) else if(details.id == rsPeers->getOwnId())
rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ; rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ;
else else
stats.total_number_of_files = details.count; stats.total_number_of_files = details.children.size();
if(stats.total_number_of_files > 0) if(stats.total_number_of_files > 0)
{ {
@ -552,7 +552,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
case COLUMN_FILENB: case COLUMN_FILENB:
return QVariant(); return QVariant();
case COLUMN_SIZE: case COLUMN_SIZE:
return misc::friendlyUnit(details.count); return misc::friendlyUnit(details.size);
case COLUMN_AGE: case COLUMN_AGE:
{ {
if(details.type == DIR_TYPE_FILE) if(details.type == DIR_TYPE_FILE)
@ -584,13 +584,13 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
return QString::fromUtf8(details.name.c_str()); return QString::fromUtf8(details.name.c_str());
break; break;
case COLUMN_FILENB: case COLUMN_FILENB:
if (details.count > 1) if (details.children.size() > 1)
{ {
return QString::number(details.count) + " " + tr("Files"); return QString::number(details.children.size()) + " " + tr("Files");
} }
return QString::number(details.count) + " " + tr("File"); return QString::number(details.children.size()) + " " + tr("File");
case COLUMN_SIZE: case COLUMN_SIZE:
return QVariant(); return misc::friendlyUnit(details.size);
case COLUMN_AGE: case COLUMN_AGE:
return misc::timeRelativeToNow(details.max_mtime); return misc::timeRelativeToNow(details.max_mtime);
case COLUMN_FRIEND_ACCESS: case COLUMN_FRIEND_ACCESS:
@ -652,7 +652,7 @@ QVariant FlatStyle_RDM::displayRole(const DirDetails& details,int coln) const
{ {
case COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); case COLUMN_NAME: return QString::fromUtf8(details.name.c_str());
case COLUMN_FILENB: return QString(); case COLUMN_FILENB: return QString();
case COLUMN_SIZE: return misc::friendlyUnit(details.count); case COLUMN_SIZE: return misc::friendlyUnit(details.size);
case COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime); case COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime);
case COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); case COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str());
case COLUMN_WN_VISU_DIR: return computeDirectoryPath(details); case COLUMN_WN_VISU_DIR: return computeDirectoryPath(details);
@ -712,7 +712,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails&
case COLUMN_FILENB: case COLUMN_FILENB:
return (qulonglong) 0; return (qulonglong) 0;
case COLUMN_SIZE: case COLUMN_SIZE:
return (qulonglong) details.count; return (qulonglong) details.size;
case COLUMN_AGE: case COLUMN_AGE:
return details.max_mtime; return details.max_mtime;
case COLUMN_FRIEND_ACCESS: case COLUMN_FRIEND_ACCESS:
@ -735,7 +735,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails&
case COLUMN_NAME: case COLUMN_NAME:
return QString::fromUtf8(details.name.c_str()); return QString::fromUtf8(details.name.c_str());
case COLUMN_FILENB: case COLUMN_FILENB:
return (qulonglong) details.count; return (qulonglong) details.children.size();
case COLUMN_SIZE: case COLUMN_SIZE:
return (qulonglong) 0; return (qulonglong) 0;
case COLUMN_AGE: case COLUMN_AGE:
@ -762,7 +762,7 @@ QVariant FlatStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails&
{ {
case COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); case COLUMN_NAME: return QString::fromUtf8(details.name.c_str());
case COLUMN_FILENB: return (qulonglong) 0; case COLUMN_FILENB: return (qulonglong) 0;
case COLUMN_SIZE: return (qulonglong) details.count; case COLUMN_SIZE: return (qulonglong) details.size;
case COLUMN_AGE: return details.max_mtime; case COLUMN_AGE: return details.max_mtime;
case COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); case COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str());
case COLUMN_WN_VISU_DIR: { case COLUMN_WN_VISU_DIR: {
@ -1287,8 +1287,7 @@ void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool inter
std::cerr << std::endl; std::cerr << std::endl;
std::list<RsPeerId> srcIds; std::list<RsPeerId> srcIds;
srcIds.push_back(details.id); srcIds.push_back(details.id);
rsFiles -> FileRequest(details.name, details.hash, rsFiles -> FileRequest(details.name, details.hash, details.size, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds);
details.count, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds);
} }
/* if it is a dir, copy all files included*/ /* if it is a dir, copy all files included*/
else if (details.type == DIR_TYPE_DIR) else if (details.type == DIR_TYPE_DIR)
@ -1309,7 +1308,7 @@ void RetroshareDirModel::downloadDirectory(const DirDetails & dirDetails, int pr
QString cleanPath = QDir::cleanPath(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()) + "/" + QString::fromUtf8(dirDetails.path.substr(prefixLen).c_str())); QString cleanPath = QDir::cleanPath(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()) + "/" + QString::fromUtf8(dirDetails.path.substr(prefixLen).c_str()));
srcIds.push_back(dirDetails.id); srcIds.push_back(dirDetails.id);
rsFiles->FileRequest(dirDetails.name, dirDetails.hash, dirDetails.count, cleanPath.toUtf8().constData(), RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds); rsFiles->FileRequest(dirDetails.name, dirDetails.hash, dirDetails.size, cleanPath.toUtf8().constData(), RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds);
} }
else if (dirDetails.type & DIR_TYPE_DIR) else if (dirDetails.type & DIR_TYPE_DIR)
{ {
@ -1394,7 +1393,7 @@ void RetroshareDirModel::getFileInfoFromIndexList(const QModelIndexList& list, s
std::cerr << "::::::::::::FileRecommend:::: " << std::endl; std::cerr << "::::::::::::FileRecommend:::: " << std::endl;
std::cerr << "Name: " << details.name << std::endl; std::cerr << "Name: " << details.name << std::endl;
std::cerr << "Hash: " << details.hash << std::endl; std::cerr << "Hash: " << details.hash << std::endl;
std::cerr << "Size: " << details.count << std::endl; std::cerr << "Size: " << details.size << std::endl;
std::cerr << "Path: " << details.path << std::endl; std::cerr << "Path: " << details.path << std::endl;
#endif #endif
// Note: for directories, the returned hash, is the peer id, so if we collect // Note: for directories, the returned hash, is the peer id, so if we collect
@ -1592,7 +1591,7 @@ QMimeData * RetroshareDirModel::mimeData ( const QModelIndexList & indexes ) con
std::cerr << "::::::::::::FileDrag:::: " << std::endl; std::cerr << "::::::::::::FileDrag:::: " << std::endl;
std::cerr << "Name: " << details.name << std::endl; std::cerr << "Name: " << details.name << std::endl;
std::cerr << "Hash: " << details.hash << std::endl; std::cerr << "Hash: " << details.hash << std::endl;
std::cerr << "Size: " << details.count << std::endl; std::cerr << "Size: " << details.size << std::endl;
std::cerr << "Path: " << details.path << std::endl; std::cerr << "Path: " << details.path << std::endl;
#endif #endif
@ -1612,9 +1611,8 @@ QMimeData * RetroshareDirModel::mimeData ( const QModelIndexList & indexes ) con
continue; /* duplicate */ continue; /* duplicate */
} }
drags[details.hash] = details.count; drags[details.hash] = details.children.size();
QString line = QString("%1/%2/%3/").arg(QString::fromUtf8(details.name.c_str()), QString::fromStdString(details.hash.toStdString()), QString::number(details.size));
QString line = QString("%1/%2/%3/").arg(QString::fromUtf8(details.name.c_str()), QString::fromStdString(details.hash.toStdString()), QString::number(details.count));
if (RemoteMode) if (RemoteMode)
{ {

View file

@ -221,7 +221,7 @@ void RsCollection::recursAddElements(QDomDocument& doc,const DirDetails& details
f.setAttribute(QString("name"),QString::fromUtf8(details.name.c_str())) ; f.setAttribute(QString("name"),QString::fromUtf8(details.name.c_str())) ;
f.setAttribute(QString("sha1"),QString::fromStdString(details.hash.toStdString())) ; f.setAttribute(QString("sha1"),QString::fromStdString(details.hash.toStdString())) ;
f.setAttribute(QString("size"),QString::number(details.count)) ; f.setAttribute(QString("size"),QString::number(details.size)) ;
e.appendChild(f) ; e.appendChild(f) ;
} }

View file

@ -203,7 +203,7 @@ void CreateGxsChannelMsg::pasteLink()
{ {
std::cerr << "Pasting links: " << std::endl; std::cerr << "Pasting links: " << std::endl;
QList<RetroShareLink> links,not_have ; QList<RetroShareLink> links;
RSLinkClipboard::pasteLinks(links) ; RSLinkClipboard::pasteLinks(links) ;
for(QList<RetroShareLink>::const_iterator it(links.begin());it!=links.end();++it) for(QList<RetroShareLink>::const_iterator it(links.begin());it!=links.end();++it)
@ -217,12 +217,17 @@ void CreateGxsChannelMsg::pasteLink()
FileInfo info ; FileInfo info ;
RsFileHash hash( (*it).hash().toStdString()) ; RsFileHash hash( (*it).hash().toStdString()) ;
#ifdef TO_REMOVE
if(rsFiles->alreadyHaveFile( hash,info ) ) if(rsFiles->alreadyHaveFile( hash,info ) )
addAttachment(hash, (*it).name().toUtf8().constData(), (*it).size(), true, RsPeerId()) ; #endif
addAttachment(hash, (*it).name().toUtf8().constData(), (*it).size(), rsFiles->alreadyHaveFile( hash,info ), RsPeerId()) ;
#ifdef TO_REMOVE
else else
not_have.push_back( *it ) ; not_have.push_back( *it ) ;
#endif
} }
#ifdef TO_REMOVE
if(!not_have.empty()) if(!not_have.empty())
{ {
QString msg = tr("You are about to add files you're not actually sharing. Do you still want this to happen?")+"<br><br>" ; QString msg = tr("You are about to add files you're not actually sharing. Do you still want this to happen?")+"<br><br>" ;
@ -234,6 +239,7 @@ void CreateGxsChannelMsg::pasteLink()
for(QList<RetroShareLink>::const_iterator it(not_have.begin());it!=not_have.end();++it) for(QList<RetroShareLink>::const_iterator it(not_have.begin());it!=not_have.end();++it)
addAttachment(RsFileHash((*it).hash().toStdString()), (*it).name().toUtf8().constData(), (*it).size(), false, RsPeerId()) ; addAttachment(RsFileHash((*it).hash().toStdString()), (*it).name().toUtf8().constData(), (*it).size(), false, RsPeerId()) ;
} }
#endif
} }
/* Dropping */ /* Dropping */
@ -520,7 +526,7 @@ void CreateGxsChannelMsg::addHtmlText(const QString& text)
RichTextEditWidget->setText(text) ; RichTextEditWidget->setText(text) ;
} }
void CreateGxsChannelMsg::addAttachment(const std::string &path) bool CreateGxsChannelMsg::addAttachment(const std::string &path)
{ {
/* add a SubFileItem to the attachment section */ /* add a SubFileItem to the attachment section */
#ifdef DEBUG_CREATE_GXS_MSG #ifdef DEBUG_CREATE_GXS_MSG
@ -540,13 +546,12 @@ void CreateGxsChannelMsg::addAttachment(const std::string &path)
for(it= mAttachments.begin(); it != mAttachments.end(); ++it){ for(it= mAttachments.begin(); it != mAttachments.end(); ++it){
if((*it)->FilePath() == path){ if((*it)->FilePath() == path){
QMessageBox::warning(this, tr("RetroShare"), tr("File already Added and Hashed"), QMessageBox::Ok, QMessageBox::Ok); QMessageBox::warning(this, tr("RetroShare"), tr("This file already in this post:")+"<br/>"+QString::fromStdString(path), QMessageBox::Ok, QMessageBox::Ok);
return; return false;
} }
} }
FileInfo fInfo;
std::string filename = RsDirUtil::getTopDir(path); std::string filename = RsDirUtil::getTopDir(path);
uint64_t size = 0; uint64_t size = 0;
RsFileHash hash ; RsFileHash hash ;
@ -570,7 +575,7 @@ void CreateGxsChannelMsg::addAttachment(const std::string &path)
updateAttachmentCount(); updateAttachmentCount();
return; return true;
} }
bool CreateGxsChannelMsg::setThumbNail(const std::string& path, int frame){ bool CreateGxsChannelMsg::setThumbNail(const std::string& path, int frame){
@ -724,31 +729,54 @@ void CreateGxsChannelMsg::sendMsg()
std::string msg = std::string(text.toUtf8()); std::string msg = std::string(text.toUtf8());
std::list<RsGxsFile> files; std::list<RsGxsFile> files;
std::list<RsGxsFile> missing_files;
std::list<RsGxsFile> files_only_extra;
std::list<SubFileItem *>::iterator fit; for(auto fit :mAttachments)
if (!fit->isHidden())
for(fit = mAttachments.begin(); fit != mAttachments.end(); ++fit)
{
if (!(*fit)->isHidden())
{ {
RsGxsFile fi; RsGxsFile fi;
fi.mHash = (*fit)->FileHash(); fi.mHash = fit->FileHash();
fi.mName = (*fit)->FileName(); fi.mName = fit->FileName();
fi.mSize = (*fit)->FileSize(); fi.mSize = fit->FileSize();
files.push_back(fi); files.push_back(fi);
/* commence downloads - if we don't have the file */ /* if we don't have the file, display info about it */
if (!(*fit)->done()) if (!fit->done() && fit->ready()) // Skips unhashed files.
missing_files.push_back(fi);
FileInfo finfo;
bool extra = rsFiles->FileDetails(fi.mHash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY, finfo );
bool local = rsFiles->FileDetails(fi.mHash, RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SPEC_ONLY, finfo );
if(extra && !local)
files_only_extra.push_back(fi);
}
if(!missing_files.empty())
{ {
if ((*fit)->ready()) QString filesstr = "<br/>";
for(auto& file: missing_files)
filesstr += "<br/>" /*+QString::fromStdString(file.mHash.toStdString()) + " "*/ + QString::fromStdString(file.mName) ;
if(QMessageBox::Cancel == QMessageBox::warning(nullptr,tr("Post refers to non shared files"),
tr("This post contains files that you are currently not sharing. Do you still want to post?")+filesstr,QMessageBox::Ok,QMessageBox::Cancel))
return;
}
if(!files_only_extra.empty())
{ {
(*fit)->download(); QString filesstr = "<br/>";
}
// Skips unhashed files. for(auto& file: files_only_extra)
} filesstr += "<br/>" /*+QString::fromStdString(file.mHash.toStdString()) + " "*/ + QString::fromStdString(file.mName) ;
}
QMessageBox::information(nullptr,
tr("Post refers to temporary shared files"),
tr("The following files will only be shared for 30 days. Think about adding them to a shared directory.")
+filesstr);
} }
sendMessage(subject, msg, files); sendMessage(subject, msg, files);

View file

@ -45,7 +45,9 @@ public:
void addHtmlText(const QString& text) ; void addHtmlText(const QString& text) ;
void addSubject(const QString& text) ; void addSubject(const QString& text) ;
void addAttachment(const std::string &path);
// adds a file to be hashed and shared. Returns false if something goes wrong.
bool addAttachment(const std::string &path);
void addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId,bool assume_file_ready = false); void addAttachment(const RsFileHash &hash, const std::string &fname, uint64_t size, bool local, const RsPeerId &srcId,bool assume_file_ready = false);
void newChannelMsg(); void newChannelMsg();

View file

@ -831,7 +831,7 @@ void MessageComposer::setFileList(const std::list<DirDetails>& dir_info)
FileInfo info ; FileInfo info ;
info.fname = it->name ; info.fname = it->name ;
info.hash = it->hash ; info.hash = it->hash ;
info.size = it->count ; info.size = it->size ;
files_info.push_back(info) ; files_info.push_back(info) ;
} }