aboutsummaryrefslogtreecommitdiff
path: root/source/blog/2015-06-27-automatically-clean-up-previous-mobile-applications.md
diff options
context:
space:
mode:
Diffstat (limited to 'source/blog/2015-06-27-automatically-clean-up-previous-mobile-applications.md')
-rw-r--r--source/blog/2015-06-27-automatically-clean-up-previous-mobile-applications.md123
1 files changed, 0 insertions, 123 deletions
diff --git a/source/blog/2015-06-27-automatically-clean-up-previous-mobile-applications.md b/source/blog/2015-06-27-automatically-clean-up-previous-mobile-applications.md
deleted file mode 100644
index e8e1dd14..00000000
--- a/source/blog/2015-06-27-automatically-clean-up-previous-mobile-applications.md
+++ /dev/null
@@ -1,123 +0,0 @@
----
-title: 'Automatically clean up "Previous Mobile Applications"'
-date: 2015-06-27T21:19:59-07:00
-date_display: June 27, 2015
----
-
-iTunes keeps a "Previous Mobile Applications" folder of questionable value, which always annoys me. It eats into disk space and wastes syncing/backup cycles and bandwidth; you can easily find horror stories online about [100GB+ PMA folders](http://forums.macrumors.com/threads/5-years-of-deleted-iphone-apps-accumulated-in-my-itunes-library.1781676/#post-19749496). The value? You might be able to roll back to an earlier version, or restore an app pulled from the App Store. Really? I never had that need in my life[^disclosure]; have you? Worst of all, there should be a periodic clean up option — just like how deleted mail are automatically purged after one month, but the option is missing.
-
-[^disclosure]: Full disclosure: unlike many people, I'm not very obsessed with my phone, and I only have about two dozen third-party apps.
-
-Therefore, I wrote a trivial Python script to do the periodic cleanup. Feel free to grab my script below (also available at <http://git.io/previous-mobile-applications>) to save a few minutes of hacking. It should be plugged into a daily or weekly or monthly cron job (or the equivalent), and it writes data to `~/.local/share/itunes/previous-mobile-applications.json` by default. To customize, just modify the global constants.
-
-```python
-#!/usr/bin/env python3
-
-"""Periodically clean up "Previous Mobile Applications" of iTunes."""
-
-import arrow
-import datetime
-import json
-import os
-import sys
-
-OFFENDING_DIR = os.path.expanduser("~/Music/iTunes/iTunes Media/Mobile Applications/Previous Mobile Applications")
-STORAGE_DIR = os.path.expanduser("~/.local/share/itunes")
-STORAGE_FILE = os.path.join(STORAGE_DIR, "previous-mobile-applications.json")
-
-DELETE_AFTER = datetime.timedelta(days=7)
-
-def load_storage():
- """Load stored dictionary of seen apps from STORAGE_FILE.
-
- Returns
- -------
- seen_app_dict : dict
- Dictionary of (app_filename, first_seen_date) key-value pairs,
- where app_filename is str, and last_seen_date is datetime.date.
-
- """
- os.makedirs(STORAGE_DIR, mode=0o700, exist_ok=True)
- try:
- with open(STORAGE_FILE, encoding="utf-8") as fp:
- serializable_seen_app_dict = json.load(fp)
- return {app_filename: arrow.get(serialized_first_seen_date).date()
- for app_filename, serialized_first_seen_date in serializable_seen_app_dict.items()}
- except OSError:
- return {}
-
-def write_storage(seen_app_dict):
- """Write the dictionary of seen apps to STORAGE_FILE.
-
- Parameters
- ----------
- seen_app_dict : dict
- See the return format of load_storage().
-
- Returns
- -------
- 0 or 1
- Return code indicating success or failure.
-
- """
- # convert datetime.time to str (ISO 8601)
- serializable_seen_app_dict = {app_filename: first_seen_date.isoformat()
- for app_filename, first_seen_date in seen_app_dict.items()}
- os.makedirs(STORAGE_DIR, mode=0o700, exist_ok=True)
- try:
- with open(STORAGE_FILE, mode="w", encoding="utf-8") as fp:
- json.dump(serializable_seen_app_dict, fp, indent=2, sort_keys=True)
- return 0
- except OSError as err:
- sys.stderr.write("error: failed to write to '%s': %s" % (STORAGE_FILE, str(err)))
- return 1
-
-def main():
- """Main.
-
- Returns
- -------
- 0 or 1
- Return code indicating success or failure.
-
- """
- if not os.path.isdir(OFFENDING_DIR):
- # good, you don't have that junk
- return 0
-
- today = datetime.date.today()
- seen_app_dict = load_storage()
- current_app_list = os.listdir(OFFENDING_DIR)
-
- # boot already disappeared apps
- for app in [app for app in seen_app_dict if app not in current_app_list]:
- seen_app_dict.pop(app)
-
- # add newly appeared apps
- for app in [app for app in current_app_list if app not in seen_app_dict]:
- seen_app_dict[app] = today
-
- # delete expired apps
- returncode = 0
- newly_deleted_apps = []
- for app in seen_app_dict:
- if today >= seen_app_dict[app] + DELETE_AFTER:
- app_path = os.path.join(OFFENDING_DIR, app)
- try:
- os.remove(app_path)
- newly_deleted_apps.append(app)
- except OSError as err:
- sys.stderr.write("error: failed to remove '%s': %s" % (app_path, str(err)))
- returncode = 1
-
- for app in newly_deleted_apps:
- seen_app_dict.pop(app)
-
- # write data to disk
- returncode |= write_storage(seen_app_dict)
-
- return returncode
-
-if __name__ == "__main__":
- exit(main())
-```