Coverage for src/lcdoc/mkdocs/lp/plugs/python/pyplugs/screenshot/__init__.py: 21.79%
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2https://dschnurr.medium.com/using-headless-chrome-as-an-automated-screenshot-tool-4b07dffba79a
3"""
6import subprocess as sp lp|index.md
8from lcdoc.mkdocs.lp.plugs import python lp|index.md
9from lcdoc.mkdocs.tools import page_dir lp|index.md
10from lcdoc.tools import app, dirname, exists, os, project, sys, write_file, read_file lp|index.md
12config, page, Session, err = (python.config, python.page, python.Session, python.err) lp|index.md
14inst = 'npm install -g chrome-remote-interface minimist' lp|index.md
17# fmt:off
18url_shot_defaults = dict( lp|index.md
19# :docs:url_shot_defaults
20 delay = 0, # wait this long before shots (setTimeout param)
21 force = False, # overwrite if shot exists
22 format = 'png', # or jpeg
23 height = 900, # height or chrome window when fetching the URL
24 into = 'img', # directory to put the screenshot into, relative to page
25 port = 9922, # port of chrome remote interface
26 width = 1440, # width of chrome window
27# :docs:url_shot_defaults
28)
29# fmt:on
31brwsr = ' '.join( lp|index.md
32 [
33 '%(browser)s',
34 '--headless',
35 '--hide-scrollbars',
36 '--remote-debugging-port=%(port)s',
37 '--disable-gpu',
38 ]
39)
42def url_to_fn(url, p, C=string.ascii_letters + '._0123456789'): lp|index.md
43 fmt = p['format']
44 url = url.replace('/', '_')
45 url = ''.join([c for c in url if c in C])
46 return url + '.' + fmt
49T_index_js = read_file(dirname(__file__) + '/index.js') lp|index.md
52def urlshot(**show_kw): lp|index.md
53 ctx = dict(url_shot_defaults)
54 ctx.update(show_kw)
55 url = ctx['url']
56 url_fn = url_to_fn(url, ctx)
57 dfn = ctx['into']
58 fn_shot = page_dir(Session.kw) + dfn + '/' + url_fn
59 md_fn = dfn + '/' + url_fn
60 if exists(fn_shot) and not ctx['force']:
61 app.info('Screenshot already exists', fn=fn_shot)
62 return md_fn
63 if config()['site_url'].startswith(url) and 'serve' in sys.argv:
64 app.error('Cannot shoot url while building the site in serve mode', url=url)
65 return md_fn
66 ctx['browser'], ctx['node'] = urlshot_requirements()
67 here = os.getcwd()
69 # node module not found, working in /tmp?! d_tmp = tempfile.mkdtemp()
70 d_tmp = project.root(config()) + '/build/urlshot'
71 os.makedirs(d_tmp, exist_ok=True)
72 app.info('Screenshot', **ctx)
73 try:
74 os.chdir(d_tmp)
75 write_file('index.js', T_index_js % ctx)
76 bp = sp.Popen(brwsr % ctx, shell=True)
77 cmd = '%(node)s index.js --url="%(url)s"' % ctx
78 e = os.system(cmd)
79 if e:
80 return err('Failed urlshot', cmd=cmd, hint=inst)
81 os.makedirs(dirname(fn_shot), exist_ok=True)
82 shutil.move('output.%(format)s' % ctx, fn_shot)
83 return md_fn
84 finally:
85 os.chdir(here)
86 bp.kill()
89def urlshot_requirements(): lp|index.md
90 browser = os.environ.get('browser', os.environ.get('BROWSER', 'nobrowser'))
91 if os.system(browser + ' --version >/dev/null'):
92 raise Exception('$BROWSER not working. hint=%s' % 'export $BROWSER')
93 node = os.environ.get('nodejs', 'node')
94 if os.system(node + ' -v >/dev/null'):
95 return err('Have no node command. hint=%s. Also: %s' % ('export $nodejs', inst))
96 return browser, node
99def register(fmts): lp|index.md
100 fmts['screenshot'] = makeshot lp|index.md
103def makeshot(cmd, url=None, **kw): lp|index.md
104 if url:
105 r = urlshot(url=url, **kw)
106 title = url.replace(']', '').replace('[', '')
107 return '![Screenshot: %s](./%s)' % (title, r)
108 python.app.die('not supported', cmd=cmd)