Skip to content

Instantly share code, notes, and snippets.

@estshorter
Last active January 5, 2020 06:19
Show Gist options
  • Save estshorter/1de6bab0590ad8743e447e50b3d61983 to your computer and use it in GitHub Desktop.
Save estshorter/1de6bab0590ad8743e447e50b3d61983 to your computer and use it in GitHub Desktop.
Python script for downloading and applying MusicBee Patches from https://getmusicbee.com/patches/
from datetime import datetime, timezone
import os
from pathlib import Path
import subprocess
from urllib import request
from zipfile import ZipFile
from bs4 import BeautifulSoup
import pytz
def determine_whether_download_mb_zip(
target_filename, datetime_save_path, mb_patch_url
):
req = request.Request(mb_patch_url, headers={"User-Agent": "Mozilla/5.0"})
with request.urlopen(req) as response:
soup = BeautifulSoup(response, "lxml")
mb_site_timestamp_str = (
soup.find("a", href=target_filename).find_next("td").string.strip()
)
current_timestamp = datetime.strptime(mb_site_timestamp_str, "%Y-%m-%d %H:%M")
if datetime_save_path.exists():
with open(datetime_save_path, mode="r") as f:
dl_date = f.readline()
last_dl_timestamp = datetime.strptime(dl_date, "%Y-%m-%d %H:%M")
else:
last_dl_timestamp = datetime(1990, 10, 1)
if current_timestamp > last_dl_timestamp:
return True, mb_site_timestamp_str
else:
return False, mb_site_timestamp_str
def download_mb_zip(target_url, download_path):
opener = request.build_opener()
opener.addheaders = [("User-agent", "Mozilla/5.0")]
request.install_opener(opener)
request.urlretrieve(target_url, download_path)
def extract_updated_files(zipfile_path, mb_path):
extract_cnt = 0
JST = pytz.timezone("Asia/Tokyo")
with ZipFile(zipfile_path, "r") as existing_zip:
for info in existing_zip.infolist():
if not info.is_dir(): # file
zip_update_datetime = datetime(
*info.date_time, tzinfo=timezone.utc
).astimezone(JST)
zip_update_timestamp = zip_update_datetime.timestamp()
file_mb_path = Path(mb_path / info.filename)
existing_datetime = (
datetime.fromtimestamp(os.stat(file_mb_path).st_mtime, JST)
if file_mb_path.exists()
else None
)
if (existing_datetime is None) or (
zip_update_datetime > existing_datetime
):
existing_zip.extract(info.filename, mb_path)
os.utime(file_mb_path, (zip_update_timestamp, zip_update_timestamp))
print(info.filename, existing_datetime, "->", zip_update_datetime)
extract_cnt += 1
else:
dir_mb_path = Path(mb_path / info.filename)
if not dir_mb_path.exists():
dir_mb_path.mkdir()
return extract_cnt
tmp_dir_path = Path(r"C:/tmp/")
datetime_save_path = tmp_dir_path / r"mb_last_download_datetime.txt"
download_path = tmp_dir_path / r"MusicBee_Patched.zip"
mb_path = Path(r"C:/Program Files (x86)/MusicBee/")
target_filename = r"MusicBee33_Patched.zip"
mb_patch_url = r"https://getmusicbee.com/patches/"
tmp_dir = Path(tmp_dir_path)
if not tmp_dir.exists():
tmp_dir.mkdir()
should_download_file, timestamp_str = determine_whether_download_mb_zip(
target_filename, datetime_save_path, mb_patch_url
)
if should_download_file:
# Kill MusioBee
subprocess.Popen(r"taskkill /im MusicBee.exe")
print("Downloading the zip file.")
download_mb_zip(mb_patch_url + target_filename, download_path)
cnt = extract_updated_files(download_path, mb_path)
if cnt == 0:
print("All files are up-to-date.")
else:
print(f"Update/added {cnt} file(s).")
with open(datetime_save_path, mode="w") as f:
f.write(timestamp_str)
# Restart MusicBee
subprocess.Popen(r"C:\\Program Files (x86)\\MusicBee\\MusicBee.exe")
else:
print("No need to download.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment