Hazel轻松管理文件-微信聊天文件自动分类存放

首先上实现效果的视频:https://v.qq.com/x/page/x3021yp3u3a.html

  1. 实现该功能所使用软件
    1. Hazel:可在网上自行下载
    2. Automator :Mac自带的Automator可通过聚焦搜索(command+space)进行搜索
  1. 具体要实现的功能
  • 当收到微信朋友发送的文件(Excel、Word、PDF等等文件)时,自动保存到相应目录,文件类型可通过变量filterRules进行设置;
  • 文件收到时间限制,比如只处理最近5分钟的文件,通过参数filterTime进行配置,单位为分钟
  • 自动保存文件的目录,可通过变量chooseFromList进行设置,也可手动选择其他文件目录
  • 文件已经存在,弹窗提示是否覆盖
  • 对文件进行标记,对每个文件打上tag(比如Excel文档标记tag excel),方便以后查找
  • 文件初次保存时,默认第一次打开
  1. 使用场景
  • 工作相关文件:我会选择移动到工作相关的目录,这里我是移动到自动处理目录,Hazel会监听该目录,对文件进行分类,打标签,如果是日志文件,我默认会在文件名称前添加时间前缀,并且打开日志文件
  • 个人文件:我会选择一个目录进行保存
  1. 实现步骤
    1. 首先是创建Hazel文件夹规则
  1. 重点讲一下MessageTemp这个文件夹的规则
  • 首先是如何让Hazel知道,微信里有朋友发了文件给你,这里只需要监听微信聊天文件缓存的文件夹即可,大概位置在/Users/xxxxxx/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/09af4488ac59013c076d683513a0e252/Message/MessageTemp/这个目录;
  • 然后是监听到了这个文件夹里有新文件时,触发一个Automator 工作流,进行文件的移动,为啥这里不能由Hazel直接移动,因为在MessageTemp目录下,是存在很多子文件夹的,聊天文件在某一个子文件夹,Hazel不能确定具体是哪一个新增的文件需要移动,所以这里使用Automator 工作流进行移动;
MessageTemp目录下,存在很多子文件夹的
  1. Automator 工作流具体实现

步骤1:创建类型为工作流的Automator

步骤2:具体实现Automator 工作流

  • 流程1:获取变量filterRules过滤规则
  • 流程2:得到Hazel监控触发的文件目录(MessageTemp下的某个子目录),然后获取该文件夹下的OpenData和File目录的所有文件,然后执行filterRules规则,过滤掉不需要处理的文件
  • 流程3:将文件转化成文件路径(现在看来有点多余了)
  • 流程4:获取变量chooseFromList值
  • 流程5:让用户选择目标目录
  • 流程6:得到用户选择的目标目录和所有待处理的文件,进行文件复制

流程2对应的AppleScript脚本如下:

on run {input, parameters}
	-- 获取过滤规则
	set rule to item -1 of input
	--将input设置为待处理的目录
	set input to item 1 of input
	set folderPath1 to (input as text) & "OpenData:"
	set folderPath2 to (input as text) & "File:"
	tell application "Finder"
		try
			set files1 to get document files of folder folderPath1
			set files2 to get document files of folder folderPath2
			set allFiles to files2
			--过滤后的文件
			set filterFiles to {}
			set theList to {}
			repeat with aFile in allFiles
				--文件扩展名
				set extensionName to the name extension of aFile
				--文件名称
				set fileName to the name of aFile
				try
					set SuffixRules to suffix of rule
					set stopStartRule to false
					--创建时间
					set theFileDate to (creation date of aFile as string)
					set oneminutes to (current date) - 1 * minutes
					if theFileDate > oneminutes then
						--是否在扩展名规则里,如果在直接 放入filterFiles 不进行后续规则过滤
						repeat with suffix in SuffixRules
							
							if (extensionName as text) ends with suffix then
								set the end of filterFiles to aFile
								set stopStartRule to true
								exit repeat
							end if
						end repeat
						-- 以什么开头规则 和 不以什么结尾规则是 且的关系
						if stopStartRule is false then
							-- 以什么开头规则 和 不能以什么结尾
							set startRules to start of rule
							repeat with startRule in startRules
								if fileName starts with startRule then
									set notEndRules to notEnd of rule
									set needAdd to true
									repeat with notEndRule in notEndRules
										if extensionName = notEndRule then
											needAdd without to
											exit repeat
										end if
									end repeat
									if needAdd is true then
										set the end of filterFiles to aFile
										exit repeat
									end if
								end if
							end repeat
						end if
					end if
				on error the error_message number the error_number
					display dialog "Error: " & the error_number & "." & the error_message buttons {"OK"}
				end try
			end repeat
			return filterFiles
		on error the error_message number the error_number
			display dialog "Error: " & the error_number & "." & the error_message buttons {"OK"}
		end try
	end tell
end run



流程3对应的AppleScript脚本如下:

