Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

The loan stats are now stored in stats table in postgres.

The couchdb stats database is still updated, but will go away
eventually.
  • Loading branch information...
commit 981b15dbd47a877a64c32bfa70a75fac7dd599bf 1 parent 81422a4
@anandology anandology authored
View
12 openlibrary/core/schema.py
@@ -38,6 +38,18 @@ def get_schema():
$$ LANGUAGE SQL IMMUTABLE;
CREATE INDEX thing_olid_idx ON thing(get_olid(key));
+
+ CREATE TABLE stats (
+ id serial primary key,
+ key text unique,
+ type text,
+ created timestamp without time zone,
+ updated timestamp without time zone,
+ json text
+ );
+ CREATE INDEX stats_type_idx ON stats(type);
+ CREATE INDEX stats_created_idx ON stats(created);
+ CREATE INDEX stats_updated_idx ON stats(updated);
"""
# monkey patch schema.sql to include the custom functions
View
59 openlibrary/core/statsdb.py
@@ -0,0 +1,59 @@
+"""Interface to Open Library stats database.
+
+The stats table in the openlibrary database is of the following schema:
+
+ CREATE TABLE stats (
+ id serial primary key,
+ key text unique,
+ type text,
+ timestamp timestamp without time zone,
+ json text
+ );
+
+see schema.py for more details.
+"""
+import logging
+import web
+import simplejson
+import datetime
+
+logger = logging.getLogger("openlibrary.statsdb")
+
+@web.memoize
+def get_db():
+ return web.database(**web.config.db_parameters)
+
+def add_entry(key, data, timestamp=None):
+ """Adds a new entry to the stats table.
+
+ If an entry is already present in the table, a warn message is logged
+ and no changes will be made to the database.
+ """
+ jsontext = simplejson.dumps(data)
+ timestamp = timestamp or datetime.datetime.utcnow()
+ t = timestamp.isoformat()
+
+ db = get_db()
+ result = db.query("SELECT * FROM stats WHERE key=$key", vars=locals())
+ if result:
+ logger.warn("Failed to add stats entry with key %r. An entry is already present.")
+ else:
+ db.insert("stats", type='loan', key=key, created=t, updated=t, json=jsontext)
+
+def update_entry(key, data, timestamp=None):
+ """Updates an already existing entry in the stats table.
+
+ If there is no entry with the given key, a new one will be added
+ after logging a warn message.
+ """
+ jsontext = simplejson.dumps(data)
+ timestamp = timestamp or datetime.datetime.utcnow()
+ t = timestamp.isoformat()
+
+ db = get_db()
+ result = db.query("SELECT * FROM stats WHERE key=$key", vars=locals())
+ if result:
+ db.update("stats", json=jsontext, updated=t, where="key=$key", vars=locals())
+ else:
+ logger.warn("stats entry with key %r doesn't exist to update. adding new entry...", key)
+ db.insert("stats", type='loan', key=key, created=t, updated=t, json=jsontext)
View
42 openlibrary/plugins/openlibrary/libraries.py
@@ -13,7 +13,7 @@
from infogami import config
from infogami.utils import delegate
from infogami.utils.view import render_template, add_flash_message, public
-from openlibrary.core import inlibrary
+from openlibrary.core import inlibrary, statsdb
from openlibrary import accounts
from openlibrary.core.iprange import find_bad_ip_ranges
@@ -565,8 +565,48 @@ def on_loan_completed(loan):
else:
logger.warn("loan document missing in the stats database: %r", key)
+def on_loan_created_statsdb(loan):
+ """Adds the loan info to the stats database.
+ """
+ key = _get_loan_key(loan)
+ t_start = datetime.datetime.utcfromtimestamp(loan['loaned_at'])
+ d = {
+ "book": loan['book'],
+ "resource_type": loan['resource_type'],
+ "t_start": t_start.isoformat(),
+ "status": "active"
+ }
+ library = inlibrary.get_library()
+ d['library'] = library and library.key
+ statsdb.add_entry(key, d)
+
+def on_loan_completed_statsdb(loan):
+ """Marks the loan as completed in the stats database.
+ """
+ key = _get_loan_key(loan)
+ t_start = datetime.datetime.utcfromtimestamp(loan['loaned_at'])
+ t_end = datetime.datetime.utcfromtimestamp(loan['returned_at'])
+ d = {
+ "book": loan['book'],
+ "resource_type": loan['resource_type'],
+ "t_start": t_start.isoformat(),
+ "t_end": t_end.isoformat(),
+ "status": "completed",
+ }
+ statsdb.update_entry(key, d)
+
+def _get_loan_key(loan):
+ # The loan key is now changed from uuid to fixed key.
+ # Using _key as key for loan stats will result in overwriting previous loans.
+ # Using the unique uuid to create the loan key and falling back to _key
+ # when uuid is not available.
+ return "loans/" + loan.get("uuid") or loan["_key"]
+
def setup():
from openlibrary.core import msgbroker
msgbroker.subscribe("loan-created", on_loan_created)
msgbroker.subscribe("loan-completed", on_loan_completed)
+
+ msgbroker.subscribe("loan-created", on_loan_created_statsdb)
+ msgbroker.subscribe("loan-completed", on_loan_completed_statsdb)
Please sign in to comment.
Something went wrong with that request. Please try again.