mirror of
https://github.com/tcsenpai/pensieve.git
synced 2025-06-06 19:25:24 +00:00
feat(win): enable autostart
This commit is contained in:
parent
a2f488858e
commit
d830b136de
31
dict/README.md
Normal file
31
dict/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# CppJieba字典
|
||||||
|
|
||||||
|
文件后缀名代表的是词典的编码方式。
|
||||||
|
比如filename.utf8 是 utf8编码,filename.gbk 是 gbk编码方式。
|
||||||
|
|
||||||
|
|
||||||
|
## 分词
|
||||||
|
|
||||||
|
### jieba.dict.utf8/gbk
|
||||||
|
|
||||||
|
作为最大概率法(MPSegment: Max Probability)分词所使用的词典。
|
||||||
|
|
||||||
|
### hmm_model.utf8/gbk
|
||||||
|
|
||||||
|
作为隐式马尔科夫模型(HMMSegment: Hidden Markov Model)分词所使用的词典。
|
||||||
|
|
||||||
|
__对于MixSegment(混合MPSegment和HMMSegment两者)则同时使用以上两个词典__
|
||||||
|
|
||||||
|
|
||||||
|
## 关键词抽取
|
||||||
|
|
||||||
|
### idf.utf8
|
||||||
|
|
||||||
|
IDF(Inverse Document Frequency)
|
||||||
|
在KeywordExtractor中,使用的是经典的TF-IDF算法,所以需要这么一个词典提供IDF信息。
|
||||||
|
|
||||||
|
### stop_words.utf8
|
||||||
|
|
||||||
|
停用词词典
|
||||||
|
|
||||||
|
|
34
dict/hmm_model.utf8
Normal file
34
dict/hmm_model.utf8
Normal file
File diff suppressed because one or more lines are too long
258826
dict/idf.utf8
Normal file
258826
dict/idf.utf8
Normal file
File diff suppressed because it is too large
Load Diff
348982
dict/jieba.dict.utf8
Normal file
348982
dict/jieba.dict.utf8
Normal file
File diff suppressed because it is too large
Load Diff
6653
dict/pos_dict/char_state_tab.utf8
Normal file
6653
dict/pos_dict/char_state_tab.utf8
Normal file
File diff suppressed because it is too large
Load Diff
166
dict/pos_dict/prob_emit.utf8
Normal file
166
dict/pos_dict/prob_emit.utf8
Normal file
File diff suppressed because one or more lines are too long
259
dict/pos_dict/prob_start.utf8
Normal file
259
dict/pos_dict/prob_start.utf8
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
#初始状态的概率
|
||||||
|
#格式
|
||||||
|
#状态:概率
|
||||||
|
B,a:-4.7623052146
|
||||||
|
B,ad:-6.68006603678
|
||||||
|
B,ag:-3.14e+100
|
||||||
|
B,an:-8.69708322302
|
||||||
|
B,b:-5.01837436211
|
||||||
|
B,bg:-3.14e+100
|
||||||
|
B,c:-3.42388018495
|
||||||
|
B,d:-3.97504752976
|
||||||
|
B,df:-8.88897423083
|
||||||
|
B,dg:-3.14e+100
|
||||||
|
B,e:-8.56355183039
|
||||||
|
B,en:-3.14e+100
|
||||||
|
B,f:-5.49163041848
|
||||||
|
B,g:-3.14e+100
|
||||||
|
B,h:-13.53336513
|
||||||
|
B,i:-6.11578472756
|
||||||
|
B,in:-3.14e+100
|
||||||
|
B,j:-5.05761912847
|
||||||
|
B,jn:-3.14e+100
|
||||||
|
B,k:-3.14e+100
|
||||||
|
B,l:-4.90588358466
|
||||||
|
B,ln:-3.14e+100
|
||||||
|
B,m:-3.6524299819
|
||||||
|
B,mg:-3.14e+100
|
||||||
|
B,mq:-6.7869530014
|
||||||
|
B,n:-1.69662577975
|
||||||
|
B,ng:-3.14e+100
|
||||||
|
B,nr:-2.23104959138
|
||||||
|
B,nrfg:-5.87372217541
|
||||||
|
B,nrt:-4.98564273352
|
||||||
|
B,ns:-2.8228438315
|
||||||
|
B,nt:-4.84609166818
|
||||||
|
B,nz:-3.94698846058
|
||||||
|
B,o:-8.43349870215
|
||||||
|
B,p:-4.20098413209
|
||||||
|
B,q:-6.99812385896
|
||||||
|
B,qe:-3.14e+100
|
||||||
|
B,qg:-3.14e+100
|
||||||
|
B,r:-3.40981877908
|
||||||
|
B,rg:-3.14e+100
|
||||||
|
B,rr:-12.4347528413
|
||||||
|
B,rz:-7.94611647157
|
||||||
|
B,s:-5.52267359084
|
||||||
|
B,t:-3.36474790945
|
||||||
|
B,tg:-3.14e+100
|
||||||
|
B,u:-9.1639172775
|
||||||
|
B,ud:-3.14e+100
|
||||||
|
B,ug:-3.14e+100
|
||||||
|
B,uj:-3.14e+100
|
||||||
|
B,ul:-3.14e+100
|
||||||
|
B,uv:-3.14e+100
|
||||||
|
B,uz:-3.14e+100
|
||||||
|
B,v:-2.67405848743
|
||||||
|
B,vd:-9.04472876024
|
||||||
|
B,vg:-3.14e+100
|
||||||
|
B,vi:-12.4347528413
|
||||||
|
B,vn:-4.33156108902
|
||||||
|
B,vq:-12.1470707689
|
||||||
|
B,w:-3.14e+100
|
||||||
|
B,x:-3.14e+100
|
||||||
|
B,y:-9.84448567586
|
||||||
|
B,yg:-3.14e+100
|
||||||
|
B,z:-7.04568111149
|
||||||
|
B,zg:-3.14e+100
|
||||||
|
E,a:-3.14e+100
|
||||||
|
E,ad:-3.14e+100
|
||||||
|
E,ag:-3.14e+100
|
||||||
|
E,an:-3.14e+100
|
||||||
|
E,b:-3.14e+100
|
||||||
|
E,bg:-3.14e+100
|
||||||
|
E,c:-3.14e+100
|
||||||
|
E,d:-3.14e+100
|
||||||
|
E,df:-3.14e+100
|
||||||
|
E,dg:-3.14e+100
|
||||||
|
E,e:-3.14e+100
|
||||||
|
E,en:-3.14e+100
|
||||||
|
E,f:-3.14e+100
|
||||||
|
E,g:-3.14e+100
|
||||||
|
E,h:-3.14e+100
|
||||||
|
E,i:-3.14e+100
|
||||||
|
E,in:-3.14e+100
|
||||||
|
E,j:-3.14e+100
|
||||||
|
E,jn:-3.14e+100
|
||||||
|
E,k:-3.14e+100
|
||||||
|
E,l:-3.14e+100
|
||||||
|
E,ln:-3.14e+100
|
||||||
|
E,m:-3.14e+100
|
||||||
|
E,mg:-3.14e+100
|
||||||
|
E,mq:-3.14e+100
|
||||||
|
E,n:-3.14e+100
|
||||||
|
E,ng:-3.14e+100
|
||||||
|
E,nr:-3.14e+100
|
||||||
|
E,nrfg:-3.14e+100
|
||||||
|
E,nrt:-3.14e+100
|
||||||
|
E,ns:-3.14e+100
|
||||||
|
E,nt:-3.14e+100
|
||||||
|
E,nz:-3.14e+100
|
||||||
|
E,o:-3.14e+100
|
||||||
|
E,p:-3.14e+100
|
||||||
|
E,q:-3.14e+100
|
||||||
|
E,qe:-3.14e+100
|
||||||
|
E,qg:-3.14e+100
|
||||||
|
E,r:-3.14e+100
|
||||||
|
E,rg:-3.14e+100
|
||||||
|
E,rr:-3.14e+100
|
||||||
|
E,rz:-3.14e+100
|
||||||
|
E,s:-3.14e+100
|
||||||
|
E,t:-3.14e+100
|
||||||
|
E,tg:-3.14e+100
|
||||||
|
E,u:-3.14e+100
|
||||||
|
E,ud:-3.14e+100
|
||||||
|
E,ug:-3.14e+100
|
||||||
|
E,uj:-3.14e+100
|
||||||
|
E,ul:-3.14e+100
|
||||||
|
E,uv:-3.14e+100
|
||||||
|
E,uz:-3.14e+100
|
||||||
|
E,v:-3.14e+100
|
||||||
|
E,vd:-3.14e+100
|
||||||
|
E,vg:-3.14e+100
|
||||||
|
E,vi:-3.14e+100
|
||||||
|
E,vn:-3.14e+100
|
||||||
|
E,vq:-3.14e+100
|
||||||
|
E,w:-3.14e+100
|
||||||
|
E,x:-3.14e+100
|
||||||
|
E,y:-3.14e+100
|
||||||
|
E,yg:-3.14e+100
|
||||||
|
E,z:-3.14e+100
|
||||||
|
E,zg:-3.14e+100
|
||||||
|
M,a:-3.14e+100
|
||||||
|
M,ad:-3.14e+100
|
||||||
|
M,ag:-3.14e+100
|
||||||
|
M,an:-3.14e+100
|
||||||
|
M,b:-3.14e+100
|
||||||
|
M,bg:-3.14e+100
|
||||||
|
M,c:-3.14e+100
|
||||||
|
M,d:-3.14e+100
|
||||||
|
M,df:-3.14e+100
|
||||||
|
M,dg:-3.14e+100
|
||||||
|
M,e:-3.14e+100
|
||||||
|
M,en:-3.14e+100
|
||||||
|
M,f:-3.14e+100
|
||||||
|
M,g:-3.14e+100
|
||||||
|
M,h:-3.14e+100
|
||||||
|
M,i:-3.14e+100
|
||||||
|
M,in:-3.14e+100
|
||||||
|
M,j:-3.14e+100
|
||||||
|
M,jn:-3.14e+100
|
||||||
|
M,k:-3.14e+100
|
||||||
|
M,l:-3.14e+100
|
||||||
|
M,ln:-3.14e+100
|
||||||
|
M,m:-3.14e+100
|
||||||
|
M,mg:-3.14e+100
|
||||||
|
M,mq:-3.14e+100
|
||||||
|
M,n:-3.14e+100
|
||||||
|
M,ng:-3.14e+100
|
||||||
|
M,nr:-3.14e+100
|
||||||
|
M,nrfg:-3.14e+100
|
||||||
|
M,nrt:-3.14e+100
|
||||||
|
M,ns:-3.14e+100
|
||||||
|
M,nt:-3.14e+100
|
||||||
|
M,nz:-3.14e+100
|
||||||
|
M,o:-3.14e+100
|
||||||
|
M,p:-3.14e+100
|
||||||
|
M,q:-3.14e+100
|
||||||
|
M,qe:-3.14e+100
|
||||||
|
M,qg:-3.14e+100
|
||||||
|
M,r:-3.14e+100
|
||||||
|
M,rg:-3.14e+100
|
||||||
|
M,rr:-3.14e+100
|
||||||
|
M,rz:-3.14e+100
|
||||||
|
M,s:-3.14e+100
|
||||||
|
M,t:-3.14e+100
|
||||||
|
M,tg:-3.14e+100
|
||||||
|
M,u:-3.14e+100
|
||||||
|
M,ud:-3.14e+100
|
||||||
|
M,ug:-3.14e+100
|
||||||
|
M,uj:-3.14e+100
|
||||||
|
M,ul:-3.14e+100
|
||||||
|
M,uv:-3.14e+100
|
||||||
|
M,uz:-3.14e+100
|
||||||
|
M,v:-3.14e+100
|
||||||
|
M,vd:-3.14e+100
|
||||||
|
M,vg:-3.14e+100
|
||||||
|
M,vi:-3.14e+100
|
||||||
|
M,vn:-3.14e+100
|
||||||
|
M,vq:-3.14e+100
|
||||||
|
M,w:-3.14e+100
|
||||||
|
M,x:-3.14e+100
|
||||||
|
M,y:-3.14e+100
|
||||||
|
M,yg:-3.14e+100
|
||||||
|
M,z:-3.14e+100
|
||||||
|
M,zg:-3.14e+100
|
||||||
|
S,a:-3.90253968313
|
||||||
|
S,ad:-11.0484584802
|
||||||
|
S,ag:-6.95411391796
|
||||||
|
S,an:-12.8402179494
|
||||||
|
S,b:-6.47288876397
|
||||||
|
S,bg:-3.14e+100
|
||||||
|
S,c:-4.78696679586
|
||||||
|
S,d:-3.90391976418
|
||||||
|
S,df:-3.14e+100
|
||||||
|
S,dg:-8.9483976513
|
||||||
|
S,e:-5.94251300628
|
||||||
|
S,en:-3.14e+100
|
||||||
|
S,f:-5.19482024998
|
||||||
|
S,g:-6.50782681533
|
||||||
|
S,h:-8.65056320738
|
||||||
|
S,i:-3.14e+100
|
||||||
|
S,in:-3.14e+100
|
||||||
|
S,j:-4.91199211964
|
||||||
|
S,jn:-3.14e+100
|
||||||
|
S,k:-6.94032059583
|
||||||
|
S,l:-3.14e+100
|
||||||
|
S,ln:-3.14e+100
|
||||||
|
S,m:-3.26920065212
|
||||||
|
S,mg:-10.8253149289
|
||||||
|
S,mq:-3.14e+100
|
||||||
|
S,n:-3.85514838976
|
||||||
|
S,ng:-4.9134348611
|
||||||
|
S,nr:-4.48366310396
|
||||||
|
S,nrfg:-3.14e+100
|
||||||
|
S,nrt:-3.14e+100
|
||||||
|
S,ns:-3.14e+100
|
||||||
|
S,nt:-12.1470707689
|
||||||
|
S,nz:-3.14e+100
|
||||||
|
S,o:-8.46446092775
|
||||||
|
S,p:-2.98684018136
|
||||||
|
S,q:-4.88865861826
|
||||||
|
S,qe:-3.14e+100
|
||||||
|
S,qg:-3.14e+100
|
||||||
|
S,r:-2.76353367841
|
||||||
|
S,rg:-10.2752685919
|
||||||
|
S,rr:-3.14e+100
|
||||||
|
S,rz:-3.14e+100
|
||||||
|
S,s:-3.14e+100
|
||||||
|
S,t:-3.14e+100
|
||||||
|
S,tg:-6.27284253188
|
||||||
|
S,u:-6.94032059583
|
||||||
|
S,ud:-7.72823016105
|
||||||
|
S,ug:-7.53940370266
|
||||||
|
S,uj:-6.85251045118
|
||||||
|
S,ul:-8.41537131755
|
||||||
|
S,uv:-8.15808672229
|
||||||
|
S,uz:-9.29925862537
|
||||||
|
S,v:-3.05329230341
|
||||||
|
S,vd:-3.14e+100
|
||||||
|
S,vg:-5.94301818437
|
||||||
|
S,vi:-3.14e+100
|
||||||
|
S,vn:-11.4539235883
|
||||||
|
S,vq:-3.14e+100
|
||||||
|
S,w:-3.14e+100
|
||||||
|
S,x:-8.42741965607
|
||||||
|
S,y:-6.19707946995
|
||||||
|
S,yg:-13.53336513
|
||||||
|
S,z:-3.14e+100
|
||||||
|
S,zg:-3.14e+100
|
5222
dict/pos_dict/prob_trans.utf8
Normal file
5222
dict/pos_dict/prob_trans.utf8
Normal file
File diff suppressed because it is too large
Load Diff
1534
dict/stop_words.utf8
Normal file
1534
dict/stop_words.utf8
Normal file
File diff suppressed because it is too large
Load Diff
4
dict/user.dict.utf8
Normal file
4
dict/user.dict.utf8
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
云计算
|
||||||
|
韩玉鉴赏
|
||||||
|
蓝翔 nz
|
||||||
|
区块链 10 nz
|
@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
import typer
|
import typer
|
||||||
@ -19,6 +19,7 @@ import subprocess
|
|||||||
import platform
|
import platform
|
||||||
from .cmds.plugin import plugin_app, bind
|
from .cmds.plugin import plugin_app, bind
|
||||||
from .cmds.library import lib_app, scan, index, watch
|
from .cmds.library import lib_app, scan, index, watch
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
|
||||||
app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})
|
app = typer.Typer(context_settings={"help_option_names": ["-h", "--help"]})
|
||||||
@ -228,19 +229,28 @@ def get_memos_dir():
|
|||||||
def generate_windows_bat():
|
def generate_windows_bat():
|
||||||
memos_dir = get_memos_dir()
|
memos_dir = get_memos_dir()
|
||||||
python_path = get_python_path()
|
python_path = get_python_path()
|
||||||
|
pythonw_path = python_path.replace("python.exe", "pythonw.exe")
|
||||||
conda_prefix = os.environ.get("CONDA_PREFIX")
|
conda_prefix = os.environ.get("CONDA_PREFIX")
|
||||||
|
log_dir = memos_dir / "logs"
|
||||||
|
log_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
if conda_prefix:
|
if conda_prefix:
|
||||||
# If we're in a Conda environment
|
# If we're in a Conda environment
|
||||||
activate_path = os.path.join(conda_prefix, "Scripts", "activate.bat")
|
activate_path = os.path.join(conda_prefix, "Scripts", "activate.bat")
|
||||||
content = f"""@echo off
|
content = f"""@echo off
|
||||||
call "{activate_path}"
|
call "{activate_path}"
|
||||||
start "Memos" cmd /c ""{python_path}" -m memos.commands record & "{python_path}" -m memos.commands serve & timeout /t 5 /nobreak >nul & "{python_path}" -m memos.commands watch"
|
start /B "" "{pythonw_path}" -m memos.commands record > "{log_dir / 'record.log'}" 2>&1
|
||||||
|
start /B "" "{pythonw_path}" -m memos.commands serve > "{log_dir / 'serve.log'}" 2>&1
|
||||||
|
timeout /t 5 /nobreak >nul
|
||||||
|
start /B "" "{pythonw_path}" -m memos.commands watch > "{log_dir / 'watch.log'}" 2>&1
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
# If we're not in a Conda environment, use the original content
|
# If we're not in a Conda environment
|
||||||
content = f"""@echo off
|
content = f"""@echo off
|
||||||
start "Memos" cmd /c ""{python_path}" -m memos.commands record & "{python_path}" -m memos.commands serve & timeout /t 5 /nobreak >nul & "{python_path}" -m memos.commands watch"
|
start /B "" "{pythonw_path}" -m memos.commands record > "{log_dir / 'record.log'}" 2>&1
|
||||||
|
start /B "" "{pythonw_path}" -m memos.commands serve > "{log_dir / 'serve.log'}" 2>&1
|
||||||
|
timeout /t 5 /nobreak >nul
|
||||||
|
start /B "" "{pythonw_path}" -m memos.commands watch > "{log_dir / 'watch.log'}" 2>&1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bat_path = memos_dir / "launch.bat"
|
bat_path = memos_dir / "launch.bat"
|
||||||
@ -291,6 +301,7 @@ def setup_windows_autostart(bat_path):
|
|||||||
shortcut = shell.CreateShortCut(str(shortcut_path))
|
shortcut = shell.CreateShortCut(str(shortcut_path))
|
||||||
shortcut.Targetpath = str(bat_path)
|
shortcut.Targetpath = str(bat_path)
|
||||||
shortcut.WorkingDirectory = str(bat_path.parent)
|
shortcut.WorkingDirectory = str(bat_path.parent)
|
||||||
|
shortcut.WindowStyle = 7 # Minimized
|
||||||
shortcut.save()
|
shortcut.save()
|
||||||
|
|
||||||
|
|
||||||
@ -364,6 +375,46 @@ def is_windows():
|
|||||||
return platform.system() == "Windows"
|
return platform.system() == "Windows"
|
||||||
|
|
||||||
|
|
||||||
|
def remove_windows_autostart():
|
||||||
|
startup_folder = Path(os.getenv("APPDATA")) / r"Microsoft\Windows\Start Menu\Programs\Startup"
|
||||||
|
shortcut_path = startup_folder / "Memos.lnk"
|
||||||
|
|
||||||
|
if shortcut_path.exists():
|
||||||
|
shortcut_path.unlink()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def disable():
|
||||||
|
"""Disable memos from running at startup"""
|
||||||
|
if is_windows():
|
||||||
|
if remove_windows_autostart():
|
||||||
|
typer.echo("Removed Memos shortcut from startup folder. Memos will no longer run at startup.")
|
||||||
|
else:
|
||||||
|
typer.echo("Memos shortcut not found in startup folder. Memos is not set to run at startup.")
|
||||||
|
elif is_macos():
|
||||||
|
plist_path = Path.home() / "Library/LaunchAgents/com.user.memos.plist"
|
||||||
|
if plist_path.exists():
|
||||||
|
user_domain = f"gui/{os.getuid()}"
|
||||||
|
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()
|
||||||
|
typer.echo("Removed plist file. Memos will no longer run at startup.")
|
||||||
|
else:
|
||||||
|
typer.echo("Plist file does not exist. Memos is not set to run at startup.")
|
||||||
|
else:
|
||||||
|
typer.echo("Unsupported operating system.")
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
def enable():
|
def enable():
|
||||||
"""Enable memos to run at startup"""
|
"""Enable memos to run at startup"""
|
||||||
@ -391,29 +442,27 @@ def enable():
|
|||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
def disable():
|
def ps():
|
||||||
"""Disable memos from running at startup"""
|
"""Show the status of Memos processes"""
|
||||||
if not is_macos():
|
services = ["serve", "watch", "record"]
|
||||||
typer.echo("Error: This feature is only supported on macOS.")
|
|
||||||
raise typer.Exit(code=1)
|
|
||||||
|
|
||||||
plist_path = Path.home() / "Library/LaunchAgents/com.user.memos.plist"
|
for service in services:
|
||||||
if plist_path.exists():
|
processes = [p for p in psutil.process_iter(['pid', 'name', 'cmdline', 'create_time'])
|
||||||
user_domain = f"gui/{os.getuid()}"
|
if 'python' in p.info['name'].lower() and
|
||||||
service_name = "com.user.memos"
|
'memos.commands' in p.info['cmdline'] and
|
||||||
|
service in p.info['cmdline']]
|
||||||
|
|
||||||
if is_service_loaded(service_name):
|
if processes:
|
||||||
subprocess.run(
|
for process in processes:
|
||||||
["launchctl", "bootout", user_domain, str(plist_path)], check=False
|
create_time = datetime.fromtimestamp(process.info['create_time']).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
)
|
running_time = str(timedelta(seconds=int(time.time() - process.info['create_time'])))
|
||||||
typer.echo("Unloaded Memos service.")
|
typer.echo(f"{service.capitalize()} is running:")
|
||||||
|
typer.echo(f" PID: {process.info['pid']}")
|
||||||
|
typer.echo(f" Started at: {create_time}")
|
||||||
|
typer.echo(f" Running for: {running_time}")
|
||||||
else:
|
else:
|
||||||
typer.echo("Memos service was not running.")
|
typer.echo(f"{service.capitalize()} is not running")
|
||||||
|
typer.echo("---")
|
||||||
plist_path.unlink()
|
|
||||||
typer.echo("Removed plist file. Memos will no longer run at startup.")
|
|
||||||
else:
|
|
||||||
typer.echo("Plist file does not exist. Memos is not set to run at startup.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
55
memos/process_webp.py
Normal file
55
memos/process_webp.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
from PIL import Image
|
||||||
|
import piexif
|
||||||
|
import json
|
||||||
|
from memos.utils import write_image_metadata, get_image_metadata
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
def convert_webp_metadata(directory):
|
||||||
|
webp_files = list(Path(directory).glob('**/*.webp'))
|
||||||
|
|
||||||
|
for webp_file in tqdm(webp_files, desc="Converting WebP metadata", unit="file"):
|
||||||
|
try:
|
||||||
|
# Try to get metadata using the new method
|
||||||
|
new_metadata = get_image_metadata(webp_file)
|
||||||
|
|
||||||
|
if new_metadata:
|
||||||
|
tqdm.write(f"Skipping {webp_file}: Already in new format")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If new method fails, try to get old metadata
|
||||||
|
img = Image.open(webp_file)
|
||||||
|
old_metadata = img.info.get("exif", None)
|
||||||
|
|
||||||
|
if old_metadata is None:
|
||||||
|
tqdm.write(f"Skipping {webp_file}: No metadata found")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if isinstance(old_metadata, bytes):
|
||||||
|
try:
|
||||||
|
old_metadata = old_metadata.decode('utf-8')
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
tqdm.write(f"Skipping {webp_file}: Unable to decode metadata")
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
metadata = json.loads(old_metadata)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
tqdm.write(f"Skipping {webp_file}: Invalid metadata format")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Convert to new format
|
||||||
|
write_image_metadata(webp_file, metadata)
|
||||||
|
tqdm.write(f"Converted metadata for {webp_file}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
tqdm.write(f"Error processing {webp_file}: {str(e)}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python convert_webp_metadata.py <directory>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
directory = sys.argv[1]
|
||||||
|
convert_webp_metadata(directory)
|
19
memos/t.py
Normal file
19
memos/t.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import typer
|
||||||
|
from rich import print
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"name": "Rick",
|
||||||
|
"age": 42,
|
||||||
|
"items": [{"name": "Portal Gun"}, {"name": "Plumbus"}],
|
||||||
|
"active": True,
|
||||||
|
"affiliation": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("Here's the data")
|
||||||
|
print(data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
typer.run(main)
|
101
memos/watchfiles.py
Normal file
101
memos/watchfiles.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
|
||||||
|
# 定义图片文件扩展名
|
||||||
|
IMAGE_EXTENSIONS = (".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp")
|
||||||
|
|
||||||
|
|
||||||
|
class ImageHandler(FileSystemEventHandler):
|
||||||
|
def __init__(self):
|
||||||
|
self.last_modified = {}
|
||||||
|
|
||||||
|
def is_image_file(self, path):
|
||||||
|
return path.lower().endswith(IMAGE_EXTENSIONS)
|
||||||
|
|
||||||
|
def is_temp_file(self, path):
|
||||||
|
filename = os.path.basename(path)
|
||||||
|
return (
|
||||||
|
filename.startswith(".")
|
||||||
|
or filename.startswith("tmp")
|
||||||
|
or filename.startswith("temp")
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle_event(self, event):
|
||||||
|
if (
|
||||||
|
not event.is_directory
|
||||||
|
and self.is_image_file(event.src_path)
|
||||||
|
and not self.is_temp_file(event.src_path)
|
||||||
|
):
|
||||||
|
current_time = time.time()
|
||||||
|
last_modified_time = self.last_modified.get(event.src_path, 0)
|
||||||
|
if current_time - last_modified_time > 1: # 防止重复触发
|
||||||
|
self.last_modified[event.src_path] = current_time
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_modified(self, event):
|
||||||
|
if self.handle_event(event):
|
||||||
|
print(f"Image file modified: {event.src_path}")
|
||||||
|
|
||||||
|
def on_created(self, event):
|
||||||
|
if self.handle_event(event):
|
||||||
|
print(f"Image file created: {event.src_path}")
|
||||||
|
|
||||||
|
def on_deleted(self, event):
|
||||||
|
if self.handle_event(event):
|
||||||
|
print(f"Image file deleted: {event.src_path}")
|
||||||
|
|
||||||
|
|
||||||
|
def watch_folders(folders, recursive):
|
||||||
|
event_handler = ImageHandler()
|
||||||
|
observer = Observer()
|
||||||
|
|
||||||
|
# 监听多个文件夹
|
||||||
|
for folder in folders:
|
||||||
|
observer.schedule(event_handler, folder, recursive=recursive)
|
||||||
|
|
||||||
|
observer.start()
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
observer.stop()
|
||||||
|
observer.join()
|
||||||
|
|
||||||
|
|
||||||
|
# main 函数保持不变
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Watch for image file changes in specified folders."
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"folders",
|
||||||
|
metavar="FOLDER",
|
||||||
|
type=str,
|
||||||
|
nargs="+",
|
||||||
|
help="One or more folders to watch for image file changes.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-r",
|
||||||
|
"--recursive",
|
||||||
|
action="store_true",
|
||||||
|
help="Watch folders recursively (may impact performance for large directories).",
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# 确认所有提供的目录都存在
|
||||||
|
for folder in args.folders:
|
||||||
|
if not os.path.isdir(folder):
|
||||||
|
print(f"Error: {folder} is not a valid directory.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
watch_folders(args.folders, args.recursive)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
BIN
simple.dll
Normal file
BIN
simple.dll
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user