Skip to content

Commit a0c0de1

Browse files
authored
Merge pull request #176 from jyapayne/blacklisting
Implement blacklisting and whitelisting
2 parents c03f669 + c6b8a60 commit a0c0de1

File tree

5 files changed

+430
-36
lines changed

5 files changed

+430
-36
lines changed

command_line.py

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import utils
4444
from utils import zip_files, join_files
4545
from utils import get_data_path, get_data_file_path
46-
from util_classes import Setting
46+
from util_classes import Setting, FileTree
4747

4848
from image_utils.pycns import save_icns
4949
from pepy.pe import PEFile
@@ -69,6 +69,8 @@ def __init__(self, quiet=False):
6969
self.readonly = True
7070
self.update_json = True
7171

72+
self.file_tree = FileTree()
73+
7274
def init(self):
7375
self.logger = config.logger
7476
self.update_nw_versions(None)
@@ -89,7 +91,7 @@ def setup_nw_versions(self):
8991
for line in f:
9092
nw_version.values.append(line.strip())
9193
except IOError:
92-
nw_version.values.append(nw_version.default_value)
94+
pass
9395

9496
def get_nw_versions(self):
9597
"""Get the already downloaded nw versions from the settings"""
@@ -320,6 +322,7 @@ def get_versions(self):
320322
nw_version = self.get_setting('nw_version')
321323

322324
old_versions = set(nw_version.values)
325+
323326
old_versions = old_versions.union(union_versions)
324327
new_versions = set(re.findall(regex, html))
325328

@@ -375,7 +378,7 @@ def download_file_with_error_handling(self):
375378
if os.path.exists(setting.save_file_path(version, location)):
376379
os.remove(setting.save_file_path(version, location))
377380

378-
exc_format = utils.format_exc_info(sys.exc_info)
381+
exc_format = utils.format_exc_info(sys.exc_info())
379382
self.show_error(exc_format)
380383
self.enable_ui_after_error()
381384

@@ -758,8 +761,12 @@ def replace_plist(self, app_path):
758761
plist_dict['CFBundleDisplayName'] = self.project_name()
759762
plist_dict['CFBundleName'] = self.project_name()
760763
version_setting = self.get_setting('version')
761-
plist_dict['CFBundleShortVersionString'] = version_setting.value
762-
plist_dict['CFBundleVersion'] = version_setting.value
764+
if version_setting.value is not None:
765+
plist_dict['CFBundleShortVersionString'] = version_setting.value
766+
plist_dict['CFBundleVersion'] = version_setting.value
767+
else:
768+
plist_dict['CFBundleShortVersionString'] = '0.0.0'
769+
plist_dict['CFBundleVersion'] = '0.0.0'
763770

764771
plistlib.writePlist(plist_dict, plist_path)
765772

@@ -870,6 +877,13 @@ def process_export_setting(self, ex_setting, output_name):
870877
self.process_win_linux_setting(app_loc, output_dir,
871878
ex_setting)
872879

880+
@property
881+
def used_project_files(self):
882+
return self.file_tree.files
883+
884+
@property
885+
def used_project_dirs(self):
886+
return self.file_tree.dirs
873887

874888
def make_output_dirs(self, write_json=True):
875889
"""Create the output directories for the application to be copied"""
@@ -878,6 +892,17 @@ def make_output_dirs(self, write_json=True):
878892

879893
self.progress_text = 'Making new directories...\n'
880894

895+
896+
whitelist_setting = self.get_setting('whitelist')
897+
blacklist_setting = self.get_setting('blacklist')
898+
899+
output_blacklist = os.path.basename(self.output_dir())
900+
901+
self.file_tree.init(self.project_dir(),
902+
blacklist=(blacklist_setting.value.split(',') +
903+
['*'+output_blacklist+'*']),
904+
whitelist=whitelist_setting.value.split(','))
905+
881906
self.copy_files_to_project_folder()
882907

