b1f86dacda2bf269094ecd86ef2761693e2a0178
2 # -*- coding: utf-8 -*-
7 Copyright (c) 2014 Frédéric Massart - FMCorz.net
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 http://github.com/FMCorz/mdk
27 from .tools
import process
28 from .config
import Conf
34 """Class wrapping CSS related functions"""
41 def __init__(self
, M
):
44 def setCompiler(self
, compiler
):
45 self
._compiler
= compiler
47 def setDebug(self
, debug
):
50 def compile(self
, theme
='bootstrapbase', sheets
=None):
51 """Compile LESS sheets contained within a theme"""
53 source
= self
.getThemeLessPath(theme
)
54 dest
= self
.getThemeCssPath(theme
)
55 if not os
.path
.isdir(source
):
56 raise Exception('Unknown theme %s, or less directory not found' %
(theme
))
59 # Guess the sheets from the theme less folder.
61 for candidate
in os
.listdir(source
):
62 if os
.path
.isfile(os
.path
.join(source
, candidate
)) and candidate
.endswith('.less'):
63 sheets
.append(os
.path
.splitext(candidate
)[0])
64 elif type(sheets
) != list:
68 logging
.warning('Could not find any sheets')
74 sheet
= name
+ '.less'
75 destSheet
= name
+ '.css'
77 if not os
.path
.isfile(os
.path
.join(source
, sheet
)):
78 logging
.warning('Could not find file %s' %
(sheet
))
83 if self
._compiler
== 'recess':
84 compiler
= Recess(source
, os
.path
.join(source
, sheet
), os
.path
.join(dest
, destSheet
))
85 elif self
._compiler
== 'lessc':
86 compiler
= Lessc(self
.getThemeDir(), os
.path
.join(source
, sheet
), os
.path
.join(dest
, destSheet
))
88 compiler
.setDebug(self
._debug
)
91 except CssCompileFailed
:
92 logging
.warning('Failed compilation of %s' %
(sheet
))
96 logging
.info('Compiled %s to %s' %
(sheet
, destSheet
))
100 def getThemeCssPath(self
, theme
):
101 return os
.path
.join(self
.getThemePath(theme
), 'style')
103 def getThemeLessPath(self
, theme
):
104 return os
.path
.join(self
.getThemePath(theme
), 'less')
106 def getThemeDir(self
):
107 return os
.path
.join(self
._M
.get('path'), 'theme')
109 def getThemePath(self
, theme
):
110 return os
.path
.join(self
.getThemeDir(), theme
)
113 class Compiler(object):
114 """LESS compiler abstract"""
122 def __init__(self
, cwd
, source
, dest
):
124 self
._source
= source
128 raise Exception('Compiler does not implement execute() method')
130 def setCompress(self
, compress
):
131 self
._compress
= compress
133 def setDebug(self
, debug
):
137 class Recess(Compiler
):
138 """Recess compiler"""
141 executable
= C
.get('recess')
143 raise Exception('Could not find executable path')
145 cmd
= [executable
, self
._source
, '--compile']
148 cmd
.append('--compress')
150 (code
, out
, err
) = process(cmd
, self
._cwd
)
151 if code
!= 0 or len(out
) == 0:
152 raise CssCompileFailed('Error during compile')
154 # Saving to destination
155 with
open(self
._dest
, 'w') as f
:
159 class Lessc(Compiler
):
163 executable
= C
.get('lessc')
165 raise Exception('Could not find executable path')
169 sourcePath
= os
.path
.relpath(self
._source
, self
._cwd
)
170 sourceDir
= os
.path
.dirname(sourcePath
)
173 cmd
.append('--source-map-rootpath=' + sourceDir
)
174 cmd
.append('--source-map-map-inline')
175 self
.setCompress(False)
178 cmd
.append('--compress')
180 # Append the source and destination.
181 cmd
.append(sourcePath
)
182 cmd
.append(os
.path
.relpath(self
._dest
, self
._cwd
))
184 (code
, out
, err
) = process(cmd
, self
._cwd
)
185 if code
!= 0 or len(out
) != 0:
186 raise CssCompileFailed('Error during compile')
189 class CssCompileFailed(Exception):