Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
manu
committed
Mar 1, 2017
1 parent
814fd28
commit f54d28a
Showing
5 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/usr/bin/python2 | ||
# -*- coding: utf-8 -*- | ||
|
||
from memacs.whatsapp import WhatsApp | ||
|
||
PROG_VERSION_NUMBER = u"0.1" | ||
PROG_VERSION_DATE = u"2017-02-28" | ||
PROG_SHORT_DESCRIPTION = u"Memacs for whatsapp" | ||
PROG_TAG = u"whatsapp" | ||
|
||
COPYRIGHT_YEAR = "2017" | ||
COPYRIGHT_AUTHORS = """Manuel Koell <mankoell@gmail.com>""" | ||
|
||
if __name__ == "__main__": | ||
memacs = WhatsApp( | ||
prog_version=PROG_VERSION_NUMBER, | ||
prog_version_date=PROG_VERSION_DATE, | ||
prog_short_description=PROG_SHORT_DESCRIPTION, | ||
prog_tag=PROG_TAG, | ||
copyright_year=COPYRIGHT_YEAR, | ||
copyright_authors=COPYRIGHT_AUTHORS | ||
) | ||
memacs.handle_main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
## This file is best viewed with GNU Emacs Org-mode: http://orgmode.org/ | ||
|
||
* memacs-whatsapp | ||
|
||
In order to use this memacs module you need the decrypted msgstore.db file. | ||
The easiest way is to use an android phone (rooted) and copy the file from | ||
~/data/data/com.whatsapp/databases/msgstore.db~. | ||
|
||
** Options | ||
|
||
- ~-f~, ~--file~ path to decrypted msgstore.db file | ||
- ~--ignore-incoming~ ignore received messages | ||
- ~--ignore-outgoing~ ignore sent messages | ||
- ~--output-format~ format string to use for the headline, default ~{verb} [[{handler}:{number}][{number}]]: {text}~ | ||
- ~--set-handler~ set link handler, default ~tel~ | ||
- ~--demojize~ replace emoji with the appropriate ~:short_code:~ | ||
- ~--skip-emoji~ skip all emoji (including emoji only messages) | ||
|
||
** Example | ||
|
||
#+BEGIN_EXAMPLE | ||
memacs_whatsapp.py -f /path/to/msgstore.db --output-format '{text}' | ||
#+END_EXAMPLE | ||
|
||
#+BEGIN_EXAMPLE | ||
** <2016-10-15 Sat 20:18> Hello World! | ||
:PROPERTIES: | ||
:TYPE: INCOMING | ||
:NUMBER: 00436604444333 | ||
:ID: d8fa64a86286432a42a13f129cad0d7ebd56873e | ||
:END: | ||
#+END_EXAMPLE |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# -*- coding: utf-8 -*- | ||
# Time-stamp: <2011-10-28 15:13:31> | ||
|
||
import os | ||
import time | ||
import unittest | ||
|
||
from memacs.whatsapp import WhatsApp | ||
|
||
|
||
class TestWhatsApp(unittest.TestCase): | ||
|
||
def setUp(self): | ||
msgstore = os.path.join( | ||
os.path.dirname(os.path.abspath(__file__)), 'data', 'msgstore.db' | ||
) | ||
|
||
self.argv = [] | ||
self.argv.append('-f') | ||
self.argv.append(msgstore) | ||
|
||
def test_whatsapp(self): | ||
self.argv.append('--output-format') | ||
self.argv.append('{text}') | ||
|
||
memacs = WhatsApp(argv=self.argv) | ||
data = memacs.test_get_entries() | ||
|
||
self.assertEqual(data[0], '** <2016-10-15 Sat 20:18> Hello World!') | ||
self.assertEqual(data[1], ' :PROPERTIES:') | ||
self.assertEqual(data[2], ' :TYPE: INCOMING') | ||
self.assertEqual(data[3], ' :NUMBER: 00436604444333') | ||
self.assertEqual(data[4], ' :ID: d8fa64a86286432a42a13f129cad0d7ebd56873e') | ||
self.assertEqual(data[5], ' :END:') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# Time-stamp: <2017-02-07 19:25 manu> | ||
|
||
import sqlite3 | ||
import logging | ||
import datetime | ||
import json | ||
import time | ||
import sys | ||
import os | ||
import re | ||
|
||
import emoji | ||
|
||
from lib.orgproperty import OrgProperties | ||
from lib.orgformat import OrgFormat | ||
from lib.memacs import Memacs | ||
|
||
|
||
class WhatsApp(Memacs): | ||
def _parser_add_arguments(self): | ||
""" | ||
overwritten method of class Memacs | ||
add additional arguments | ||
""" | ||
Memacs._parser_add_arguments(self) | ||
|
||
self._parser.add_argument( | ||
"-f", "--file", dest="msgstore", | ||
action="store", type=file, required=True, | ||
help="path to decrypted msgstore.db file") | ||
|
||
self._parser.add_argument( | ||
"--ignore-incoming", dest="ignore_incoming", | ||
action="store_true", help="ignore received messages") | ||
|
||
self._parser.add_argument( | ||
"--ignore-outgoing", dest="ignore_outgoing", | ||
action="store_true", help="ignore sent messages") | ||
|
||
self._parser.add_argument( | ||
"--output-format", dest="output_format", | ||
action="store", default="{verb} [[{handler}:{number}][{number}]]: {text}", | ||
help="format string to use for the headline") | ||
|
||
self._parser.add_argument( | ||
"--set-handler", dest="handler", | ||
action="store", default="tel", | ||
help="set link handler") | ||
|
||
self._parser.add_argument( | ||
"--demojize", dest="demojize", | ||
action="store_true", help="replace emoji with the appropriate :shortcode:") | ||
|
||
self._parser.add_argument( | ||
"--skip-emoji", dest="skip_emoji", | ||
action="store_true", help="skip all emoji") | ||
|
||
def _parser_parse_args(self): | ||
""" | ||
overwritten method of class Memacs | ||
all additional arguments are parsed in here | ||
""" | ||
Memacs._parser_parse_args(self) | ||
|
||
def _is_ignored(self, msg): | ||
"""check for ignored message type""" | ||
|
||
if msg['type'] is 'INCOMING' and self._args.ignore_incoming: | ||
return True | ||
|
||
if msg['type'] is 'OUTGOING' and self._args.ignore_outgoing: | ||
return True | ||
|
||
def _handle_message(self, msg): | ||
"""parse a single message row""" | ||
|
||
msg['number'] = '00' + msg['number'].split('@')[0] | ||
msg['verb'] = 'to' if msg['type'] else 'from' | ||
msg['type'] = 'OUTGOING' if msg['type'] else 'INCOMING' | ||
msg['handler'] = self._args.handler | ||
|
||
if msg['text']: | ||
if self._args.demojize: | ||
msg['text'] = emoji.demojize(msg['text']) | ||
|
||
if self._args.skip_emoji: | ||
msg['text'] = re.sub(emoji.get_emoji_regexp(), '', msg['text']) | ||
|
||
timestamp = datetime.datetime.fromtimestamp(msg['timestamp'] / 1000) | ||
|
||
properties = OrgProperties(data_for_hashing=json.dumps(msg)) | ||
properties.add('NUMBER', msg['number']) | ||
properties.add('TYPE', msg['type']) | ||
|
||
output = self._args.output_format.decode('utf-8').format(**msg) | ||
|
||
if msg['text'] and not self._is_ignored(msg): | ||
self._writer.write_org_subitem(timestamp=OrgFormat.datetime(timestamp), | ||
output=output, properties=properties) | ||
|
||
def _main(self): | ||
""" | ||
get's automatically called from Memacs class | ||
""" | ||
|
||
conn = sqlite3.connect(os.path.abspath(self._args.msgstore.name)) | ||
query = conn.execute('SELECT * FROM messages') | ||
|
||
for row in query: | ||
self._handle_message({ | ||
'timestamp': row[7], | ||
'number': row[1], | ||
'type': row[2], | ||
'text': row[6] | ||
}) | ||
|
||
logging.debug(row) |