def convertable(img_elem, data_width): ''' Determine whether this is an image whose src attribute should be converted to an imgserve URL. Note carefully the dimension types. data_width is either an integer, or None. The width and heigh attributes of img_elem, if they are present, are strings. @param img_elem : The image element being considered @type img_elem : lxml.html.HtmlElement @param data_width : The measured width of he source image in pixels; or None if that is not known @type data_width : int > 0; or, None @return : True iff this img's source attribute should be converted to an imgserve URL @rtype : bool ''' from imgserve import normalize_img_size if data_width is not None: assert type(data_width) == int, type(data_width) if 'width' in img_elem.attrib: if data_width is None: return True tag_width = normalize_img_size(img_elem.attrib.get('width', None)) if tag_width != data_width: return True return False
def to_imgserve(elem): ''' Convert all img tags within the tree to point to imgserve source, as needed This filter access the imgserve database of image source values. When the height and width data is available for an image, that info will be used to decide whether we need to scale the image for the mobile device. If we do, the img tag's src attribute is modified appropriately. ''' from imgserve import ( normalize_img_size, ImgDb, ) imgdb = ImgDb() for img_elem in elem.iter(tag='img'): if 'src' in img_elem.attrib: if elem.attrib.get('src', '').lower().startswith('data:'): logger.error('Should not be converting data URL: {}'.format(elem.attrib.get('src', ''))) continue img_data = imgdb.get(img_elem.attrib['src']) or {} tag_width = normalize_img_size(img_elem.attrib.get('width', None)) tag_height = normalize_img_size(img_elem.attrib.get('height', None)) data_width = img_data.get('width', None) data_height = img_data.get('height', None) sizes = new_img_sizes(tag_width, tag_height, data_width, data_height) # need to cast size values to type str, for lxml for k, v in sizes.items(): sizes[k] = str(v) for k in 'width', 'height': if k in img_elem.attrib: del img_elem.attrib[k] img_elem.attrib.update(sizes) if convertable(img_elem, data_width): if 'height' in img_elem.attrib: maxh = int(img_elem.attrib['height']) else: maxh = None img_elem.attrib['src'] = to_imgserve_url(img_elem.attrib['src'], int(img_elem.attrib['width']), maxh)