9 changed files with 206 additions and 21 deletions
@ -0,0 +1,4 @@ |
|||||
|
from constants import Constants |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,36 @@ |
|||||
|
import json |
||||
|
import os |
||||
|
|
||||
|
from .logging import logger |
||||
|
from .constants import Constants |
||||
|
|
||||
|
|
||||
|
def load_storage(): |
||||
|
if os.path.exists(Constants.STORAGE): |
||||
|
logger.debug(f"Loading storage from {Constants.STORAGE}") |
||||
|
with open(Constants.STORAGE, "r") as f: |
||||
|
return json.load(f) |
||||
|
return {} |
||||
|
|
||||
|
|
||||
|
def save_storage(data): |
||||
|
with open(Constants.STORAGE, "w") as f: |
||||
|
json.dump(data, f) |
||||
|
|
||||
|
|
||||
|
def save_to_storage(key, value): |
||||
|
storage = load_storage() |
||||
|
storage[key] = value |
||||
|
save_storage(storage) |
||||
|
|
||||
|
|
||||
|
def load_from_storage(key): |
||||
|
storage = load_storage() |
||||
|
if key in storage: |
||||
|
return storage[key] |
||||
|
return {} |
||||
|
|
||||
|
|
||||
|
def clear_storage(): |
||||
|
if os.path.exists(Constants.STORAGE): |
||||
|
os.remove(Constants.STORAGE) |
@ -0,0 +1,17 @@ |
|||||
|
import os |
||||
|
|
||||
|
class Constants: |
||||
|
STORAGE = os.path.join(os.path.expanduser('~'), 'wf.json') |
||||
|
INBOX_ID = "13859f14-79ab-b758-7224-8dad0236f1e2" |
||||
|
TASKS_ID = "042d7e11-f613-856c-fb97-c0e6ee7ece05" |
||||
|
DIARY_ID = "01205285-f5b1-8026-0cfa-942f514e297e" |
||||
|
LIFE_IDS = { |
||||
|
"life": "f6f993a3-c696-c070-296e-6e5055fc834f", |
||||
|
"admin": "d3911123-138e-8eb3-f2ba-2495d8169660", |
||||
|
"art": "c2e9f4b2-59ce-d127-4da6-949e54ec1442", |
||||
|
"health": "4fc929b8-f04b-0dde-9a1a-9d889a13316d", |
||||
|
"mind": "c6db70a1-72e3-dbcc-f4b9-bfb10a1b4280", |
||||
|
"social": "60e3d667-eb40-3d26-cc3f-6b151cc5efa4", |
||||
|
"church": "5c68fad5-ad2b-8018-6535-b1462aed1277", |
||||
|
"work": "4c4970fc-9023-f861-1392-dbf88dd89187", |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
import json |
||||
|
import os |
||||
|
import uuid |
||||
|
from datetime import datetime, timedelta |
||||
|
from constants import Constants |
||||
|
from logging import logger |
||||
|
|
||||
|
|
||||
|
def get_ordinal(n): |
||||
|
if 10 <= n % 100 <= 20: |
||||
|
suffix = 'th' |
||||
|
else: |
||||
|
suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, 'th') |
||||
|
return str(n) + suffix |
||||
|
|
||||
|
|
||||
|
def get_today(): |
||||
|
now = datetime.now() |
||||
|
return now.strftime("%a, %b %d, %Y") |
||||
|
|
||||
|
|
||||
|
def get_sunday(): |
||||
|
now = datetime.now() |
||||
|
sunday = now - timedelta(days=now.weekday()) - timedelta(days=1) |
||||
|
return sunday.strftime("%a, %b %d, %Y") |
||||
|
|
||||
|
|
||||
|
def generate_uuid(): |
||||
|
return str(uuid.uuid4()) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,36 @@ |
|||||
|
from rich.theme import Theme |
||||
|
|
||||
|
solarized_theme = Theme({ |
||||
|
"base03": "bright_black", |
||||
|
"base02": "black", |
||||
|
"base01": "bright_green", |
||||
|
"base00": "bright_yellow", |
||||
|
"base0": "bright_blue", |
||||
|
"base1": "bright_cyan", |
||||
|
"base2": "white", |
||||
|
"base3": "bright_white", |
||||
|
"orange": "bright_red", |
||||
|
"violet": "bright_magenta", |
||||
|
"red": "red", |
||||
|
"bold red": "bold red", |
||||
|
"underline base03": "underline bright_black", |
||||
|
"underline base02": "underline black", |
||||
|
"underline base01": "underline bright_green", |
||||
|
"underline base00": "underline bright_yellow", |
||||
|
"underline base0": "underline bright_blue", |
||||
|
"underline base1": "underline bright_cyan", |
||||
|
"underline base2": "underline white", |
||||
|
"underline base3": "underline bright_white", |
||||
|
"underline orange": "bright_red underline", |
||||
|
"underline violet": "bright_magenta underline", |
||||
|
"bold base03": "bold bright_black", |
||||
|
"bold base02": "bold black", |
||||
|
"bold base01": "bold bright_green", |
||||
|
"bold base00": "bold bright_yellow", |
||||
|
"bold base0": "bold bright_blue", |
||||
|
"bold base1": "bold bright_cyan", |
||||
|
"bold base2": "bold white", |
||||
|
"bold base3": "bold bright_white", |
||||
|
"bold orange": "bright_red bold", |
||||
|
"bold violet": "bright_magenta bold", |
||||
|
}) |
@ -0,0 +1,9 @@ |
|||||
|
import logging |
||||
|
from rich.console import Console |
||||
|
from rich.logging import RichHandler |
||||
|
from theme import solarized_theme |
||||
|
|
||||
|
console = Console(highlight=False, theme=solarized_theme) |
||||
|
logging.basicConfig(handlers=[RichHandler(level="NOTSET", console=console)]) |
||||
|
logger = logging.getLogger('rich') |
||||
|
logger.setLevel(logging.INFO) |
@ -0,0 +1,70 @@ |
|||||
|
# main.py |
||||
|
|
||||
|
import os |
||||
|
import json |
||||
|
import requests |
||||
|
import browser_cookie3 |
||||
|
|
||||
|
from .console import console, logger |
||||
|
|
||||
|
class WF: |
||||
|
|
||||
|
def __init__(self): |
||||
|
self._data = {} |
||||
|
self._path = None |
||||
|
|
||||
|
@property |
||||
|
def _cookie(self): |
||||
|
return self._data.get('cookie', None) |
||||
|
|
||||
|
def _load(self): |
||||
|
if os.path.exists(self.path): |
||||
|
logger.info(f'Loading data from {self.path}') |
||||
|
with open(self.path, 'r') as f: |
||||
|
self._data = json.load(f) |
||||
|
else: |
||||
|
logger.warning(f'No data found at {self.path}') |
||||
|
self._data = {} |
||||
|
|
||||
|
def _save(self): |
||||
|
logger.info(f'Saving data to {self.path}') |
||||
|
with open(self.path, 'w') as f: |
||||
|
json.dump(self._data, f) |
||||
|
|
||||
|
def _refresh_cookie(self): |
||||
|
logger.info('Refreshing cookies') |
||||
|
cookies = browser_cookie3.chrome() |
||||
|
for cookie in cookies: |
||||
|
if cookie.name == "sessionid" and "workflowy.com" in cookie.domain: |
||||
|
self._data['cookie'] = cookie.value |
||||
|
break |
||||
|
logger.warning('No cookie found') |
||||
|
|
||||
|
def _refresh_data(self): |
||||
|
if not self._cookie: |
||||
|
logger.warning('No cookie found') |
||||
|
return |
||||
|
logger.info('Refreshing data') |
||||
|
|
||||
|
url = "https://workflowy.com/get_initialization_data?client_version=15" |
||||
|
headers = {"Cookie": f"sessionid={self._cookie}"} |
||||
|
response = requests.get(url, headers=headers) |
||||
|
|
||||
|
if response.status_code == 200: |
||||
|
data = response.json() |
||||
|
data_globals = {item[0]: item[1] for item in data["globals"]} |
||||
|
|
||||
|
self._data["userid"] = data_globals["USER_ID"] |
||||
|
self._data["joined"] = data["projectTreeData"]["mainProjectTreeInfo"]["dateJoinedTimestampInSeconds"] |
||||
|
self._data["transid"] = data["projectTreeData"]["mainProjectTreeInfo"]["initialMostRecentOperationTransactionId"] |
||||
|
self._data["pollid"] = generate_uuid() # Simulate g() + g() |
||||
|
storage["root"] = {"nm": "root", "ch": data["projectTreeData"]["mainProjectTreeInfo"]["rootProjectChildren"]} |
||||
|
save_storage(storage) |
||||
|
console.log("Successfully refreshed and saved Workflowy data.") |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue