Skip to content

Commit 41ad6a8

Browse files
author
goto100
committed
Imported from svn by Bitbucket
0 parents  commit 41ad6a8

28 files changed

+2999
-0
lines changed

__init__.py

Whitespace-only changes.

build.bat

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
set pyinstaller=d:\works\pyinstaller-1.5-rc1
2+
python %pyinstaller%/makespec.py --onefile --upx --paths .;cssutils-0.9.7a3-py2.6.egg;C:\Python27\Lib\site-packages\flup-1.0.3.dev_20110405-py2.7.egg --name scompiler staticcompiler.py
3+
python %pyinstaller%/build.py scompiler.spec

commands.py

+371
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
#python
2+
#encoding=utf-8
3+
import os
4+
import sys
5+
import ui
6+
import utils.commandline
7+
from utils.commandline import arg, cwdarg, option, usage
8+
from staticcompiler import StaticPackage, Workspace, PublishPackageException, NoPublishPathException, PackageNotFoundException
9+
10+
@cwdarg
11+
@usage(u'scompiler workspace [源库路径]')
12+
def workspace(root_path):
13+
u''' 源库所在工作区 '''
14+
if StaticPackage.get_root(root_path):
15+
ui.msg(Workspace.get_workspace(root_path))
16+
else:
17+
ui.msg(u'不是一个源库')
18+
return 1
19+
20+
@arg('filename')
21+
@option('force', '-f', '--force', action = 'store_true', help = u'强制重新编译')
22+
@usage(u'scompiler compile 发布库中的某个js/css文件 [options]')
23+
def compile(filename, force = False):
24+
u'编译一个css/js文件'
25+
root_path = StaticPackage.get_root(filename)
26+
if not root_path:
27+
ui.error(u'没有找到源文件')
28+
else:
29+
package = StaticPackage(root_path)
30+
try:
31+
package.compile(filename, force = force)
32+
except IOError, e:
33+
ui.error('%s file not found' % e.filename)
34+
except PackageNotFoundException, e:
35+
ui.error('%s package not found' % e.url)
36+
37+
package.build_files()
38+
39+
@cwdarg
40+
@arg('link_path')
41+
@option('force', '-f', '--force', action='store_true', help=u'强制建立发布文件夹')
42+
def link(path, link_path, force = False):
43+
u''' 将发布库与源库进行映射
44+
45+
如果库设置了url,则同时使用.package文件进行连接,需要工作区支持,如果没有url,则只进行本地连接。'''
46+
47+
publish_path, root_path = StaticPackage.get_roots(path)
48+
if not publish_path and not root_path and link_path:
49+
publish_path, root_path = StaticPackage.get_roots(link_path)
50+
path, link_path = link_path, path
51+
52+
if not publish_path:
53+
publish_path = os.path.realpath(link_path)
54+
else:
55+
root_path = os.path.realpath(link_path)
56+
57+
if not root_path:
58+
ui.error('package not found')
59+
60+
package = StaticPackage(root_path, publish_path = publish_path)
61+
62+
if not os.path.exists(publish_path):
63+
if force:
64+
os.makedirs(publish_path)
65+
else:
66+
ui.msg(u'%s path not exists, run scompiler link path -f to create it.' % publish_path)
67+
return 1
68+
69+
package.link()
70+
71+
ui.msg(u'linked publish %s to %s'% (publish_path, root_path))
72+
73+
@cwdarg
74+
@arg('publish_path')
75+
@option('force', '-f', '--force', help = u'强制编译', action = 'store_true')
76+
@usage(u'scompiler publish [源库路径] [发布库路径] [options]')
77+
def publish(path, publish_path = None, force = False):
78+
u'''将整个目录进行发布'''
79+
80+
do_link = False
81+
# 指定了第二个参数,则path一定是一个源库,第二个参数则是发布库,并自动进行link
82+
if publish_path:
83+
root_path = StaticPackage.get_root(path)
84+
path = publish_path # 发布整个库
85+
do_link = True
86+
# 没有指定第二个参数,则path一定是一个发布库
87+
else:
88+
publish_path, root_path = StaticPackage.get_roots(path)
89+
90+
def get_files(dir_path):
91+
paths = []
92+
for root, dirs, files in os.walk(dir_path):
93+
if '.svn' in root:
94+
dirs[:] = []
95+
continue
96+
for file in files:
97+
path = os.path.join(root, file)
98+
if os.path.splitext(path)[1] in ('.css', '.js'):
99+
paths.append(path)
100+
101+
return paths
102+
103+
if not publish_path:
104+
ui.msg(u'No publish path.')
105+
else:
106+
package = StaticPackage(root_path, publish_path = publish_path)
107+
if not package.publish_path:
108+
ui.msg(u'No publish path.')
109+
else:
110+
ui.msg(u'publish to %s from %s' % (path, package.root))
111+
all_files = get_files(path)
112+
for file in all_files:
113+
try:
114+
package.compile(file, force = force)
115+
except IOError, e:
116+
ui.error('%s file not found' % e.filename)
117+
except PackageNotFoundException, e:
118+
ui.error('No package found ' + e.url)
119+
120+
package.build_files()
121+
if do_link:
122+
package.link()
123+
124+
@cwdarg
125+
@usage(u'scompiler load [工作区路径]')
126+
def load(workspace_path):
127+
u''' 加载本地工作区 '''
128+
129+
if os.path.isfile(workspace_path):
130+
workspace_path = os.path.dirname(workspace_path)
131+
132+
workspace = Workspace(workspace_path)
133+
added_count = 0
134+
for root, dirs, files in os.walk(workspace_path):
135+
if StaticPackage.is_root(root):
136+
dirs[:] = []
137+
if not workspace.has_package(root):
138+
workspace.add_package(root)
139+
added_count = added_count + 1
140+
141+
if len(workspace.useless_packages):
142+
for package in workspace.useless_packages:
143+
ui.msg(u'删除无用package %s' % package)
144+
145+
workspace.rebuild_package()
146+
147+
ui.msg(u'已加入 %s 个源库' % added_count)
148+
149+
@cwdarg
150+
@option('show_url', '-u', '--show-url', action = 'store_true', help = u'显示有url的源库的url')
151+
@usage(u'scompiler packages [工作区路径]')
152+
def packages(workspace_path, show_url = False):
153+
u''' 本工作区中所有源库 '''
154+
155+
if os.path.isfile(workspace_path):
156+
workspace_path = os.path.dirname(workspace_path)
157+
158+
# 有可能不是workspace跟路径,而是某个子路径
159+
workspace_path = Workspace.get_workspace(workspace_path)
160+
if not workspace_path:
161+
ui.error(u'没有工作区')
162+
return 1
163+
else:
164+
workspace = Workspace(workspace_path)
165+
if show_url:
166+
for url in workspace.url_packages.keys():
167+
ui.msg(url)
168+
else:
169+
for local_path in workspace.local_packages.keys():
170+
ui.msg(os.path.realpath(os.path.join(workspace.root, local_path)))
171+
172+
@cwdarg
173+
@option('publish_path', '-p', '--publish-path', type = 'string', help = u'发布目录')
174+
@option('force', '-f', '--force', action = 'store_true', help = u'强制建立发布目录')
175+
def init(root_path, publish_path = None, force = False):
176+
u''' 初始化一个新的库
177+
178+
初始化一个新的库,建立template-config.xml配置文件及常用的目录,如果指定了 -p 参数,还可以自动建立与发布目录的连接'''
179+
ui.msg(u'初始化%s' % root_path)
180+
try:
181+
StaticPackage.init(root_path)
182+
except PublishPackageException:
183+
ui.error(u'发布目录不能被初始化')
184+
return 1
185+
186+
if publish_path:
187+
link(root_path, publish_path, force = force)
188+
189+
@cwdarg
190+
@usage(u'scompiler root [源库路径]')
191+
def root(root_path):
192+
u''' 源库的根路径 '''
193+
ui.msg(StaticPackage.get_root(root_path))
194+
195+
@cwdarg
196+
@usage(u'scompiler source [源库路径] [options]')
197+
def source(publish_path):
198+
u''' 映射的源库路径 '''
199+
if StaticPackage.get_publish(publish_path):
200+
StaticPackage.get_root(publish_path)
201+
else:
202+
ui.error(u'不是一个发布库')
203+
204+
@cwdarg
205+
@usage(u'scompiler libs [源库路径]')
206+
@option('show_url', '-u', '--show-url', help=u'显示url而非本地路径', action='store_true')
207+
@option('all', '-a', '--all', help=u'递归显示所有', action='store_true')
208+
@option('reverse', '-r', '--reverse', help=u'显示被依赖的', action='store_true')
209+
def libs(root_path, show_url = False, all = False, reverse = False):
210+
u''' 库的相关依赖库 '''
211+
root_path = StaticPackage.get_root(root_path)
212+
if not root_path:
213+
ui.error(u'不是源库')
214+
return 1
215+
216+
package = StaticPackage(root_path)
217+
# 这个库没有设置url,不可能被别的库依赖
218+
if not package.url:
219+
ui.error(u'no url')
220+
return 1
221+
222+
# 显示依赖自己的
223+
if reverse:
224+
libs = package.get_reverse_libs(all = all)
225+
# 显示依赖了谁
226+
else:
227+
libs = package.get_libs(all = all)
228+
229+
if show_url:
230+
if package.workspace:
231+
for local_path in libs:
232+
url = package.workspace.local_packages.get(local_path)
233+
if url:
234+
ui.msg(url)
235+
236+
else:
237+
ui.error(u'没有工作区')
238+
else:
239+
for local_path in libs:
240+
ui.msg(local_path)
241+
242+
@arg('filename')
243+
def includes(filename):
244+
u''' 某文件所有依赖的文件 '''
245+
filename = os.path.realpath(filename)
246+
root_path = StaticPackage.get_root(filename)
247+
package = StaticPackage(root_path)
248+
249+
for file in package.get_includes(filename):
250+
print file
251+
252+
@arg('filename')
253+
@option('all', '-a', '--all', help=u'递归显示所有', action='store_true')
254+
def included(filename, all = False):
255+
u''' 所有引用了此文件的文件 '''
256+
filename = os.path.realpath(filename)
257+
root_path = StaticPackage.get_root(filename)
258+
package = StaticPackage(root_path)
259+
260+
for file in package.get_included(filename, all = all):
261+
print file
262+
263+
@arg('workspace_path')
264+
@option('fastcgi', '--fastcgi', help = u'使用fastcgi进行serve', action = 'store_true')
265+
@option('port', '--port', help = u'指定端口号', type = 'int')
266+
@option('debug', '-d', '--debug', help = u'debug模式', action = 'store_true')
267+
def serve(workspace_path = None, fastcgi = False, port = 8080, debug = False):
268+
u''' 启动一个静态服务器
269+
270+
请指定工作区路径'''
271+
272+
if workspace_path:
273+
workspace = Workspace(os.path.realpath(workspace_path))
274+
else:
275+
workspace = None
276+
277+
def print_request(environ, start_response):
278+
''' 输出fastcgi本次请求的相关信息 '''
279+
280+
import cgi
281+
start_response('200 OK', [('Content-Type', 'text/html')])
282+
yield '<html><head><title>Hello World!</title></head>\n' \
283+
'<body>\n' \
284+
'<p>Hello World!</p>\n' \
285+
'<table border="1">'
286+
names = environ.keys()
287+
names.sort()
288+
for name in names:
289+
yield '<tr><td>%s</td><td>%s</td></tr>\n' % (
290+
name, cgi.escape(`environ[name]`))
291+
292+
form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ,
293+
keep_blank_values=1)
294+
if form.list:
295+
yield '<tr><th colspan="2">Form data</th></tr>'
296+
297+
for field in form.list:
298+
yield '<tr><td>%s</td><td>%s</td></tr>\n' % (
299+
field.name, field.value)
300+
301+
yield '</table>\n' \
302+
'</body></html>\n'
303+
304+
def listen(environ, start_response):
305+
''' 监听请求 '''
306+
if environ['DOCUMENT_URI'].endswith('/fuck.css'):
307+
return print_request(environ, start_response)
308+
309+
DEBUG = debug
310+
311+
filename = os.path.realpath(environ['REQUEST_FILENAME'])
312+
url = environ['DOCUMENT_URI']
313+
314+
force = False # 是否强制重新编译
315+
# 没有 referer 时强制重新编译
316+
if not 'HTTP_REFERER' in environ.keys():
317+
force = True
318+
319+
publish_path, root_path = StaticPackage.get_roots(filename, workspace = workspace)
320+
if root_path:
321+
package = StaticPackage(root_path, publish_path, workspace = workspace)
322+
323+
try:
324+
package.compile(filename, force = force, workspace = workspace)
325+
except IOError, e:
326+
start_response('400 Compile Error', [])
327+
return '%s file not found' % e.filename
328+
except PackageNotFoundException, e:
329+
start_response('400 Compile Error', [])
330+
return '%s package not found' % e.url
331+
332+
package.build_files()
333+
334+
mimetypes = {
335+
'.css': 'text/css',
336+
'.js': 'text/javascript'
337+
}
338+
mimetype = mimetypes[os.path.splitext(filename)[1]]
339+
340+
if not os.path.exists(filename):
341+
# 文件不存在
342+
start_response('404 Not Found', [])
343+
return '404 Not Found'
344+
345+
start_response('200 OK', [('Content-Type', mimetype)])
346+
return [open(filename).read()]
347+
348+
if fastcgi:
349+
from flup.server.fcgi import WSGIServer
350+
351+
WSGIServer(listen, bindAddress=('localhost', port), debug = debug).run()
352+
else:
353+
ui.msg(u'现在还不支持server,请使用 scompiler serve --fastcgi 方式')
354+
355+
def main():
356+
commands = [init, compile, publish, link, load, serve, packages, workspace, root, source, libs, includes, included]
357+
if len(sys.argv) < 2:
358+
ui.msg(u'使用 scompiler help 得到用法')
359+
else:
360+
command = sys.argv[1]
361+
if command == 'help':
362+
subcommand = None
363+
if len(sys.argv) > 2:
364+
subcommand = globals()[sys.argv[2]]
365+
utils.commandline.help(commands, subcommand)
366+
else:
367+
all = globals()
368+
if command in all:
369+
utils.commandline.call(commands, globals()[command])
370+
else:
371+
utils.commandline.help(commands)

css/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)