PDA

View Full Version : storing images locally


DPK
May 14th, 2009, 04:23 AM
How would I download an image locally to my applications/cache/whatever directory for future reference? Like an image that would change on a day to day basis? It has to be possible considering boxee does this numerous times itself.

I've tried using read/write python functions but am getting permission denied errors on my test app. I can easily pull an image from any server, but hit a brick wall when I want to store it.

DPK
May 14th, 2009, 05:14 AM
Well here's my solution after stumbling across a python script that's used to download NASA satellite images of all things, lol:

import urllib

img_src = "http://www.domain.com/image.jpg"
img_loc = "t:\\apps\\my.app.name\\path\\to\save\\image.jpg"

urllib.urlretrieve(img_src, img_loc)

Works great. Still needs some tweaking and error handling though.

idan
May 14th, 2009, 05:19 AM
you can do two things, one is getting the temp path on the machine using
mc.GetTempDir()
downloading the image there yourself (not very safe) and using it later by specifying the exact local image path - but as its in the temp dir no promises there that it will actually stay there.
another mechanism which is much safer is adding images to a list either by defining special tags into an rss you are loading

<boxee:property name="Image0">http://www.something.com/first_large_image.jpg</boxee:property>
<boxee:property name="Image1">http://www.something.com/second_large_image.jpg</boxee:property>

or by creating the list yourself from python and adding to each item these external images like this

listitem.SetImage(0, "http://www.something.com/second_large_image.jpg")
listitem.SetImage(1, "http://www.something.com/second_large_image.jpg")

now, once the list is loaded boxee downloads the images (with out changing their size, thumbnail images are rescaled) and caches them (i think the cache is cleaned every week or two). but that means the images are now available and every time you refer to the specific image location boxee will grab it from the cache and wont download it all over again.
in any of these cases you could later access the image either from the skin itself using listitem properties inside a list like this:

<control type="image">
<posx>0</posx>
<posy>0</posy>
<width>948</width>
<height>414</height>
<texture>$INFO[ListItem.Property(image0)]</texture>
</control>

or outside of a list like this:

<control type="image">
<posx>0</posx>
<posy>0</posy>
<width>948</width>
<height>414</height>
<texture>$INFO[Container(120).ListItem.Property(image0)]</texture>
</control>

hope that helped.

DPK
May 14th, 2009, 06:20 AM
Definitely prefer the latter method you described with setting a list up in python and having boxee do the leg work. I wasn't fond of what I came up with as I don't like specifying path names in an effort to be as you said, more secure.

Going to try adopting my code to that now. Thanks again from one Dan to another, lol.

DPK
May 17th, 2009, 08:07 AM
So is there a way to force boxee to redownload an image?

rectalogic
May 22nd, 2009, 06:16 PM
or by creating the list yourself from python and adding to each item these external images like this

listitem.SetImage(0, "http://www.something.com/second_large_image.jpg")
listitem.SetImage(1, "http://www.something.com/second_large_image.jpg")

...
in any of these cases you could later access the image either from the skin itself using listitem properties ... outside of a list like this:

<control type="image">
<posx>0</posx>
<posy>0</posy>
<width>948</width>
<height>414</height>
<texture>$INFO[Container(120).ListItem.Property(image0)]</texture>
</control>



This doesn't seem to work because ListItem.SetImage(0,XXX) stores the property under the key "Image0" on the underlying FileItem - but ListItem.GetProperty() always prepends the string "custom:" to the key and so looks for "custom:Image0" on the FileItem and fails to find it.

So I cannot find a way to retrieve the property value.

i.e. in xbmc/app/XAPP_ListItem.cpp see the following:

void ListItem::SetImage(int id, const std::string& url)
{
CStdString propName;
propName.Format("Image%d", id);
m_fileItem->SetProperty(propName, url);
}

std::string ListItem::GetProperty(const std::string& key) const
{
std::string customKey = "custom:";
customKey += key;
return m_fileItem->GetProperty(customKey);
}

rectalogic
May 29th, 2009, 02:19 PM
OK, I was only able to get this to work for a ListItem that is not a video.

Basically the Image0 property is not loaded by CBackgroundInfoLoader::LoadCustomImages() unless CBackgroundLoaderFactory::RunBackgroundLoader() decides to use a CPictureThumbLoader - if it uses a CVideoThumbLoader then the image properties are not loaded.

So if the ListItem is any of the video types like MEDIA_VIDEO_CLIP, or if it's content-type is video/ or if it's path ends with a video file suffix - then the Image0 property won't be loaded. If it is an RSS feed it will load (this is why the Hulu app works).

See the set of tests in CBackgroundLoaderFactory::RunBackgroundLoader() which decides what type of thumb loader to use.

I'm not sure what the best workaround is - I might load a parallel hidden list with non-video ListItems and use those to store the image properties on. Or configure my video ListItems as non-video and without a path and store the video path in a custom property and manually invoke the player in onclick.