-
Notifications
You must be signed in to change notification settings - Fork 203
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add xmodel download from vendor site capability
- Loading branch information
Keith Westley
committed
Jan 12, 2018
1 parent
10b9f79
commit 9779df4
Showing
17 changed files
with
2,186 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,4 +17,5 @@ | |
#include "icicles.xpm" | ||
#include "import.xpm" | ||
#include "polyline.xpm" | ||
#include "download.xpm" | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* XPM */ | ||
static const char *download[] = { | ||
"48 48 3 1", | ||
" c None", | ||
". c #000000", | ||
"+ c #FFFFFF", | ||
"................................................", | ||
"................................................", | ||
"................................................", | ||
"................................................", | ||
"................................................", | ||
"................+++++++++++++++++...............", | ||
"...............++++++++++++++++++...............", | ||
"...............++++++++++++++++++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"...............+++............+++...............", | ||
"........++++++++++............+++++++++++.......", | ||
"........++++++++++............+++++++++++.......", | ||
"........++++++++++.............++++++++++.......", | ||
".........++++.......................++++........", | ||
"..........++++.....................++++.........", | ||
"...........++++...................++++..........", | ||
"............++++.................++++...........", | ||
".............+++.................++++...........", | ||
".............++++...............++++............", | ||
"..............++++.............++++.............", | ||
"...............++++...........++++..............", | ||
"................++++.........++++...............", | ||
".................++++.......++++................", | ||
"..................+++.......++++................", | ||
"..................++++.....++++.................", | ||
"...................++++...++++..................", | ||
"....................++++.++++...................", | ||
".....................+++++++....................", | ||
"......................+++++.....................", | ||
".......................++++.....................", | ||
".......................+++......................", | ||
"................................................", | ||
"................................................", | ||
"................................................", | ||
"................................................"}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,318 @@ | ||
#include "CachedFileDownloader.h" | ||
|
||
#include <wx/wx.h> | ||
#include <wx/protocol/http.h> | ||
#include <wx/sstream.h> | ||
#include <log4cpp/Category.hh> | ||
#include <wx/dir.h> | ||
#include <wx/xml/xml.h> | ||
|
||
#define LONGCACHEDAYS 5 | ||
|
||
FileCacheItem::FileCacheItem(wxXmlNode* n) | ||
{ | ||
_url = n->GetAttribute("URI", ""); | ||
_fileName = n->GetAttribute("FileName", ""); | ||
_cacheFor = (CACHEFOR)wxAtoi(n->GetAttribute("CacheFor", "0")); | ||
} | ||
|
||
FileCacheItem::FileCacheItem(wxURI url, CACHEFOR cacheFor) | ||
{ | ||
_url = url; | ||
_cacheFor = cacheFor; | ||
Download(); | ||
} | ||
|
||
void FileCacheItem::Save(wxFile& f) | ||
{ | ||
f.Write(" <item URI=\"" + _url.BuildURI() + | ||
"\" FileName=\"" + _fileName + | ||
"\" CacheFor=\"" + wxString::Format("%d", _cacheFor) + | ||
"\"/>\n"); | ||
} | ||
|
||
void FileCacheItem::Download() | ||
{ | ||
_fileName = DownloadURLToTemp(_url); | ||
} | ||
|
||
// A major constraint of this function is that it does not support https | ||
bool FileCacheItem::DownloadURL(wxURI url, wxFileName filename) const | ||
{ | ||
bool ok = true; | ||
|
||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
if (url.GetScheme() == "https") | ||
{ | ||
logger_base.warn("Unable to retrieve '%s' as xLights cannot access https pages.", (const char *)url.GetPath().c_str()); | ||
} | ||
|
||
wxHTTP http; | ||
http.SetMethod("GET"); | ||
int port = 80; | ||
if (wxAtoi(url.GetPort()) != 0) | ||
{ | ||
port = wxAtoi(url.GetPort()); | ||
} | ||
bool connected = http.Connect(url.GetServer(), port); | ||
|
||
if (connected) | ||
{ | ||
logger_base.debug("Making request to '%s'.", (const char *)url.BuildURI().c_str()); | ||
wxStopWatch sw; | ||
wxInputStream *httpStream = http.GetInputStream(url.GetPath()); | ||
|
||
if (http.GetError() == wxPROTO_NOERR) | ||
{ | ||
logger_base.debug(" Result %d.", http.GetResponse()); | ||
|
||
if (http.GetResponse() >= 300 && http.GetResponse() < 400) | ||
{ | ||
wxDELETE(httpStream); | ||
|
||
wxURI redir = http.GetHeader("LOCATION"); | ||
if (redir.GetPath() == url.GetPath()) | ||
{ | ||
return false; | ||
} | ||
return DownloadURL(redir, filename); | ||
} | ||
|
||
wxFile f; | ||
long size = 0; | ||
if (f.Open(filename.GetFullPath(), wxFile::write)) | ||
{ | ||
wxByte buffer[65536]; | ||
while (!httpStream->Eof() && httpStream->CanRead()) | ||
{ | ||
httpStream->Read(buffer, sizeof(buffer)); | ||
f.Write(buffer, httpStream->LastRead()); | ||
size += httpStream->LastRead(); | ||
} | ||
f.Close(); | ||
logger_base.debug(" File downloaded %.1f kbytes in %ldms.", (float)size / 1024.0, sw.Time()); | ||
} | ||
else | ||
{ | ||
ok = false; | ||
} | ||
} | ||
else | ||
{ | ||
logger_base.error("Unable to connect to '%s' : %d.", (const char *)url.GetPath().c_str(), http.GetError()); | ||
ok = false; | ||
} | ||
|
||
wxDELETE(httpStream); | ||
} | ||
else | ||
{ | ||
ok = false; | ||
} | ||
|
||
return ok; | ||
} | ||
|
||
std::string FileCacheItem::DownloadURLToTemp(wxURI url) | ||
{ | ||
wxString type = url.GetPath().AfterLast('.'); | ||
wxString fn = wxFileName::CreateTempFileName("xl"); | ||
wxRemoveFile(fn); | ||
wxString filename = fn.BeforeLast('.') + "." + type; | ||
if (fn.BeforeLast('.') == "") | ||
{ | ||
filename = fn + "." + type; | ||
} | ||
|
||
if (DownloadURL(url, filename)) | ||
{ | ||
return filename.ToStdString(); | ||
} | ||
|
||
return ""; | ||
} | ||
|
||
void FileCacheItem::PurgeIfAged() const | ||
{ | ||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
if (!Exists()) return; | ||
|
||
wxDateTime modified = wxFileName(_fileName).GetModificationTime(); | ||
switch(_cacheFor) | ||
{ | ||
case CACHETIME_SESSION: | ||
// do nothing | ||
break; | ||
case CACHETIME_DAY: | ||
if (wxDateTime::Now().GetDateOnly() != modified.GetDateOnly()) | ||
{ | ||
logger_base.debug("%s purged from file cache because it was not created today.", (const char *)_url.BuildURI().c_str()); | ||
Delete(); | ||
} | ||
break; | ||
case CACHETIME_FOREVER: | ||
// do nothing | ||
break; | ||
case CACHETIME_LONG: | ||
wxTimeSpan age = wxDateTime::Now() - modified; | ||
if (age.GetDays() > LONGCACHEDAYS) | ||
{ | ||
logger_base.debug("%s purged from file cache because it was more than %d days old: %d.", (const char *)_url.BuildURI().c_str(), LONGCACHEDAYS, age.GetDays()); | ||
Delete(); | ||
} | ||
break; | ||
} | ||
} | ||
|
||
void CachedFileDownloader::SaveCache() | ||
{ | ||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
logger_base.debug("Saving File Cache %s.", (const char *)_cacheFile.c_str()); | ||
|
||
wxFile f; | ||
if (f.Create(_cacheFile, true) && f.IsOpened()) | ||
{ | ||
wxString lit("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); | ||
f.Write(lit, lit.size()); | ||
lit = "<filecache>\n"; | ||
f.Write(lit, lit.size()); | ||
|
||
int i = 0; | ||
for (auto it = _cacheItems.begin(); it != _cacheItems.end(); ++it) | ||
{ | ||
if ((*it)->ShouldSave()) | ||
{ | ||
(*it)->Save(f); | ||
i++; | ||
} | ||
} | ||
|
||
lit = "</filecache>"; | ||
f.Write(lit, lit.size()); | ||
f.Close(); | ||
logger_base.debug(" File Cache %d items saved.", i); | ||
} | ||
else | ||
{ | ||
logger_base.warn(" Problem saving File Cache."); | ||
} | ||
} | ||
|
||
void CachedFileDownloader::LoadCache() | ||
{ | ||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
logger_base.debug("Loading File Cache %s.", (const char *)_cacheFile.c_str()); | ||
_cacheItems.empty(); | ||
|
||
if (wxFile::Exists(_cacheFile) && wxFileName(_cacheFile).GetSize() > 0) | ||
{ | ||
wxXmlDocument d; | ||
d.Load(_cacheFile); | ||
if (d.IsOk()) | ||
{ | ||
wxXmlNode* root = d.GetRoot(); | ||
if (root != nullptr && root->GetName().Lower() == "filecache") | ||
{ | ||
logger_base.debug(" Cache opened."); | ||
for (wxXmlNode* n = root->GetChildren(); n != nullptr; n = n->GetNext()) | ||
{ | ||
if (n->GetName().Lower() == "item") | ||
_cacheItems.push_back(new FileCacheItem(n)); | ||
} | ||
logger_base.debug(" %d items loaded.", _cacheItems.size()); | ||
} | ||
} | ||
else | ||
{ | ||
logger_base.warn("File Cache was invalid."); | ||
} | ||
} | ||
else | ||
{ | ||
logger_base.warn("File Cache does not exist."); | ||
} | ||
} | ||
|
||
FileCacheItem* CachedFileDownloader::Find(wxURI url) | ||
{ | ||
for (auto it = _cacheItems.begin(); it != _cacheItems.end(); ++it) | ||
{ | ||
if (**it == url) | ||
{ | ||
return *it; | ||
} | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
CachedFileDownloader::CachedFileDownloader(const std::string cacheDir) | ||
{ | ||
_cacheDir = cacheDir; | ||
if (_cacheDir == "" || !wxDirExists(_cacheDir)) | ||
{ | ||
_cacheDir = wxFileName::GetTempDir(); | ||
} | ||
|
||
_cacheFile = _cacheDir + "/xLightsCache.xml"; | ||
|
||
LoadCache(); | ||
PurgeAgedItems(); | ||
} | ||
|
||
CachedFileDownloader::~CachedFileDownloader() | ||
{ | ||
// Dont save ... this is done when the dialog is exited. | ||
//SaveCache(); | ||
} | ||
|
||
void CachedFileDownloader::ClearCache() | ||
{ | ||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
logger_base.debug("File Cache cleared."); | ||
for (auto it= _cacheItems.begin(); it != _cacheItems.end(); ++it) | ||
{ | ||
(*it)->Delete(); | ||
} | ||
} | ||
|
||
void CachedFileDownloader::PurgeAgedItems() | ||
{ | ||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
logger_base.debug("File Cache purging aged items."); | ||
for (auto it= _cacheItems.begin(); it != _cacheItems.end(); ++it) | ||
{ | ||
(*it)->PurgeIfAged(); | ||
} | ||
} | ||
|
||
std::string CachedFileDownloader::GetFile(wxURI url, CACHEFOR cacheFor) | ||
{ | ||
static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base")); | ||
|
||
FileCacheItem* fci = Find(url); | ||
if (fci == nullptr) | ||
{ | ||
logger_base.debug("File Cache downloading file %s.", (const char *)url.BuildURI().c_str()); | ||
fci = new FileCacheItem(url, cacheFor); | ||
_cacheItems.push_back(fci); | ||
} | ||
else if (!fci->Exists()) | ||
{ | ||
logger_base.debug("File Cache re-downloading file %s.", (const char *)url.BuildURI().c_str()); | ||
fci->Download(); | ||
} | ||
|
||
if (fci->GetFileName() == "") | ||
{ | ||
logger_base.debug("File Cache file %s could not be retrieved.", (const char *)url.BuildURI().c_str()); | ||
} | ||
|
||
return fci->GetFileName(); | ||
} |
Oops, something went wrong.
9779df4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am having problems with this on Linux.
When the CachedFileDownloader is instanced via "CachedFileDownloader VendorModelDialog::_cache;" it is crashing. It looks like the 'cacheDir' is invalid (see #4 in the stack below)
I've tried forcing the value but it still keeps the reference and so messes up later in LoadCache.
Any ideas what is going on here?
====
#0 0x000055555616e8e8 in wxString::AsCharBuf(wxMBConv const&) const (this=0x7fffffffd2c0, conv=...) at /usr/local/include/wx-3.1/wx/string.h:3367
#1 0x000055555691ddae in (anonymous namespace)::DoStatAny(stat&, wxString, bool) ()
#2 0x000055555691deb0 in (anonymous namespace)::wxFileSystemObjectExists(wxString const&, int) ()
#3 0x0000555556175271 in CachedFileDownloader::LoadCache() (this=0x555558029780 VendorModelDialog::_cache) at /home/cjd/git/xlights/xLights/CachedFileDownloader.cpp:228
#4 0x00005555561759c0 in CachedFileDownloader::CachedFileDownloader(std::cxx11::basic_string<char, std::char_traits, std::allocator >) (this=0x555558029780 VendorModelDialog::_cache, cacheDir="\260\331\377\377\377\177", '\000' <repeats 18 times>, "\223\311yVUU", '\000' <repeats 11 times>, "\246\354\330\336\036\346\r\360\331\377\377\377\177\000\000 \001\000\000\000\000\000\000\370#\336WUU\000\000\070\333\377\377\377\177\000\000\000\332\377\377\377\177\000\000\366[zVUU\000\000\247\002\000\000\000\000\000\000\275\277\374VUU", '\000' <repeats 18 times>, "p\277\374VUU\000\000p\a\023VUU\000\000 \333\377\377\377\177", '\000' <repeats 18 times>, "\200s\232\361\377\177\000\000\001\000\000\000\001\000\000\000(\333\377\377\377\177\000\000\001\000\000\000\001\000\000\000\037\311~VUU\000\000\001\000\000\000\000\000\000\000\340\347\060\362\377\177\000\000\320e\377\367\377\177\000\000\001\000\000\000\000\000\000\000(\333\377\377\377\177\000\000\070\333\377\377\377\177\000\000\001\000\000\000\000\000\000\000\312y\336\367\377\177\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000(\333\377\377\377\177\000\000\070\333\377\377\377\177\000\000h\341\377\367\377\177\000\000\333z\336\367\377\177", '\000' <repeats 18 times>, "p\a\023VUU\000\000 \333\377\377\377\177\000\000\000\000\000\000\000\000\000\000\232\a\023VUU\000\000\030\333\377\377\377\177\000\000\034\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000o\337\377\377\377\177\000\000\000\000\000\000\000\000\000\000\221\337\377\377\377\177\000\000\247\337\377\377\377\177\000\000\343\337\377\377\377\177\000\000\237\345\377\377\377\177\000\000\301\345\377\377\377\177\000\000\330\345\377\377\377\177\000\000\356\345\377\377\377\177\000\000\002\346\377\377\377\177\000\000\023\346\377\377\377\177\000\000*\346\377\377\377\177\000\000\065\346\377\377\377\177\000\000A\346\377\377\377\177\000\000c\346\377\377\377\177\000\000w\346\377\377\377\177\000\000\201\346\377\377\377\177\000\000\226\346\377\377\377\177\000\000\252\346\377\377\377\177\000\000\267\346\377\377\377\177\000\000\334\346\377\377\377\177\000\000\000\347\377\377\377\177\000\000\v\347\377\377\377\177\000\000\064\347\377\377\377\177\000\000i\347\377\377\377\177\000\000{\347\377\377\377\177\000\000\215\347\377\377\377\177\000\000\266\347\377\377\377\177\000\000\277\347\377\377\377\177\000\000\330\347\377\377\377\177\000\000\356\347\377\377\377\177\000\000\000\350\377\377\377\177\000\000\031\350\377\377\377\177\000\000-\350\377\377\377\177\000\000\350\377\377\377\177\000\000\201\350\377\377\377\177\000\000\212\350\377\377\377\177\000\000\231\350\377\377\377\177\000\000\264\350\377\377\377\177\000\000\313\350\377\377\377\177\000\000\362\350\377\377\377\177\000\000\005\351\377\377\377\177\000\000\030\351\377\377\377\177\000\000-\351\377\377\377\177\000\000\v\352\377\377\377\177\000\000 \352\377\377\377\177\000\000\065\352\377\377\377\177\000\000O\352\377\377\377\177\000\000i\352\377\377\377\177\000\000\201\352\377\377\377\177\000\000\231\352\377\377\377\177\000\000\335\352\377\377\377\177\000\000\350\352\377\377\377\177\000\000\374\352\377\377\377\177\000\000\t\353\377\377\377\177\000\000\031\353\377\377\377\177\000\000*\353\377\377\377\177\000\000>\353\377\377\377\177\000\000L\353\377\377\377\177\000\000^\353\377\377\377\177\000\000r\353\377\377\377\177\000\000\214\353\377\377\377\177\000\000\257\353\377\377\377\177\000\000\302\353\377\377\377\177\000\000\321\353\377\377\377\177\000\000\331\353\377\377\377\177\000\000\353\353\377\377\377\177\000\000\005\354\377\377\377\177\000\000\033\354\377\377\377\177\000\000g\354\377\377\377\177\000\000{\354\377\377\377\177\000\000\307\354\377\377\377\177\000\000\331\354\377\377\377\177\000\000\003\355\377\377\377\177\000\000\031\355\377\377\377\177\000\000*\355\377\377\377\177\000\000V\355\377\377\377\177\000\000b\355\377\377\377\177\000\000\230\355\377\377\377\177\000\000\267\355\377\377\377\177\000\000\340\355\377\377\377\177\000\000\f\356\377\377\377\177\000\000\235\356\377\377\377\177\000\000\263\356\377\377\377\177\000\000\301\356\377\377\377\177\000\000\022\357\377\377\377\177\000\000\063\357\377\377\377\177\000\000E\357\377\377\377\177\000\000\227\357\377\377\377\177\000\000\243\357\377\377\377\177\000\000\303\357\377\377\377\177\000\000\000\000\000\000\000\000\000\000!\000\000\000\000\000\000\000\000\240\377\367\377\177\000\000\020\000\000\000\000\000\000\000\377\373\353\277\000\000\000\000\006\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\021\000\000\000\000\000\000\000d\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000@@uuuu\000\000\004\000\000\000\000\000\000\000\070\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\n\000\000\000\000\000\000\000\a\000\000\000\000\000\000\000\000p\335\367\377\177\000\000\b", '\000' <repeats 15 times>, "\t\000\000\000\000\000\000\000p\a\023VUU\000\000\v\000\000\000\000\000\000\000\350\003\000\000\000\000\000\000\f\000\000\000\000\000\000\000\350\003\000\000\000\000\000\000\r\000\000\000\000\000\000\000\350\003\000\000\000\000\000\000\016\000\000\000\000\000\000\000\350\003\000\000\000\000\000\000\027", '\000' <repeats 15 times>, "\031\000\000\000\000\000\000\000I\337\377\377\377\177\000\000\032", '\000' <repeats 15 times>, "\037\000\000\000\000\000\000\000\326\357\377\377\377\177\000\000\017\000\000\000\000\000\000\000Y\337\377\377\377\177", '\000' <repeats 19 times>, "\262\246\354\330\336\036\346\rD\202ߵ\006\060\361&x86_64", '\000' <repeats 16 times>, "/home/cjd/git/xlights/bin/xLights\000CLUTTER_IM_MODULE=xim\000LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu:/usr/local/lib:\000LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:.tar=01;31:.tgz=01;31:.arc=01;31:.arj=01;31:.taz=01;31:.lha=01;31:.lz4=01;31:.lzh=01;31:.lzma=01;31:.tlz=01;31:.txz=01;31:.tzo=01;31:.t7z=01;31:.zip=01;31:.z=01;31:.Z=01;31:.dz=01;31:.gz=01;31:.lrz=01;31:.lz=01;31:.lzo=01;31:.xz=01;31:.zst=01;31:.tzst=01;31:.bz2=01;31:.bz=01;31:.tbz=01;31:.tbz2=01;31:.tz=01;31:.deb=01;31:.rpm=01;31:.jar=01;31:.war=01;31:.ear=01;31:.sar=01;31:.rar=01;31:.alz=01;31:.ace=01;31:.zoo=01;31:.cpio=01;31:.7z=01;31:.rz=01;31:.cab=01;31:.jpg=01;35:.jpeg=01;35:.mjpg=01;35:.mjpeg=01;35:.gif=01;35:.bmp=01;35:.pbm=01;35:.pgm=01;35:.ppm=01;35:.tga=01;35:.xbm=01;35:.xpm=01;35:.tif=01;35:.tiff=01;35:.png=01;35:.svg=01;35:.svgz=01;35:.mng=01;35:.pcx=01;35:.mov=01;35:.mpg=01;35:.mpeg=01;35:.m2v=01;35:.mkv=01;35:.webm=01;35:.ogm=01;35:.mp4=01;35:.m4v=01;35:.mp4v=01;35:.vob=01;35:.qt=01;35:.nuv=01;35:.wmv=01;35:.asf=01;35:.rm=01;35:.rmvb=01;35:.flc=01;35:.avi=01;35:.fli=01;35:.flv=01;35:.gl=01;35:.dl=01;35:.xcf=01;35:.xwd=01;35:.yuv=01;35:.cgm=01;35:.emf=01;35:.ogv=01;35:.ogx=01;35:.aac=00;36:.au=00;36:.flac=00;36:.m4a=00;36:.mid=00;36:.midi=00;36:.mka=00;36:.mp3=00;36:.mpc=00;36:.ogg=00;36:.ra=00;36:.wav=00;36:.oga=00;36:.opus=00;36:.spx=00;36:.xspf=00;36:\000LESSCLOSE=/usr/bin/lesspipe %s %s\000XDG_MENU_PREFIX=gnome-\000=/usr/bin/codeblocks\000BYOBU_ULIMIT=ulimit\000LANG=en_AU.UTF-8\000HISTCONTROL=ignoreboth\000DISPLAY=:1\000IGNOREEOF=1\000BYOBU_CONFIG_DIR=/home/cjd/.byobu\000BYOBU_DARK=\#333333\000EDITOR=vi\000BYOBU_LIGHT=\#EEEEEE\000COLORTERM=truecolor\000USERNAME=cjd\000JAVA_HOME=/usr/lib/jvm/java-8-oracle\000J2SDKDIR=/usr/lib/jvm/java-8-oracle\000XDG_VTNR=2\000SSH_AUTH_SOCK=/run/user/1000/keyring/ssh\000MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path\000BYOBU_PREFIX=/usr\000XDG_SESSION_ID=12\000DERBY_HOME=/usr/lib/jvm/java-8-oracle/db\000USER=cjd\000PAGER=/usr/bin/less -ins\000DESKTOP_SESSION=gnome\000QT4_IM_MODULE=xim\000BYOBU_HIGHLIGHT=\#DD4814\000BYOBU_DISTRO=Ubuntu\000DEFAULTS_PATH=/usr/share/gconf/gnome.default.path\000PWD=/home/cjd/git/xlights/xLights\000LINES=24\000HOME=/home/cjd\000BYOBU_PAGER=sensible-pager\000JOURNAL_STREAM=8:34342\000J2REDIR=/usr/lib/jvm/java-8-oracle/jre\000SSH_AGENT_PID=1571\000QT_ACCESSIBILITY=1\000XDG_SESSION_TYPE=x11\000XDG_DATA_DIRS=/usr/share/gnome:/home/cjd/.local/share/flatpak/exports/share/:/var/lib/flatpak/exports/share/:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop:/var/lib/snapd/desktop:/home/cjd/snap/anbox/common/app-data\000BYOBU_DATE=%Y-%m-%d \000BYOBU_PYTHON=python3\000XDG_SESSION_DESKTOP=gnome\000EMAIL=chris@adebenham.com\000GJS_DEBUG_OUTPUT=stderr\000BYOBU_READLINK=readlink\000GTK_MODULES=canberra-gtk-module:canberra-gtk-module:gail:atk-bridge\000COLUMNS=80\000BYOBU_WINDOW_NAME=-\000WINDOWPATH=2\000SHELL=/bin/bash\000VTE_VERSION=4402\000TERM=xterm-256color\000BYOBU_SED=sed\000QT_IM_MODULE=ibus\000XMODIFIERS=@im=ibus\000XDG_CURRENT_DESKTOP=GNOME\000QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1\000BYOBU_BACKEND=tmux\000XDG_SEAT=seat0\000SHLVL=1\000LANGUAGE=en_AU:en\000G_FILENAME_ENCODING=UTF-8\000BYOBU_ACCENT=\#75507B\000PROMPT_COMMAND=history -a;echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"\000BYOBU_TIME=%H:%M:%S\000MANPATH=/usr/local/man:/usr/gnu/share/man:/usr/share/man:/usr/X11/share/man\000WINDOWID=54525958\000BYOBU_RUN_DIR=/dev/shm/byobu-cjd-KMu3FZbp\000PKG_CLIENT_TIMEOUT=90\000GDMSESSION=gnome\000GNOME_DESKTOP_SESSION_ID=this-is-deprecated\000LOGNAME=cjd\000DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus\000XDG_RUNTIME_DIR=/run/user/1000\000XAUTHORITY=/run/user/1000/gdm/Xauthority\000XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg\000PATH=/usr/bin:/usr:/home/cjd/Owncloud/Apps/bin:/usr/local/bin:/usr/local/android-studio/sdk/tools:/usr/gnu/bin:/usr/X11/bin:/usr/sbin:/sbin:/bin\000SDL_AUDIODRIVER=pulse\000HISTSIZE=1000\000XDG_SESSION_COOKIE=9f2fb5cf9f6fbe0d0c5c1298490d1fa6-1515652668.135077-2142940284\000GJS_DEBUG_TOPICS=JS ERROR;JS LOG\000HISTFILESIZE=1000\000SESSION_MANAGER=local/jimbob:@/tmp/.ICE-unix/1470,unix/jimbob:/tmp/.ICE-unix/1470\000CVS_RSH=ssh\000LESSOPEN=| /usr/bin/lesspipe %s\000GTK_IM_MODULE=ibus\000/home/cjd/git/xlights/bin/xLights\000\000\000\000\000\000\000\000\000"...<error: Cannot access memory at address 0x7ffffffff000>) at /home/cjd/git/xlights/xLights/CachedFileDownloader.cpp:282
#5 0x00005555567a5989 in __static_initialization_and_destruction_0(int, int) (__initialize_p=1, __priority=65535) at /home/cjd/git/xlights/xLights/VendorModelDialog.cpp:14
#6 0x00005555567a5bf6 in _GLOBAL__sub_I__ZN17VendorModelDialog6_cacheE() () at /home/cjd/git/xlights/xLights/VendorModelDialog.cpp:1421
#7 0x0000555556fcbfbd in __libc_csu_init ()
#8 0x00007ffff19a7380 in __libc_start_main (main=0x5555567ec91f <main(int, char**)>, argc=1, argv=0x7fffffffdb28, init=0x555556fcbf70 <__libc_csu_init>, fini=, rtld_fini=, stack_end=0x7fffffffdb18) at ../csu/libc-start.c:247
#9 0x000055555613079a in _start ()
9779df4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _cache member is static to the vendor model dialog.
The constructor would be called very early in execution of xLights
The constructor is called with a default parameter of "" which is saved in _cacheDir.
We then call wxFileName::GetTempDir() ... on windows this returns the users temp folder ... I would be checking on Linux that that happens
We then append this cache dir in front of a / and the cache file index file. If the temp folder is returned on Linux as blank then i guess it is trying to write that file into the root folder which I assume the user process has not access to. Maybe we should check the existence of the _cacheFile and if it doesnt exist ... not sure ... I dont really want to put them in the current folder ... maybe we can make the cache object refuse to cache anything so it downloads them to the current folder but forces everything to be only cached for the current session.
Can you validate for me what GetTempDir() is returning?
9779df4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The quick fix doesn't resolve the crash.
The crash is within GetTempDir itself so it doesn't return anything.
I'm wondering if this is happening too early in the initialisation so the wxFileName stuff is not ready as yet
This is supported by if I force _cacheDir to be /tmp it continues but then crashes later on in CachedFileDownloader::LoadCache when doing the wxFileName(_cacheFile).GetSize()
=== stack ==
9779df4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or could be a character conversion issue as eventual crash is in wxString::AsCharBuf when doing
if ( conv.IsUTF8() )
9779df4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you just force it blank and live with session caching only.
9779df4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does work as a quick fix to get people running until I figure it out.
Do we want this temp directory to remain between reboots, or just for the current boot? (just trying to figure out if this should be in /tmp or ~/.cache