Hide keyboard shortcuts

Hot-keys 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'''Main UI application''' 

2import io 

3import os 

4import json 

5import gramex.cache 

6from hashlib import md5 

7from tornado.gen import coroutine, Return 

8from gramex.config import variables, app_log, merge 

9 

10 

11def join(*args): 

12 return os.path.normpath(os.path.join(*args)) 

13 

14 

15folder = os.path.dirname(os.path.abspath(__file__)) 

16config_file = join(folder, 'config.yaml') 

17uicomponents_path = join(folder, 'bootstrap-theme.scss') 

18cache_dir = join(variables['GRAMEXDATA'], 'apps', 'ui') 

19bootstrap_path = join(folder, 'node_modules', 'bootstrap', 'scss', 'bootstrap') 

20sass_path = join(folder, 'node_modules', 'node-sass', 'bin', 'node-sass') 

21if not os.path.exists(cache_dir): 21 ↛ 22line 21 didn't jump to line 22, because the condition on line 21 was never true

22 os.makedirs(cache_dir) 

23 

24 

25@coroutine 

26def sass(handler, template=uicomponents_path): 

27 ''' 

28 Return a bootstrap theme based on the custom SASS variables provided. 

29 ''' 

30 args = dict(variables.get('ui-bootstrap', {})) 

31 args.update({key: handler.get_arg(key) for key in handler.args}) 

32 args = {key: val for key, val in args.items() if val} 

33 

34 # Set default args 

35 config = gramex.cache.open(config_file) 

36 merge(args, config.get('defaults'), mode='setdefault') 

37 

38 cache_key = {'template': template, 'args': args} 

39 cache_key = json.dumps( 

40 cache_key, sort_keys=True, ensure_ascii=True).encode('utf-8') 

41 cache_key = md5(cache_key).hexdigest()[:5] 

42 

43 # Replace fonts from config file, if available 

44 google_fonts = set() 

45 for key in ('font-family-base', 'headings-font-family'): 

46 if key in args and args[key] in config['fonts']: 

47 fontinfo = config['fonts'][args[key]] 

48 args[key] = fontinfo['stack'] 

49 if 'google' in fontinfo: 49 ↛ 45line 49 didn't jump to line 45, because the condition on line 49 was never false

50 google_fonts.add(fontinfo['google']) 

51 

52 # Cache based on the dict and config as template.<cache-key>.css 

53 base = os.path.splitext(os.path.basename(template))[0] + '.' + cache_key 

54 cache_path = join(cache_dir, base + '.css') 

55 if not os.path.exists(cache_path) or os.stat(template).st_mtime > os.stat(cache_path).st_mtime: 55 ↛ 57line 55 didn't jump to line 57, because the condition on line 55 was never true

56 # Create a SCSS file based on the args 

57 scss_path = join(cache_dir, base + '.scss') 

58 with io.open(scss_path, 'wb') as handle: 

59 result = gramex.cache.open(template, 'template').generate( 

60 variables=args, 

61 uicomponents_path=uicomponents_path.replace('\\', '/'), 

62 bootstrap_path=bootstrap_path.replace('\\', '/'), 

63 google_fonts=google_fonts, 

64 ) 

65 handle.write(result) 

66 # Run sass to generate the output 

67 options = ['--output-style', 'compressed'] 

68 proc = gramex.cache.Subprocess( 

69 ['node', sass_path, scss_path, cache_path] + options) 

70 out, err = yield proc.wait_for_exit() 

71 if proc.proc.returncode: 

72 app_log.error('node-sass error: %s', err) 

73 raise RuntimeError('Compilation failure') 

74 

75 handler.set_header('Content-Type', 'text/css') 

76 raise Return(gramex.cache.open(cache_path, 'bin', mode='rb'))