Last active
February 17, 2023 02:42
-
-
Save unknownzerx/9a8eb98cb9e70695f37fabf901e676b0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import filecmp | |
def print_usage(): | |
print("Usage:") | |
print(" cd /Applications") | |
print(" sudo ./office-thinner.py 'Microsoft Word.app' 'Microsoft Excel.app' 'Microsoft PowerPoint.app' ... ") | |
print("") | |
print("Or generally, link same files with same paths in other_dir to main_dir") | |
print(" ./office-thinner.py main_dir other_dir") | |
if len(sys.argv) < 3: | |
print_usage() | |
exit(0) | |
main_dir = sys.argv[1] | |
other_dirs = sys.argv[2:] | |
if not os.path.isdir(main_dir): | |
print("%s does not exist." % main_dir) | |
print_usage() | |
exit(1) | |
def get_ino(path): | |
return os.stat(path).st_ino | |
def get_common_files_helper(base_dir, dcmp): | |
if os.path.islink(os.path.join(dcmp.right)): | |
# print "skip dir link %s" % os.path.join(dcmp.left, base_dir) | |
return [] | |
else: | |
rs = [] | |
rs0 = filecmp.cmpfiles(dcmp.left, dcmp.right, dcmp.same_files, False) | |
for name in rs0[0]: | |
rs.append(os.path.join(base_dir, name)) | |
# for name in rs0[1]: | |
# print "%s is false same" % os.path.join(base_dir, name) | |
for name, sub_dcmp in dcmp.subdirs.items(): | |
path = os.path.join(base_dir, name) | |
rs += get_common_files_helper(path, sub_dcmp) | |
return rs | |
def get_common_files(dir1, dir2): | |
return get_common_files_helper("", filecmp.dircmp(dir1, dir2)) | |
def makelink(dir1, dir2): | |
common_files = [] | |
try: | |
print("calculating common files...") | |
common_files += get_common_files(dir1, dir2) | |
except OSError as ex: | |
print("Error: %s" % ex.strerror) | |
print("Maybe you have installed Office in a non-default location.") | |
n_actual_linked = 0 | |
n_common_files = len(common_files) | |
print("n_common_files: %s" % n_common_files) | |
i = 0 | |
for filename in common_files: | |
path1 = os.path.join(dir1, filename) | |
path2 = os.path.join(dir2, filename) | |
if os.path.islink(path1) or os.path.islink(path2): | |
print(" ignore symlink %s" % filename) | |
pass | |
elif get_ino(path1) == get_ino(path2): | |
print(" same inode for %s" % filename) | |
pass | |
else: | |
# print "diff inode for %s" % filename | |
# os.rename won't create parent dir for me | |
# os.renames will prune empty dir from src | |
# Let's be lazy to skip backuping... | |
os.remove(path2) | |
os.link(path1, path2) | |
n_actual_linked += 1 | |
i += 1 | |
if i % (n_common_files / 10) == 0: | |
print('%s files linked...' % i) | |
print("actually linked: ", n_actual_linked) | |
print("done") | |
def link_if_exist(dir_app): | |
if os.path.isdir(dir_app): | |
print("make link for %s" % dir_app) | |
makelink(main_dir, dir_app) | |
else: | |
print("%s not found. skipped" % dir_app) | |
for the_dir in other_dirs: | |
link_if_exist(the_dir) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Will you extend it to support all Office products at the same time ?