feat(mac): update enable disable start stop

This commit is contained in:
arkohut 2024-10-15 17:44:32 +08:00
parent d823d834b9
commit 417d45c846

View File

@ -164,12 +164,16 @@ def typsense_index_default_library(
print("Default library does not exist.") print("Default library does not exist.")
return return
typesense_index(default_library["id"], force=force, folders=None, batchsize=batchsize) typesense_index(
default_library["id"], force=force, folders=None, batchsize=batchsize
)
@app.command("reindex") @app.command("reindex")
def reindex_default_library( def reindex_default_library(
force: bool = typer.Option(False, "--force", help="Force recreate FTS and vector tables before reindexing") force: bool = typer.Option(
False, "--force", help="Force recreate FTS and vector tables before reindexing"
)
): ):
""" """
Reindex the default library for memos. Reindex the default library for memos.
@ -351,8 +355,6 @@ def generate_plist():
</array> </array>
<key>RunAtLoad</key> <key>RunAtLoad</key>
<true/> <true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key> <key>StandardOutPath</key>
<string>/tmp/memos.log</string> <string>/tmp/memos.log</string>
<key>StandardErrorPath</key> <key>StandardErrorPath</key>
@ -385,15 +387,12 @@ def is_service_loaded(service_name):
def load_plist(plist_path): def load_plist(plist_path):
user_domain = f"gui/{os.getuid()}"
service_name = "com.user.memos" service_name = "com.user.memos"
if is_service_loaded(service_name): if is_service_loaded(service_name):
subprocess.run( subprocess.run(["launchctl", "unload", str(plist_path)], check=False)
["launchctl", "bootout", user_domain, str(plist_path)], check=False
)
subprocess.run(["launchctl", "bootstrap", user_domain, str(plist_path)], check=True) subprocess.run(["launchctl", "load", str(plist_path)], check=True)
def is_macos(): def is_macos():
@ -405,9 +404,11 @@ def is_windows():
def remove_windows_autostart(): def remove_windows_autostart():
startup_folder = Path(os.getenv("APPDATA")) / r"Microsoft\Windows\Start Menu\Programs\Startup" startup_folder = (
Path(os.getenv("APPDATA")) / r"Microsoft\Windows\Start Menu\Programs\Startup"
)
shortcut_path = startup_folder / "Memos.lnk" shortcut_path = startup_folder / "Memos.lnk"
if shortcut_path.exists(): if shortcut_path.exists():
shortcut_path.unlink() shortcut_path.unlink()
return True return True
@ -419,25 +420,21 @@ def disable():
"""Disable memos from running at startup""" """Disable memos from running at startup"""
if is_windows(): if is_windows():
if remove_windows_autostart(): if remove_windows_autostart():
typer.echo("Removed Memos shortcut from startup folder. Memos will no longer run at startup.") typer.echo(
"Removed Memos shortcut from startup folder. Memos will no longer run at startup."
)
else: else:
typer.echo("Memos shortcut not found in startup folder. Memos is not set to run at startup.") typer.echo(
"Memos shortcut not found in startup folder. Memos is not set to run at startup."
)
elif is_macos(): elif is_macos():
plist_path = Path.home() / "Library/LaunchAgents/com.user.memos.plist" plist_path = Path.home() / "Library/LaunchAgents/com.user.memos.plist"
if plist_path.exists(): if plist_path.exists():
user_domain = f"gui/{os.getuid()}" subprocess.run(["launchctl", "unload", str(plist_path)], check=True)
service_name = "com.user.memos"
if is_service_loaded(service_name):
subprocess.run(
["launchctl", "bootout", user_domain, str(plist_path)], check=False
)
typer.echo("Unloaded Memos service.")
else:
typer.echo("Memos service was not running.")
plist_path.unlink() plist_path.unlink()
typer.echo("Removed plist file. Memos will no longer run at startup.") typer.echo(
"Unloaded and removed plist file. Memos will no longer run at startup."
)
else: else:
typer.echo("Plist file does not exist. Memos is not set to run at startup.") typer.echo("Plist file does not exist. Memos is not set to run at startup.")
else: else:
@ -446,7 +443,7 @@ def disable():
@app.command() @app.command()
def enable(): def enable():
"""Enable memos to run at startup""" """Enable memos to run at startup (without starting it immediately)"""
if not sys.executable: if not sys.executable:
typer.echo("Error: Unable to detect Python environment.") typer.echo("Error: Unable to detect Python environment.")
raise typer.Exit(code=1) raise typer.Exit(code=1)
@ -465,7 +462,9 @@ def enable():
plist_path = generate_plist() plist_path = generate_plist()
typer.echo(f"Generated plist file at {plist_path}") typer.echo(f"Generated plist file at {plist_path}")
load_plist(plist_path) load_plist(plist_path)
typer.echo("Loaded plist file. Memos will now run at startup.") typer.echo(
"Loaded plist file. Memos will run at next startup or when 'start' command is used."
)
else: else:
typer.echo("Unsupported operating system.") typer.echo("Unsupported operating system.")
@ -475,28 +474,31 @@ def ps():
"""Show the status of Memos processes""" """Show the status of Memos processes"""
services = ["serve", "watch", "record"] services = ["serve", "watch", "record"]
table_data = [] table_data = []
for service in services: for service in services:
processes = [p for p in psutil.process_iter(['pid', 'name', 'cmdline', 'create_time']) processes = [
if 'python' in p.info['name'].lower() and p
p.info['cmdline'] is not None and for p in psutil.process_iter(["pid", "name", "cmdline", "create_time"])
'memos.commands' in p.info['cmdline'] and if "python" in p.info["name"].lower()
service in p.info['cmdline']] and p.info["cmdline"] is not None
and "memos.commands" in p.info["cmdline"]
and service in p.info["cmdline"]
]
if processes: if processes:
for process in processes: for process in processes:
create_time = datetime.fromtimestamp(process.info['create_time']).strftime('%Y-%m-%d %H:%M:%S') create_time = datetime.fromtimestamp(
running_time = str(timedelta(seconds=int(time.time() - process.info['create_time']))) process.info["create_time"]
table_data.append([ ).strftime("%Y-%m-%d %H:%M:%S")
service, running_time = str(
"Running", timedelta(seconds=int(time.time() - process.info["create_time"]))
process.info['pid'], )
create_time, table_data.append(
running_time [service, "Running", process.info["pid"], create_time, running_time]
]) )
else: else:
table_data.append([service, "Not Running", "-", "-", "-"]) table_data.append([service, "Not Running", "-", "-", "-"])
headers = ["Name", "Status", "PID", "Started At", "Running For"] headers = ["Name", "Status", "PID", "Started At", "Running For"]
typer.echo(tabulate(table_data, headers=headers, tablefmt="plain")) typer.echo(tabulate(table_data, headers=headers, tablefmt="plain"))
@ -504,30 +506,51 @@ def ps():
@app.command() @app.command()
def stop(): def stop():
"""Stop all running Memos processes""" """Stop all running Memos processes"""
services = ["serve", "watch", "record"] if is_windows():
stopped = False services = ["serve", "watch", "record"]
stopped = False
for service in services: for service in services:
processes = [p for p in psutil.process_iter(['pid', 'name', 'cmdline']) processes = [
if 'python' in p.info['name'].lower() and p
p.info['cmdline'] is not None and for p in psutil.process_iter(["pid", "name", "cmdline"])
'memos.commands' in p.info['cmdline'] and if "python" in p.info["name"].lower()
service in p.info['cmdline']] and p.info["cmdline"] is not None
and "memos.commands" in p.info["cmdline"]
for process in processes: and service in p.info["cmdline"]
try: ]
os.kill(process.info['pid'], signal.SIGTERM)
typer.echo(f"Stopped {service} process (PID: {process.info['pid']})") for process in processes:
stopped = True try:
except ProcessLookupError: os.kill(process.info["pid"], signal.SIGTERM)
typer.echo(f"Process {service} (PID: {process.info['pid']}) not found") typer.echo(
except PermissionError: f"Stopped {service} process (PID: {process.info['pid']})"
typer.echo(f"Permission denied to stop {service} process (PID: {process.info['pid']})") )
stopped = True
except ProcessLookupError:
typer.echo(
f"Process {service} (PID: {process.info['pid']}) not found"
)
except PermissionError:
typer.echo(
f"Permission denied to stop {service} process (PID: {process.info['pid']})"
)
if not stopped:
typer.echo("No running Memos processes found")
else:
typer.echo("All Memos processes have been stopped")
elif is_macos():
service_name = "com.user.memos"
try:
subprocess.run(["launchctl", "stop", service_name], check=True)
typer.echo("Stopped Memos processes.")
except subprocess.CalledProcessError:
typer.echo("Failed to stop Memos processes. They may not be running.")
if not stopped:
typer.echo("No running Memos processes found")
else: else:
typer.echo("All Memos processes have been stopped") typer.echo("Unsupported operating system.")
@app.command() @app.command()
@ -540,25 +563,19 @@ def start():
if not bat_path.exists(): if not bat_path.exists():
typer.echo("Launch script not found. Please run 'memos enable' first.") typer.echo("Launch script not found. Please run 'memos enable' first.")
return return
try: try:
subprocess.Popen([str(bat_path)], shell=True, creationflags=subprocess.CREATE_NEW_CONSOLE) subprocess.Popen(
[str(bat_path)], shell=True, creationflags=subprocess.CREATE_NEW_CONSOLE
)
typer.echo("Started Memos processes. Check the logs for more information.") typer.echo("Started Memos processes. Check the logs for more information.")
except Exception as e: except Exception as e:
typer.echo(f"Failed to start Memos processes: {str(e)}") typer.echo(f"Failed to start Memos processes: {str(e)}")
elif is_macos(): elif is_macos():
launch_sh_path = memos_dir / "launch.sh" service_name = "com.user.memos"
if not launch_sh_path.exists(): subprocess.run(["launchctl", "start", service_name], check=True)
typer.echo("Launch script not found. Please run 'memos enable' first.") typer.echo("Started Memos processes.")
return
try:
subprocess.Popen(["bash", str(launch_sh_path)], start_new_session=True)
typer.echo("Started Memos processes. Check the logs for more information.")
except Exception as e:
typer.echo(f"Failed to start Memos processes: {str(e)}")
else: else:
typer.echo("Unsupported operating system.") typer.echo("Unsupported operating system.")
@ -570,4 +587,4 @@ def config():
if __name__ == "__main__": if __name__ == "__main__":
app() app()