Skip to content

Commit

Permalink
Release 0.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ngld committed May 15, 2018
2 parents 17d4ff0 + 5b260f8 commit 27184a2
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 30 deletions.
1 change: 1 addition & 0 deletions file_list.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"knossos/clibs.py",
"knossos/integration.py",
"knossos/ipc.py",
"knossos/itaskbarlist3.py",
"knossos/launcher.py",
"knossos/nebula.py",
"knossos/parsetab.py",
Expand Down
10 changes: 9 additions & 1 deletion html/templates/kn-devel-page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,14 @@ export default {
},
saveDep() {
let version = this.edit_dep_version;
if(version !== null && this.edit_dep_allow_new) {
version = '>=' + version;
}
let dep = {
id: this.edit_dep_mod,
version: (this.edit_dep_allow_new ? '>=' : '') + this.edit_dep_version,
version: version,
packages: []
};
Expand Down Expand Up @@ -519,6 +524,9 @@ export default {
Mod Path:
<br>
<span class="version-link"><a href="#" @click.prevent="openModFolder">{{ selected_mod.folder }}</a></span>
<br>

<a :href="'https://fsnebula.org/mod/' + encodeURIComponent(selected_mod.id)" class="open-ext">Download Link</a>
</div>
<div class="dev-instructions" v-else>
This is the Development tab. Here you can create new mods or edit currently installed mods. This is also where you can apply experimental mod settings, work with the Freespace Mission Editor, and alter the mod flags and commandline options. <br><br>Consider this an advanced section of Knossos but also a great place to get started if you wish to learn the ins and outs of modding with Freespace 2 Open.
Expand Down
26 changes: 21 additions & 5 deletions html/templates/kn-global-flags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ export default {
data: () => ({
engine_builds: [],
fso_build: null,
fso_build: 'invalid',
cmdline: '',
loading_flags: false,
easy_flags: {},
custom_flags: '',
flags: {},
selected_easy_flags: '',
flag_states: {},
Expand Down Expand Up @@ -72,7 +73,7 @@ export default {
}
}
this.cmdline = cmdline;
this.cmdline = cmdline + this.custom_flags;
},
selectCustomBuild() {
Expand All @@ -84,11 +85,11 @@ export default {
},
isValidBuild() {
return this.fso_build && this.fso_build.indexOf('#') > -1;
return this.fso_build !== 'invalid' && this.fso_build.indexOf('#') > -1;
},
updateFsoBuild() {
if(this.fso_build) {
if(this.fso_build !== 'invalid') {
let sel_build = this.fso_build.split('#');
this.loading_flags = true;
Expand All @@ -98,6 +99,11 @@ export default {
});
call(fs2mod.getGlobalFlags, this.fso_build, (flags) => {
this.flag_states = JSON.parse(flags);
if(this.flag_states['#custom']) {
this.custom_flags = this.flag_states['#custom'];
delete this.flag_states['#custom'];
}
this.updateFlags();
});
} else {
Expand All @@ -106,7 +112,10 @@ export default {
},
save() {
fs2mod.saveGlobalFlags(this.fso_build, JSON.stringify(this.flag_states));
fs2mod.saveGlobalFlags(this.fso_build, JSON.stringify({
...this.flag_states,
'#custom': this.custom_flags
}));
}
}
}
Expand Down Expand Up @@ -139,6 +148,13 @@ export default {
</div>
-->

<div class="form-group">
<label class="col-sm-4 control-label">Custom Flags:</label>
<div class="col-sm-8">
<input type="text" class="form-control" v-model="custom_flags">
</div>
</div>

<div class="form-group">
<label class="col-sm-4 control-label">Full Commandline:</label>
<div class="col-sm-8">
Expand Down
5 changes: 4 additions & 1 deletion html/templates/kn-mod-explore.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ export default {
</div>
</div>
<div class="mod-installed" v-if="mod.installed">
<div class="mod-banner mod-banner-blue" v-if="!mod.versions[0].installed">
<div class="mod-banner mod-banner-blue" v-if="!mod.versions[0].installed">
<span>Update Avail!</span>
</div>
<div class="mod-banner mod-banner-blue" v-else-if="mod.status === 'updating'">
<span>Installing...</span>
</div>
<div class="mod-banner mod-banner-green" v-else>
<span>Installed!</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion knossos/center.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

# The version should follow the http://semver.org guidelines.
# Only remove the -dev tag if you're making a release!
VERSION = '0.9.4'
VERSION = '0.10.0'
UPDATE_LINK = 'https://fsnebula.org/knossos'
INNOEXTRACT_LINK = 'https://dev.tproxy.de/knossos/innoextract.txt'
DEBUG = os.getenv('KN_DEBUG', '0').strip() == '1'
Expand Down
6 changes: 5 additions & 1 deletion knossos/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ def run_knossos():
integration.init()
mod_db = os.path.join(center.settings_path, 'mods.json')
if os.path.isfile(mod_db):
center.mods.load_json(mod_db)
try:
center.mods.load_json(mod_db)
except Exception:
logging.exception('Failed to load local mod list!')
center.mods.clear()

center.main_win = HellWindow()
center.main_win.open()
Expand Down
10 changes: 8 additions & 2 deletions knossos/progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,10 @@ def _get_work(self):
return None

with self._tasks_lock:
for task in self._tasks:
work = task._get_work()
# Only run one task at once to avoid problems caused by multiple tasks modifying
# the installed mods repo.
if self._tasks:
work = self._tasks[0]._get_work()
if work is not None:
return work

Expand Down Expand Up @@ -203,6 +205,10 @@ def check_tasks(self):
self._tasks.remove(task)
task._attached = False

# There are still tasks left. Tell the workers to start them.
if self._tasks:
self.wake_workers()

def wake_workers(self):
with self._worker_cond:
self._worker_cond.notify_all()
Expand Down
17 changes: 13 additions & 4 deletions knossos/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
# You have to fill this using https://github.com/workhorsy/py-cpuinfo .
CPU_INFO = None
STABILITES = ('nightly', 'rc', 'stable')
DEBUG_DEPS = False


class ModNotFound(Exception):
Expand Down Expand Up @@ -296,7 +297,8 @@ def process_pkg_selection(self, pkgs, recursive=True):
dep_dict = {}
ndeps = pkgs

logging.debug('Dep resolution started with %s, r = %r', pkgs, recursive)
if DEBUG_DEPS:
logging.debug('Dep resolution started with %s, r = %r', pkgs, recursive)

for pkg in pkgs:
mod = pkg.get_mod()
Expand All @@ -313,7 +315,10 @@ def process_pkg_selection(self, pkgs, recursive=True):

for pkg in _nd:
deps = pkg.resolve_deps()
logging.debug('%s -> %s', pkg, ['%s %s' % (pkg, str(spec)) for pkg, spec in deps])

if DEBUG_DEPS:
logging.debug('%s -> %s', pkg, ['%s %s' % (pkg, str(spec)) for pkg, spec in deps])

for dep, version in deps:
dd = dep_dict.setdefault(dep.get_mod().mid, {})
dd = dd.setdefault(version, {})
Expand Down Expand Up @@ -388,7 +393,9 @@ def process_pkg_selection(self, pkgs, recursive=True):
del remains[-1]['#mod']
dep_list |= set(remains[-1].values())

logging.debug('Dep resolution result = %s', dep_list)
if DEBUG_DEPS:
logging.debug('Dep resolution result = %s', dep_list)

return dep_list

def get_dependents(self, pkgs):
Expand Down Expand Up @@ -1058,7 +1065,9 @@ def get_mod_flag(self):

mod = mods[mid]
if mod.dev_mode:
for pkg in mod.packages:
# Sort packages by their folder name since FSO also sorts VPs by their name.
# See https://github.com/ngld/knossos/issues/107 for more details.
for pkg in sorted(mod.packages, key=lambda pkg: pkg.folder):
if pkg.check_env():
paths.append((os.path.join(mod.folder, pkg.folder), '%s - %s' % (mod.title, pkg.name)))
dev_involved = True
Expand Down
9 changes: 8 additions & 1 deletion knossos/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,15 @@ def apply_global_flags(mod):
logging.debug('No global flags found for %s' % build)
return mod.cmdline

custom_flags = ''
if '#custom' in flag_states:
custom_flags = ' ' + flag_states['#custom']

cmdline = shlex.split(mod.cmdline)
for flag, state in flag_states.items():
if flag == '#custom':
continue

if state == 0:
# Off
if flag in cmdline:
Expand All @@ -436,4 +443,4 @@ def apply_global_flags(mod):
if flag not in cmdline:
cmdline.append(flag)

return ' '.join([shlex.quote(p) for p in cmdline])
return ' '.join([shlex.quote(p) for p in cmdline]) + custom_flags
72 changes: 69 additions & 3 deletions knossos/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import hashlib
import semantic_version

from . import center, util, progress, nebula, repo, vplib
from . import center, util, progress, nebula, repo, vplib, settings
from .repo import Repo
from .qt import QtCore, QtWidgets, read_file

Expand Down Expand Up @@ -805,6 +805,55 @@ def finish(self):
run_task(LoadLocalModsTask())


class RemoveModFolder(progress.Task):
_error = None
_success = False

def __init__(self, mod):
super(RemoveModFolder, self).__init__()
self._mod = mod

self.title = 'Deleting %s...' % mod.folder
self.done.connect(self.finish)

self.add_work(('',))

def work(self, dummy):
items = []
path = self._mod.folder

for sub, d, f in os.walk(path):
for name in f:
items.append(os.path.join(path, sub, name))

count = float(len(items))
try:
for i, name in enumerate(items):
progress.update(i / count, 'Deleting files...')

os.unlink(name)

# Delete the remaining empty directories and other stuff
shutil.rmtree(path)
except Exception as exc:
logging.exception('Failed to delete mod folder for %s!' % self._mod.mid)
self._error = str(exc)
else:
progress.update(1, 'Done')
self._success = True

def finish(self):
if self._success:
QtWidgets.QMessageBox.information(None, 'Knossos', 'Successfully deleted folder for %s %s.' % (self._mod.title, self._mod.version))
elif self._error:
QtWidgets.QMessageBox.critical(None, 'Knossos', 'Failed to delete %s. Reason:\n%s' % (self._mod.folder, self._error))
else:
QtWidgets.QMessageBox.critical(None, 'Knossos', 'Failed to delete %s.' % self._mod.folder)

# Update the local mod list which will remove the uninstalled mod
run_task(LoadLocalModsTask())


class UpdateTask(InstallTask):
_old_mod = None
__check_after = True
Expand All @@ -821,7 +870,23 @@ def __init__(self, mod, check_after=True):
if pkg.name in old_pkgs or pkg.status == 'required':
pkgs.append(pkg)

super(UpdateTask, self).__init__(pkgs, new_mod, check_after=False)
# carry the dev_mode setting over to the new version
editable = {}
if mod.dev_mode:
editable.add(mod.mid)

super(UpdateTask, self).__init__(pkgs, new_mod, check_after=False, editable=editable)

def work4(self, _):
super(UpdateTask, self).work4(_)

fso_path = settings.get_fso_profile_path()
old_settings = os.path.join(fso_path, os.path.basename(self._old_mod.folder))
new_settings = os.path.join(fso_path, os.path.basename(self._mods[0].folder))

# If we have generated files for the old mod copy them over to the new one (i.e. checkpoints and other script generated stuff).
if os.path.isdir(old_settings) and not os.path.isdir(new_settings):
shutil.copytree(old_settings, new_settings)

def finish(self):
super(UpdateTask, self).finish()
Expand Down Expand Up @@ -913,6 +978,7 @@ def init1(self):
'packages': []
})

# TODO: Verify dependencies against the online repo, not against the local one.
try:
self._mod.resolve_deps(recursive=False)
except repo.ModNotFound:
Expand Down Expand Up @@ -1115,7 +1181,7 @@ def work1(self, pkg):

progress.update(0, 'Packing...')
if pkg.is_vp:
vp_name = pkg.name + '.vp'
vp_name = os.path.basename(pkg.folder) + '.vp'
vp_path = os.path.join(self._dir.name, vp_name)
vp = vplib.VpWriter(vp_path)
pkg_path = os.path.join(self._mod.folder, pkg.folder)
Expand Down
4 changes: 2 additions & 2 deletions knossos/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -1201,12 +1201,12 @@ def nebDeleteMod(self, mid, version):
QtWidgets.QMessageBox.critical(None, 'Knossos',
'Request failed. You might have problems connecting to fsnebula.org.')
else:
QtWidgets.QMessageBox.critical(None, 'Knossos', 'The release was successfully deleted.')
QtWidgets.QMessageBox.information(None, 'Knossos', 'The release was successfully deleted.')

if fine:
result = QtWidgets.QMessageBox.question(None, 'Knossos', 'Should the local files be deleted?')
if result == QtWidgets.QMessageBox.Yes:
tasks.run_task(tasks.UninstallTask(mod.packages))
tasks.run_task(tasks.RemoveModFolder(mod))

@QtCore.Slot(result=str)
def selectCustomBuild(self):
Expand Down
Loading

0 comments on commit 27184a2

Please sign in to comment.