| 
									
										
										
										
											2023-07-07 11:45:42 +02:00
										 |  |  | #!/usr/bin/env python3 | 
					
						
							|  |  |  | import argparse | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import pathlib | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(): | 
					
						
							|  |  |  | 	cli = argparse.ArgumentParser( | 
					
						
							|  |  |  | 		prog="media-to-borg-patterns", | 
					
						
							| 
									
										
										
										
											2023-08-23 20:06:46 +02:00
										 |  |  | 		description="""Generate Borg patterns to backup media and emoji files belonging to
 | 
					
						
							| 
									
										
										
										
											2023-07-07 11:45:42 +02:00
										 |  |  | 		this instance. You can pass the output to Borg or Borgmatic as a patterns file. | 
					
						
							| 
									
										
										
										
											2023-08-23 20:06:46 +02:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		For example: gotosocial admin media list-attachments --local-only | media-to-borg-patterns | 
					
						
							| 
									
										
										
										
											2023-07-07 11:45:42 +02:00
										 |  |  | 		<storage-local-base-path>. You can pass a second argument, the destination file, to | 
					
						
							|  |  |  | 		write the patterns in. If it's ommitted the patterns will be emitted on stdout | 
					
						
							|  |  |  | 		instead and you can redirect the output to a file yourself. | 
					
						
							| 
									
										
										
										
											2023-08-23 20:06:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		For emojis, use gotosocial admin media list-emojis --local-only | media-to-borg-patterns | 
					
						
							|  |  |  | 		instead. | 
					
						
							| 
									
										
										
										
											2023-07-07 11:45:42 +02:00
										 |  |  | 		""",
 | 
					
						
							|  |  |  | 		epilog="Be gay, do backups. Trans rights!" | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	cli.add_argument("storageroot", type=pathlib.Path, help="same value as storage-local-base-path in your GoToSocial configuration") | 
					
						
							|  |  |  | 	cli.add_argument("destination", nargs="?", type=pathlib.Path, help="file to write patterns to, or stdout if ommitted") | 
					
						
							|  |  |  | 	args = cli.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	output = open(args.destination, 'w') if args.destination else sys.stdout | 
					
						
							|  |  |  | 	# Start recursing from the storage root, including the storage root itself | 
					
						
							|  |  |  | 	output.write("R "+str(args.storageroot)+"\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	prefixes=set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for line in sys.stdin: | 
					
						
							|  |  |  | 		# Skip any log lines | 
					
						
							|  |  |  | 		if "msg=" in line: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		# Reduce the path to the storage path plus the account ID. By | 
					
						
							|  |  |  | 		# doing this we can emit path-prefix patterns, one for each account, | 
					
						
							|  |  |  | 		# instead of a path-file pattern for each file. | 
					
						
							|  |  |  | 		prefixes.add(os.path.join(*line.split("/")[:-3])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for prefix in prefixes: | 
					
						
							|  |  |  | 		# Add a path-prefix, pp:, for each path we want to include. | 
					
						
							|  |  |  | 		output.write("+ pp:"+os.path.join(os.path.sep, prefix)+"\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Exclude every file and directory under the storage root. This excludes | 
					
						
							|  |  |  | 	# everything that wasn't matched by any of our prior patterns. This turns | 
					
						
							|  |  |  | 	# the emitted patterns into an "include only" list. | 
					
						
							|  |  |  | 	output.write("- "+os.path.join(args.storageroot, "*")+"\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if output is not sys.stdout: | 
					
						
							|  |  |  | 		output.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  | 	main() |