883908
if write_json:
@@ -914,15 +939,28 @@ def get_app_nw_loc(self, temp_dir, output_dir):
914939
"""Copy the temporary app to the output_dir"""
915940
app_file = utils.path_join(temp_dir, self.project_name()+'.nw')
916941

942+
proj_dir = self.project_dir()
943+
917944
if self.uncompressed:
918945
app_nw_folder = utils.path_join(temp_dir,
919946
self.project_name()+'.nwf')
947+
for dir in self.used_project_dirs:
948+
if not os.path.exists(dir):
949+
os.makedirs(dir)
950+
951+
for file in self.used_project_files:
952+
src = utils.path_join(proj_dir, file)
953+
dest = utils.path_join(app_nw_folder, file)
954+
955+
base, _ = os.path.split(dest)
956+
957+
if not os.path.exists(base):
958+
os.makedirs(base)
920959

921-
utils.copytree(self.project_dir(), app_nw_folder,
922-
ignore=shutil.ignore_patterns(output_dir))
960+
utils.copy(src, dest)
923961
return app_nw_folder
924962
else:
925-
zip_files(app_file, self.project_dir(), exclude_paths=[output_dir])
963+
zip_files(app_file, proj_dir, *self.used_project_files)
926964
return app_file
927965

928966
def get_version_tuple(self):
@@ -1455,7 +1493,6 @@ class ArgParser(argparse.ArgumentParser):
14551493
"""Custom argparser that prints help if there is an error"""
14561494
def error(self, message):
14571495
sys.stderr.write('error: {}\n'.format(message))
1458-
self.print_help()
14591496
sys.exit(2)
14601497

14611498
def get_arguments(command_base):
@@ -1520,8 +1557,9 @@ def generate_setting_args(command_base, parser):
15201557
if setting_name == 'name':
15211558
kwargs.update({'default': command_base.project_name})
15221559
else:
1523-
kwargs.update({'required': setting.required,
1524-
'default': setting.default_value})
1560+
kwargs.update({'required': setting.required})
1561+
if setting.default_value is not None:
1562+
kwargs.update({'default': setting.default_value})
15251563
action = 'store'
15261564
option_name = setting_name.replace('_', '-')
15271565

files/settings.cfg

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ linux_64_dir_prefix = 'nwjs-v{}-linux-x64'
128128
default_value=''
129129
type='string'
130130
description='Type "%(" to see a list of options to reference. Name your output folder.\n Include slashes to make sub-directories.'
131+
[[[blacklist]]]
132+
display_name='Blacklist'
133+
default_value=''
134+
type='string'
135+
description='Glob-style blacklist files/directories. Each line is a new pattern. Ex: *.jpeg, .git, *file[s].txt'
136+
[[[whitelist]]]
137+
display_name='Whitelist'
138+
default_value=''
139+
type='string'
140+
description='Glob-style whitelist files/directories. Each line is a new pattern. Ex: *.jpeg, .git, *file[s].txt.\nWhitelist trumps blacklist.'
131141

132142
[[window_settings]]
133143
[[[id]]]
@@ -238,6 +248,7 @@ linux_64_dir_prefix = 'nwjs-v{}-linux-x64'
238248
[[download_settings]]
239249
[[[nw_version]]]
240250
display_name='NW.js version'
251+
required=True
241252
default_value=None
242253
values=[]
243254
type='list'

main.py

Lines changed: 118 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from util_classes import ExistingProjectDialog
3838
from util_classes import BackgroundThread, Validator
3939
from util_classes import CompleterLineEdit, TagsCompleter
40+
from util_classes import TreeBrowser
4041

4142
from PySide import QtGui, QtCore
4243
from PySide.QtGui import (QApplication, QHBoxLayout, QVBoxLayout)
@@ -209,18 +210,6 @@ def open_recent_file(self):
209210
if action:
210211
self.load_project(action.data())
211212

212-
def setup_nw_versions(self):
213-
"""Loads stored versions that were previously retrieved."""
214-
nw_version = self.get_setting('nw_version')
215-
try:
216-
f = codecs.open(utils.get_data_file_path(config.VER_FILE),
217-
encoding='utf-8')
218-
for line in f:
219-
nw_version.values.append(line.strip())
220-
f.close()
221-
except IOError:
222-
nw_version.values.append(nw_version.default_value)
223-
224213
def create_application_layout(self):
225214
"""Create all widgets and set the central widget."""
226215
self.main_layout = QtGui.QVBoxLayout()
@@ -989,6 +978,15 @@ def load_project(self, directory, readonly=False):
989978

990979
self.set_window_icon()
991980
self.open_export_button.setEnabled(True)
981+
982+
blacklist_setting = self.get_setting('blacklist')
983+
984+
output_blacklist = os.path.basename(self.output_dir())
985+
986+
self.tree_browser.init(directory,
987+
blacklist=(blacklist_setting.value.split('\n') +
988+
['*'+output_blacklist+'*']))
989+
992990
self.update_json = True
993991

994992
def init_main_field(self, directory):
@@ -1159,23 +1157,116 @@ def create_export_settings(self):
11591157

11601158
ex_setting_order = self.settings['order']['export_setting_order']
11611159

1162-
vlayout = self.create_layout(ex_setting_order, cols=4)
1160+
vlayout = self.create_layout(ex_setting_order, cols=1)
1161+
vlayout.setContentsMargins(0, 10, 0, 0)
11631162

11641163
output_name_layout = self.create_output_name_pattern_line()
11651164

11661165
output_layout = self.create_output_directory_line()
11671166

11681167
script_layout = self.create_script_layout()
11691168

1169+
hlayout = QtGui.QHBoxLayout()
1170+
1171+
platform_group = QtGui.QGroupBox('Platforms')
1172+
platform_group.setContentsMargins(0, 10, 0, 0)
1173+
playout = QtGui.QVBoxLayout()
1174+
playout.addLayout(vlayout)
1175+
platform_group.setLayout(playout)
1176+
1177+
hlayout.addWidget(platform_group)
1178+
1179+
tree_layout = self.create_blacklist_layout(hlayout)
1180+
tree_layout.setContentsMargins(0, 10, 0, 0)
1181+
11701182
vbox = QtGui.QVBoxLayout()
1171-
vbox.addLayout(vlayout)
1183+
vbox.addLayout(hlayout)
11721184
vbox.addLayout(output_name_layout)
11731185
vbox.addLayout(output_layout)
11741186
vbox.addLayout(script_layout)
11751187

11761188
group_box.setLayout(vbox)
11771189
return group_box
11781190

1191+
def create_blacklist_layout(self, blacklist_layout):
1192+
1193+
self.tree_browser = TreeBrowser()
1194+
self.tree_browser.setContentsMargins(0, 0, 0, 0)
1195+
1196+
self.blacklist_text = QtGui.QPlainTextEdit()
1197+
self.whitelist_text = QtGui.QPlainTextEdit()
1198+
1199+
hlayout = QtGui.QHBoxLayout()
1200+
1201+
blacklayout = QtGui.QVBoxLayout()
1202+
whitelayout = QtGui.QHBoxLayout()
1203+
1204+
blacklayout.addWidget(self.blacklist_text)
1205+
whitelayout.addWidget(self.whitelist_text)
1206+
1207+
whitelist_setting = self.get_setting('whitelist')
1208+
blacklist_setting = self.get_setting('blacklist')
1209+
1210+
self.blacklist_text.setStatusTip(blacklist_setting.description)
1211+
self.whitelist_text.setStatusTip(whitelist_setting.description)
1212+
1213+
self.blacklist_text.setObjectName(blacklist_setting.name)
1214+
self.whitelist_text.setObjectName(whitelist_setting.name)
1215+
1216+
blackgroup = QtGui.QGroupBox(blacklist_setting.display_name)
1217+
whitegroup = QtGui.QGroupBox(whitelist_setting.display_name)
1218+
1219+
blackgroup.setLayout(blacklayout)
1220+
whitegroup.setLayout(whitelayout)
1221+
1222+
blacklist_layout.addWidget(blackgroup)
1223+
blacklist_layout.addWidget(whitegroup)
1224+
blacklist_layout.addWidget(self.tree_browser)
1225+
1226+
self.blacklist_text.textChanged.connect(
1227+
self.call_with_object('setting_changed',
1228+
self.blacklist_text,
1229+
blacklist_setting)
1230+
)
1231+
1232+
self.whitelist_text.textChanged.connect(
1233+
self.call_with_object('setting_changed',
1234+
self.whitelist_text,
1235+
whitelist_setting)
1236+
)
1237+
1238+
self.blacklist_text.textChanged.connect(
1239+
self.call_with_object('blacklist_changed',
1240+
self.blacklist_text,
1241+
blacklist_setting)
1242+
)
1243+
1244+
self.whitelist_text.textChanged.connect(
1245+
self.call_with_object('whitelist_changed',
1246+
self.whitelist_text,
1247+
whitelist_setting)
1248+
)
1249+
1250+
return blacklist_layout
1251+
1252+
def blacklist_changed(self, text, blacklist_setting):
1253+
new_val = text.toPlainText()
1254+
output_blacklist = os.path.basename(self.output_dir())
1255+
self.tree_browser.refresh(blacklist=(new_val.split('\n') +
1256+
['*'+output_blacklist+'*']))
1257+
1258+
def whitelist_changed(self, text, whitelist_setting):
1259+
new_val = text.toPlainText()
1260+
self.tree_browser.refresh(whitelist=new_val.split('\n'))
1261+
1262+
@property
1263+
def used_project_files(self):
1264+
return self.tree_browser.files
1265+
1266+
@property
1267+
def used_project_dirs(self):
1268+
return self.tree_browser.dirs
1269+
11791270
def create_output_name_pattern_line(self):
11801271
output_name_layout = QtGui.QHBoxLayout()
11811272

@@ -1415,7 +1506,10 @@ def reset_settings(self):
14151506
old_val = setting.default_value
14161507

14171508
setting.value = old_val.replace('\\', '\\\\')
1418-
widget.setText(old_val)
1509+
if hasattr(widget, 'setText'):
1510+
widget.setText(old_val)
1511+
elif hasattr(widget, 'setPlainText'):
1512+
widget.setPlainText(old_val)
14191513
elif setting.type == 'strings':
14201514
old_val = []
14211515
if setting.default_value is not None:
@@ -1477,7 +1571,11 @@ def setting_changed(self, obj, setting, *args):
14771571
setting.type == 'file' or
14781572
setting.type == 'folder' or
14791573
setting.type == 'int'):
1480-
setting.value = args[0]
1574+
if args:
1575+
setting.value = args[0]
1576+
else:
1577+
setting.value = obj.toPlainText()
1578+
14811579
if not setting.value:
14821580
setting.value = setting.default_value
14831581
elif setting.type == 'strings':
@@ -1629,7 +1727,10 @@ def load_package_json(self, json_path=None):
16291727
setting.type == 'folder' or
16301728
setting.type == 'int'):
16311729
val_str = self.convert_val_to_str(setting.value)
1632-
setting_field.setText(setting.filter_name(val_str))
1730+
if hasattr(setting_field, 'setText'):
1731+
setting_field.setText(setting.filter_name(val_str))
1732+
elif hasattr(setting_field, 'setPlainText'):
1733+
setting_field.setPlainText(setting.filter_name(val_str))
16331734
if setting.type == 'strings':
16341735
vals = [self.convert_val_to_str(v) for v in setting.value]
16351736
setting_field.setText(','.join(vals))

0 commit comments

Comments
 (0)