📄 sharing.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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.
*/
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Sharing.h"
#include "GiftCommand.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
namespace KCeasyEngine {
// class TSharedFile
// private
TSharedFile::TSharedFile()
: FileSize(0),
FileType(FTUnknown),
Hashes(NULL),
AddedManually(false)
{
Hashes = new THashSet();
}
TSharedFile::TSharedFile(const TSharedFile* File)
: Hashes(NULL),
FileName(File->FileName),
FileDir(File->FileDir),
FileSize(File->FileSize),
MimeType(File->MimeType),
FileType(File->FileType),
MetaData(File->MetaData),
AddedManually(false)
{
Hashes = new THashSet(File->GetHashes());
SetUData (File->GetUData());
}
TSharedFile::~TSharedFile()
{
delete Hashes;
}
string TSharedFile::GetMagnetStr() const
{
TMagnet* Magnet = new TMagnet();
// add urns
Magnet->SetExactTopicHashes(GetHashes());
// add display name
if(MetaData.Exists("artist") && MetaData.Exists("title"))
Magnet->SetDisplayName(MetaData.Get("artist") + " - " + MetaData.Get("title"));
else
Magnet->SetDisplayName(FileName);
string MagnetStr = Magnet->Assemble();
delete Magnet;
return MagnetStr;
}
// class TShares
// private
TShares::TShares(TEngine* ParentEngine)
: Engine(ParentEngine),
FilesGiftId(0),
DirsGiftId(0),
Hidden(false),
Syncing(false)
{
}
TShares::~TShares()
{
LockFiles();
while(!Files.empty()) {
delete Files.front();
Files.pop_front();
}
ReleaseFiles();
}
bool TShares::ProcessItem(TGiftCommand* Cmd)
{
if(Cmd->Name != "ITEM" || string_to_int(Cmd->Value) != FilesGiftId)
return false;
LockFiles();
if(Cmd->Nodes.empty()) {
// end of SHARES request
FilesGiftId = 0;
ReleaseFiles();
return true;
}
TSharedFile* File = new TSharedFile();
for(TGiftCommand::Iterator itr=Cmd->Nodes.begin();itr!=Cmd->Nodes.end();++itr)
if((*itr).Name == "hash")
File->Hashes->AddGiftHash((*itr).Value);
File->FileName = FileFromPath(Cmd->GetNode("path").Value);
File->FileDir = DirFromPath(Cmd->GetNode("path").Value);
if (Engine->IsUsingLocalGift())
File->FileDir = UnixToWindowsPath(File->FileDir);
File->FileSize = string_to_int(Cmd->GetNode("size").Value);
File->MimeType = Cmd->GetNode("mime").Value;
File->FileType = FileTypeFromMime(File->MimeType);
// get meta data
if(Cmd->NodeExists("META")) {
TGiftCommand& MetaCmd = Cmd->GetNode("META");
for(TGiftCommand::Iterator itr=MetaCmd.Nodes.begin();itr!=MetaCmd.Nodes.end();++itr)
File->MetaData.Set((*itr).Name,(*itr).Value);
}
Files.push_back(File);
ReleaseFiles();
// notify UI
Engine->SendCallback(CbcSharesAddFile,(void*)this,(void*)File);
return true;
}
bool TShares::ProcessShare(TGiftCommand* Cmd)
{
if(Cmd->Name != "SHARE")
return false;
if(Cmd->GetNode("action").Value == "show") {
Hidden = false;
Engine->SendCallback(CbcSharesHiddenUpdate,(void*)this);
} else if(Cmd->GetNode("action").Value == "hide") {
Hidden = true;
Engine->SendCallback(CbcSharesHiddenUpdate,(void*)this);
} else if(Cmd->GetNode("action").Value == "sync") {
Syncing = !(Cmd->GetNode("status").Value == "done");
Engine->SendCallback(CbcSharesSyncUpdate,(void*)this,(void*)string_to_int(Cmd->GetNode("status").Value));
}
return true;
}
// public
bool TShares::UpdateFiles()
{
if(UpdatingFiles())
return false;
FilesGiftId = Engine->GetNextGiftId();
Engine->SendCallback(CbcSharesDelFile,(void*)this,NULL);
LockFiles();
while(!Files.empty()) {
delete Files.front();
Files.pop_front();
}
ReleaseFiles();
Engine->QueueCommand(new TGiftCommand("SHARES",int_to_string(FilesGiftId)));
return true;
}
bool TShares::RemoveFile(TSharedFile* SharedFile)
{
// find file in list
LockFiles();
TFilesIterator itr = Files.begin();
while(itr != Files.end() && (*itr) != SharedFile)
++itr;
if(itr == Files.end()) {
ReleaseFiles();
return false;
}
ReleaseFiles();
// notify ui
Engine->SendCallback(CbcSharesDelFile,(void*)this,SharedFile);
// remove file
LockFiles();
Files.remove(SharedFile);
delete SharedFile;
ReleaseFiles();
return true;
}
bool TShares::RenameFile(TSharedFile* SharedFile, const string& NewFileName)
{
if (NewFileName == "" || NewFileName.find_first_of("/\\") != -1)
return false;
// find file in list
LockFiles();
TFilesIterator itr = Files.begin();
while(itr != Files.end() && (*itr) != SharedFile)
++itr;
if(itr == Files.end()) {
ReleaseFiles();
return false;
}
// change file name
SharedFile->FileName = NewFileName;
ReleaseFiles();
// notify ui
Engine->SendCallback(CbcSharesChangeFile,(void*)this,SharedFile);
return true;
}
bool TShares::AddFile(const TSharedFile* SharedFile)
{
if(GetFileByPath(SharedFile->FileDir + "/" + SharedFile->FileName))
return false;
// create copy of file
TSharedFile* File = new TSharedFile(SharedFile);
File->AddedManually = true;
// make sure we got the right path format
if (Engine->IsUsingLocalGift())
File->FileDir = UnixToWindowsPath(File->FileDir);
// add it
LockFiles();
Files.push_back(File);
ReleaseFiles();
// notify UI
Engine->SendCallback(CbcSharesAddFile,(void*)this,(void*)File);
return true;
}
TSharedFile* TShares::GetFileByHashes(const THashSet* Hashes)
{
LockFiles();
for(TFilesIterator itr=Files.begin(); itr != Files.end(); ++itr) {
if(*Hashes == *(*itr)->GetHashes()) {
ReleaseFiles();
return (*itr);
}
}
ReleaseFiles();
return NULL;
}
TSharedFile* TShares::GetFileByPath(const string& Path)
{
string FileName = FileFromPath(Path);
string FileDir = DirFromPath(Path);
if (Engine->IsUsingLocalGift())
FileDir = UnixToWindowsPath(FileDir);
LockFiles();
for(TFilesIterator itr=Files.begin(); itr != Files.end(); ++itr) {
if((*itr)->FileName == FileName && (*itr)->FileDir == FileDir) {
ReleaseFiles();
return (*itr);
}
}
ReleaseFiles();
return NULL;
}
// this is gonna be asynchronous in the future
bool TShares::UpdateDirs()
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->Load();
CompletedDir = UnixToWindowsPath(Engine->GetGiftConf()->GetValue("download/completed"));
IncomingDir = UnixToWindowsPath(Engine->GetGiftConf()->GetValue("download/incoming"));
LockDirs();
Dirs.clear();
string root = Engine->GetGiftConf()->GetValue("sharing/root");
Dirs = string_split(root,":");
for(TDirsIterator itr = Dirs.begin(); itr != Dirs.end(); ++itr)
(*itr) = UnixToWindowsPath(*itr);
list<string> DirsCpy = Dirs;
ReleaseDirs();
// remove dirs which are no longer on disk
for(TDirsIterator itr = DirsCpy.begin(); itr != DirsCpy.end(); ++itr) {
if(GetFileAttributes((*itr).c_str()) == 0xFFFFFFFF)
RemoveDir((*itr));
}
Engine->SendCallback(CbcSharedDirsUpdate,(void*)this,0);
return true;
}
bool TShares::AddDir(const string& SharedDir)
{
if(!Engine->IsUsingLocalGift())
return false;
LockDirs();
TDirsIterator itr = Dirs.begin();
while(itr != Dirs.end() && (*itr) != SharedDir)
++itr;
if(itr == Dirs.end()) {
Dirs.push_back(SharedDir);
itr = Dirs.begin();
string root = WindowsToUnixPath(*itr);
for(++itr;itr != Dirs.end();++itr)
root += string(":") + WindowsToUnixPath(*itr);
Engine->GetGiftConf()->SetValue("sharing/root",root.c_str());
Engine->GetGiftConf()->Save();
}
ReleaseDirs();
Engine->SendCallback(CbcSharedDirsUpdate,(void*)this,(void*)1);
return true;
}
bool TShares::RemoveDir(const string& SharedDir)
{
if(!Engine->IsUsingLocalGift())
return false;
LockDirs();
TDirsIterator itr = Dirs.begin();
while(itr != Dirs.end() && (*itr) != SharedDir)
++itr;
if(itr == Dirs.end())
return false;
Dirs.erase(itr);
string root;
for(itr = Dirs.begin();itr != Dirs.end();++itr)
root += WindowsToUnixPath(*itr) + ":";
if(root.length() > 0)
root.erase(root.length()-1,1); // remove last ':'
Engine->GetGiftConf()->SetValue("sharing/root",root.c_str());
Engine->GetGiftConf()->Save();
ReleaseDirs();
Engine->SendCallback(CbcSharedDirsUpdate,(void*)this,(void*)1);
return true;
}
bool TShares::SetDirs(const list<string>& NewDirs)
{
if(!Engine->IsUsingLocalGift())
return false;
LockDirs();
Dirs.clear();
Dirs = NewDirs;
string root;
for(TDirsIterator itr = Dirs.begin();itr != Dirs.end();++itr)
root += WindowsToUnixPath(*itr) + ":";
if(root.length() > 0)
root.erase(root.length()-1,1); // remove last ':'
Engine->GetGiftConf()->SetValue("sharing/root",root.c_str());
Engine->GetGiftConf()->Save();
ReleaseDirs();
Engine->SendCallback(CbcSharedDirsUpdate,(void*)this,(void*)1);
return true;
}
bool TShares::SetCompletedDir(const string& NCompletedDir)
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->SetValue("download/completed",WindowsToUnixPath(NCompletedDir));
Engine->GetGiftConf()->Save();
CompletedDir = UnixToWindowsPath(Engine->GetGiftConf()->GetValue("download/completed"));
Engine->SendCallback(CbcSharesDownloadDirsUpdate,(void*)this,NULL);
return true;
}
bool TShares::SetIncomingDir(const string& NIncomingDir)
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->SetValue("download/incoming",WindowsToUnixPath(NIncomingDir));
Engine->GetGiftConf()->Save();
IncomingDir = UnixToWindowsPath(Engine->GetGiftConf()->GetValue("download/incoming"));
Engine->SendCallback(CbcSharesDownloadDirsUpdate,(void*)this,NULL);
return true;
}
bool TShares::Hide(bool Hide)
{
TGiftCommand* Cmd = new TGiftCommand("SHARE","");
if(Hide)
Cmd->AddNode(TGiftCommand("action","hide"));
else
Cmd->AddNode(TGiftCommand("action","show"));
Engine->QueueCommand(Cmd);
return true;
}
bool TShares::UpdateHide()
{
TGiftCommand* Cmd = new TGiftCommand("SHARE","");
Cmd->AddNode(TGiftCommand("action",""));
Engine->QueueCommand(Cmd);
return true;
}
bool TShares::Sync()
{
TGiftCommand* Cmd = new TGiftCommand("SHARE","");
Cmd->AddNode(TGiftCommand("action","sync"));
Engine->QueueCommand(Cmd);
return true;
}
// bandwidth settings
bool TShares::GetSharingEnabled()
{
if(!Engine->IsUsingLocalGift())
return false;
return (Engine->GetGiftConf()->GetValueInt("sharing/shares_hidden") == 0);
}
bool TShares::SetSharingEnabled(bool Enabled)
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->SetValueInt("sharing/shares_hidden",Enabled ? 0 : 1);
Engine->GetGiftConf()->Save(); // FIXME: there is a chance here of overwriting other changes
return true;
}
bool TShares::GetKeepCorruptedDownloads()
{
if(!Engine->IsUsingLocalGift())
return false;
return (Engine->GetGiftConf()->GetValueInt("download/keep_corrupted") != 0);
}
bool TShares::SetKeepCorruptedDownloads(bool Keep)
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->SetValueInt("download/keep_corrupted",Keep ? 1 : 0);
Engine->GetGiftConf()->Save(); // FIXME: there is a chance here of overwriting other changes
return true;
}
int TShares::GetMaxUploads()
{
if(!Engine->IsUsingLocalGift())
return -1;
return Engine->GetGiftConf()->GetValueInt("sharing/max_uploads");
}
bool TShares::SetMaxUploads(int No)
{
if(!Engine->IsUsingLocalGift() || No < 0)
return false;
Engine->GetGiftConf()->SetValueInt("sharing/max_uploads",No);
Engine->GetGiftConf()->Save(); // FIXME: there is a chance here of overwriting other changes
return true;
}
int TShares::GetMaxPerUserUploads()
{
if(!Engine->IsUsingLocalGift())
return -1;
return Engine->GetGiftConf()->GetValueInt("sharing/max_peruser_uploads");
}
bool TShares::SetMaxPerUserUploads(int No)
{
if(!Engine->IsUsingLocalGift() || No <= 0)
return false;
Engine->GetGiftConf()->SetValueInt("sharing/max_peruser_uploads",No);
Engine->GetGiftConf()->Save();
return true;
}
unsigned int TShares::GetUploadBandwidth()
{
if(!Engine->IsUsingLocalGift())
return 0;
return Engine->GetGiftConf()->GetValueInt("bandwidth/upstream");
}
bool TShares::SetUploadBandwidth(unsigned int Bps)
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->SetValueInt("bandwidth/upstream",Bps);
Engine->GetGiftConf()->Save();
return true;
}
unsigned int TShares::GetDownloadBandwidth()
{
if(!Engine->IsUsingLocalGift())
return 0;
return Engine->GetGiftConf()->GetValueInt("bandwidth/downstream");
}
bool TShares::SetDownloadBandwidth(unsigned int Bps)
{
if(!Engine->IsUsingLocalGift())
return false;
Engine->GetGiftConf()->SetValueInt("bandwidth/downstream",Bps);
Engine->GetGiftConf()->Save();
return true;
}
} // namespace KCeasyEngine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -