Skip to content

Commit

Permalink
Add xmodel download from vendor site capability
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Westley committed Jan 12, 2018
1 parent 10b9f79 commit 9779df4
Show file tree
Hide file tree
Showing 17 changed files with 2,186 additions and 34 deletions.
1 change: 1 addition & 0 deletions include/models/ModelImages.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@
#include "icicles.xpm"
#include "import.xpm"
#include "polyline.xpm"
#include "download.xpm"
#endif
54 changes: 54 additions & 0 deletions include/models/download.xpm
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",
"................................................",
"................................................",
"................................................",
"................................................",
"................................................",
"................+++++++++++++++++...............",
"...............++++++++++++++++++...............",
"...............++++++++++++++++++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"...............+++............+++...............",
"........++++++++++............+++++++++++.......",
"........++++++++++............+++++++++++.......",
"........++++++++++.............++++++++++.......",
".........++++.......................++++........",
"..........++++.....................++++.........",
"...........++++...................++++..........",
"............++++.................++++...........",
".............+++.................++++...........",
".............++++...............++++............",
"..............++++.............++++.............",
"...............++++...........++++..............",
"................++++.........++++...............",
".................++++.......++++................",
"..................+++.......++++................",
"..................++++.....++++.................",
"...................++++...++++..................",
"....................++++.++++...................",
".....................+++++++....................",
"......................+++++.....................",
".......................++++.....................",
".......................+++......................",
"................................................",
"................................................",
"................................................",
"................................................"};
318 changes: 318 additions & 0 deletions xLights/CachedFileDownloader.cpp
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();
}
Loading

6 comments on commit 9779df4

@cjd
Copy link
Member

@cjd cjd commented on 9779df4 Jan 17, 2018

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 ()

@keithsw1111
Copy link
Collaborator

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?

@cjd
Copy link
Member

@cjd cjd commented on 9779df4 Jan 18, 2018

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 ==

where
#0 0x000055555616e948 in wxString::AsCharBuf(wxMBConv const&) const (this=0x7fffffffd470, conv=...) at /usr/local/include/wx-3.1/wx/string.h:3367
#1 0x000055555691e29e in (anonymous namespace)::DoStatAny(stat&, wxString, bool) ()
#2 0x000055555691e3a0 in (anonymous namespace)::wxFileSystemObjectExists(wxString const&, int) ()
#3 0x000055555691e509 in (anonymous namespace)::CheckIfDirExists(wxString const&) ()
#4 0x0000555556921cd1 in wxFileName::GetTempDir() ()
#5 0x0000555556175a38 in CachedFileDownloader::CachedFileDownloader(std::cxx11::basic_string<char, std::char_traits, std::allocator >) (this=0x555558029780 VendorModelDialog::_cache, cacheDir="\220\331\377\377\377\177", '\000' <repeats 18 times>, "\031\313yVUU", '\000' <repeats 11 times>, "\210\000\064\240\252ϭ\320\331\377\377\377\177\000\000 \001\000\000\000\000\000\000\370#\336WUU\000\000\030\333\377\377\377\177\000\000\340\331\377\377\377\177\000\000|]zVUU\000\000\247\002\000\000\000\000\000\000\255\304\374VUU", '\000' <repeats 18 times>, "`\304\374VUU\000\000p\a\023VUU\000\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\b\333\377\377\377\177\000\000\001\000\000\000\001\000\000\000\245\312~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\b\333\377\377\377\177\000\000\030\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\b\333\377\377\377\177\000\000\030\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\000\333\377\377\377\177\000\000\000\000\000\000\000\000\000\000\232\a\023VUU\000\000\370\332\377\377\377\177\000\000\034\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000^\337\377\377\377\177\000\000\000\000\000\000\000\000\000\000\200\337\377\377\377\177\000\000\226\337\377\377\377\177\000\000\322\337\377\377\377\177\000\000\216\345\377\377\377\177\000\000\260\345\377\377\377\177\000\000\307\345\377\377\377\177\000\000\335\345\377\377\377\177\000\000\361\345\377\377\377\177\000\000\002\346\377\377\377\177\000\000\031\346\377\377\377\177\000\000$\346\377\377\377\177\000\000\060\346\377\377\377\177\000\000R\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\000\071\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\000I\337\377\377\377\177", '\000' <repeats 27 times>, "̈\000\064\240\252ϭ\206\317\017\062ܖ\345\345x86_64", '\000' <repeats 15 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\000OLDPWD=/home/cjd\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=44040198\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:287
#6 0x00005555567a5b0f in __static_initialization_and_destruction_0(int, int) (__initialize_p=1, __priority=65535) at /home/cjd/git/xlights/xLights/VendorModelDialog.cpp:14
#7 0x00005555567a5d7c in _GLOBAL__sub_I__ZN17VendorModelDialog6_cacheE() () at /home/cjd/git/xlights/xLights/VendorModelDialog.cpp:1421
#8 0x0000555556fcc4ad in __libc_csu_init ()
#9 0x00007ffff19a7380 in __libc_start_main (main=0x5555567ecaa5 <main(int, char**)>, argc=1, argv=0x7fffffffdb08, init=0x555556fcc460 <__libc_csu_init>, fini=, rtld_fini=, stack_end=0x7fffffffdaf8) at ../csu/libc-start.c:247
#10 0x000055555613079a in _start ()
====

@cjd
Copy link
Member

@cjd cjd commented on 9779df4 Jan 18, 2018

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() )

@keithsw1111
Copy link
Collaborator

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.

@cjd
Copy link
Member

@cjd cjd commented on 9779df4 Jan 18, 2018

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

Please sign in to comment.