class FileUploadField(Group): def __init__(self, dimensions, storage=NullStorage()): self.storage = storage super(FileUploadField, self).__init__(dimensions) self.choose_file_button = Button((0, 3, 100, 17), "Choose File", sizeStyle="small", callback=self.choose_file) self.remove_file_button = Button((-60, 3, 60, 17), "Remove", sizeStyle="small", callback=self.remove_file) self.filepath_label = TextBox((18, 3, -70, 20), "") self.filepath_button = ImageButton((0, 3, -70, 20), "", callback=self.reveal_file) self.filepath_button.getNSButton().setTransparent_(True) self.filetype_image = ImageView((0, 4, 16, 16)) self.filepath = self.storage.retrieve() def choose_file(self, sender): filepath = getFile("Choose a .txt or .pdf document to use as a license", "Select License", fileTypes=("txt", "md", "pdf")) if filepath is not None: self.storage.store(filepath[0]) self.filepath = filepath[0] def remove_file(self, sender): self.storage.store(None) self.filepath = None def reveal_file(self, sender): workspace = NSWorkspace.sharedWorkspace() workspace.selectFile_inFileViewerRootedAtPath_(self.filepath, os.path.dirname(self.filepath)) @property def filename(self): if self.filepath is not None: return os.path.basename(self.filepath) else: return "" @property def filepath(self): return self._filepath @filepath.setter def filepath(self, value): self._filepath = value selected = value is not None and value is not '' icon = NSWorkspace.sharedWorkspace().iconForFile_(self._filepath) self.choose_file_button.show(not selected) self.remove_file_button.show(selected) self.filepath_label.show(selected) self.filepath_label.set(self.filename) self.filepath_button.show(selected) self.filetype_image.show(selected) self.filetype_image.setImage(imageObject=icon)
class FileUploadField(Group): def __init__(self, dimensions, storage=NullStorage()): self.storage = storage super(FileUploadField, self).__init__(dimensions) self.choose_file_button = Button((0, 3, 100, 17), "Choose File", sizeStyle="small", callback=self.choose_file) self.remove_file_button = Button((-60, 3, 60, 17), "Remove", sizeStyle="small", callback=self.remove_file) self.filepath_label = TextBox((18, 3, -70, 20), "") self.filepath_button = ImageButton((0, 3, -70, 20), "", callback=self.reveal_file) self.filepath_button.getNSButton().setTransparent_(True) self.filetype_image = ImageView((0, 4, 16, 16)) self.filepath = self.storage.retrieve() def choose_file(self, sender): filepath = getFile("Choose a .txt or .pdf document to use as a license", "Select License", fileTypes=("txt", "md", "pdf")) if filepath is not None: self.storage.store(filepath[0]) self.filepath = filepath[0] def remove_file(self, sender): self.storage.store(None) self.filepath = None def reveal_file(self, sender): workspace = NSWorkspace.sharedWorkspace() workspace.selectFile_inFileViewerRootedAtPath_(self.filepath, os.path.dirname(self.filepath)) @property def filename(self): if self.filepath is not None: return os.path.basename(self.filepath) else: return "" @property def filepath(self): return self._filepath @filepath.setter def filepath(self, value): self._filepath = value selected = value is not None and value is not '' icon = NSWorkspace.sharedWorkspace().iconForFile_(self._filepath) self.choose_file_button.show(not selected) self.remove_file_button.show(selected) self.filepath_label.show(selected) self.filepath_label.set(WhiteText(self.filename)) self.filepath_button.show(selected) self.filetype_image.show(selected) self.filetype_image.setImage(imageObject=icon)
class ApplicantList(Group): def __init__(self, dimensions, font, applicants, recipients, after_approve=None): super(ApplicantList, self).__init__(dimensions) _, _, width, height = self.getPosSize() self.recipients = recipients self.applicants = applicants self.font = font self.after_approve = after_approve self.border = DashedRectangle((0, 0, width, height)) self.activate_registry_button = CenteredButton(width, height, 190, 24, "Activate Registration Page", callback=self.activate) self.label = TextBox((0, 0, -0, 22), "Applicants") self.list = List((0, 23, 0, -34), applicants) self.approve_applicant_button = Button((0, -24, 90, 24), "Approve", callback=self.approve_applicant) self.open_registration_page_button = Button((-150, -20, 150, 17), "Open Registration Page", callback=self.open_registration_page, sizeStyle="small") self.activated = font.lib.has_key('pm.ghostlines.ghostlines.registry_token') def open_registration_page(self, *args): response = Ghostlines('v0.1').registry(self.font.lib['pm.ghostlines.ghostlines.registry_token']) registry = response.json() webbrowser.open(registry['url']) def approve_applicant(self, *args): selected_applicants = [self.list[i] for i in self.list.getSelection()] for applicant in selected_applicants: Ghostlines('v0.1').approve(self.font.lib['pm.ghostlines.ghostlines.registry_token'], applicant) self.after_approve(applicant) self.fetch() def activate(self, *args): response = Ghostlines('v0.1').enable_applicants({ 'font_name': self.font.info.familyName, 'designer': self.font.info.designer }) registry = response.json() self.font.lib['pm.ghostlines.ghostlines.registry_token'] = registry['token'] self.activated = True def fetch(self): if self.font.lib.has_key('pm.ghostlines.ghostlines.registry_token'): response = Ghostlines('v0.1').registry(self.font.lib['pm.ghostlines.ghostlines.registry_token']) registry = response.json() applicant_emails = [r['email_address'] for r in registry['applicants'] if not r['approved_at']] self.list.set(applicant_emails) @property def activated(self): return self._activated @activated.setter def activated(self, value): self._activated = value self.label.show(value) self.list.show(value) self.approve_applicant_button.show(value) self.border.show(not value) self.activate_registry_button.show(not value) self.open_registration_page_button.show(value) return self.activated
class UpdatesTab(BaseTab, ThreadedObject): title = "Updates" image = "toolbarScriptReload" identifier = "updates" def setup(self): self.list = UpdateList((20, 20, -20, -60), editCallback=self.update_interface, refreshCallback=self.update_interface) self.updated_at_text = UpdatedTimeTextBox((120, -38, -20, 20), sizeStyle="small") self.update_button = UpdateButton((-160, -42, 140, 20), callback=self.in_thread.install_updates) self.refresh_button = Button((20, -42, 90, 20), "Refresh", callback=self.in_thread.update_list) if env.environment == 'production': self.refresh_button.show(False) self.update_interface() def activate(self): self.set_default_button(self.update_button) self.in_thread.update_list() @progress.each('installable') @progress.tick('repositoryWillDownload', 'Downloading {repository.repo}') @progress.tick('extensionWillInstall', 'Installing {extension.bundle.name}') def install_updates(self, sender=None): for extension in self.installable: extension.update() self.update_list(force=True) def update_list(self, force=False): if self.list.is_refreshing: return None try: self.update_progress = Overlay("Checking for updates...", (20, 20, -20, -60), opacity=0.6, offset=90) self.refresh_button.enable(False) self.list.refresh(force=force) self.enable() except UpdateList.ConnectionError: self.disable("Couldn't connect to the internet...") finally: del self.update_progress self.refresh_button.enable(True) def update_interface(self, sender=None): self.updated_at_text.update() self.update_button.update(len(self.list.selected)) def disable(self, *args, **kwargs): self.list.enable(False) super(UpdatesTab, self).disable(*args, **kwargs) def enable(self, *args, **kwargs): self.list.enable(True) super(UpdatesTab, self).enable(*args, **kwargs) @property def installable(self): return self.list.selected
class ApplicantList(Group): columns = [{ "title": "Name", "key": "name", "editable": False }, { "title": "Email Address", "key": "email_address", "editable": False }] def __init__(self, dimensions, applicant_roster, font_family_id, after_approve=None): super(ApplicantList, self).__init__(dimensions) _, _, width, height = self.getPosSize() self.applicant_roster = applicant_roster self.family_id = font_family_id self.after_approve = after_approve self.border = DashedRectangle((0, 0, width, height)) self.enable_registry_button = CenteredButton(width, height, 190, 24, "Create Application Form", callback=self.enable) self.label = TextBox((0, 0, -0, 22), "Applicants", sizeStyle="small") self.list = List((0, 23, 0, -34), [], columnDescriptions=self.columns) self.approve_applicant_button = Button((0, -24, 90, 24), "Approve", callback=self.approve_applicant) self.open_registration_page_button = Button( (-150, -20, 150, 17), "Open Application Form", callback=self.open_registration_page, sizeStyle="small") self.enabled = self.applicant_roster is not None def open_registration_page(self, *args): webbrowser.open(self.applicant_roster['url']) def approve_applicant(self, *args): selected_applicants = [self.list[i] for i in self.list.getSelection()] for applicant in selected_applicants: token = AppStorage("accessToken").retrieve() Ghostlines('v1', token=token).approve_applicant(applicant["id"]) self.after_approve() self.fetch() def enable(self, *args): token = AppStorage("accessToken").retrieve() response = Ghostlines('v1', token=token).enable_applicants_v1(self.family_id) json = response.json() if response.status_code == 201: self.applicant_roster = json self.enabled = True else: ErrorMessage("Could not enable applicants", json["errors"]).open() def fetch(self): if self.enabled: token = AppStorage("accessToken").retrieve() response = Ghostlines('v1', token=token).applicant_roster(self.family_id) self.applicant_roster = response.json() self.set(self.applicant_roster["applicants"]) def set(self, applicants): unapproved = [a for a in applicants if a["approved_at"] is None] self.list.set(unapproved) @property def enabled(self): return self._enabled @enabled.setter def enabled(self, value): self._enabled = value self.label.show(value) self.list.show(value) self.approve_applicant_button.show(value) self.border.show(not value) self.enable_registry_button.show(not value) self.open_registration_page_button.show(value) return self.enabled
class ApplicantList(Group): def __init__(self, dimensions, font, applicants, recipients, after_approve=None): super(ApplicantList, self).__init__(dimensions) _, _, width, height = self.getPosSize() self.recipients = recipients self.applicants = applicants self.font = font self.after_approve = after_approve self.border = DashedRectangle((0, 0, width, height)) self.activate_registry_button = CenteredButton( width, height, 190, 24, "Create Application Form", callback=self.activate) self.label = TextBox((0, 0, -0, 22), "Applicants") self.list = List((0, 23, 0, -34), applicants) self.approve_applicant_button = Button((0, -24, 90, 24), "Approve", callback=self.approve_applicant) self.open_registration_page_button = Button( (-150, -20, 150, 17), "Open Application Form", callback=self.open_registration_page, sizeStyle="small") self.activated = font.lib.has_key( 'pm.ghostlines.ghostlines.registry_token') def open_registration_page(self, *args): response = Ghostlines('v0.1').registry( self.font.lib['pm.ghostlines.ghostlines.registry_token']) registry = response.json() webbrowser.open(registry['url']) def approve_applicant(self, *args): selected_applicants = [self.list[i] for i in self.list.getSelection()] for applicant in selected_applicants: Ghostlines('v0.1').approve( self.font.lib['pm.ghostlines.ghostlines.registry_token'], applicant) self.after_approve(applicant) self.fetch() def activate(self, *args): response = Ghostlines('v0.1').enable_applicants({ 'font_name': self.font.info.familyName, 'designer': self.font.info.openTypeNameDesigner }) registry = response.json() self.font.lib['pm.ghostlines.ghostlines.registry_token'] = registry[ 'token'] self.activated = True def fetch(self): if self.font.lib.has_key('pm.ghostlines.ghostlines.registry_token'): response = Ghostlines('v0.1').registry( self.font.lib['pm.ghostlines.ghostlines.registry_token']) registry = response.json() applicant_emails = [ r['email_address'] for r in registry['applicants'] if not r['approved_at'] ] self.list.set(applicant_emails) @property def activated(self): return self._activated @activated.setter def activated(self, value): self._activated = value self.label.show(value) self.list.show(value) self.approve_applicant_button.show(value) self.border.show(not value) self.activate_registry_button.show(not value) self.open_registration_page_button.show(value) return self.activated
class UpdatesTab(BaseTab, ThreadedObject): title = "Updates" image = "toolbarScriptReload" identifier = "updates" max_tab_size = (500, 10000) def setup(self): self.list = UpdateList((20, 20, -20, -60), editCallback=self.update_interface, refreshCallback=self.update_interface) self.updated_at_text = UpdatedTimeTextBox((120, -38, -20, 20), sizeStyle="small") self.update_button = UpdateButton( (-160, -42, 140, 20), callback=self.in_thread.install_updates) self.refresh_button = Button((20, -42, 90, 20), "Refresh", callback=self.in_thread.update_list) if env.environment == 'production': self.refresh_button.show(False) self.update_interface() def activate(self): self.set_default_button(self.update_button) self.in_thread.update_list() @progress.each('installable') @progress.tick('repositoryWillDownload', 'Downloading {repository.repo}') @progress.tick('extensionWillInstall', 'Installing {extension.bundle.name}') def install_updates(self, sender=None): for extension in self.installable: extension.update() self.update_list(force=True) def update_list(self, force=False): if self.list.is_refreshing: return None try: self.update_progress = Overlay("Checking for updates...", (20, 20, -20, -60), opacity=0.6, offset=90) self.refresh_button.enable(False) self.list.refresh(force=force) self.enable() except UpdateList.ConnectionError: self.disable("Couldn't connect to the internet...") finally: del self.update_progress self.refresh_button.enable(True) def update_interface(self, sender=None): self.updated_at_text.update() self.update_button.update(len(self.list.selected)) def disable(self, *args, **kwargs): self.list.enable(False) super(UpdatesTab, self).disable(*args, **kwargs) def enable(self, *args, **kwargs): self.list.enable(True) super(UpdatesTab, self).enable(*args, **kwargs) @property def installable(self): return self.list.selected