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())
51 doc
="The number of instances of this image"
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
.signal_connect(Event
.PollingStoppedSignal
,
68 self
._polling
_stopped
)
69 return property(**locals())
71 def incr_count(self
): self
._count
+= 1
72 def decr_count(self
): self
._count
-= 1
74 def _polling_stopped(self
):
75 self
._pollstopper
= None
77 def _save_count(self
):
78 ItemStore
.get_instance().set_image_count(self
._image
.url
, self
._count
)
81 class Cache(Event
.SignalEmitter
):
82 """Image cache with explicit reference counting."""
84 Event
.SignalEmitter
.__init
__(self
)
85 self
.initialize_slots(Event
.ImageUpdatedSignal
)
86 # self.__cache contains items of the form [Image, refcount]
89 def __getitem__(self
, key
):
90 return self
.__cache
[key
].image
92 def add_refer(self
, key
, restore
= False, item
= None):
93 if key
not in self
.__cache
:
96 image
= Image(key
, Image
.WAITING
)
97 ic
= ImageConsumer(image
)
100 if item
and item
.feed
:
101 headers
['Referer'] = item
.feed
.location
103 stopper
= URLFetch
.get_instance().request(
105 priority
=NetworkConstants
.PRIORITY_IMAGE
,
107 except URLFetch
.RequestSchemeException
, e
:
110 error
.logtb("ImageCache.add_refer: ", str(e
))
112 self
.__cache
[key
] = CacheEntry(
113 image
, 1, PollManager
.PollStopper(stopper
, image
), restore
=restore
)
115 image
= Image(key
, Image
.DATA_IN_DB
)
116 self
.__cache
[key
] = CacheEntry(image
, 1, pollstopper
=None, restore
=restore
)
117 elif key
in self
.__cache
and not restore
:
118 self
.__cache
[key
].incr_count()
120 def remove_refer(self
, key
):
121 if self
.__cache
.has_key(key
):
122 entry
= self
.__cache
[key
]
125 del self
.__cache
[key
]
126 self
.emit_signal(Event
.ImageUpdatedSignal(self
, key
, None))
128 def image_updated(self
, url
, data
):
129 self
.__cache
[url
].pollstopper
= None
130 self
.emit_signal(Event
.ImageUpdatedSignal(self
, url
, data
))
132 def set_image(self
, url
, image
):
133 if self
.__cache
.has_key(url
):
134 self
.__cache
[url
].incr_count()
136 self
.__cache
[url
] = CacheEntry(image
, 1)
138 def set_image_with_count(self
, url
, image
, count
, restore
=False):
139 self
.__cache
[url
] = CacheEntry(image
, count
, restore
=restore
)
141 def stop_transfer(self
, url
):
142 image
= self
.__cache
.get(url
, None)
143 if image
and image
.pollstopper
:
144 self
.__cache
[url
].pollstopper
.stop()
145 self
.__cache
[url
].pollstopper
= None
152 def __init__(self
, url
, status
= DATA_IN_DB
):
157 if self
.status
== self
.WAITING
:
158 return STATUS_IMAGE_WAITING
159 elif self
.status
== self
.DATA_IN_DB
:
160 data
= self
.read_data()
162 self
.status
= self
.FAILED
163 return STATUS_IMAGE_BROKEN
166 return STATUS_IMAGE_BROKEN
168 def set_data(self
, data
):
169 cache
.image_updated(self
.url
, data
)
170 self
.status
= self
.DATA_IN_DB
172 def set_failed(self
):
173 self
.status
= self
.FAILED
176 istore
= ItemStore
.get_instance()
177 return istore
.read_image(self
.url
)
179 def _return_id(self
):
180 return "%d %s" % (id(self
), self
.url
)
185 def __init__(self
, imobj
):
188 def http_results(self
, status
, headers
, data
):
190 self
._imobj
.set_data(data
)
192 self
._imobj
.set_failed()
194 def http_failed(self
, exception
):
195 self
._imobj
.set_failed()
197 def operation_stopped(self
):
198 self
._imobj
.set_failed()
201 global STATUS_IMAGE_WAITING
202 global STATUS_IMAGE_BROKEN
203 libdir
= utils
.find_image_dir()
204 STATUS_IMAGE_WAITING
= open(
205 libdir
+ "/image-loading.svg").read()
206 STATUS_IMAGE_BROKEN
= open(
207 libdir
+ "/image-missing.svg").read()