3 Module for handling images
5 __copyright__
= "Copyright (c) 2002-2005 Free Software Foundation, Inc."
7 Straw is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
12 Straw is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA. """
20 import NetworkConstants
29 STATUS_IMAGE_WAITING
= None
30 STATUS_IMAGE_BROKEN
= None
32 class CacheEntry(object):
33 def __init__(self
, image
, count
, pollstopper
= None, restore
= False):
36 self
._pollstopper
= pollstopper
42 doc
="The image object that is associated with this class"
45 def fset(self
, image
):
47 return property(**locals())
54 def fset(self
, count
):
57 return property(**locals())
61 doc
="the stopper object for this cache entry"
63 return self
._pollstopper
64 def fset(self
, pollstopper
):
65 self
._pollstopper
= pollstopper
67 pollstopper
.connect('stopped', self
._polling
_stopped
)
68 return property(**locals())
70 def incr_count(self
): self
._count
+= 1
71 def decr_count(self
): self
._count
-= 1
73 def _polling_stopped(self
, poller
):
74 self
._pollstopper
= None
76 def _save_count(self
):
77 ItemStore
.get_instance().set_image_count(self
._image
.url
, self
._count
)
80 class Cache(gobject
.GObject
):
81 """Image cache with explicit reference counting."""
84 'image-updated' : (gobject
.SIGNAL_RUN_LAST
, gobject
.TYPE_NONE
,
85 (gobject
.TYPE_STRING
, gobject
.TYPE_PYOBJECT
))
89 gobject
.GObject
.__init
__(self
)
90 # self.__cache contains items of the form [Image, refcount]
93 def __getitem__(self
, key
):
94 return self
.__cache
[key
].image
96 def add_refer(self
, key
, restore
= False, item
= None):
97 if key
not in self
.__cache
:
100 image
= Image(key
, Image
.WAITING
)
101 ic
= ImageConsumer(image
)
104 if item
and item
.feed
:
105 headers
['Referer'] = item
.feed
.location
107 stopper
= URLFetch
.get_instance().request(
109 priority
=NetworkConstants
.PRIORITY_IMAGE
,
111 except URLFetch
.RequestSchemeException
, e
:
114 error
.logtb("ImageCache.add_refer: ", str(e
))
116 self
.__cache
[key
] = CacheEntry(
117 image
, 1, PollManager
.PollStopper(stopper
, image
), restore
=restore
)
119 image
= Image(key
, Image
.DATA_IN_DB
)
120 self
.__cache
[key
] = CacheEntry(image
, 1, pollstopper
=None, restore
=restore
)
121 elif key
in self
.__cache
and not restore
:
122 self
.__cache
[key
].incr_count()
124 def remove_refer(self
, key
):
125 if self
.__cache
.has_key(key
):
126 entry
= self
.__cache
[key
]
129 del self
.__cache
[key
]
130 self
.emit('image-updated', url
, None)
132 def image_updated(self
, url
, data
):
133 self
.__cache
[url
].pollstopper
= None
134 self
.emit('image-updated', url
, data
)
136 def set_image(self
, url
, image
):
137 if self
.__cache
.has_key(url
):
138 self
.__cache
[url
].incr_count()
140 self
.__cache
[url
] = CacheEntry(image
, 1)
142 def set_image_with_count(self
, url
, image
, count
, restore
=False):
143 self
.__cache
[url
] = CacheEntry(image
, count
, restore
=restore
)
145 def stop_transfer(self
, url
):
146 image
= self
.__cache
.get(url
, None)
147 if image
and image
.pollstopper
:
148 self
.__cache
[url
].pollstopper
.stop()
149 self
.__cache
[url
].pollstopper
= None
156 def __init__(self
, url
, status
= DATA_IN_DB
):
161 if self
.status
== self
.WAITING
:
162 return STATUS_IMAGE_WAITING
163 elif self
.status
== self
.DATA_IN_DB
:
164 data
= self
.read_data()
166 self
.status
= self
.FAILED
167 return STATUS_IMAGE_BROKEN
170 self
.status
= self
.FAILED
171 return STATUS_IMAGE_BROKEN
173 def set_data(self
, data
):
174 cache
.image_updated(self
.url
, data
)
175 self
.status
= self
.DATA_IN_DB
177 def set_failed(self
):
178 self
.status
= self
.FAILED
181 istore
= ItemStore
.get_instance()
182 return istore
.read_image(self
.url
)
184 def _return_id(self
):
185 return "%d %s" % (id(self
), self
.url
)
190 def __init__(self
, imobj
):
193 def http_results(self
, status
, data
):
195 self
._imobj
.set_data(data
)
197 self
._imobj
.set_failed()
199 def http_failed(self
, exception
):
200 self
._imobj
.set_failed()
202 def operation_stopped(self
):
203 # XXX operation stopped is not really failed
204 self
._imobj
.set_failed()
207 global STATUS_IMAGE_WAITING
208 global STATUS_IMAGE_BROKEN
209 libdir
= utils
.find_image_dir()
210 STATUS_IMAGE_WAITING
= open(
211 libdir
+ "/image-loading.svg").read()
212 STATUS_IMAGE_BROKEN
= open(
213 libdir
+ "/image-missing.svg").read()