def get_width_height(fname, orig_modtime=None): """get (possibly cached) width and height of .svg file with inkscape""" # compute filename of cached width/height wh_cache_path, wh_cache_fname = os.path.split(fname) wh_cache_fname = CACHE_PREFIX + os.path.splitext( wh_cache_fname)[0] + '.txt' wh_cache_fname = os.path.join(wh_cache_path, wh_cache_fname) # read cache if it exists if os.path.exists(wh_cache_fname): modtime = os.stat(wh_cache_fname)[stat.ST_MTIME] if orig_modtime is None: orig_modtime = os.stat(fname)[stat.ST_MTIME] if modtime > orig_modtime: width, height = open(wh_cache_fname).read().strip().split() return width, height # no cache, query inkscape for information tmpf = tempfile.NamedTemporaryFile(suffix='.png') tmpf.close() cmd = [INKSCAPE, '-C', fname, '-e', tmpf.name] get_stdout(cmd) import Image # XXX TODO: convert to reading XML file instead of using PIL im = Image.open(tmpf.name) (width, height) = im.size os.unlink(tmpf.name) fd = open(wh_cache_fname, mode="w") fd.write("%s %s\n" % (width, height)) fd.close() return width, height
def get_width_height( fname, orig_modtime=None ): """get (possibly cached) width and height of .svg file with inkscape""" # compute filename of cached width/height wh_cache_path, wh_cache_fname = os.path.split(fname) wh_cache_fname = CACHE_PREFIX+os.path.splitext(wh_cache_fname)[0]+'.txt' wh_cache_fname = os.path.join( wh_cache_path, wh_cache_fname ) # read cache if it exists if os.path.exists( wh_cache_fname ): modtime = os.stat(wh_cache_fname)[stat.ST_MTIME] if orig_modtime is None: orig_modtime = os.stat(fname)[stat.ST_MTIME] if modtime > orig_modtime: width,height = open( wh_cache_fname ).read().strip().split() return width,height # no cache, query inkscape for information tmpf = tempfile.NamedTemporaryFile(suffix='.png') tmpf.close() cmd = [INKSCAPE,'-C',fname,'-e',tmpf.name] get_stdout(cmd) import Image # XXX TODO: convert to reading XML file instead of using PIL im = Image.open(tmpf.name) (width, height) = im.size os.unlink(tmpf.name) fd = open (wh_cache_fname,mode="w") fd.write("%s %s\n"%(width,height)) fd.close() return width, height
def p2p_set_nego(mac): print 'p2p_set_nego:' print 'mac: %s' % mac get_stdout('iwpriv eth0 p2p_set nego=%s' % mac) # Enter negotiation loop while 1: # Wait for result time.sleep(0.5) # Poll status peer_status = p2p_status_get() print 'peer_status: %d' % peer_status # For Windows 8.1 support, we consider 19 as negotiation completed if peer_status in [10, 19]: print 'Negotiation suceeded!' break # Get role role = p2p_role_get() print 'Role: %s' % role # TODO: doesn't seem to return anything #p2p_opch_get() # Get peer interface address peer_mac_get() p2p_go_mode_set()
def p2p_set_nego(mac): print 'p2p_set_nego:' print 'mac: %s' % mac get_stdout('iwpriv wlan1 p2p_set nego=%s' % mac) # Enter negotiation loop while 1: # Wait for result time.sleep(0.5) # Poll status peer_status = p2p_status_get() print 'peer_status: %d' % peer_status # For Windows 8.1 support, we consider 19 as negotiation completed if peer_status in [10, 19]: print 'Negotiation suceeded!' break # Get role role = p2p_role_get() print 'Role: %s' % role # TODO: doesn't seem to return anything #p2p_opch_get() # Get peer interface address peer_mac_get() p2p_go_mode_set()
def wfd_connection_wait(): get_stdout(cmd_killall_wpa_spplicant) get_stdout(cmd_killall_hostapd) # Disable p2p p2p_disable() time.sleep(0.5) # Enable p2p p2p_enable() #p2p_peer_scan() print 'Waiting for incoming connection...' while 1: peer_status = p2p_status_get() print 'peer_status: %d' % peer_status if peer_status == 0: print 'p2p disabled! Re-enable p2p...' p2p_enable() if peer_status in [8, 19, 22]: # Discovery request or gonego fail print 'Discovery request received!' peer_found = p2p_peer_scan() if peer_found: break p2p_disable() time.sleep(1) print 'Getting peer device address...' # Get peer device address mac = p2p_peer_devaddr_get() print 'peer_devaddr: %s' % mac # Notify received wps info p2p_wpsinfo() print 'Getting peer authentication type...' # Get request configuration p2p_req_cm_get() print 'Confirming peer authentication...' # Set negotiation p2p_set_nego(mac)
def p2p_go_mode_set(): # Start hostAPd and wait for it to daemonize; ignore stdout get_stdout(["./hostapd", "-B", "p2p_hostapd.conf"]) # Wait for initialization time.sleep(1) do_wps() # Wait for host apd interval time.sleep(1)
def p2p_peer_port_get(): print 'p2p_peer_port_get:' output = get_stdout('iwpriv wlan0 p2p_get peer_port') print output match = re.search(r'^Port=(\d+)$', output, re.M) print match.group(1) return int(match.group(1))
def p2p_peer_devaddr_get(): print 'p2p_peer_devaddr_get:' output = get_stdout(["iwpriv", "wlan0", "p2p_get", "peer_deva"]) match = re.search(r'\n(.*)$', output) mac = ':'.join(re.findall('..', match.group(1))) return mac
def p2p_enable(): # Enable p2p get_stdout('iwpriv eth0 p2p_set enable=1') # Set intent get_stdout('iwpriv eth0 p2p_set intent=15') # Set operation channel get_stdout('iwpriv eth0 p2p_set op_ch=%d' % 11) # Sleep for 50ms time.sleep(0.05) # Set ssid get_stdout('iwpriv eth0 p2p_set ssid=DIRECT-RT') # Set DN get_stdout('iwpriv eth0 p2p_set setDN=Piracast')
def p2p_enable(): # Enable p2p get_stdout('iwpriv wlan1 p2p_set enable=1') # Set intent get_stdout('iwpriv wlan1 p2p_set intent=15') # Set operation channel get_stdout('iwpriv wlan1 p2p_set op_ch=%d' % 11) # Sleep for 50ms time.sleep(0.05) # Set ssid get_stdout('iwpriv wlan1 p2p_set ssid=DIRECT-RT') # Set DN get_stdout('iwpriv wlan1 p2p_set setDN=Piracast')
def p2p_go_mode_set(): # Start hostAPd and wait for it to daemonize; ignore stdout get_stdout(["./hostapd", "-B", "p2p_hostapd.conf"]) # Wait for initialization time.sleep(1) do_wps() # Wait for host apd interval time.sleep(1) while 1: status = read_all_sta() if status: print 'Wireless display negotiation completed!' break time.sleep(1)
def do_wps(): while 1: print 'do_wps:' output = get_stdout(["./hostapd_cli", "wps_pbc", "any"]) print output if 'OK' in output: print 'wps passed!' return time.sleep(1)
def p2p_peer_devaddr_get(): print 'p2p_peer_devaddr_get:' output = get_stdout(["iwpriv", "wlan0", "p2p_get", "peer_deva"]) match = re.search(r'\n(.*)$', output) mac = '%s%s:%s%s:%s%s:%s%s:%s%s:%s%s' % match.group(1)[0:11] #mac = match.group(1)[0] + match.group(1)[1] + ':' \ # + match.group(1)[2] + match.group(1)[3] + ':' \ # + match.group(1)[4] + match.group(1)[5] + ':' \ # + match.group(1)[6] + match.group(1)[7] + ':' \ # + match.group(1)[8] + match.group(1)[9] + ':' \ # + match.group(1)[10] + match.group(1)[11] return mac
def p2p_peer_devaddr_get(): print 'p2p_peer_devaddr_get:' output = get_stdout(["iwpriv", "eth0", "p2p_get", "peer_deva"]) match = re.search(r'\n(.*)$', output) mac = ':'.join(re.findall('..', match.group(1))) #mac = match.group(1)[0] + match.group(1)[1] + ':' \ # + match.group(1)[2] + match.group(1)[3] + ':' \ # + match.group(1)[4] + match.group(1)[5] + ':' \ # + match.group(1)[6] + match.group(1)[7] + ':' \ # + match.group(1)[8] + match.group(1)[9] + ':' \ # + match.group(1)[10] + match.group(1)[11] return mac
def p2p_peer_devaddr_get(): print 'p2p_peer_devaddr_get:' output = get_stdout(["iwpriv", "wlan1", "p2p_get", "peer_deva"]) match = re.search(r'\n(.*)$', output) mac = ':'.join(re.findall('..', match.group(1))) #mac = match.group(1)[0] + match.group(1)[1] + ':' \ # + match.group(1)[2] + match.group(1)[3] + ':' \ # + match.group(1)[4] + match.group(1)[5] + ':' \ # + match.group(1)[6] + match.group(1)[7] + ':' \ # + match.group(1)[8] + match.group(1)[9] + ':' \ # + match.group(1)[10] + match.group(1)[11] return mac
def p2p_peer_scan(): count = 0 while 1: output = get_stdout(cmd_iwlist_wlan1_scan) print output if 'No scan results' not in output: return True if count > 3: return False count += 1
def p2p_peer_scan(): count = 0 while 1: output = get_stdout(cmd_iwlist_eth0_scan) print output if 'No scan results' not in output: return True if count > 3: return False count += 1
def p2p_peer_devaddr_get(): print 'p2p_peer_devaddr_get:' output = get_stdout('iwpriv wlan0 p2p_get peer_deva') print output match = re.search(r'^([0-9A-Fa-f]{12})$', output, re.M) print match.group(1) mac = '%s:%s:%s:%s:%s:%s' % tuple(re.findall('[0-9A-Fa-f]{2}',match.group(1))) print mac #mac = match.group(1)[0] + match.group(1)[1] + ':' \ # + match.group(1)[2] + match.group(1)[3] + ':' \ # + match.group(1)[4] + match.group(1)[5] + ':' \ # + match.group(1)[6] + match.group(1)[7] + ':' \ # + match.group(1)[8] + match.group(1)[9] + ':' \ # + match.group(1)[10] + match.group(1)[11] return mac
cmd_dhcp_start = ['/usr/sbin/dhcpd', '-pf', './dhcpd.pid', '-cf', '../env/dhcpd.conf', '-lf', lease_file, 'wlan0'] cmd_dhcp_stop = 'kill $(cat ./dhcpd.pid)' def lease_file_timestamp_get(): return get_stdout('ls -l "%s"' % lease_file) # get the leased IP address def leased_ip_get(): contents = open(lease_file).read() ip_list = re.findall(r'lease (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', contents) # return the most recently leased IP address return ip_list[-1] print 'Bring up wlan0 just in case...' get_stdout(cmd_wlan0_up) print 'Increase rmem_default...' get_stdout(cmd_inc_rmem_default) print 'Kill running application...' #core_channel.end() print get_stdout(cmd_kill_core_app) while 1: # Launch application get_stdout(cmd_launch_core_app) # Start DHCP print get_stdout(cmd_dhcp_start)
def p2p_role_get(): print 'p2p_role_get:' output = get_stdout('iwpriv eth0 p2p_get role') match = re.search(r'Role=(\d*)', output) role = int(match.group(1)) return role
def p2p_disable(): get_stdout('iwpriv wlan1 p2p_set enable=0')
def visit_inklayers_html(self, node): orig_fname = os.path.join(SRC_DIR, node.src) orig_modtime = os.stat(orig_fname)[stat.ST_MTIME] root = etree.parse(orig_fname).getroot() layer_ids = [] for child in root: if child.tag == tag_name: if child.attrib.get(attrib_key, None) == 'layer': layer_ids.append(child.attrib['id']) # output .png images in new path out_dir = 'inklayers' + os.environ.get('BURST_S5_INKLAYERS_SUFFIX', '') if not os.path.exists(out_dir): os.mkdir(out_dir) out_base_fname = os.path.split(orig_fname)[-1] out_base_fname = os.path.splitext(out_base_fname)[0] out_base_fname = os.path.join(out_dir, out_base_fname) # but .svg files must remain alongside originals to maintain links svg_base_path, svg_base_fname = os.path.split(orig_fname) svg_base_fname = CACHE_PREFIX + os.path.splitext(svg_base_fname)[0] svg_base_fname = os.path.join(svg_base_path, svg_base_fname) source_fname = orig_fname image_fnames = [] srcwidth, srcheight = get_width_height(source_fname, orig_modtime) STD_HEIGHT = 600.0 # height of slide div in 1024x768 STD_DPI = 90.0 target_height = float(os.environ.get('BURST_S5_HEIGHT', STD_HEIGHT)) max_width = float(os.environ.get('BURST_S5_MAX_WIDTH', STD_HEIGHT * 1.667)) # aspect of slide div in 1024x768 if 'stdheight' in node.options: zheight = float(node.options['stdheight']) frac = zheight / STD_HEIGHT # fraction of standard height height = frac * target_height scale = height / float(srcheight) width = float(srcwidth) * scale if width > max_width: newscale = max_width / width width *= newscale height *= newscale scale *= newscale width = int(round(width)) height = int(round(height)) node.options['width'] = width node.options['height'] = height dpi = str(STD_DPI * scale) else: width = node.options.get('width', srcwidth) height = node.options.get('height', srcheight) dpi = str(STD_DPI) for i, layer_id in enumerate(layer_ids): out_fname = out_base_fname + layer_id + '.png' image_fnames.append(out_fname) skip_png = False if os.path.exists(out_fname): modtime = os.stat(out_fname)[stat.ST_MTIME] if modtime > orig_modtime: skip_png = True if skip_png: continue if node.mode == 'overlay': cmd_extra = ['-i', layer_id] elif node.mode == 'replace': out_svg_fname = svg_base_fname + '-' + layer_id + '.svg' skip_svg = False if os.path.exists(out_svg_fname): modtime = os.stat(out_svg_fname)[stat.ST_MTIME] if modtime > orig_modtime: skip_svg = True if not skip_svg: newroot = copy.deepcopy(root) # remove undisplayed layers elems = newroot.findall(tag_name) for remove_layer_id in layer_ids[i + 1:]: removed = False for child in elems: if (child.attrib.get(attrib_key, None) == 'layer' and child.attrib['id'] == remove_layer_id): newroot.remove(child) removed = True break if not removed: raise ValueError('could not remove layer_id "%s"' % remove_layer_id) # turn on all layers (sometimes files are saved with layers turned off) elems = newroot.findall(tag_name) for child in elems: if 'style' in child.attrib: del child.attrib['style'] etree.ElementTree(newroot).write(out_svg_fname) source_fname = out_svg_fname cmd_extra = [ '-b', 'white', # white background '-y', '0xFF', # fully opaque ] cmd = [ INKSCAPE, '-j', # only export this layer '-C', # export canvas (page) '-d', dpi, source_fname, '-e', out_fname, ] + cmd_extra get_stdout(cmd) if 1: # export all layers for handout out_fname = out_base_fname + '.png' skip_final_png = False if os.path.exists(out_fname): modtime = os.stat(out_fname)[stat.ST_MTIME] if modtime > orig_modtime: skip_final_png = True if not skip_final_png: cmd = [ INKSCAPE, '-C', # export canvas (page) '-d', dpi, source_fname, '-e', out_fname, ] get_stdout(cmd) image_fnames.append(out_fname) html = ('<div class="animation container inklayers" ' 'style="width: %spx; height: %spx;">\n' % (width, height)) for i, image_fname in enumerate(image_fnames): classes = [] if i != 0: classes.append('incremental') # This is slightly different than docutils documentation # suggests: make each layer in incremental, hidden and # slide-display classes, but have an extra render of all # layers than is only displayed in the handout. if i != len(image_fnames) - 1: classes.append('hidden') classes.append('slide-display') else: classes = ['handout'] if len(classes): class_str = ' class="%s"' % (' '.join(classes), ) else: class_str = '' atts = [] for name in ['width', 'height']: if name in node.options: atts.append('%s="%s"' % (name, node.options[name])) if len(atts): atts_str = ' ' + ' '.join(atts) else: atts_str = '' html += ' <img%s%s src="%s" alt="%s">\n' % (class_str, atts_str, image_fname, image_fname) html += '</div>' self.body.append(html)
def p2p_opch_get(): print 'p2p_opch_get:' print '---------------------------' output = get_stdout('iwpriv wlan1 p2p_get op_ch') print output print '---------------------------'
def p2p_req_cm_get(): print 'p2p_req_cm_get:' print get_stdout('iwpriv wlan1 p2p_get req_cm')
def lease_file_timestamp_get(): return get_stdout('ls -l "%s"' % lease_file)
def wpa_supplicant_start(): print 'wpa_supplicant_start:' get_stdout( ["./wpa_supplicant", "-i", "wlan1", "-c", "./wpa_0_8.conf", "-B"]) time.sleep(1)
def wfd_connection_wait(): get_stdout(cmd_killall_wpa_spplicant) get_stdout(cmd_killall_hostapd) # Disable p2p p2p_disable() time.sleep(0.5) # Enable p2p p2p_enable() #p2p_peer_scan() print 'Waiting for incoming connection...' while 1: peer_status = p2p_status_get() print 'peer_status: %d' % peer_status if peer_status == 0: print 'p2p disabled! Re-enable p2p...' p2p_enable() #if peer_status == 11: # print 'p2p request received! Scan for peer ...' # p2p_peer_scan() # status 8 is the original Discovery Request # status 22 needs to be handled this way, or Nexus 4 4.4 won't always work # status 19 was added to try to implement windows 8.1 support if peer_status in [8, 19, 22]: # Discovery request or gonego fail print 'Discovery request received!' peer_found = p2p_peer_scan() if peer_found: break p2p_disable() time.sleep(1) print 'Getting peer device address...' # Get peer device address mac = p2p_peer_devaddr_get() print 'peer_devaddr: %s' % mac # Notify received wps info p2p_wpsinfo() print 'Getting peer authentication type...' # Get request configuration p2p_req_cm_get() print 'Confirming peer authentication...' #print 'Getting status...' # Get status #peer_status = p2p_status_get() #print 'peer_status: ', peer_status # Set negotiation p2p_set_nego(mac)
def p2p_disable(): get_stdout('iwpriv eth0 p2p_set enable=0')
def read_all_sta(): print 'read_all_sta:' output = get_stdout(["./hostapd_cli", "all_sta"]) return ('dot11RSNAStatsSTAAddress' in output)
lease_file = '/var/lib/dhcp/dhcpd.leases' def lease_file_timestamp_get(): return get_stdout('ls -l "%s"' % lease_file) # get the leased IP address def leased_ip_get(): contents = open(lease_file).read() ip_list = re.findall(r'lease (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', contents) # return the most recently leased IP address return ip_list[-1] print 'Bring up eth0 just in case...' get_stdout(cmd_eth0_up) print 'Increase rmem_default...' get_stdout(cmd_inc_rmem_default) # Don't kill running application as # it is started explicitly #print 'Kill running application...' #core_channel.end() #print get_stdout(cmd_kill_core_app) while 1: # Don't launch application, because it stuck # the execution # get_stdout(cmd_launch_core_app)
def wps_status_get(): print 'wps_status_get:' output = get_stdout(["./wpa_cli", "status"]) print output
lease_file = '/var/lib/dhcp/dhcpd.leases' def lease_file_timestamp_get(): return get_stdout('ls -l "%s"' % lease_file) # get the leased IP address def leased_ip_get(): contents = open(lease_file).read() ip_list = re.findall(r'lease (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', contents) # return the most recently leased IP address return ip_list[-1] print 'Bring up wlan0 just in case...' get_stdout(cmd_wlan0_up) print 'Increase rmem_default...' get_stdout(cmd_inc_rmem_default) # Don't kill running application as # it is started explicitly #print 'Kill running application...' #core_channel.end() #print get_stdout(cmd_kill_core_app) while 1: # Don't launch application, because it stuck # the execution # get_stdout(cmd_launch_core_app)
def p2p_status_get(): #print 'p2p_status_get:' output = get_stdout('iwpriv wlan1 p2p_get status') match = re.search(r'Status=(\d*)', output) return int(match.group(1))
def p2p_role_get(): print 'p2p_role_get:' output = get_stdout('iwpriv wlan1 p2p_get role') match = re.search(r'Role=(\d*)', output) role = int(match.group(1)) return role
def p2p_req_cm_get(): print 'p2p_req_cm_get:' print get_stdout('iwpriv eth0 p2p_get req_cm')
lease_file = '/var/lib/dhcp/dhcpd.leases' def lease_file_timestamp_get(): return get_stdout('ls -l "%s"' % lease_file) # get the leased IP address def leased_ip_get(): contents = open(lease_file).read() ip_list = re.findall(r'lease (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', contents) # return the most recently leased IP address return ip_list[-1] print 'Bring up wlan0 just in case...' get_stdout(cmd_wlan0_up) while 1: # Don't launch application, because it stuck # the execution # get_stdout(cmd_launch_core_app) # Start DHCP # print get_stdout(cmd_dhcp_start) # Get previous timestamp prev_ts = lease_file_timestamp_get() # Wait for connection wfd.wfd_connection_wait()
def p2p_status_get(): #print 'p2p_status_get:' output = get_stdout('iwpriv eth0 p2p_get status') match = re.search(r'Status=(\d*)', output) return int(match.group(1))
def lease_file_timestamp_get(): return get_stdout('ls -l "%s"' % lease_file) # get the leased IP address def leased_ip_get(): contents = open(lease_file).read() ip_list = re.findall(r'lease (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', contents) # return the most recently leased IP address return ip_list[-1] print 'Bring up wlan0 just in case...' get_stdout(cmd_wlan0_up) while 1: # Don't launch application, because it stuck # the execution # get_stdout(cmd_launch_core_app) # Start DHCP # print get_stdout(cmd_dhcp_start) # Get previous timestamp prev_ts = lease_file_timestamp_get() # Wait for connection wfd.wfd_connection_wait()
def peer_mac_get(): output = get_stdout('iwpriv eth0 p2p_get peer_ifa') match = re.search(r'MAC (.*)$', output) return match.group(1)
def p2p_opch_get(): print 'p2p_opch_get:' print '---------------------------' output = get_stdout('iwpriv eth0 p2p_get op_ch') print output print '---------------------------'
def peer_mac_get(): output = get_stdout('iwpriv wlan1 p2p_get peer_ifa') match = re.search(r'MAC (.*)$', output) return match.group(1)
def wps_auth(): print 'wps_auth:' output = get_stdout(["./hostapd_cli", "wps_pbc", "any"]) print output time.sleep(1)
def p2p_wpsinfo(): print 'p2p_wpsinfo:' get_stdout('iwpriv wlan1 p2p_set got_wpsinfo=3')
def p2p_wpsinfo(): print 'p2p_wpsinfo:' get_stdout('iwpriv eth0 p2p_set got_wpsinfo=3')
def wpa_supplicant_start(): print 'wpa_supplicant_start:' get_stdout(["./wpa_supplicant", "-i", "eth0", "-c", "./wpa_0_8.conf", "-B"]) time.sleep(1)
def visit_inklayers_html(self,node): orig_fname = os.path.join(SRC_DIR,node.src) orig_modtime = os.stat(orig_fname)[stat.ST_MTIME] root = etree.parse(orig_fname).getroot() layer_ids = [] for child in root: if child.tag == tag_name: if child.attrib.get(attrib_key,None) == 'layer': layer_ids.append( child.attrib['id'] ) # output .png images in new path out_dir = 'inklayers' + os.environ.get('BURST_S5_INKLAYERS_SUFFIX','') if not os.path.exists(out_dir): os.mkdir(out_dir) out_base_fname = os.path.split(orig_fname)[-1] out_base_fname = os.path.splitext(out_base_fname)[0] out_base_fname = os.path.join( out_dir, out_base_fname ) # but .svg files must remain alongside originals to maintain links svg_base_path, svg_base_fname = os.path.split(orig_fname) svg_base_fname = CACHE_PREFIX + os.path.splitext(svg_base_fname)[0] svg_base_fname = os.path.join( svg_base_path, svg_base_fname ) source_fname = orig_fname image_fnames = [] srcwidth, srcheight = get_width_height( source_fname, orig_modtime ) STD_HEIGHT = 600.0 # height of slide div in 1024x768 STD_DPI = 90.0 target_height = float(os.environ.get('BURST_S5_HEIGHT',STD_HEIGHT)) max_width = float(os.environ.get('BURST_S5_MAX_WIDTH',STD_HEIGHT*1.667)) # aspect of slide div in 1024x768 if 'stdheight' in node.options: zheight = float(node.options['stdheight']) frac = zheight/STD_HEIGHT # fraction of standard height height = frac*target_height scale = height/float(srcheight) width = float(srcwidth)*scale if width> max_width: newscale = max_width/width width *= newscale height *= newscale scale *= newscale width = int(round(width)) height = int(round(height)) node.options['width'] = width node.options['height'] = height dpi = str(STD_DPI*scale) else: width = node.options.get('width',srcwidth) height = node.options.get('height',srcheight) dpi = str(STD_DPI) for i,layer_id in enumerate(layer_ids): out_fname = out_base_fname + layer_id + '.png' image_fnames.append( out_fname ) skip_png = False if os.path.exists(out_fname): modtime = os.stat(out_fname)[stat.ST_MTIME] if modtime > orig_modtime: skip_png = True if skip_png: continue if node.mode == 'overlay': cmd_extra = ['-i',layer_id] elif node.mode == 'replace': out_svg_fname = svg_base_fname + '-' + layer_id + '.svg' skip_svg = False if os.path.exists(out_svg_fname): modtime = os.stat(out_svg_fname)[stat.ST_MTIME] if modtime > orig_modtime: skip_svg = True if not skip_svg: newroot = copy.deepcopy(root) # remove undisplayed layers elems = newroot.findall(tag_name) for remove_layer_id in layer_ids[i+1:]: removed = False for child in elems: if (child.attrib.get(attrib_key,None) == 'layer' and child.attrib['id'] == remove_layer_id): newroot.remove( child ) removed = True break if not removed: raise ValueError('could not remove layer_id "%s"'%remove_layer_id) # turn on all layers (sometimes files are saved with layers turned off) elems = newroot.findall(tag_name) for child in elems: if 'style' in child.attrib: del child.attrib['style'] etree.ElementTree(newroot).write( out_svg_fname ) source_fname = out_svg_fname cmd_extra = [ '-b','white', # white background '-y','0xFF', # fully opaque ] cmd = [INKSCAPE, '-j', # only export this layer '-C', # export canvas (page) '-d', dpi, source_fname, '-e',out_fname, ] + cmd_extra get_stdout(cmd) if 1: # export all layers for handout out_fname = out_base_fname + '.png' skip_final_png = False if os.path.exists(out_fname): modtime = os.stat(out_fname)[stat.ST_MTIME] if modtime > orig_modtime: skip_final_png = True if not skip_final_png: cmd = [INKSCAPE, '-C', # export canvas (page) '-d', dpi, source_fname, '-e',out_fname, ] get_stdout(cmd) image_fnames.append( out_fname ) html = ('<div class="animation container inklayers" ' 'style="width: %spx; height: %spx;">\n'%(width,height)) for i,image_fname in enumerate( image_fnames ): classes = [] if i != 0: classes.append('incremental') # This is slightly different than docutils documentation # suggests: make each layer in incremental, hidden and # slide-display classes, but have an extra render of all # layers than is only displayed in the handout. if i != len(image_fnames)-1: classes.append('hidden') classes.append('slide-display') else: classes = ['handout'] if len(classes): class_str = ' class="%s"'%( ' '.join(classes), ) else: class_str = '' atts = [] for name in ['width','height']: if name in node.options: atts.append( '%s="%s"'%(name,node.options[name])) if len(atts): atts_str = ' ' + ' '.join(atts) else: atts_str = '' html += ' <img%s%s src="%s" alt="%s">\n'%(class_str,atts_str, image_fname, image_fname) html += '</div>' self.body.append(html)