Source code for seamm.tk_publish

# -*- coding: utf-8 -*-

"""The GUI for publishing -- flowcharts for the moment."""

import collections.abc
import logging
import tkinter as tk
import tkinter.ttk as ttk

import Pmw

import seamm_util
import seamm_widgets as sw

logger = logging.getLogger(__name__)


[docs] class TkPublish(collections.abc.MutableMapping): def __init__(self, tk_flowchart): self.tk_flowchart = tk_flowchart self._widgets = {"parent": tk_flowchart.pw} # Provide dict like access to the widgets to make # the code cleaner def __getitem__(self, key): """Allow [] access to the widgets!""" return self._widgets[key] def __setitem__(self, key, value): """Allow x[key] access to the data""" self._widgets[key] = value def __delitem__(self, key): """Allow deletion of keys""" if key in self._widgets: self._widgets[key].destroy() del self._widgets[key] def __iter__(self): """Allow iteration over the object""" return iter(self._widgets) def __len__(self): """The len() command""" return len(self._widgets)
[docs] def create_dialog(self): """Create the dialog for publishing.""" if "dialog" in self: return toplevel = self["parent"].winfo_toplevel() self["dialog"] = d = Pmw.Dialog( toplevel, buttons=("Publish", "Cancel"), master=toplevel, title="Publish the flowchart", ) d.withdraw() frame = self["frame"] = d.interior() # P = self.parameters # for item in ("what", "destination"): # self[item] = P[item].widget(frame) w = self["what"] = sw.LabeledCombobox( frame, labeltext="Publish the", values=("flowchart",), state="readonly", ) w.set("flowchart") w = self["destination"] = sw.LabeledCombobox( frame, labeltext="to", values=("Zenodo", "Zenodo sandbox"), state="readonly", ) w.set("Zenodo") for item in ("what",): self[item].bind("<<ComboboxSelected>>", self.reset_dialog) self[item].bind("<Return>", self.reset_dialog) self[item].bind("<FocusOut>", self.reset_dialog) # Need the start node for editing the flowchart metadata start_node = self.tk_flowchart.get_node("1") self["flowchart metadata"] = start_node.create_frame(frame) self["doi"] = ttk.Label(frame, text="") self.reset_dialog()
[docs] def edit(self): """Present a dialog for editing the parameters.""" # Create the dialog if it doesn't exist self.create_dialog() # update the flowchart metadata start_node = self.tk_flowchart.get_node("1") start_node.update_widgets() self.reset_dialog() # And put it on-screen, the first time centered. result = self["dialog"].activate(geometry="centerscreenfirst") if result != "Publish": # Reset everything! start_node.cleanup_authors() else: # Handle the metadata first start_node.capture_metadata() start_node.cleanup_authors() # Capture the parameters from the widgets what = self["what"].get() destination = self["destination"].get() if what == "flowchart": if destination == "Zenodo": doi = self.publish_flowchart_to_zenodo() elif destination == "Zenodo sandbox": doi = self.publish_flowchart_to_zenodo(sandbox=True) else: raise RuntimeError(f"cannot handle destination '{destination}'") tk.messagebox.showinfo( master=self["parent"], title="Published", message=f"Published the {what} to {destination}\nDOI = {doi}", ) else: raise RuntimeError(f"cannot handle publishing '{what}'")
[docs] def reset_dialog(self): """Layout the widgets in the dialog according to the parameters.""" what = self["what"].get() # Temporary if what != "flowchart": what = "flowchart" self["what"].set(what) # Remove all the widgets frame = self["frame"] for slave in frame.grid_slaves(): slave.grid_forget() # and put them back in as needed. row = 0 self["what"].grid(row=row, column=0, sticky=tk.EW) row += 1 self["destination"].grid(row=row, column=0, sticky=tk.EW) row += 1 if what == "flowchart": self["flowchart metadata"].grid(row=row, column=0, sticky=tk.EW) row += 1 self["doi"].grid(row=row, column=0, sticky=tk.W) row += 1 metadata = self.tk_flowchart.flowchart.metadata if "doi" in metadata: self["doi"]["text"] = metadata["doi"] else: self["doi"]["text"] = "not published"
[docs] def publish_flowchart_to_zenodo(self, sandbox=False): """Publish the flowchart to Zenodo. Parameters ---------- sandbox : bool = False If true, publish to the Zenodo sandbox. Returns ------- str The DOI. """ flowchart = self.tk_flowchart.flowchart # Get check if the flowchart is fully released if sandbox: if flowchart.is_development: print("Publishing a dirty version to the Zenodo sandbox.") logger.warning("Publishing a dirty version to the Zenodo sandbox.") else: if flowchart.is_development: return None zenodo = seamm_util.Zenodo(use_sandbox=sandbox) # If this flowchart has an existing DOI, create a new version. metadata = flowchart.metadata if "doi" in metadata: _id = metadata["doi"].split("/zenodo.")[1] record = zenodo.add_version(_id) for filename in record.files(): record.remove_file(filename) else: record = zenodo.create_record() # Set up the metadata for Zenodo. record.upload_type = "other" record.creators = metadata["creators"] record.title = metadata["title"] record.description = metadata["description"] record.keywords = ["seamm-flowchart", *metadata["keywords"]] if "grants" in metadata: record.grants = [{"id": g} for g in metadata["grants"]] # Update the metadata at Zenodo record.update_metadata() # Update the metadata in the flowchart metadata["doi"] = record.doi conceptdoi = record.conceptdoi if conceptdoi is not None: metadata["conceptdoi"] = conceptdoi # Now we can add the flowchart to Zenodo with the correct DOI, etc. record.add_file("flowchart.flow", contents=flowchart.to_text()) # And, finally, can publish! record.publish() return record.doi