⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sharing.cpp

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 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 + -