Source code for afwf.item

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

"""
Alfred Workflow Script Filter Item module.
"""

import typing as T

import attrs
from attrs import validators as vs
from attrs_mate import AttrsClass
from .vendor.better_enum import BetterStrEnum

from .script_filter_object import ScriptFilterObject


[docs]@attrs.define class Icon(ScriptFilterObject): """ represent an icon object in script filter item. Reference: - Search ``icon : OBJECT (optional)`` in https://www.alfredapp.com/help/workflows/inputs/script-filter/json/ """
[docs] class TypeEnum(BetterStrEnum): fileicon = "fileicon" filetype = "filetype"
# fmt: off path: str = AttrsClass.ib_str() type: str = attrs.field(validator=vs.optional(vs.in_(TypeEnum.get_values())), default=None) # fmt: on
[docs] @classmethod def from_image_file(cls, path: str) -> "Icon": """ Create an Icon object that using a file on local file system as an icon. """ return cls(path=path)
[docs]class VarKeyEnum(BetterStrEnum): """ List of available variable keys in this framework. """ open_file = "open_file" open_file_path = "open_file_path" launch_app_or_file = "launch_app_or_file" launch_app_or_file_path = "launch_app_or_file_path" reveal_file_in_finder = "reveal_file_in_finder" reveal_file_in_finder_path = "reveal_file_in_finder_path" browse_in_terminal = "browse_in_terminal" browse_in_terminal_path = "browse_in_terminal_path" browse_in_alfred = "browse_in_alfred" browse_in_alfred_path = "browse_in_alfred_path" action_in_alfred = "action_in_alfred" file_buffer = "file_buffer" default_web_search = "default_web_search" open_url = "open_url" open_url_arg = "open_url_arg" system_command = "system_command" itunes_command = "itunes_command" run_script = "run_script" run_script_arg = "run_script_arg" run_ns_apple_script = "run_ns_apple_script" run_ns_apple_script_arg = "run_ns_apple_script_arg" terminal_command = "terminal_command" terminal_command_arg = "terminal_command_arg" send_notification = "send_notification" send_notification_title = "send_notification_title" send_notification_subtitle = "send_notification_subtitle" _open_log_file = "_open_log_file" _open_log_file_path = "_open_log_file_path"
[docs]class VarValueEnum(BetterStrEnum): """ List of available variable values in this framework. """ y = "y" n = "n"
[docs]@attrs.define class Text(ScriptFilterObject): """ Represent a text object in script filter item. Reference: - Search ``text : OBJECT (optional)`` in https://www.alfredapp.com/help/workflows/inputs/script-filter/json/ """ copy: str = AttrsClass.ib_str(default=None) largetype: str = AttrsClass.ib_str(default=None)
[docs]class ModEnum(BetterStrEnum): """ List of available modifier keys. Hit enter with the modifier key can lead to different behavior. Reference: - Search ``mods : OBJECT (optional)`` in https://www.alfredapp.com/help/workflows/inputs/script-filter/json/ """ cmd = "cmd" shift = "shift" alt = "alt" ctrl = "ctrl" fn = "fn" cmd_alt = "cmd+alt" cmd_ctrl = "cmd+ctrl" cmd_shift = "cmd+shift"
T_ITEM_ACTION = T.Union[str, T.List[str], T.Dict[str, T.Any]]
[docs]@attrs.define class Item(ScriptFilterObject): """ Data model for alfred dropdown menu items. .. note:: Please make sure the attribute name is exactly the same as the field name in the following document. Ref: https://www.alfredapp.com/help/workflows/inputs/script-filter/json/ """
[docs] class TypeEnum(BetterStrEnum): file = "file" file_skipcheck = "file:skipcheck"
# fmt: off title: str = AttrsClass.ib_str() subtitle: str = AttrsClass.ib_str(default=None) arg: str = AttrsClass.ib_str(default=None) autocomplete: str = AttrsClass.ib_str(default=None) icon: Icon = Icon.ib_nested(default=None) valid: bool = AttrsClass.ib_bool(default=True) uid: str = AttrsClass.ib_str(default=None) match: str = AttrsClass.ib_str(default=None) type: str = attrs.field(validator=vs.optional(vs.in_(TypeEnum.get_values())), default=None) mods: dict = AttrsClass.ib_dict(default=None) action: T_ITEM_ACTION = attrs.field(default=None) text: Text = Text.ib_nested(default=None) quicklookurl: str = AttrsClass.ib_str(default=None) variables: dict = AttrsClass.ib_dict(factory=dict) # fmt: on # -------------------------------------------------------------------------- # Set attribute value # --------------------------------------------------------------------------
[docs] def set_icon(self, path: str) -> "Item": """ Set icon for item. """ self.icon = Icon.from_image_file(path) return self
[docs] def set_modifier( self, mod: str = ModEnum.cmd.value, subtitle: subtitle = None, arg: str = None, valid: bool = True, ) -> "Item": """ Add modifier to item. Modifier allow you to return different title, subtitle and argument in Alfred drop down menu item when you hit a modifier key. :param mode: the modifier key :param subtitle: the subtitle you want to display :param arg: the argument passed to subsequence action :param valid: whether the item is valid """ if mod not in ModEnum.get_values(): raise ValueError dct = { k: v for k, v in dict( subtitle=subtitle, arg=arg, valid=valid, ).items() if v } if self.mods is None: self.mods = dict() self.mods[mod] = dct return self
# -------------------------------------------------------------------------- # Set variables # -------------------------------------------------------------------------- def _open_log_file(self, path: str) -> "Item": # pragma: no cover """ This is a special variable that will open the last error file in the editor. It is for internal implementation only, not for public API. """ self.variables[VarKeyEnum._open_log_file.value] = VarValueEnum.y.value self.variables[VarKeyEnum._open_log_file_path.value] = path return self
[docs] def open_file(self, path: str) -> "Item": """ Set variables to tell subsequence Alfred action to open a file. Use the "Utilities -> Conditional" widget and set: if ``{var:open_file}`` is equal to "y". Use the "Actions -> Open File" widget and set: File: ``{var:open_file_path}`` :param path: the absolute path of the file to open """ self.variables[VarKeyEnum.open_file.value] = VarValueEnum.y.value self.variables[VarKeyEnum.open_file_path.value] = path return self
[docs] def launch_app_or_file(self, path: str) -> "Item": """ Set variables to tell subsequence Alfred action to launch an app or file. Use the "Utilities -> Conditional" widget and set: if ``{var:launch_app_or_file}`` is equal to "y". Use the "Actions -> Launch Apps / Files" widget. :param path: the absolute path of the file or app to launch """ self.variables[VarKeyEnum.launch_app_or_file.value] = VarValueEnum.y.value self.variables[VarKeyEnum.launch_app_or_file_path.value] = path return self
[docs] def reveal_file_in_finder(self, path: str) -> "Item": """ Set variables to tell subsequence Alfred action to launch an app or file. Use the "Utilities -> Conditional" widget and set: if ``{var:reveal_file_in_finder}`` is equal to "y". Use the "Actions -> Reveal File in Finder" widget. :param path: the absolute path of the file to reveal in Finder """ self.variables[VarKeyEnum.reveal_file_in_finder.value] = VarValueEnum.y.value self.variables[VarKeyEnum.reveal_file_in_finder_path.value] = path return self
[docs] def browse_in_terminal(self, path: str) -> "Item": """ Set variables to tell subsequence Alfred action to browse in terminal. Use the "Utilities -> Conditional" widget and set: if ``{var:browse_in_terminal}`` is equal to "y". Use the "Actions -> Browse in Terminal" widget. """ self.variables[VarKeyEnum.browse_in_terminal.value] = VarValueEnum.y.value self.variables[VarKeyEnum.browse_in_terminal_path.value] = path return self
[docs] def browse_in_alfred(self, path: str) -> "Item": """ Set variables to tell subsequence Alfred action to browse in Alfred. Use the "Utilities -> Conditional" widget and set: if ``{var:browse_in_alfred}`` is equal to "y". Use the "Actions -> Browse in Alfred" widget. """ self.variables[VarKeyEnum.browse_in_alfred.value] = VarValueEnum.y.value self.variables[VarKeyEnum.browse_in_alfred_path.value] = path return self
[docs] def open_url(self, url: str) -> "Item": """ Set variables to tell subsequence Alfred action to open url. Use the "Utilities -> Conditional" widget and set: if ``{var:open_url}`` is equal to "y". Use the "Actions -> Open URL" widget and set: - File = ``{var:open_url_arg}`` :param url: the url to open in browser """ self.variables[VarKeyEnum.open_url.value] = VarValueEnum.y.value self.variables[VarKeyEnum.open_url_arg.value] = url return self
[docs] def run_script(self, cmd: str) -> "Item": """ Set variables to tell subsequence Alfred action to run script. Use the "Utilities -> Conditional" widget and set: if ``{var:run_script}`` is equal to "y". Use the "Actions -> Run Script" widget and set: - Language = ``/bin/bash`` - "with input as {query}" - running instances = "Sequentially" - Script = ``{query}`` :param cmd: the full command to run, for example ``python3 /path/to/test.py`` """ self.variables[VarKeyEnum.run_script.value] = VarValueEnum.y.value self.variables[VarKeyEnum.run_script_arg.value] = cmd self.arg = cmd return self
[docs] def terminal_command(self, cmd: str) -> "Item": """ Use the "Utilities -> Conditional" widget and set: if ``{var:terminal_command}`` is equal to "y". Use the "Actions -> Terminal Command" widget and set: - Command = ``{query}`` :param cmd: the full command to run in terminal, for example ``python3 /path/to/test.py`` """ self.variables[VarKeyEnum.terminal_command.value] = VarValueEnum.y.value self.variables[VarKeyEnum.terminal_command_arg.value] = cmd self.arg = cmd return self
[docs] def send_notification(self, title: str, subtitle: str = "") -> "Item": """ Set variables to tell subsequence Alfred action to send notification. Use the "Utilities -> Conditional" widget and set: if ``{var:send_notification}`` is equal to "y". Use the "Outputs -> Post Notification" widget and set: - Title = ``{var:send_notification_title}`` - Subtitle = ``{var:send_notification_subtitle}`` :param title: the title of the notification :param subtitle: the subtitle of the notification """ self.variables[VarKeyEnum.send_notification.value] = VarValueEnum.y.value self.variables[VarKeyEnum.send_notification_title.value] = title self.variables[VarKeyEnum.send_notification_subtitle.value] = subtitle return self