""".. versionadded:: 0.0.6
Control the macOS Stocks application using JXA-like syntax.
"""
from typing import Union
from AppKit import NSPredicate, NSMutableArray, NSURL
from PyXA import XABase
from PyXA import XABaseScriptable
from ..XAProtocols import XAClipboardCodable
[docs]
class XAStocksApplication(XABase.XAApplication):
"""A class for managing and interacting with Stocks.app.
.. seealso:: :class:`XAStocksSavedStock`
.. versionadded:: 0.0.6
"""
def __init__(self, properties):
super().__init__(properties)
@property
def sidebar_showing(self) -> bool:
"""Whether the sidebar is currently showing."""
sidebar = (
self.front_window.xa_elem.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[1]
.groups()[0]
.groups()[0]
.groups()[1]
)
return sidebar.get() is not None
[docs]
def show_symbol(self, ticker: str) -> "XAStocksApplication":
"""Displays the page for the specified ticker symbol.
:param ticker: The ticker symbol for the desired stock
:type ticker: str
:return: A reference to the application object
:rtype: XAStocksApplication
.. versionadded:: 0.0.6
"""
XABase.XAURL("stocks://?symbol=" + ticker).open()
[docs]
def go_back(self) -> "XAStocksApplication":
"""Clicks the 'back' button (from a new article when viewed in the Stocks app).
:return: A reference to the application object
:rtype: XAStocksApplication
.. versionadded:: 0.0.6
"""
self.front_window.toolbars()[0].buttons()[0].actions()[0].perform()
return self
[docs]
def show_business_news(self) -> "XAStocksApplication":
"""Shows the 'Business News' tab in the front stock window.
:return: A reference to the application object
:rtype: XAStocksApplication
.. versionadded:: 0.0.6
"""
self.front_window.groups().at(0).groups().at(0).groups().at(0).groups().at(
0
).groups().at(0).groups().at(0).groups().at(0).groups().at(1).groups().at(
0
).groups().at(
0
).groups().at(
0
).groups().at(
0
).groups().at(
0
).groups().at(
0
).groups().at(
0
).groups().at(
1
).groups().at(
0
).groups().at(
0
).groups().at(
1
).groups().at(
0
).ui_elements().at(
2
).buttons().at(
0
).actions()[
0
].perform()
[docs]
def new_tab(self):
"""Opens a new tab.
.. versionadded:: 0.0.6
"""
predicate = NSPredicate.predicateWithFormat_("name == %@", "AXPress")
press_action = (
self.front_window.xa_elem.tabGroups()[0]
.buttons()[0]
.actions()
.filteredArrayUsingPredicate_(predicate)[0]
)
press_action.perform()
[docs]
def saved_stocks(self) -> "XAStocksSavedStockList":
"""Gets a list of stocks.
:return: The list of stocks
:rtype: XAStocksStockList
.. versionadded:: 0.0.6
"""
stock_element_list = (
self.front_window.xa_elem.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[1]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[0]
.groups()[1]
.groups()[0]
.groups()[0]
.groups()[1]
.groups()[0]
.groups()
)
stocks = []
def add_stock(element, index, stop):
nonlocal stocks
groups = element.groups()
if len(groups) == 1:
stocks.append(groups[0].UIElements()[0])
stock_element_list.enumerateObjectsUsingBlock_(add_stock)
return self._new_element(
NSMutableArray.alloc().initWithArray_(stocks), XAStocksSavedStockList
)
[docs]
class XAStocksSavedStockList(XABase.XAList, XAClipboardCodable):
"""A wrapper around a list of stocks.
.. versionadded:: 0.0.6
"""
def __init__(self, properties: dict, filter: Union[dict, None] = None):
super().__init__(properties, XAStocksSavedStock, filter)
[docs]
def properties(self) -> list[str]:
return self.xa_elem.arrayByApplyingSelector_("properties")
[docs]
def name(self) -> list[str]:
return [x.name for x in self]
[docs]
def symbol(self) -> list[str]:
return [x.symbol for x in self]
[docs]
def price(self) -> list[str]:
return [x.price for x in self]
[docs]
def change(self) -> list[str]:
return [x.change for x in self]
[docs]
def selected(self) -> list[str]:
ls = self.xa_elem.arrayByApplyingSelector_("selected")
return [x.get() for x in ls]
[docs]
def get_clipboard_representation(self) -> list[Union[str, NSURL]]:
"""Gets a clipboard-codable representation of each stock in the list.
When the clipboard content is set to a list of saved stocks, each stocks's name, price, and stocks URI are added to the clipboard.
:return: Each stock's name, price, and stocks URI
:rtype: list[Union[str, NSURL]]
.. versionadded:: 0.0.8
"""
items = []
names = self.name()
prices = self.price()
symbols = self.symbol()
for index, name in enumerate(names):
items.append(name + " - " + str(prices[index]))
items.append(XABase.XAURL("stocks://?symbol=" + symbols[index]).xa_elem)
return items
def __repr__(self):
return "<" + str(type(self)) + str(self.object_description()) + ">"
[docs]
class XAStocksSavedStock(XABase.XAObject, XAClipboardCodable):
"""A class for interacting with stocks in Stocks.app.
.. versionadded:: 0.0.6
"""
def __init__(self, properties):
super().__init__(properties)
@property
def properties(self) -> dict:
"""All properties of the stock."""
return self.xa_elem.properties()
@property
def name(self) -> str:
"""The name of the stock (The company name)."""
reversed = self.xa_elem.objectDescription().get()[::-1]
return reversed[reversed.index(",") + 1 :][::-1]
@property
def symbol(self) -> str:
"""The symbol for the stock."""
return self.xa_elem.objectDescription().get().split(", ")[-1]
@property
def price(self) -> float:
"""The current price of the stock."""
value = self.xa_elem.value().get()
value = value.replace("selected, ", "")
return float(value.split(", ")[0].replace(",", ""))
@property
def change(self) -> str:
"""The percentage or point change of the stock in the current trading session."""
value = self.xa_elem.value().get()
return value.split(", ")[-1]
@property
def selected(self) -> bool:
"""Whether the stock is the currently selected stock."""
return self.xa_elem.selected().get()
[docs]
def show(self):
"""Shows the stock's tab in the front stock window.
.. versionadded:: 0.0.6
"""
self.xa_elem.actions()[0].perform()
[docs]
def get_clipboard_representation(self) -> list[Union[str, NSURL]]:
"""Gets a clipboard-codable representation of the stock.
When the clipboard content is set to a saved stock, the stocks's name, price, and stocks URI are added to the clipboard.
:return: The stock's name, price, and stocks URI
:rtype: list[Union[str, NSURL]]
.. versionadded:: 0.0.8
"""
return [
self.name + " - " + str(self.price),
XABase.XAURL("stocks://?symbol=" + self.symbol).xa_elem,
]