-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdbconnect.py
More file actions
106 lines (93 loc) · 3.52 KB
/
dbconnect.py
File metadata and controls
106 lines (93 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#################################
# Programmer: Kenneth Sinder
# Date Created: 2017-02-11
# Filename: dbconnect.py
# Description: SQLite3 DB Querying code for search.py
#################################
import sqlite3
import os
import datetime
import html
class ConversationRetrievalService(object):
"""
Service to retrieve Skype conversations.
Implements `retrieve([bool]) -> list of dict`.
"""
_connection = None
_path = None
_disconnected_string = "Disconnected"
def __init__(self, username):
""" (str) -> ConversationRetrievalService
Requires a valid Skype `username` that has logged in
and had conversations on this computer.
"""
# Determine the path to the main.db file
self._path = os.path.join(os.getenv('APPDATA'), 'skype', username, 'main.db')
if not os.path.isfile(self._path):
raise ValueError("{0} is not a valid username, or no main.db file exists".format(username))
self._connection = sqlite3.connect(self._path)
def __str__(self) -> str:
""" () -> str
Returns a string representation of this `ConversationRetrievalService`.
"""
if self._connection is not None:
return "Connected to main DB at {0}".format(self._path)
return self._disconnected_string
def retrieve(self, close_connection=False):
""" ([bool]) -> list of dict
Returns a list of chat messages in the following format:
[
{'display_name': '___', 'username': '___', 'local_datetime': '2016-01-01 01:01:01',
'message': '___', 'conversation_id': ___},
...
]
Not guaranteed to be in any specific order.
Also closes the database connection afterwards if the given flag is True
"""
cursor = self._connection.cursor()
cursor.execute(QueryResultConverter.query)
result = QueryResultConverter.convert(cursor.fetchall())
if close_connection:
self.cleanup()
return result
def cleanup(self):
""" () -> None
Closes the database connection.
"""
if self._connection is not None:
self._connection.close()
self._connection = None
class QueryResultConverter(object):
"""
Converter from sqlite3 db output to a list
of dictionaries. Provides the required SQL
query.
"""
query = "SELECT from_dispname, author, timestamp, body_xml, convo_id " + \
"FROM Messages ORDER BY timestamp"
@staticmethod
def convert(tuples):
""" (list of tuple) -> list of dict
Database results converter used internally.
"""
result = []
for row in tuples:
message = {}
message['display_name'] = row[0]
message['username'] = row[1]
message['local_datetime'] = QueryResultConverter._convert_timestamp_to_iso(row[2])
message['message'] = '' if not row[3] else html.unescape(row[3])
message['conversation_id'] = row[4]
result.append(message)
return result
@staticmethod
def _convert_timestamp_to_iso(timestamp):
""" (int) -> str
Returns an ISO 8601 representation of the given
Unix timestamp. Time will be local, not UTC, based on
how Skype prepares the Unix timestamps.
"""
dt = datetime.datetime.fromtimestamp(int(timestamp))
return dt.strftime('%Y-%m-%d %H:%M:%S')
if __name__ == '__main__':
print(r"Should execute main script .\search.py instead.")