|
#!/usr/bin/python3 |
|
# -*- coding: utf-8 -*- |
|
import cgi |
|
import datetime |
|
import os |
|
import vk_api |
|
|
|
import simplejson as json |
|
|
|
start_file = """ |
|
<!DOCTYPE html> |
|
<head> |
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
|
<link rel="stylesheet" type="text/css" href="../style.css" /> |
|
</head> |
|
|
|
<body> |
|
<div class="message_list"> |
|
""" |
|
|
|
end_file = """ |
|
</div> |
|
</body> |
|
</html> |
|
""" |
|
|
|
message_template = """ |
|
<div class="message"> |
|
<div class="avatar"> |
|
<img width="32" height="32" src="{avatar}"/> |
|
</div> |
|
|
|
<div class="date right"><a name="{id}" href="http://vk.com/im?msgid={id}&sel={sel}">#{id} {date}</a></div> |
|
<div class="username"><a href="http://vk.com/id{user_id}">{user_name}</a></div> |
|
|
|
<div class="left"> |
|
<div class="body">{body}</div> |
|
|
|
<div class="attachments"> |
|
{fwd}{attachments} |
|
</div> |
|
</div> |
|
<div class="clear"></div> |
|
</div> |
|
""" |
|
|
|
fwd_template = """ |
|
<div class="fwd_message"> |
|
<div class="avatar"> |
|
<img width="32" height="32" src="{avatar}"/> |
|
</div> |
|
|
|
<div class="username username_fwd"><a href="http://vk.com/id{user_id}">{user_name}</a></div> |
|
<div class="date date_fwd"><a href="http://vk.com/im?msgid={id}&sel={sel}">{date}</a></div> |
|
<div class="clear"></div> |
|
|
|
<div class="left"> |
|
<div class="body">{body}</div> |
|
|
|
<div class="fwd_attachments"> |
|
{fwd}{attachments} |
|
</div> |
|
</div> |
|
<div class="clear"></div> |
|
</div> |
|
""" |
|
|
|
info_template = """ |
|
<div class="message"> |
|
<a href="http://vk.com/im?sel={sel}">Link</a> |
|
</div> |
|
""" |
|
|
|
photo_template = """ |
|
<a href="{fullsize}"><img src="{thumbnail}" /></a> |
|
""" |
|
|
|
PHOTO_SIZES = ( |
|
'photo_75', 'photo_130', 'photo_604', |
|
'photo_807', 'photo_1280', 'photo_2560' |
|
) |
|
|
|
|
|
def get_photo_attach(photo): |
|
thumbnail = photo['photo_130'] |
|
fullsize = None |
|
|
|
for i in PHOTO_SIZES[::-1]: |
|
if i in photo: |
|
fullsize = photo[i] |
|
break |
|
|
|
return {'thumbnail': thumbnail, 'fullsize': fullsize} |
|
|
|
|
|
class Message(object): |
|
def __init__(self, raw, users, sel, template=message_template): |
|
self.raw = raw |
|
self.users = users |
|
self.sel = sel |
|
self.template = template |
|
|
|
def get_body(self): |
|
body = cgi.escape(self.raw['body']).replace('\n', '<br/>') |
|
return body |
|
|
|
def __str__(self): |
|
try: |
|
if 'from_id' in self.raw: |
|
from_user = self.users[self.raw['from_id']] |
|
elif 'user_id' in self.raw: |
|
from_user = self.users[self.raw['user_id']] |
|
except: |
|
from_user = { |
|
'photo_50': 'http://vk.com/images/deactivated_c.gif', |
|
'id': '0', |
|
'first_name': 'DELETED', |
|
'last_name': '' |
|
} |
|
|
|
date = datetime.datetime.fromtimestamp(self.raw['date']) |
|
fwd_messages = [] |
|
|
|
for i in self.raw.get('fwd_messages', []): |
|
fwd_messages.append(Message(i, self.users, self.sel, fwd_template)) |
|
|
|
attachments = [] |
|
|
|
for attach in self.raw.get('attachments', ()): |
|
if attach['type'] == 'photo': |
|
photo = get_photo_attach(attach['photo']) |
|
attachments.append( |
|
photo_template.format(**photo) |
|
) |
|
else: |
|
attachments.append('<div>{}</div>'.format(attach['type'])) |
|
|
|
values = { |
|
'id': self.raw.get('id', ''), |
|
'sel': self.sel, |
|
'avatar': from_user['photo_50'], |
|
'date': date.strftime('%d.%m.%Y %H:%M'), |
|
'user_id': from_user['id'], |
|
'user_name': ' '.join([from_user['first_name'], |
|
from_user['last_name']]), |
|
'body': self.get_body(), |
|
'attachments': ''.join(attachments), |
|
'fwd': '\n'.join(str(i) for i in fwd_messages) |
|
} |
|
|
|
return self.template.format(**values) |
|
|
|
|
|
class Main(object): |
|
def __init__(self): |
|
self.vk = vk_api.VkApi() |
|
|
|
self.users = {} |
|
|
|
def get_user(self, ids): |
|
values = { |
|
'user_ids': ','.join(str(i) for i in ids), |
|
'fields': 'photo_50' |
|
} |
|
|
|
response = self.vk.method('users.get', values) |
|
|
|
for i in response: |
|
self.users.update({i['id']: i}) |
|
|
|
def render(self, dump): |
|
with open('./html/%s.html' % dump['id'], 'w', encoding='utf-8') as f: |
|
f.write(start_file) |
|
f.write(info_template.format(sel=dump['sel'])) |
|
|
|
for i in dump['items']: |
|
message = Message(i, self.users, dump['sel']) |
|
f.write(str(message)) # .encode('utf-8', errors='replace').decode("utf-8")) |
|
|
|
f.write(end_file) |
|
|
|
def run(self): |
|
try: |
|
os.mkdir('html') |
|
except: |
|
pass |
|
|
|
listdir = os.listdir('./dumps/') |
|
|
|
for x, i in enumerate(listdir, 1): |
|
print('{}. {}'.format(x, i)) |
|
|
|
self.path = './dumps/' + listdir[int(input('>')) - 1] |
|
|
|
print('Selected {}'.format(self.path)) |
|
|
|
for filename in os.listdir(self.path): |
|
print('Render %s' % filename) |
|
|
|
f = open(os.path.join(self.path, filename), 'r', encoding='utf-8') |
|
dump = json.load(f) |
|
f.close() |
|
|
|
users = [] |
|
for i in dump['items']: |
|
if not i['from_id'] in users: |
|
users.append(i['from_id']) |
|
|
|
for f in i.get('fwd_messages', []): |
|
if not f['user_id'] in users: |
|
users.append(i['user_id']) |
|
|
|
self.get_user(users) |
|
|
|
if dump['id'] > 2e9: |
|
sel = "c%s" % (dump['id'] - 2e9) |
|
else: |
|
sel = dump['id'] |
|
|
|
dump.update({'sel': sel}) |
|
|
|
self.render(dump) |
|
|
|
|
|
if __name__ == '__main__': |
|
main = Main() |
|
main.run() |