Skip to content

Commit

Permalink
Use native notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
jenskutilek committed Mar 19, 2024
1 parent 80453aa commit 53e6d70
Showing 1 changed file with 180 additions and 51 deletions.
231 changes: 180 additions & 51 deletions Favourites.glyphsPlugin/Contents/Resources/plugin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
from pathlib import Path
from time import time
import objc
from AppKit import NSMenuItem, NSTimer
from GlyphsApp import Glyphs, WINDOW_MENU, DOCUMENTDIDCLOSE, DOCUMENTOPENED
from AppKit import (
NSApplicationDidBecomeActiveNotification,
NSApplicationWillResignActiveNotification,
NSMenuItem,
NSNotificationCenter,
NSTimer,
NSWindowDidBecomeMainNotification,
NSWindowDidResignMainNotification,
)
from GlyphsApp import (
Glyphs,
WINDOW_MENU,
DOCUMENTACTIVATED,
DOCUMENTDIDCLOSE,
DOCUMENTOPENED,
)
from GlyphsApp.plugins import GeneralPlugin

from glyphsFavourites import FavouritesUI, libkey
Expand All @@ -19,31 +33,33 @@ def start(self):
newMenuItem = NSMenuItem(self.name, self.showWindow_)
Glyphs.menu[WINDOW_MENU].append(newMenuItem)
self.window = None
self.launch_time = time()
self.launch_time = int(time())
self.became_active_time = self.launch_time
print(f"Glyphs launched at {self.became_active_time}")

# Initialize the time counter
for key in ("time_session", "time_total"):
for key in ("TimeSession", "TimeTotal"):
if Glyphs.defaults[libkey % key] is None:
Glyphs.defaults[libkey % key] = 0

# Add any time from last session to the total time
Glyphs.defaults[libkey % "time_total"] += Glyphs.defaults[
libkey % "time_session"
]
# print(f"Usage: {Glyphs.defaults[libkey % 'time_total']} minutes")
self.time_total = Glyphs.defaults[libkey % "time_total"]
Glyphs.defaults[libkey % "TimeTotal"] += Glyphs.defaults[libkey % "TimeSession"]
# print(f"Usage: {Glyphs.defaults[libkey % 'TimeTotal']} seconds")
self.time_total = Glyphs.defaults[libkey % "TimeTotal"]

# Record the session time every x seconds
self.timer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(
10.0, self, self.logTime_, None, True
)
# # Record the session time every x seconds
# self.timer = (
# NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(
# 10.0, self, self.logTime_, None, True
# )
# )

