Как и Skype – Linux-клиент Viber хранит данные в локальной SQLite базе:
$ ls -l ~/.ViberPC/38096***26/ | grep db -rw-r--r-- 1 setevoy setevoy 38912 Jun 30 15:30 data.db -rw-r--r-- 1 setevoy setevoy 32768 Jul 10 10:38 data.db-shm -rw-r--r-- 1 setevoy setevoy 1048032 Jul 10 10:38 data.db-wal -rw-r--r-- 1 setevoy setevoy 5072896 Jul 10 09:59 viber.db -rw-r--r-- 1 setevoy setevoy 32768 Jul 10 10:15 viber.db-shm -rw-r--r-- 1 setevoy setevoy 2329736 Jul 10 10:15 viber.db-wal
История чатов лежит в базе viber.db
.
Задача – бекапить по крону чат с одним контактом, и записывать его в текстовый файл.
Содержание
SQLite
Сначала – проверяем вручную, потом добавим скрипт.
Подключаемся к базе:
[simterm]
$ cd ~/.ViberPC/38096***26 $ sqlite3 viber.db SQLite version 3.19.3 2017-06-08 14:26:16 Enter ".help" for usage hints. sqlite>
[/simterm]
Таблицы тут:
[simterm]
sqlite> .tables Calls ChatsMetaData Events RecycleBin ChatInfo Contact EventsMetaData Settings ChatRecovery DownloadFile LikeRelation UploadFile ChatRelation EventInfo Messages Versions
[/simterm]
Нас интересует eventinfo
, получаем её описание:
[simterm]
sqlite> pragma table_info(eventinfo); 0|EventID|integer|0||0 ... 33|EncryptedNumber|TEXT|0||0 34|Number|TEXT|0||0
[/simterm]
И Contact
:
[simterm]
sqlite> pragma table_info(contact); 0|ContactID|integer|0||1 1|Name|TEXT|0||0 2|ABContact|smallint (0,1)|1|0|0 3|SortName|TEXT|0||0 4|Number|TEXT|0||0 5|ViberContact|smallint (0,1)|1|0|0 6|ClientName|TEXT|0||0 7|DownloadID|TEXT|0||0 8|EncryptedNumber|TEXT|0||0 9|MID|TEXT|0||0 10|VID|TEXT|0||0 11|ContactFlags|long|0|0|0
[/simterm]
Находим пользователя и ID:
[simterm]
sqlite> select name, mid from contact where name='Имя'; Имя|O6ZfYO7jST4=
[/simterm]
Теперь, используя этот ID – находим все сообщения пользователя:
[simterm]
sqlite> select datetime(timestamp, 'unixepoch'), chattoken, body from eventinfo where chattoken like "O6ZfYO7jST4=%" order by timestamp;
[/simterm]
Либо выводим только последние 2 записи:
[simterm]
sqlite> select datetime(timestamp, 'unixepoch'), chattoken, body from eventinfo where chattoken like "O6ZfYO7jST4=%" order by timestamp desc limit 2; 2017-07-10 07:15:46|O6ZfYO7jST4=1494955353356|Согласна 2017-07-10 07:15:28|O6ZfYO7jST4=1494955353356|Господи, ненавижу разговорчивых таксистов... Не умолкает, сцуко!
[/simterm]
Либо сообщения только за сегодня:
[simterm]
sqlite> select datetime(timestamp, 'unixepoch'), chattoken, body from eventinfo where chattoken like "O6ZfYO7jST4=%" and datetime(timestamp, 'unixepoch') like "2017-07-10%" order by timestamp; 2017-07-10 06:07:37|O6ZfYO7jST4=1494955353356| 2017-07-10 06:16:06|O6ZfYO7jST4=1494955353356| 2017-07-10 06:16:10|O6ZfYO7jST4=1494955353356|утречка 2017-07-10 07:15:28|O6ZfYO7jST4=1494955353356|Господи, ненавижу разговорчивых таксистов... Не умолкает, сцуко! 2017-07-10 07:15:46|O6ZfYO7jST4=1494955353356|Согласна
[/simterm]
Python – скрипт бекапа
И последним шагом – небольшой python
-скрипт для бекапа чатов с этим контактом:
#!/usr/bin/env python import os import sys import sqlite3 import datetime # phone number to find path # i.e. /home/setevoy/.ViberPC/380968889900 if len(sys.argv) < 2: print('ERROR: specify your cell num as first argument.') exit(1) # some globals db_name = 'viber.db' dbpath = '/home/setevoy/.ViberPC/' contact_name = "Имя" back_path = '/home/setevoy/Backups/ViberChats' def get_mid(): """Get contact's MID""" cur = conn.cursor() mid = cur.execute("""select name, mid from contact where name='{}';""".format(contact_name)) for i in mid: return(i[1]) def get_todays_history(mid): """Select all messages for today from Contact's MID""" cur = conn.cursor() history_today = cur.execute("""select datetime(timestamp, 'unixepoch'), chattoken, body \ from eventinfo where chattoken like '{mid}%' and datetime(timestamp, 'unixepoch') like "{day}%" \ order by timestamp""".format(mid=mid, day=today)); return history_today def save_history(): """Save all todays messages to /home/setevoy/Backups/ViberChats/Name_datetime""" mid = get_mid() back_file = contact_name + "_" + today if not os.path.isdir(back_path): print('WARNING: o {} directory found, creating.').format(back_path) os.mkdir(back_path) else: print("OK: {} found.".format(back_path)) os.chdir(back_path) with open(back_file, 'w') as bf: for mes in get_todays_history(mid): data = "{}\n".format(mes) bf.write(data) if __name__ == "__main__": my_num = sys.argv[1] # Create database connection, conn = sqlite3.connect(os.path.join(dbpath, my_num, db_name)) # 2017_07_10 today = datetime.datetime.now().strftime('%Y_%m_%d') save_history()
Скрипт можно взять тут>>> (с небольшим изменением – Имя контакта передаётся вторым аргументом).
Его выполнение:
[simterm]
$ ./viber_backup.py 38096***6 OK: /home/setevoy/Backups/ViberChats found.
[/simterm]
Проверяем:
[simterm]
$ ls -l ../Backups/ViberChats/ total 4 -rw-r--r-- 1 setevoy setevoy 836 Jul 10 13:34 Имя_2017_07_1
[/simterm]
Содержимое:
[simterm]
$ cat ../Backups/ViberChats/Имя_2017_07_10 ('2017-07-10 06:07:37', 'O6ZfYO7jST4=1494955353356', None) ('2017-07-10 06:16:06', 'O6ZfYO7jST4=1494955353356', None) ('2017-07-10 06:16:10', 'O6ZfYO7jST4=1494955353356', 'утречка') ('2017-07-10 07:15:28', 'O6ZfYO7jST4=1494955353356', 'Господи, ненавижу разговорчивых таксистов... \nНе умолкает, сцуко!') ('2017-07-10 07:15:46', 'O6ZfYO7jST4=1494955353356', 'Согласна')
[/simterm]
Последним шагом – добавляем задачу в крон:
[simterm]
$ crontab -e
[/simterm]
0 0 * * * /home/setevoy/Work/RTFM/rtfm/14657/viber_backup.py 38096*****26 Имя
Готово.
Каталог ~/Backups
у меня бекапится в AWS S3 с помощью другой утилиты – myBackup.
Из недостатков – смайлики в текстовый файл сохранить проблематично, поэтому они будут None.