├── .gitignore
├── config-db.sample.php
├── contacts.php
├── archive.php
├── export-sql.php
├── export-csv.php
├── include.php
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | messages/*
2 | .DS_Store
3 | contacts.txt
4 | last.txt
5 | vendor/
6 | config-db.php
7 |
--------------------------------------------------------------------------------
/config-db.sample.php:
--------------------------------------------------------------------------------
1 | 'aaronpk',
4 | 'host' => '127.0.0.1',
5 | 'username' => 'root',
6 | 'password' => ''
7 | );
8 |
--------------------------------------------------------------------------------
/contacts.php:
--------------------------------------------------------------------------------
1 | query('SELECT * FROM handle');
12 | while($q = $query->fetch(PDO::FETCH_ASSOC)) {
13 | if(!in_array($q['id'], $contacts)) {
14 | echo $q['id'] . "\n";
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/archive.php:
--------------------------------------------------------------------------------
1 | fetch(PDO::FETCH_ASSOC)) {
15 | $fn = filename_for_message($line['contact'], $line['date']);
16 | echo $fn."\n";
17 | if(!file_exists(dirname($fn))) {
18 | mkdir(dirname($fn));
19 | }
20 | if(!file_exists($fn)) {
21 | file_put_contents($fn, html_template());
22 | }
23 |
24 | $attachment_query = $db->query('SELECT attachment.*
25 | FROM attachment
26 | JOIN message_attachment_join ON message_attachment_join.attachment_id=attachment.ROWID
27 | WHERE message_attachment_join.message_id = ' . $line['ROWID']);
28 | $attachments = array();
29 | while($attachment = $attachment_query->fetch(PDO::FETCH_ASSOC)) {
30 | $attachments[] = $attachment;
31 | }
32 |
33 | if(!entry_exists($line, $attachments, $fn)) {
34 | $fp = fopen($fn, 'a');
35 | $log = format_line($line, $attachments);
36 | fwrite($fp, $log."\n");
37 | fclose($fp);
38 | echo date('c', $line['date']) . "\t" . $line['contact'] . "\t" . $line['text'] . "\n";
39 | foreach($attachments as $at) {
40 | $imgsrc = attachment_folder($line['contact'], $line['date']) . $at['transfer_name'];
41 | if(!file_exists(dirname($imgsrc)))
42 | mkdir(dirname($imgsrc));
43 | copy(str_replace('~/',$_SERVER['HOME'].'/',$at['filename']), $imgsrc);
44 | }
45 | }
46 |
47 | if($line['date'] > $last_timestamp) {
48 | $last_timestamp = $line['date'];
49 | }
50 | }
51 |
52 | if($last_timestamp > 0)
53 | file_put_contents($last_fn, $last_timestamp);
54 |
55 |
--------------------------------------------------------------------------------
/export-sql.php:
--------------------------------------------------------------------------------
1 | exec('SET CHARACTER SET utf8mb4');
8 |
9 | $query = $sql->prepare('SELECT * FROM messages ORDER BY date DESC LIMIT 1');
10 | $query->execute();
11 | $last = $query->fetch(PDO::FETCH_OBJ);
12 | if($last) {
13 | $last = $last->timestamp;
14 | } else {
15 | $last = 0;
16 | }
17 |
18 | $insert = $sql->prepare('INSERT INTO messages
19 | (`timestamp`, `date`, `time`, `from`, `from_name`, `to`, `to_name`, `message`, `num_emoji`, `num_attachments`)
20 | VALUES(?,?,?,?,?,?,?,?,?,?)');
21 |
22 | $query = query_messages_since($db, $last);
23 | $last_timestamp = 0;
24 | while($line = $query->fetch(PDO::FETCH_ASSOC)) {
25 |
26 | $attachment_query = $db->query('SELECT attachment.*
27 | FROM attachment
28 | JOIN message_attachment_join ON message_attachment_join.attachment_id=attachment.ROWID
29 | WHERE message_attachment_join.message_id = ' . $line['ROWID']);
30 | $attachments = array();
31 | while($attachment = $attachment_query->fetch(PDO::FETCH_ASSOC)) {
32 | $attachments[] = $attachment;
33 | }
34 |
35 | if($line['is_from_me']) {
36 | $from = $me;
37 | $to = $line['contact'];
38 | } else {
39 | $from = $line['contact'];
40 | $to = $me;
41 | }
42 | $from_name = contact_name($from);
43 | $to_name = contact_name($to);
44 |
45 | $num_emoji = 0;
46 | if(preg_match_all('/(?:[0-9|#][\x{20E3}])|[\x{00ae}|\x{00a9}|\x{203C}|\x{2047}|\x{2048}|\x{2049}|\x{3030}|\x{303D}|\x{2139}|\x{2122}|\x{3297}|\x{3299}][\x{FE00}-\x{FEFF}]?|[\x{2190}-\x{21FF}][\x{FE00}-\x{FEFF}]?|[\x{2300}-\x{23FF}][\x{FE00}-\x{FEFF}]?|[\x{2460}-\x{24FF}][\x{FE00}-\x{FEFF}]?|[\x{25A0}-\x{25FF}][\x{FE00}-\x{FEFF}]?|[\x{2600}-\x{27BF}][\x{FE00}-\x{FEFF}]?|[\x{2900}-\x{297F}][\x{FE00}-\x{FEFF}]?|[\x{2B00}-\x{2BF0}][\x{FE00}-\x{FEFF}]?|[\x{1F000}-\x{1F6FF}][\x{FE00}-\x{FEFF}]?/u', $line['text'], $matches)) {
47 | $num_emoji = count($matches[0]);
48 | }
49 |
50 | $insert->bindValue(1, $line['date']);
51 | $insert->bindValue(2, date('Y-m-d', $line['date']));
52 | $insert->bindValue(3, date('H:i:s', $line['date']));
53 | $insert->bindValue(4, $from);
54 | $insert->bindValue(5, $from_name);
55 | $insert->bindValue(6, $to);
56 | $insert->bindValue(7, $to_name);
57 | $insert->bindValue(8, trim($line['text']));
58 | $insert->bindValue(9, $num_emoji);
59 | $insert->bindValue(10, count($attachments));
60 | $insert->execute();
61 |
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/export-csv.php:
--------------------------------------------------------------------------------
1 | fetch(PDO::FETCH_ASSOC)) {
48 |
49 | $attachment_query = $db->query('SELECT attachment.*
50 | FROM attachment
51 | JOIN message_attachment_join ON message_attachment_join.attachment_id=attachment.ROWID
52 | WHERE message_attachment_join.message_id = ' . $line['ROWID']);
53 | $attachments = array();
54 | while($attachment = $attachment_query->fetch(PDO::FETCH_ASSOC)) {
55 | $attachments[] = $attachment;
56 | }
57 |
58 | if($line['is_from_me']) {
59 | $from = $me;
60 | $to = $line['contact'];
61 | } else {
62 | $from = $line['contact'];
63 | $to = $me;
64 | }
65 | $from_name = contact_name($from);
66 | $to_name = contact_name($to);
67 |
68 | $num_emoji = 0;
69 | if(preg_match_all('/(?:[0-9|#][\x{20E3}])|[\x{00ae}|\x{00a9}|\x{203C}|\x{2047}|\x{2048}|\x{2049}|\x{3030}|\x{303D}|\x{2139}|\x{2122}|\x{3297}|\x{3299}][\x{FE00}-\x{FEFF}]?|[\x{2190}-\x{21FF}][\x{FE00}-\x{FEFF}]?|[\x{2300}-\x{23FF}][\x{FE00}-\x{FEFF}]?|[\x{2460}-\x{24FF}][\x{FE00}-\x{FEFF}]?|[\x{25A0}-\x{25FF}][\x{FE00}-\x{FEFF}]?|[\x{2600}-\x{27BF}][\x{FE00}-\x{FEFF}]?|[\x{2900}-\x{297F}][\x{FE00}-\x{FEFF}]?|[\x{2B00}-\x{2BF0}][\x{FE00}-\x{FEFF}]?|[\x{1F000}-\x{1F6FF}][\x{FE00}-\x{FEFF}]?/u', $line['text'], $matches)) {
70 | $num_emoji = count($matches[0]);
71 | }
72 |
73 | fputcsv($fp, array(
74 | $line['date'],
75 | date('Y-m-d', $line['date']),
76 | date('H:i:s', $line['date']),
77 | $from,
78 | $from_name,
79 | $to,
80 | $to_name,
81 | trim($line['text']),
82 | $num_emoji,
83 | count($attachments)
84 | ));
85 |
86 | }
87 |
88 | fclose($fp);
89 |
90 |
--------------------------------------------------------------------------------
/include.php:
--------------------------------------------------------------------------------
1 | $key) {
15 | $data[trim($key)] = trim($matches[2][$i]);
16 | }
17 | }
18 | return $data;
19 | }
20 |
21 | function contact($id) {
22 | $data = load_contacts();
23 |
24 | if(preg_match('/.+@.+\..+/', $id)) {
25 | $href = 'mailto:' . $id;
26 | } else {
27 | $href = 'sms:' . $id;
28 | }
29 |
30 | if(array_key_exists($id, $data)) {
31 | return '' . $data[$id] . '';
32 | } else {
33 | return '' . $id . '';
34 | }
35 | }
36 |
37 | function contact_name($id) {
38 | $data = load_contacts();
39 | if(array_key_exists($id, $data)) {
40 | return $data[$id];
41 | } else {
42 | return $id;
43 | }
44 | }
45 |
46 | function query_messages_since(&$db, $timestamp) {
47 | return $db->query('SELECT message.ROWID, substr(date,1,9)+978307200 AS date,
48 | message.text, is_from_me, handle.id AS contact
49 | FROM message
50 | LEFT JOIN handle ON message.handle_id = handle.ROWID
51 | WHERE cache_roomnames IS NULL
52 | AND substr(date,1,9)+978307200 > ' . $timestamp . '
53 | ORDER BY date
54 | ');
55 | }
56 |
57 | function filename_for_message($contact, $ts) {
58 | $folder = contact_name($contact);
59 | return 'messages/' . $folder . '/' . date('Y-m', $ts) . '.html';
60 | }
61 |
62 | function attachment_folder($contact, $ts, $relative=false) {
63 | $folder = contact_name($contact);
64 | return ($relative ? '' : 'messages/' . $folder . '/') . date('Y-m', $ts) . '/';
65 | }
66 |
67 | function format_line($line, $attachments) {
68 | global $me;
69 |
70 | if($line['is_from_me'])
71 | $contact = $me;
72 | else
73 | $contact = $line['contact'];
74 |
75 | $attachments_html = '';
76 |
77 | if(count($attachments)) {
78 | foreach($attachments as $at) {
79 | $imgsrc = attachment_folder($line['contact'], $line['date'], true) . $at['transfer_name'];
80 | $attachments_html .= '';
81 | }
82 | }
83 |
84 | return '