1
0
mirror of https://github.com/mikf/gallery-dl.git synced 2024-11-22 10:42:34 +01:00
gallery-dl/gallery_dl/cache.py
2016-03-05 17:49:18 +01:00

97 lines
2.7 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2016 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
import sqlite3
import pickle
import time
import tempfile
import os
from . import config
class CacheInvalidError(Exception):
pass
def init_database():
global _db
path_default = os.path.join(tempfile.gettempdir(), ".gallery-dl.cache")
path = config.get(("cache", "file"), path_default)
# timeout = config.get(("cache", "timeout"), 30)
_db = sqlite3.connect(path, timeout=30)
_db.execute("CREATE TABLE IF NOT EXISTS data ("
"key TEXT PRIMARY KEY,"
"value TEXT,"
"expires INTEGER"
")")
def cache(max_age=3600):
"""decorator - cache function return values in memory and database"""
def wrap(func):
key = "{}.{}".format(func.__module__, func.__name__)
def wrapped(*args):
timestamp = time.time()
try:
result = lookup_cache(timestamp)
except CacheInvalidError:
try:
result = func(*args)
expires = int(timestamp+max_age)
_cache[key] = (result, expires)
_db.execute("INSERT OR REPLACE INTO data VALUES (?,?,?)",
(key, pickle.dumps(result), expires))
finally:
_db.commit()
return result
def lookup_cache(timestamp):
try:
result, expires = _cache[key]
if timestamp < expires:
return result
except KeyError:
pass
result, expires = lookup_database(timestamp)
_cache[key] = (result, expires)
return result
def lookup_database(timestamp):
try:
cursor = _db.cursor()
cursor.execute("BEGIN EXCLUSIVE")
cursor.execute("SELECT value, expires FROM data WHERE key=?",
(key,))
result, expires = cursor.fetchone()
if timestamp < expires:
_db.commit()
return pickle.loads(result), expires
except Exception as e:
print(e)
raise CacheInvalidError()
return wrapped
return wrap
# --------------------------------------------------------------------
# internals
_db = None
_cache = {}
# @cache(50)
# def f():
# time.sleep(15)
# print("called f()")
# return 1
# init_database()
# for i in range(10):
# print(f())
# time.sleep(1)
# print(f())