Skip to content

Instantly share code, notes, and snippets.

@hucsmn
Created August 30, 2015 11:54
Show Gist options
  • Save hucsmn/0e86ddbcb09011e1cce9 to your computer and use it in GitHub Desktop.
Save hucsmn/0e86ddbcb09011e1cce9 to your computer and use it in GitHub Desktop.
自动下载 github 上的软件
#!/usr/bin/env python3
import sys, os, subprocess, time
import re, json
from collections import namedtuple
from urllib.request import urlopen
class AddressError(Exception): pass
class DownloadError(Exception): pass
class File(namedtuple("File", "name, type, size, url, ctime, mtime")):
def download(self, out, downloadcmd = "curl -sLo {out} {url}".split()):
try:
cmd = [i.format(url=self.url, out=out) for i in downloadcmd]
subprocess.check_call(cmd)
mtime = time.mktime(self.mtime)
os.utime(out, (mtime, mtime))
except Exception as err:
raise DownloadError(str(err))
class Repo:
_addrpat = re.compile(r"^(?:(?:https?://)?(?:www\.)?github.com/)?(?P<user>[\w-]+)/(?P<repo>[\w-]+)/?$")
_timefmt = "%Y-%m-%dT%H:%M:%SZ"
def __init__(self, addr):
m = self._addrpat.match(addr)
if m is None:
raise AddressError(addr)
self.user = m.group('user')
self.repo = m.group('repo')
def refresh(self):
rawdata = urlopen("https://api.github.com/repos/%s/%s/releases" % (self.user, self.repo)).read().decode('utf-8')
data = json.loads(rawdata)
self.releases = []
for release in data:
files = []
for info in release['assets']:
name = info['name']
type = info['content_type']
size = info['size']
url = info['browser_download_url']
ctime = time.strptime(info['created_at'], self._timefmt)
mtime = time.strptime(info['updated_at'], self._timefmt)
files.append(File(name, type, size, url, ctime, mtime))
self.releases.append((release['name'], files))
repos = [Repo(i) for i in sys.argv[1:]]
if len(repos) == 0:
os.exit(1)
while True:
for repo in repos:
repo.refresh()
version, files = repo.releases[0]
file = files[0]
out = os.path.join(os.getcwd(), repo.repo + os.path.splitext(file.name)[1])
try:
try:
mtime = time.localtime(os.stat(out).st_mtime)
if file.mtime > mtime:
print("%s: updating..." % repo.repo, end='', flush=True)
file.download(out)
print("done []" % version)
else:
print("%s: already updated to %s" % (repo.repo, version))
except FileNotFoundError:
print("%s: initial syncing..." % repo.repo, end='', flush=True)
file.download(out)
print("done [%s]" % version)
except DownloadError as err:
print("failed [%s]" % err)
time.sleep(6 * 3600)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment