Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML Dumper. #9

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions dumpers/html/dumper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
require "pathname"
require_relative '../dumper_interface'

MAIN_TEMPLATE = File.read(File.join(File.dirname(__FILE__), 'template'))

LEFT_BUBBLE_TEMPLATE =
'''
<div class="bubble white">
<i>%s</i> <b>%s</b><br>
%s
</div>
'''

RIGHT_BUBBLE_TEMPLATE =
'''
<div class="bubble bubble-alt white">
<i>%s</i> <b>%s</b><br>
%s
</div>
'''

SERVICE_TEMPLATE = '<p class="service">%s</p>'

IMAGE_TEMPLATE = '<p><img src="%s"></p>%s'

RTL_TEMPLATE = '<p dir="rtl">%s</p>'

# Characters of RTL languages.
RTL_CHARS = ['ا', 'آ', 'ب', 'پ', 'ت', 'ث', 'ج', 'چ', 'ح', 'خ', 'د', 'ذ', 'ر', 'ز', 'ژ', 'س', 'ش', 'ص', 'ض', 'ط', 'ظ', 'ع', 'غ', 'ف', 'ق', 'ک', 'گ', 'ل', 'م', 'ن', 'و', 'ه', 'ی']

class Dumper < DumperInterface

def start_dialog(dialog)
@content = ""
@previous_name = ""
@use_right_bubble = false
end

def dump_msg(dialog, msg)
if msg['event'] == 'message'

if msg['service'] == false
# Getting sent time.
message_time = msg['from']['when']
if not message_time
message_time = msg['to']['when']
end

# Alternating left/right bubbles.
if msg['from']['print_name'] != @previous_name
@use_right_bubble = !@use_right_bubble
end
@previous_name = msg['from']['print_name']

# Dumping text message.
if msg['text']

message = msg['text'].gsub(">", "&gt;").gsub("<", "&lt;").gsub("\n", "<br>")
if message.start_with?(*RTL_CHARS)
message = sprintf(RTL_TEMPLATE, message)
end
add_text(message_time, msg['from']['print_name'], message, @use_right_bubble)
end

# Dumping medias.
if msg['media']
if msg['media']['type'] == 'photo'
add_image(message_time, msg['from']['print_name'], msg['media']['caption'], msg['media']['file'], @use_right_bubble)
end
end

end
end
end

def end_dialog(dialog)
output_file = File.join(get_backup_dir, get_safe_name(dialog['print_name']) + '.html')

File.open(output_file, 'w') {|f| f.write(sprintf(MAIN_TEMPLATE, dialog['print_name'], @content))}

@content = ''
end

def add_text(time, title, text, use_right_bubble)
# Messages will be passed to the dumper, from newest to oldest.
# I wanted them in the reverse order: oldest to newest.
# That's why I inserted it at the beginning.

if use_right_bubble
template = RIGHT_BUBBLE_TEMPLATE
else
template = LEFT_BUBBLE_TEMPLATE
end

@content = sprintf(template, time, title, text) + @content
end

def add_image(time, title, text, file_path, use_right_bubble)
if use_right_bubble
template = RIGHT_BUBBLE_TEMPLATE
else
template = LEFT_BUBBLE_TEMPLATE
end

# Getting path of the image file, relative to the output_dir.
relative_path = Pathname.new(file_path).relative_path_from(Pathname.new(get_backup_dir)).to_s
inner_tag = sprintf(IMAGE_TEMPLATE, relative_path, text)

@content = sprintf(template, time, title, inner_tag) + @content
end

end

168 changes: 168 additions & 0 deletions dumpers/html/template
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html">
<title>%s</title>
<style type="text/css">
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%%;
font: inherit;
vertical-align: baseline;
outline: none;
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: 100%%;
-ms-text-size-adjust: 100%%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html { overflow-y: scroll; }
body {
background-color: #dbe1ed;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 62.5%%;
line-height: 1;
color: #414141;
}