data = Glyphs.defaults[libkey % "data"]
data = Glyphs.defaults[libkey % "Data"]
self.data = {}
if data is not None:
for path, total, session in data:
self.data[path] = {"total": total + session, "session": 0}
# print("Loaded:", self.data)
print("Loaded:", self.data)
# Session data for opened files
# {path, open_time, session_time}
self.session = {}
Expand All @@ -60,7 +76,7 @@ def add_entry(self, path):
def save_data(self):
# print("save_data")
# print(self.data)
Glyphs.defaults[libkey % "data"] = [
Glyphs.defaults[libkey % "Data"] = [
(path, entry["total"], entry["session"])
for path, entry in self.data.items()
]
Expand All @@ -70,56 +86,162 @@ def showWindow_(self, sender):
Show the window
"""
if not self.hasNotification:
Glyphs.addCallback(self.docOpened, DOCUMENTOPENED)
Glyphs.addCallback(self.docClosed, DOCUMENTDIDCLOSE)
# Glyphs.addCallback(self.docActivated, DOCUMENTACTIVATED)
# Glyphs.addCallback(self.docOpened, DOCUMENTOPENED)
# Glyphs.addCallback(self.docClosed, DOCUMENTDIDCLOSE)

self.center = NSNotificationCenter.defaultCenter()
self.center.addObserver_selector_name_object_(
self,
objc.selector(self.docActivated_, signature=b"v@:"),
NSWindowDidBecomeMainNotification,
None,
)
self.center.addObserver_selector_name_object_(
self,
objc.selector(self.docDeactivated_, signature=b"v@:"),
NSWindowDidResignMainNotification,
None,
)
self.center.addObserver_selector_name_object_(
self,
objc.selector(self.appActivated_, signature=b"v@:"),
NSApplicationDidBecomeActiveNotification,
None,
)
self.center.addObserver_selector_name_object_(
self,
objc.selector(self.appDeactivated_, signature=b"v@:"),
NSApplicationWillResignActiveNotification,
None,
)
self.hasNotification = True
if self.window is None:
self.window = FavouritesUI(self)

def appActivated_(self, info):
self.became_active_time = int(time())
print(f"Glyphs became active at {self.became_active_time}")

def appDeactivated_(self, info):
# Save time in seconds
became_inactive_time = int(time())
print(f"Glyphs became inactive at {became_inactive_time}")
if self.became_active_time < self.launch_time:
print(
"Time of becoming active is before app launch time, something is wrong."
)
print(f"Launch {self.launch_time} vs. activation {self.became_active_time}")
return

session_time = became_inactive_time - self.became_active_time
Glyphs.defaults[libkey % "TimeSession"] += session_time
print(
f"Log session: +{session_time} (total session {Glyphs.defaults[libkey % 'TimeSession']}) seconds"
)

@objc.python_method
def docClosed(self, info):
obj = info.object() # GSDocument
if not hasattr(obj, "filePath"):
def getPath(self, info):
"""Extract the file path from the info object (GSWindow)
Returns:
str | None: The path if it could be extracted; otherwise None
"""
obj = info.object()
print(f"getPath: {obj}")
try:
doc = obj.windowController().glyphsDocument()
except: # noqa: E722
try:
doc = obj.windowController().document()
print(f"obj.windowController().document(): {doc}")
except: # noqa: E722
return

if not hasattr(doc, "filePath"):
return

path = obj.filePath
path = doc.filePath
if path not in self.data:
# File is not in favourites
return

return path

def docActivated_(self, info):
path = self.getPath(info)
if path is None:
return

print(f"docActivated_: {path}")
# We should watch this file
self.session[path] = int(time())
print(f"Resume watching {Path(path).name}.")
print(f" Session: {self.data[path]['session']}")
print(f" Total: {self.data[path]['total']}")

def docDeactivated_(self, info):
path = self.getPath(info)
if path is None:
return

print(f"docDectivated_: {path}")
if path not in self.session:
# This happended to me once, but why?
# The path shown started with "~/Documents/..."
print(f"ERROR: Path not found in current session: '{path}' in")
print(self.session)
return

# We should watch this file
session_time = int(time() - self.session[path]) // 60
active_time = int(time()) - self.session[path]
del self.session[path]
self.data[path]["session"] += session_time
print(
f"Closed {Path(path).name} after {session_time} minutes "
f"({self.data[path]['total']} minutes total so far)"
)
self.save_data()
self.data[path]["session"] += active_time
print(f"Deactivated {Path(path).name} after {active_time} seconds.")
print(f" Session: {self.data[path]['session']}")
print(f" Total: {self.data[path]['total']}")

@objc.python_method
def docOpened(self, info):
obj = info.object() # GSDocument
if not hasattr(obj, "filePath"):
return
# @objc.python_method
# def docClosed(self, info):
# obj = info.object() # GSDocument
# if not hasattr(obj, "filePath"):
# return

path = obj.filePath
if path not in self.data:
return
# path = obj.filePath
# if path not in self.data:
# # File is not in favourites
# return

# We should watch this file
self.session[path] = int(time())
print(
f"Start watching {Path(path).name} "
f"({self.data[path]['total']} minutes total so far)"
)
# if path not in self.session:
# # This happended to me once, but why?
# # The path shown started with "~/Documents/..."
# print(f"ERROR: Path not found in current session: '{path}' in")
# print(self.session)
# return

# # We should watch this file
# session_time = int(time() - self.session[path])
# del self.session[path]
# self.data[path]["session"] += session_time
# print(
# f"Closed {Path(path).name} after {session_time} seconds "
# f"({self.data[path]['total']} seconds total so far)"
# )
# self.save_data()

# @objc.python_method
# def docOpened(self, info):
# obj = info.object() # GSDocument
# if not hasattr(obj, "filePath"):
# return

# path = obj.filePath
# if path not in self.data:
# return

# # We should watch this file
# self.session[path] = int(time())
# print(
# f"Start watching {Path(path).name} "
# f"({self.data[path]['total']} seconds total so far)"
# )

@objc.python_method
def __del__(self):
Expand All @@ -128,11 +250,18 @@ def __del__(self):
Glyphs.removeCallback(self.docOpened)
self.hasNotification = False

def logTime_(self, info):
# Save time in minutes
session_time = int(time() - self.launch_time) // 60
Glyphs.defaults[libkey % "time_session"] = session_time
# print("Session:", Glyphs.defaults[libkey % "time_session"], "minutes")
def logTime_(self, info=None):
# Save time in seconds
if self.became_active_time < self.launch_time:
print(
"Time of becoming active is before app launch time, something is wrong."
)
print(f"Launch {self.launch_time} vs. activation {self.became_active_time}")
return

session_time = int(time() - self.became_active_time)
Glyphs.defaults[libkey % "TimeSession"] += session_time
print("Log session:", Glyphs.defaults[libkey % "TimeSession"], "seconds")

@objc.python_method
def __file__(self):
Expand Down

0 comments on commit 53e6d70

Please sign in to comment.