From b6dd2b8ec1bb65671833c15dc96e890dcfa1f2bd Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Dec 2022 15:07:12 +0100 Subject: [PATCH] makepanda: Add file associations and shortcuts for pstats --- makepanda/installer.nsi | 20 ++++++++++- makepanda/installpanda.py | 76 ++++++++++++++++++++++++++------------- makepanda/pstats.desktop | 12 +++++++ 3 files changed, 83 insertions(+), 25 deletions(-) create mode 100644 makepanda/pstats.desktop diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index 13b433dce7..6cb6113dc4 100644 --- a/makepanda/installer.nsi +++ b/makepanda/installer.nsi @@ -342,6 +342,13 @@ Section "Tools and utilities" SecTools WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell" "" "open" WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract" "" "Extract here" WriteRegStr HKCU "Software\Classes\Panda3D.Multifile\shell\extract\command" "" '"$INSTDIR\bin\multify.exe" -xf "%1"' + + IfFileExists "$INSTDIR\bin\pstats.exe" 0 SkipPStatsFileAssociation + WriteRegStr HKCU "Software\Classes\Panda3D.PStatsSession" "" "PStats Session" + WriteRegStr HKCU "Software\Classes\Panda3D.PStatsSession\DefaultIcon" "" "%SystemRoot%\system32\imageres.dll,144" + WriteRegStr HKCU "Software\Classes\Panda3D.PStatsSession\shell" "" "open" + WriteRegStr HKCU "Software\Classes\Panda3D.PStatsSession\shell\open\command" "" '"$INSTDIR\bin\pstats.exe" "%1"' + SkipPStatsFileAssociation: SectionEnd SectionGroup "Python modules" SecGroupPython @@ -639,6 +646,9 @@ Section "Sample programs" SecSamples WriteINIStr $INSTDIR\Manual.url "InternetShortcut" "URL" "https://docs.panda3d.org/${MAJOR_VER}" WriteINIStr $INSTDIR\Samples.url "InternetShortcut" "URL" "https://docs.panda3d.org/${MAJOR_VER}/python/more-resources/samples/index" SetOutPath $INSTDIR + IfFileExists "$INSTDIR\bin\pstats.exe" 0 SkipPStatsShortcut + CreateShortCut "$SMPROGRAMS\${TITLE}\Panda3D Stats Monitor.lnk" "$INSTDIR\bin\pstats.exe" "" "%SystemRoot%\system32\imageres.dll" 144 "" "" "Panda3D Stats Monitor" + SkipPStatsShortcut: CreateShortCut "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk" "$INSTDIR\Manual.url" "" "$INSTDIR\pandaIcon.ico" 0 "" "" "Panda3D Manual" CreateShortCut "$SMPROGRAMS\${TITLE}\Panda3D Website.lnk" "$INSTDIR\Website.url" "" "$INSTDIR\pandaIcon.ico" 0 "" "" "Panda3D Website" CreateShortCut "$SMPROGRAMS\${TITLE}\Sample Program Manual.lnk" "$INSTDIR\Samples.url" "" "$INSTDIR\pandaIcon.ico" 0 "" "" "Sample Program Manual" @@ -739,7 +749,7 @@ Section -post DetailPrint "Registering file type associations..." SetDetailsPrint listonly - ; Register various model files + ; Register various file extensions WriteRegStr HKCU "Software\Classes\.egg" "" "Panda3D.Model" WriteRegStr HKCU "Software\Classes\.egg" "Content Type" "application/x-egg" WriteRegStr HKCU "Software\Classes\.egg" "PerceivedType" "gamemedia" @@ -753,6 +763,9 @@ Section -post WriteRegStr HKCU "Software\Classes\.prc" "" "inifile" WriteRegStr HKCU "Software\Classes\.prc" "Content Type" "text/plain" WriteRegStr HKCU "Software\Classes\.prc" "PerceivedType" "text" + WriteRegStr HKCU "Software\Classes\.pstats" "" "Panda3D.PStatsSession" + WriteRegStr HKCU "Software\Classes\.pstats" "Content Type" "application/vnd.panda3d.pstats" + WriteRegStr HKCU "Software\Classes\.pstats" "PerceivedType" "application" ; For convenience, if nobody registered .pyd, we will. ReadRegStr $0 HKCR "Software\Classes\.pyd" "" @@ -813,6 +826,11 @@ Section Uninstall DeleteRegKey HKCU "Software\Classes\Panda3D.Multifile\DefaultIcon" DeleteRegKey HKCU "Software\Classes\Panda3D.Multifile\shell" + ReadRegStr $0 HKCU "Software\Classes\Panda3D.PStatsSession\DefaultIcon" "" + StrCmp $0 "$INSTDIR\bin\pstats.exe" 0 +3 + DeleteRegKey HKCU "Software\Classes\Panda3D.PStatsSession\DefaultIcon" + DeleteRegKey HKCU "Software\Classes\Panda3D.PStatsSession\shell" + !ifdef INCLUDE_PYVER ReadRegStr $0 HKLM "Software\Python\PythonCore\${INCLUDE_PYVER}\InstallPath" "" StrCmp $0 "$INSTDIR\python" 0 +2 diff --git a/makepanda/installpanda.py b/makepanda/installpanda.py index 1c57b32b53..a059e772db 100644 --- a/makepanda/installpanda.py +++ b/makepanda/installpanda.py @@ -18,29 +18,36 @@ from distutils.sysconfig import get_python_lib MIME_INFO = ( - ("egg", "model/x-egg", "EGG model file", "pview"), - ("bam", "model/x-bam", "Panda3D binary model file", "pview"), - ("egg.pz", "model/x-compressed-egg", "Compressed EGG model file", "pview"), - ("bam.pz", "model/x-compressed-bam", "Compressed Panda3D binary model file", "pview"), + # ext, mime, desc, app, magic + ("egg", "model/x-egg", "EGG model file", "pview", None), + ("bam", "model/x-bam", "Panda3D binary model file", "pview", None), + ("egg.pz", "model/x-compressed-egg", "Compressed EGG model file", "pview", None), + ("bam.pz", "model/x-compressed-bam", "Compressed Panda3D binary model file", "pview", None), + ("pstats", "application/vnd.panda3d.pstats", "PStats session file", "pstats", b"pstat\0\n\r"), ) APP_INFO = ( - ("pview", "Panda3D Model Viewer", ("egg", "bam", "egg.pz", "bam.pz")), + ("pview", "Panda3D Model Viewer", ("egg", "bam", "egg.pz", "bam.pz"), True), + ("pstats", "Panda3D Profiling Tool", ("pstats",), False), ) -def WriteApplicationsFile(fname, appinfo, mimeinfo): +def WriteApplicationsFile(fname, appinfo, mimeinfo, bindir): fhandle = open(fname, "w") - for app, desc, exts in appinfo: + for app, desc, exts, multiple in appinfo: + if not os.path.isfile(os.path.join(bindir, app)): + continue + fhandle.write("%s\n" % (app)) fhandle.write("\tcommand=%s\n" % (app)) fhandle.write("\tname=%s\n" % (desc)) - fhandle.write("\tcan_open_multiple_files=true\n") + fhandle.write("\tcan_open_multiple_files=%s\n" % ('true' if multiple else 'false')) + fhandle.write("\tstartup_notify=%s\n" % ('true' if app == 'pstats' else 'false')) fhandle.write("\texpects_uris=false\n") fhandle.write("\trequires_terminal=false\n") fhandle.write("\tmime_types=") first = True - for ext, mime, desc2, app2 in mimeinfo: - if ext in exts: + for ext, mime, desc2, app2, magic in mimeinfo: + if app == app2 and ext in exts: if first: fhandle.write(mime) first = False @@ -50,37 +57,53 @@ def WriteApplicationsFile(fname, appinfo, mimeinfo): fhandle.close() -def WriteMimeXMLFile(fname, info): +def WriteMimeXMLFile(fname, info, bindir): fhandle = open(fname, "w") fhandle.write("\n") fhandle.write("\n") - for ext, mime, desc, app in info: + for ext, mime, desc, app, magic in info: + if not os.path.isfile(os.path.join(bindir, app)): + continue + fhandle.write("\t\n" % (mime)) fhandle.write("\t\t%s\n" % (desc)) + if app == "pstats": + fhandle.write("\t\t\n") + if magic: + magic = magic.decode('latin-1').encode('unicode-escape').decode('latin-1') + fhandle.write("\t\t\n\t\t\t\n\t\t\n" % (magic)) fhandle.write("\t\t\n" % (ext)) fhandle.write("\t\n") fhandle.write("\n") fhandle.close() -def WriteMimeFile(fname, info): +def WriteMimeFile(fname, info, bindir): fhandle = open(fname, "w") - for ext, mime, desc, app in info: - fhandle.write("%s:\n" % (mime)) + for ext, mime, desc, app, magic in info: + if not os.path.isfile(os.path.join(bindir, app)): + continue + + fhandle.write("%s\n" % (mime)) if "." in ext: - fhandle.write("\tregex,2: %s$\n" % (ext.replace(".", "\\."))) + fhandle.write("\tregex,2: \\.%s$\n" % (ext.replace(".", "\\."))) fhandle.write("\text: %s\n" % (ext)) fhandle.write("\n") fhandle.close() -def WriteKeysFile(fname, info): +def WriteKeysFile(fname, info, bindir): fhandle = open(fname, "w") - for ext, mime, desc, app in info: - fhandle.write("%s:\n" % (mime)) + for ext, mime, desc, app, magic in info: + if not os.path.isfile(os.path.join(bindir, app)): + continue + + fhandle.write("%s\n" % (mime)) fhandle.write("\tdescription=%s\n" % (desc)) fhandle.write("\tdefault_action_type=application\n") fhandle.write("\tshort_list_application_ids_for_novice_user_level=%s\n" % (app)) + fhandle.write("\tshort_list_application_ids_for_intermediate_user_level=%s\n" % (app)) + fhandle.write("\tshort_list_application_ids_for_advanced_user_level=%s\n" % (app)) fhandle.write("\topen=%s %%f\n" % (app)) fhandle.write("\tview=%s %%f\n" % (app)) fhandle.write("\n") @@ -215,12 +238,15 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir( if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]): oscmd(f"cp {outputdir}/panda3d/{base} {destdir}{platlib}/panda3d/{base}") - WriteMimeFile(dest_prefix + "/share/mime-info/panda3d.mime", MIME_INFO) - WriteKeysFile(dest_prefix + "/share/mime-info/panda3d.keys", MIME_INFO) - WriteMimeXMLFile(dest_prefix + "/share/mime/packages/panda3d.xml", MIME_INFO) - WriteApplicationsFile(dest_prefix + "/share/application-registry/panda3d.applications", APP_INFO, MIME_INFO) + bindir = outputdir + "/bin" + WriteMimeFile(dest_prefix + "/share/mime-info/panda3d.mime", MIME_INFO, bindir) + WriteKeysFile(dest_prefix + "/share/mime-info/panda3d.keys", MIME_INFO, bindir) + WriteMimeXMLFile(dest_prefix + "/share/mime/packages/panda3d.xml", MIME_INFO, bindir) + WriteApplicationsFile(dest_prefix + "/share/application-registry/panda3d.applications", APP_INFO, MIME_INFO, bindir) if os.path.isfile(outputdir + "/bin/pview"): oscmd(f"cp makepanda/pview.desktop {dest_prefix}/share/applications/pview.desktop") + if os.path.isfile(outputdir + "/bin/pstats"): + oscmd(f"cp makepanda/pstats.desktop {dest_prefix}/share/applications/pstats.desktop") oscmd(f"cp doc/ReleaseNotes {dest_prefix}/share/panda3d/ReleaseNotes") @@ -326,5 +352,7 @@ if __name__ == "__main__": if not destdir: warn_prefix = "%sNote:%s " % (GetColor("red"), GetColor()) - print(warn_prefix + "You may need to call this command to update the library cache:") + print(warn_prefix + "You may need to call these commands to update system caches:") print(" sudo ldconfig") + print(" sudo update-desktop-database") + print(" sudo update-mime-database -n %s/share/mime" % (options.prefix)) diff --git a/makepanda/pstats.desktop b/makepanda/pstats.desktop new file mode 100644 index 0000000000..0f5b7e6d77 --- /dev/null +++ b/makepanda/pstats.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Name=Panda3D Stats Monitor +GenericName=Profiling Tool +Comment=Analyze performance of Panda3D applications +TryExec=pstats +Exec=pstats %f +StartupNotify=true +NoDisplay=false +Terminal=false +Type=Application +Categories=Utility;Development; +MimeType=application/vnd.panda3d.pstats;