aboutsummaryrefslogtreecommitdiff
path: root/src/Cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cache.cpp')
-rw-r--r--src/Cache.cpp106
1 files changed, 73 insertions, 33 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 0610a18..cba346b 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -4,12 +4,14 @@
#include "../include/FileUtil.hpp"
#include "../include/Gif.hpp"
#include "../include/Chatbar.hpp"
+#include "../include/WebPagePreview.hpp"
#include <boost/filesystem/convenience.hpp>
#include <unordered_map>
#include <process.hpp>
#include <odhtdb/Hash.hpp>
#include <sibs/SafeSerializer.hpp>
#include <sibs/SafeDeserializer.hpp>
+#include <libpreview.h>
#if OS_FAMILY == OS_FAMILY_POSIX
#include <pwd.h>
@@ -22,7 +24,7 @@ using namespace TinyProcessLib;
namespace dchat
{
- unordered_map<string, ImageByUrlResult> imageUrlCache;
+ unordered_map<string, ContentByUrlResult> contentUrlCache;
boost::filesystem::path getHomeDir()
{
@@ -115,38 +117,71 @@ namespace dchat
fileReplace(getDchatDir() / "binds", StringView((const char*)serializer.getBuffer().data(), serializer.getBuffer().size()));
}
- ImageByUrlResult loadImageFromFile(const boost::filesystem::path &filepath)
+ static ContentByUrlResult loadImageFromFile(const boost::filesystem::path &filepath)
{
StringView fileContent;
try
{
fileContent = getFileContent(filepath);
- if(Gif::isDataGif(fileContent))
- {
- Gif *gif = new Gif(move(fileContent));
- return { gif, ImageByUrlResult::Type::CACHED };
- }
- else
+
+ sf::String webPageTitle;
+ bool foundHtmlContent = false;
+ preview_state state;
+ preview_init(&state);
+ size_t offset = 0;
+ do
{
- sf::Texture *texture = new sf::Texture();
- if(texture->loadFromMemory(fileContent.data, fileContent.size))
+ // TODO: Get file content before doing this, the file might be in utf-16 encoding. That can happen for example if file contains html.
+ // Content type can be retrieved from HTTP response header when downloading content
+ offset += preview_step(&state, fileContent.data + offset, fileContent.size - offset);
+ if(state.step_result == PREVIEW_FOUND_IMAGE)
{
- delete fileContent.data;
- fileContent.data = nullptr;
- texture->setSmooth(true);
- texture->generateMipmap();
- return { texture, ImageByUrlResult::Type::CACHED };
+ if(Gif::isDataGif(fileContent))
+ {
+ Gif *gif = new Gif(move(fileContent));
+ return { gif, ContentByUrlResult::Type::CACHED };
+ }
+ else
+ {
+ sf::Texture *texture = new sf::Texture();
+ if(texture->loadFromMemory(fileContent.data, fileContent.size))
+ {
+ delete fileContent.data;
+ fileContent.data = nullptr;
+ texture->setSmooth(true);
+ texture->generateMipmap();
+ return { texture, ContentByUrlResult::Type::CACHED };
+ }
+ delete texture;
+ }
+ break;
}
- delete texture;
- delete fileContent.data;
- fileContent.data = nullptr;
+ else if(state.step_result == PREVIEW_FOUND_TITLE)
+ {
+ foundHtmlContent = true;
+ webPageTitle = sf::String::fromUtf8(state.title, state.title + state.title_length);
+ }
+ else if(state.step_result == PREVIEW_FOUND_PARAGRAPH)
+ {
+ foundHtmlContent = true;
+ }
+ } while(offset < fileContent.size);
+
+ delete fileContent.data;
+ fileContent.data = nullptr;
+
+ if(foundHtmlContent)
+ {
+ // TODO: Use move semantics for webPageTitle when SFML supports it
+ WebPagePreview *webPagePreview = new WebPagePreview(webPageTitle);
+ return { webPagePreview, ContentByUrlResult::Type::CACHED };
}
}
catch(std::exception &e)
{
fprintf(stderr, "Failed to load image %s, reason: %s\n", filepath.string().c_str(), e.what());
}
- return { (sf::Texture*)nullptr, ImageByUrlResult::Type::FAILED_DOWNLOAD };
+ return { (sf::Texture*)nullptr, ContentByUrlResult::Type::FAILED_DOWNLOAD };
}
Cache::Cache() :
@@ -168,13 +203,13 @@ namespace dchat
odhtdb::Hash urlHash(it->url.data(), it->url.size());
filepath /= urlHash.toString();
- ImageByUrlResult imageByUrlResult = loadImageFromFile(filepath);
+ ContentByUrlResult contentByUrlResult = loadImageFromFile(filepath);
imageDownloadMutex.lock();
- imageUrlCache[it->url] = imageByUrlResult;
+ contentUrlCache[it->url] = contentByUrlResult;
imageDownloadMutex.unlock();
- if(imageByUrlResult.type == ImageByUrlResult::Type::CACHED)
+ if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
{
- printf("Download %s from url: %s\n", imageByUrlResult.isGif ? "gif" : "image", it->url.c_str());
+ printf("Download content from url: %s\n", it->url.c_str());
}
}
it = imageDownloadProcesses.erase(it);
@@ -208,11 +243,11 @@ namespace dchat
downloadWaitThread.join();
}
- const ImageByUrlResult Cache::getImageByUrl(const string &url, int downloadLimitBytes)
+ const ContentByUrlResult Cache::getContentByUrl(const string &url, int downloadLimitBytes)
{
lock_guard<mutex> lock(imageDownloadMutex);
- auto it = imageUrlCache.find(url);
- if(it != imageUrlCache.end())
+ auto it = contentUrlCache.find(url);
+ if(it != contentUrlCache.end())
return it->second;
// TODO: Verify hashed url is not too long for filepath on windows
@@ -220,16 +255,21 @@ namespace dchat
odhtdb::Hash urlHash(url.data(), url.size());
filepath /= urlHash.toString();
- ImageByUrlResult imageByUrlResult = loadImageFromFile(filepath);
- if(imageByUrlResult.type == ImageByUrlResult::Type::CACHED)
+ ContentByUrlResult contentByUrlResult = loadImageFromFile(filepath);
+ if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
+ {
+ contentUrlCache[url] = contentByUrlResult;
+ printf("Loaded content from file cache: %s\n", url.c_str());
+ return contentByUrlResult;
+ }
+ else if(contentByUrlResult.type == ContentByUrlResult::Type::FAILED_DOWNLOAD && boost::filesystem::exists(filepath))
{
- imageUrlCache[url] = imageByUrlResult;
- printf("Loaded image from file cache: %s, is gif: %s\n", url.c_str(), imageByUrlResult.isGif ? "yes" : "no");
- return imageByUrlResult;
+ contentUrlCache[url] = contentByUrlResult;
+ return contentByUrlResult;
}
- ImageByUrlResult result((sf::Texture*)nullptr, ImageByUrlResult::Type::DOWNLOADING);
- imageUrlCache[url] = result;
+ ContentByUrlResult result((sf::Texture*)nullptr, ContentByUrlResult::Type::DOWNLOADING);
+ contentUrlCache[url] = result;
string downloadLimitBytesStr = to_string(downloadLimitBytes);