on run {input, parameters}
	if (count of input) ≤ 0 then
		-- 没有需要移动的文件
		display notification "没有需要移动的文件"
		return {}
	else
		local params
		set params to {}
		repeat with aFile in input
			set curPath to aFile as text
			set params to params & curPath & "|"
		end repeat
		return params
	end if
end run

on theSplit(theString, theDelimiter)
	-- 保存分隔符来恢复旧的设置
	set oldDelimiters to AppleScript's text item delimiters
	-- 设置分隔符分隔符使用
	set AppleScript's text item delimiters to theDelimiter
	-- 创建数组 并且 数组theArray为文本类型
	set theArray to text items of theString
	--恢复旧的设置
	set AppleScript's text item delimiters to oldDelimiters
	return theArray
end theSplit

流程5对应的AppleScript脚本如下:

on run {input, parameters}
	-- 获取下拉框选项值
	set chooseFromList to item -1 of input
	set chooseFromList to theSplit(chooseFromList, "|")
	--将变量参数剔除
	set input to items 1 through -2 of input
	if input is {} then
		return {}
	else
		set flodPath to choose from list chooseFromList & "选择文件夹"
		--display dialog ((flodPath) as text)
		if flodPath is false then
			return
		end if
		set re to item -1 of flodPath
		if re = "选择文件夹" then
			set folderSelected to choose folder "Select a folder"
			if folderSelected is false then return
			set re to POSIX path of folderSelected
		end if
		set input to input & re
		return input
	end if
	(* Your script goes here *)
	
	return input
end run


on theSplit(theString, theDelimiter)
	-- 保存分隔符来恢复旧的设置
	set oldDelimiters to AppleScript's text item delimiters
	-- 设置分隔符分隔符使用
	set AppleScript's text item delimiters to theDelimiter
	
	-- 创建数组 并且 数组theArray为文本类型
	set theArray to text items of theString
	
	--恢复旧的设置
	set AppleScript's text item delimiters to oldDelimiters
	
	return theArray
end theSplit

流程6对应的AppleScript脚本如下:

on run {input, parameters}
	if the length of input < 2 then
		return
	end if
	--获取目标路劲
	set targetPath to item -1 of input
	--获取文件路劲
	set filesPaths to items 1 through -2 of input
	repeat with aFile in filesPaths
		try
			
			set theLength to the length of ((aFile) as text)
			if (theLength > 0 and isDirectory(aFile) is false) then
				
				set filePath to POSIX path of aFile as text
				tell application "Finder" to set fileExists to exists my POSIX file filePath
				if fileExists is true then
					set fArray to my theSplit((filePath) as string, "/")
					set fname to item -1 of fArray
					--判断目标路劲是否存在同名文件
					set targetPathFile to targetPath & fname
					set file1 to POSIX file filePath
					set relTargetPath to POSIX file targetPath as text
					tell application "Finder" to set targetPathFileExists to exists my POSIX file targetPathFile
					
					if targetPathFileExists is true then
						set tempVar to display dialog "文件 [" & fname & "] 已存在,是否覆盖" buttons {"是", "否"}
						set theButtonPressed to button returned of tempVar
						if theButtonPressed = "是" then
							tell application "Finder"
								--覆盖 复制
								duplicate file1 to relTargetPath with replacing
								display notification "成功移动到:" & targetPath with title ("文件: " & fname as text)
							end tell
						else
							--exit repeat
						end if
					else
						tell application "Finder"
							--复制
							duplicate file1 to relTargetPath
							display notification "成功移动到:" & targetPath with title ("文件: " & fname as text)
						end tell
					end if
					
					
				end if
			end if
		on error the error_message number the error_number
			display dialog "Error: " & the error_number & "." & the error_message buttons {"OK"}
		end try
	end repeat
end run

on theSplit(theString, theDelimiter)
	--display dialog ((theString) as text)
	-- 保存分隔符来恢复旧的设置
	set oldDelimiters to AppleScript's text item delimiters
	-- 设置分隔符分隔符使用
	set AppleScript's text item delimiters to theDelimiter
	
	-- 创建数组 并且 数组theArray为文本类型
	set theArray to text items of theString
	
	--恢复旧的设置
	set AppleScript's text item delimiters to oldDelimiters
	
	-- return the result
	return theArray
end theSplit

on isDirectory(someItem)
	set filePosixPath to quoted form of (POSIX path of someItem)
	set fileType to (do shell script "file -b " & filePosixPath)
	if fileType ends with "directory" then return true
	return false
end isDirectory
  1. 总结

以上就是实现该功能的所有步骤,有需要的也可在文章后面的附件自行下载,实现过程历经艰辛,因为自己之前也没接触过AppleScript语言。

Automator CICD cms Consul Consul-template docker docker-compose elasticsearch G1 gc gitlab gitlab-runner harbor Hazel hybris java jvm kubernetes lua mac macx高效率 nginx rancher redis spring boot spring cloud swarm ThreadPool vim 分布式 大流量架构 序列号 有规则 架构

标签:

发表评论

邮箱地址不会被公开。 必填项已用*标注