br { display: block; line-height: 1.6em; }

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
ol, ul { list-style: none; }

input, textarea {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: 100%%;
-ms-text-size-adjust: 100%%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
outline: none;
}

blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
strong, b { font-weight: bold; }
em, i { font-style: italic; }

table { border-collapse: collapse; border-spacing: 0; }
img { border: 0; max-width: 100%%; }

p {
font-size: 1.2em;
line-height: 1.25em;
}

.service {
display: block;
text-align: center;
font-weight: bold;
margin-bottom: 8px;
color: #8b91a0;
text-shadow: 1px 1px 0 rgba(255,255,255,0.6);
}

/** page structure **/
.container {
padding: 40px 20px;
margin: 0 auto;
max-width: 600px;
}

/** ios1-ios6 bubbles **/
.bubble {
box-sizing: border-box;
float: left;
width: auto;
max-width: 80%%;
position: relative;
clear: both;

background: #95c2fd;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.15, #bee2ff), color-stop(1, #95c2fd));
background-image: -webkit-linear-gradient(bottom, #bee2ff 15%%, #95c2fd 100%%);
background-image: -moz-linear-gradient(bottom, #bee2ff 15%%, #95c2fd 100%%);
background-image: -ms-linear-gradient(bottom, #bee2ff 15%%, #95c2fd 100%%);
background-image: -o-linear-gradient(bottom, #bee2ff 15%%, #95c2fd 100%%);
background-image: linear-gradient(bottom, #bee2ff 15%%, #95c2fd 100%%);
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#95c2fd', endColorstr='#bee2ff');

border: solid 1px rgba(0,0,0,0.5);
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
border-radius: 20px;

-webkit-box-shadow: inset 0 8px 5px rgba(255,255,255,0.65), 0 1px 2px rgba(0,0,0,0.2);
-moz-box-shadow: inset 0 8px 5px rgba(255,255,255,0.65), 0 1px 2px rgba(0,0,0,0.2);
box-shadow: inset 0 8px 5px rgba(255,255,255,0.65), 0 1px 2px rgba(0,0,0,0.2);

margin-bottom: 20px;
padding: 6px 20px;
color: #000;
text-shadow: 0 1px 1px rgba(255,255,255,0.8);
word-wrap: break-word;
}

.bubble:before, .bubble:after {
border-radius: 20px / 5px;
content: '';
display: block;
position: absolute;
}
.bubble:before {
border: 10px solid transparent;
border-bottom-color: rgba(0,0,0,0.5);
bottom: 0px;
left: -7px;
z-index: -2;
}
.bubble:after {
border: 8px solid transparent;
border-bottom-color: #bee2ff; /* arrow color */
bottom: 1px;
left: -5px;
}

.bubble-alt {
float: right;
}
.bubble-alt:before {
left: auto;
right: -7px;
}
.bubble-alt:after {
left: auto;
right: -5px;
}

.bubble p {
font-size: 1.4em;
}

/* white bubble */
.white {
background: #7acd47;
background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.15, #e5e5e5),color-stop(1, #dbdbdb));
background-image: -webkit-linear-gradient(bottom, #e5e5e5 15%%, #dbdbdb 100%%);
background-image: -moz-linear-gradient(bottom, #e5e5e5 15%%, #dbdbdb 100%%);
background-image: -ms-linear-gradient(bottom, #e5e5e5 15%%, #dbdbdb 100%%);
background-image: -o-linear-gradient(bottom, #e5e5e5 15%%, #dbdbdb 100%%);
background-image: linear-gradient(bottom, #e5e5e5 15%%, #dbdbdb 100%%);
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#dbdbdb', endColorstr='#e5e5e5');
}
.white:after {
border-bottom-color: #e5e5e5;
}
</style>
</head>

<body>
<div class="container">
%s
</div>
</body>
</html>