############################################################################## # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ############################################################################## """QRCodeAdapter Implementation $Id$ """ from zope.interface import implements from zope.app.annotation.interfaces import IAnnotatable, IAttributeAnnotatable from zope.app.annotation.interfaces import IAnnotations from zope.app.dublincore.interfaces import IZopeDublinCore from zope.app.file.image import Image from zope.app.file.file import File from zope.component import adapts from zope.app import zapi from zope import component, interface from interfaces import IQRCodeAdapter from StringIO import StringIO CIKey = 'z3qrcodeadapter.qrcodeadapter.QRCodeAdapter' class QRCodeAdapter(object): """adapter for generate QR-Code Image form Title or ID. Verify the interface implementation >>> from zope.interface.verify import verifyClass, verifyObject >>> verifyClass(IQRCodeAdapter, QRCodeAdapter) True Create a any Annotatable object (i.e. Image), and adapt. >>> image = Image() >>> qr = IQRCodeAdapter(image) >>> verifyObject(IQRCodeAdapter, qr) True """ implements(IQRCodeAdapter) adapts(IAttributeAnnotatable) def __init__(self, context): ''' ''' self.context = context annotations = IAnnotations(self.context) qrobj = annotations.get(CIKey, QRCodeObject(None)) annotations[CIKey] = qrobj self.qrobj = qrobj def update(self, request=None): title = self.get_title() url = self.get_url(request) text = '\n'.join(filter(None, [title, url])) if self.qrobj.name != text: self.qrobj.name = text converted_text = self.convert_charset(text) self.qrobj['image'] = self.create_qrimage(converted_text) self.qrobj['swf'] = self.create_qrswf(converted_text) def get_title(self): title = IZopeDublinCore(self.context).title if not title: title = zapi.name(self.context) title = title or 'No Title' return title def get_url(self, request): try: viewobj = component.queryMultiAdapter((self.context, request)) url = zapi.absoluteURL(viewobj, request) except: url = '' return url def get_image(self): """get current QR-Code image. >>> from zope.interface.verify import verifyClass, verifyObject >>> image = Image() >>> qr = IQRCodeAdapter(image) Only adopt to new content, get_image have no data. >>> bool(qr.get_image()) False update adapter information, get_image return object. >>> qr.update() >>> qrimage = qr.get_image() >>> bool(qrimage) True Re update without modifiy, get_image return same instance. >>> qr.update() >>> qr.get_image() == qrimage True Re update with modify DublinCore's title, return new image instance. >>> dc = IZopeDublinCore(image) >>> dc.setTitle('hoge') >>> qr.update() >>> qr.get_image() == qrimage False """ return self.qrobj.get('image', None) def get_swf(self): """get current QR-Code flash file. >>> from zope.interface.verify import verifyClass >>> image = Image() >>> qr = IQRCodeAdapter(image) Only adopt to new content, get_swf have no data. >>> bool(qr.get_swf()) False update adapter information, get_swf return object. >>> qr.update() >>> qr_swf = qr.get_swf() >>> bool(qr_swf) True Re update without modifiy, get_swf return same instance. >>> qr.update() >>> qr.get_swf() == qr_swf True Re update with modify DublinCore's title, return new image instance. >>> dc = IZopeDublinCore(image) >>> dc.setTitle('hoge') >>> qr.update() >>> qr.get_swf() == qr_swf False """ return self.qrobj.get('swf', None) def create_qrimage(self, text): """convert text to QR-Code image. >>> from zope.app.file.interfaces import IImage >>> from zope.interface.verify import verifyClass, verifyObject >>> >>> image = Image() >>> qr = IQRCodeAdapter(image) >>> qrimage = qr.create_qrimage('TestString') >>> verifyObject(IImage, qrimage) True check File object's content type. >>> qrimage.contentType 'image/png' """ from contrib import create_qrimage cooked = StringIO() create_qrimage.main(text, cooked) return Image(cooked.getvalue()) def create_qrswf(self, text): """convert text to QR-Code flash file. >>> from zope.interface.verify import verifyObject >>> from zope.app.file.interfaces import IFile >>> >>> image = Image() >>> qr = IQRCodeAdapter(image) >>> qr_swf = qr.create_qrswf('TestString') >>> verifyObject(IFile, qr_swf) True check File object's content type. >>> qr_swf.contentType 'application/x-shockwave-flash' """ from contrib import create_qrswf cooked = StringIO() create_qrswf.main(text, cooked) return File(cooked.getvalue(), 'application/x-shockwave-flash') def convert_charset(self, text): text = text.encode('shift-jis') # for japanese... return text class QRCodeObject(dict): """QR-Code Image/Flash holder class for annotation. create first. >>> id = 'sample' >>> obj = QRCodeObject(id) >>> obj.name 'sample' use as same as dict object. >>> obj.get('val1', 'none') 'none' >>> obj['val1'] = 'VAL1' >>> obj.get('val1', 'none') 'VAL1' >>> obj['val1'] 'VAL1' """ def __init__(self, name): dict.__init__(self) self.name = name