2015-05-12 22:03:23 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
wakatime.session_cache
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Persist requests.Session for multiprocess SSL handshake pooling.
|
|
|
|
|
|
|
|
:copyright: (c) 2015 Alan Hamlett.
|
|
|
|
:license: BSD, see LICENSE for more details.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import pickle
|
|
|
|
import sys
|
|
|
|
|
|
|
|
try:
|
|
|
|
import sqlite3
|
|
|
|
HAS_SQL = True
|
2015-09-29 10:11:25 +00:00
|
|
|
except ImportError: # pragma: nocover
|
2015-05-12 22:03:23 +00:00
|
|
|
HAS_SQL = False
|
|
|
|
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'packages'))
|
|
|
|
|
|
|
|
from .packages import requests
|
|
|
|
|
|
|
|
|
|
|
|
log = logging.getLogger('WakaTime')
|
|
|
|
|
|
|
|
|
|
|
|
class SessionCache(object):
|
|
|
|
DB_FILE = os.path.join(os.path.expanduser('~'), '.wakatime.db')
|
|
|
|
|
|
|
|
def connect(self):
|
|
|
|
conn = sqlite3.connect(self.DB_FILE)
|
|
|
|
c = conn.cursor()
|
|
|
|
c.execute('''CREATE TABLE IF NOT EXISTS session (
|
|
|
|
value BLOB)
|
|
|
|
''')
|
|
|
|
return (conn, c)
|
|
|
|
|
|
|
|
|
|
|
|
def save(self, session):
|
|
|
|
"""Saves a requests.Session object for the next heartbeat process.
|
|
|
|
"""
|
|
|
|
|
2015-09-29 10:11:25 +00:00
|
|
|
if not HAS_SQL: # pragma: nocover
|
2015-05-12 22:03:23 +00:00
|
|
|
return
|
|
|
|
try:
|
|
|
|
conn, c = self.connect()
|
|
|
|
c.execute('DELETE FROM session')
|
|
|
|
values = {
|
2015-08-28 22:05:55 +00:00
|
|
|
'value': sqlite3.Binary(pickle.dumps(session, protocol=2)),
|
2015-05-12 22:03:23 +00:00
|
|
|
}
|
|
|
|
c.execute('INSERT INTO session VALUES (:value)', values)
|
|
|
|
conn.commit()
|
|
|
|
conn.close()
|
2015-09-29 10:11:25 +00:00
|
|
|
except: # pragma: nocover
|
2016-03-06 20:48:42 +00:00
|
|
|
log.traceback('debug')
|
2015-05-12 22:03:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get(self):
|
|
|
|
"""Returns a requests.Session object.
|
|
|
|
|
|
|
|
Gets Session from sqlite3 cache or creates a new Session.
|
|
|
|
"""
|
|
|
|
|
2015-09-29 10:11:25 +00:00
|
|
|
if not HAS_SQL: # pragma: nocover
|
2015-05-12 22:03:23 +00:00
|
|
|
return requests.session()
|
|
|
|
|
|
|
|
try:
|
|
|
|
conn, c = self.connect()
|
|
|
|
except:
|
2016-03-06 20:48:42 +00:00
|
|
|
log.traceback('debug')
|
2015-05-12 22:03:23 +00:00
|
|
|
return requests.session()
|
|
|
|
|
|
|
|
session = None
|
|
|
|
try:
|
|
|
|
c.execute('BEGIN IMMEDIATE')
|
|
|
|
c.execute('SELECT value FROM session LIMIT 1')
|
|
|
|
row = c.fetchone()
|
|
|
|
if row is not None:
|
|
|
|
session = pickle.loads(row[0])
|
2015-09-29 10:11:25 +00:00
|
|
|
except: # pragma: nocover
|
2016-03-06 20:48:42 +00:00
|
|
|
log.traceback('debug')
|
2015-05-12 22:03:23 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
conn.close()
|
2015-09-29 10:11:25 +00:00
|
|
|
except: # pragma: nocover
|
2016-03-06 20:48:42 +00:00
|
|
|
log.traceback('debug')
|
2015-05-12 22:03:23 +00:00
|
|
|
|
|
|
|
return session if session is not None else requests.session()
|
|
|
|
|
|
|
|
|
|
|
|
def delete(self):
|
|
|
|
"""Clears all cached Session objects.
|
|
|
|
"""
|
|
|
|
|
2015-09-29 10:11:25 +00:00
|
|
|
if not HAS_SQL: # pragma: nocover
|
2015-05-12 22:03:23 +00:00
|
|
|
return
|
|
|
|
try:
|
|
|
|
conn, c = self.connect()
|
|
|
|
c.execute('DELETE FROM session')
|
|
|
|
conn.commit()
|
|
|
|
conn.close()
|
|
|
|
except:
|
2016-03-06 20:48:42 +00:00
|
|
|
log.traceback('debug')
|