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

64 statements  

1""" 

2https://dschnurr.medium.com/using-headless-chrome-as-an-automated-screenshot-tool-4b07dffba79a 

3""" 

4import shutil lp|index.md

5import string lp|index.md

6import subprocess as sp lp|index.md

7 

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

11 

12config, page, Session, err = (python.config, python.page, python.Session, python.err) lp|index.md

13 

14inst = 'npm install -g chrome-remote-interface minimist' lp|index.md

15 

16 

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 

30 

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) 

40 

41 

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 

47 

48 

49T_index_js = read_file(dirname(__file__) + '/index.js') lp|index.md

50 

51 

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() 

68 

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() 

87 

88 

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 

97 

98 

99def register(fmts): lp|index.md

100 fmts['screenshot'] = makeshot lp|index.md

101 

102 

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)