Project > Publish
NWD Publisher
Publishes the document as a numbered NWD with title, author and expiry, after a Preflight, and moves older versions into an Archive folder.
Status
Launched Ran inside Navisworks at least once with no error logged; nobody checked the result yet.
Related asks to confirm
No quote is on record yet. These threads look related, but a person still has to open and read them.
- https://forums.autodesk.com/t5/navisworks-forum/save-as-oldversion-nwd-with-expiry-date/td-p/7694195
Events it listens to
None. It runs only when you click it.
Files
Paths are relative to the Playground.extension folder.
Project.tab/Publish.panel/NWD_Publisher.pushbutton/bundle.yamlProject.tab/Publish.panel/NWD_Publisher.pushbutton/icon.dark.pngProject.tab/Publish.panel/NWD_Publisher.pushbutton/icon.pngProject.tab/Publish.panel/NWD_Publisher.pushbutton/icon.small.dark.pngProject.tab/Publish.panel/NWD_Publisher.pushbutton/icon.small.pngProject.tab/Publish.panel/NWD_Publisher.pushbutton/script.py
Install
- Only this tool. In Navisworks, click pyNavis > Playground, search for NWD Publisher, tick it and click Install.
- The whole extension. Download
Playground.extension.zip, unzip it, put thePlayground.extensionfolder in%APPDATA%\pyNavis\extensions\, and click pyNavis > Reload. NWD Publisher is on the Project tab, Publish panel.
You need pyNavis 1.3.0 or later.
Tried it? Tell us whether it worked or not. That report is what moves a tool up the status ladder.
ReportSource
The tool's own files, word for word as published in pynavis/Playground. Paths are relative to the Playground.extension folder.
script.py
The script that runs on a click.
Project.tab/Publish.panel/NWD_Publisher.pushbutton/script.py View on GitHub# -*- coding: utf-8 -*-
"""Publishes the document as the next numbered NWD, after a Preflight, and archives older versions."""
import os
from pynavis import doc as navis_doc
from pynavis import forms, script, toast
from namo import config as namo_config
from namo import modelmgmt, naming, paths, preflight, progress, publish, ui
LAST = 'Last used settings'
def choose_settings(config):
"""The settings to pre-fill: the last used ones, or a saved profile. None = cancel."""
saved = publish.profile_names()
last = publish.normalize_settings(config.get('last') or {})
if not saved:
return last, None
options = [LAST] + saved
checked = config.get('profile') if config.get('profile') in saved else LAST
picked = forms.select_from_list(options, title='NWD Publisher',
prompt='Start from which settings?', checked=[checked])
if picked is None:
return None, None
if picked == LAST:
return last, None
return (publish.load_profile(picked) or last), picked
def run():
doc = navis_doc.get_doc()
doc_path = navis_doc.get_filename(doc) or ''
config = script.get_config({'last': {}, 'profile': ''})
settings, profile_name = choose_settings(config)
if settings is None:
return
values = naming.standard_values(doc)
folder_now = publish.target_folder(dict(settings, folder=publish.start_folder(settings, doc_path)))
_version, preview = publish.plan_target(settings['template'], values, publish.list_files(folder_now))
fields = publish.form_fields(settings, doc_path, preflight.profile_names(), namo_config.user_name())
answers = ui.form('NWD Publisher', fields, ok='Publish', width=560,
intro='Next file: %s in %s.' % (preview, folder_now))
if answers is None:
return
save_as = (answers.pop('save_as') or '').strip()
chosen = publish.normalize_settings(dict(settings, **answers))
folder = publish.target_folder(chosen)
preflight_text = 'skipped'
if chosen['preflight']:
profile = preflight.load_profile(chosen['preflight_profile']) or \
preflight.normalize_profile(preflight.DEFAULT_PROFILE)
checks = progress.run('Preflight', lambda report: preflight.run_profile(profile, doc, report),
'Reading the models')
if checks is progress.CANCELLED:
return
preflight_text = preflight.summary_text(checks)
failed = [c for c in checks if c['level'] == 'fail']
if failed:
question = ('Preflight (%s) found %d failed check%s: %s. Publish anyway?'
% (profile['name'], len(failed), '' if len(failed) == 1 else 's',
preflight.failures_text(checks)))
if not forms.confirm(question, title='NWD Publisher'):
return
preflight_text += ', published anyway'
existing = publish.list_files(folder)
version, name = publish.plan_target(chosen['template'], values, existing)
path = os.path.join(folder, name)
# Never write over, or archive, the open document or a file a model was loaded from.
try:
model_files = [p for info in modelmgmt.models_info(doc) for p in (info['file'], info['source'])]
except Exception:
model_files = []
protected = publish.protected_paths(doc_path, model_files)
problem = publish.target_problem(path, protected)
if problem:
toast.error('Nothing was published', problem)
return
staying = [n for n in existing if publish.is_protected(os.path.join(folder, n), protected)]
to_archive = 0
if chosen['archive']:
to_archive = len(publish.archive_plan(existing, chosen['template'], values, name, keep=staying))
# The one question before anything is written: the exact file, and what moves.
if not forms.confirm(publish.confirm_text(name, folder, chosen['method'], to_archive,
os.path.basename(doc_path)), title='NWD Publisher'):
return
try:
paths.ensure_dir(folder)
except Exception as error:
toast.error('Could not create the folder', '%s: %s' % (folder, error))
return
props = dict(chosen)
named = dict(values, version=version)
props['title'] = naming.render(chosen['title'], named)[0].strip() or os.path.splitext(name)[0]
props['comments'] = naming.render(chosen['comments'], named)[0]
props['publisher'] = namo_config.user_name()
try:
publish.publish(doc, path, chosen['method'], props)
except Exception as error:
toast.error('Could not write %s' % name,
'%s. Check that %s can be written to, then try again.'
% (str(error) or type(error).__name__, folder))
return
if not os.path.isfile(path):
toast.error('Navisworks did not write %s' % name,
'Nothing is at %s. Check the folder can be written to.' % path)
return
moved, archive_failed = [], []
if chosen['archive']:
plan = publish.archive_plan(publish.list_files(folder), chosen['template'], values, name,
publish.list_files(os.path.join(folder, publish.ARCHIVE_FOLDER)),
keep=staying)
moved, archive_failed = publish.archive(folder, plan)
size = os.path.getsize(path)
record = publish.history_record(path, version, chosen['method'], size,
preflight_text, namo_config.user_name(), doc_path, len(moved))
history_note = publish.log_history(record, doc, doc_path)
last = dict(chosen)
script.save_config({'last': last, 'profile': profile_name or ''})
if save_as:
try:
publish.save_profile(save_as, chosen)
except (IOError, OSError, ValueError) as error:
history_note = ((history_note or '') + ' The profile was not saved: %s.' % error).strip()
level, message, detail = publish.toast_text(name, folder, len(moved), archive_failed,
history_note, chosen['method'], size)
toast.show(level, message, detail)
if chosen['open_folder']:
ui.show_in_explorer(path)
run()
Library modules this tool uses
From the shared namo library, which installs with every tool. Each name opens the module on GitHub.
namo.configPlayground-wide settings: one JSON file shared by every Playground tool.namo.modelmgmtAppended models: listing, identifying, file freshness, batch append and model actions.namo.namingName templates: '{test} - {n:000}', '{date:%Y%m%d} {project}', '{{literal braces}}'.namo.pathsWhere Playground keeps its files, and how it writes them safely.namo.preflightPreflight: is this document ready to share? A profile of checks, each pass, warn or fail.namo.progressGlue between pyNavis' cancellable progress window and Playground's progress callbacks.namo.publishNWD Publisher: versioned NWD files with publish properties, older versions archived.namo.uiWPF building blocks for Playground tools, themed from the pyNavis design system.
bundle.yaml
The bundle contract: the keys pyNavis reads for this tool.
Project.tab/Publish.panel/NWD_Publisher.pushbutton/bundle.yaml View on GitHubtitle: NWD\nPublisher
tooltip: Publishes the document as a numbered NWD with title, author and expiry, after a Preflight, and moves older versions into an Archive folder.
context: doc