-
Notifications
You must be signed in to change notification settings - Fork 96
add html formating #92
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,9 @@ | |
| 'id', 'name', 'mime_type', 'size', 'thumbnail_id', 'type', 'local_id', | ||
| 'volume_id', 'secret', 'extra' | ||
| )) | ||
| Forward = namedtuple('Forward', ( | ||
| 'id', 'original_date', 'from_id', 'channel_post', 'post_author' | ||
| )) | ||
|
|
||
|
|
||
| class BaseFormatter: | ||
|
|
@@ -186,7 +189,7 @@ def format(self, target, file=None, *args, **kwargs): | |
| file = sys.stdout | ||
| elif isinstance(file, (str, Path)): | ||
| if os.path.isdir(file): | ||
| file = os.path.join(file, str(target)) | ||
| file = os.path.join(file, str(target)+ "." + self.name()) | ||
| file = open(file, 'w') | ||
| elif not isinstance(file, TextIOWrapper): # Is there a better way? | ||
| raise TypeError( | ||
|
|
@@ -427,5 +430,30 @@ def get_media(self, mid): | |
| return None | ||
| return Media(*row) | ||
|
|
||
| def get_forward(self, forward_id): | ||
| cur = self.dbconn.cursor() | ||
| cur.execute("SELECT ID, OriginalDate, FromID, ChannelPost, PostAuthor FROM Forward " | ||
| "WHERE ID = ?;", (forward_id,)) | ||
| row = cur.fetchone() | ||
| if not row: | ||
| return None | ||
| row = row[:1] + (datetime.datetime.fromtimestamp(row[1]),) + row[2:] | ||
| return Forward(*row) | ||
|
|
||
| def get_human_readable_forwarded(self, forward): | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in my comment, I think this should be moved to a higher level (i.e. htmlformatter) |
||
| if not forward: | ||
| return "Unknow forward" | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo here. |
||
| if forward.from_id: | ||
| ent = self.get_user(forward.from_id) | ||
| if not ent: | ||
| return "Unknown user: %s" % forward.from_id | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please change these % formats to use "{}".format() style formatting |
||
| elif forward.channel_post: | ||
| ent = self.get_channel(forward.channel_post) | ||
| if not ent: | ||
| return "Unknown channel: %s" % forward.channel_post | ||
| else: | ||
| return "Unknown forward type" | ||
| return self.get_display_name(ent) | ||
|
|
||
| # if __name__ == '__main__': | ||
| # main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,9 @@ | |
| """ | ||
| from . import BaseFormatter | ||
|
|
||
| import utils as export_utils | ||
|
mr-tron marked this conversation as resolved.
Outdated
|
||
| from .htmltemplates import * | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Alternatively, use a namespaced import so you can do things like
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @expectocode you should try the new beta feature from GitHub ```suggestion from .htmltemplates import column_width, styles, header, basic_message_template, normal_body_template ``` |
||
|
|
||
|
|
||
| class HtmlFormatter(BaseFormatter): | ||
| """A Formatter class to generate HTML""" | ||
|
|
@@ -13,23 +16,55 @@ def name(): | |
|
|
||
| def output_header(self, file, context): | ||
| """Output the header of the page. Context should be a namedtuple""" | ||
| # TODO HTML | ||
| print(self.get_display_name(context), file=file) | ||
| name = self.get_display_name(context) | ||
|
|
||
| print(header.format(name, styles, name), file=file) | ||
|
|
||
| def generate_message_html(self, message): | ||
| def generate_message_html(self, message, context): | ||
| """ | ||
| Return HTML for a message, showing reply message, forward headers, | ||
| view count, post author, and media (if applicable). | ||
| """ | ||
| # TODO HTML | ||
| from_name = self.get_display_name(message.from_id) or "(???)" | ||
| return "{}: {}".format(from_name, message.text) | ||
|
|
||
| def _format(self, context_id, file, *args, **kwargs): | ||
| if message.media_id: | ||
| media = self.get_media(message.media_id) | ||
| if media.type == 'photo': | ||
|
|
||
| media_path = "%s-%s.%s%s" % (media.type, media.name, media.id, | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. % formatting, again.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The media path is user-configurable, so ideally this would use the format string specified by the user. I understand that is a bit more work, and perhaps should be in the BaseFormatter. It really should happen before rolling out to users, though. |
||
| export_utils.get_extension(media.mime_type)) | ||
| media_path = 'usermedia/%s-%s/%s' %(self.get_display_name(context), context.id, media_path) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This name shadowing on media_path is confusing. |
||
| body = photo_body_template.format(img_path=media_path) | ||
| else: | ||
| text = "Unsupported media type: %s. Message_id: %s, media_id: %s" % \ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. % formatting
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With inconsistent spacing. But yes, use |
||
| (media.type, message.id, media.id) | ||
| body = normal_body_template.format(text=text) | ||
| else: | ||
| text = message.text | ||
| body = normal_body_template.format(text=text) | ||
| if message.reply_message_id: | ||
| body = reply_template.format(message_id=message.reply_message_id) + body | ||
| if message.forward_id: | ||
| forward = self.get_forward(message.forward_id) | ||
| body = forwaded_wrapper_template.format( | ||
| forward_from=self.get_human_readable_forwarded(forward), | ||
| body=body, | ||
| date=forward.original_date) | ||
| rendered = basic_message_template.format( | ||
| message_id=message.id, | ||
| from_name=from_name, | ||
| body=body, | ||
| full_date=message.date, | ||
| time=message.date.strftime("%H:%M")) | ||
|
|
||
| return rendered | ||
|
|
||
| def _format(self, context_id, file, *args, **kwargs,): | ||
| """Format the given context as HTML and output to 'file'""" | ||
| entity = self.get_entity(context_id) | ||
|
|
||
| # file = sys.stdout | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like it should have been deleted |
||
| self.output_header(file, entity) | ||
| for message in self.get_messages_from_context(context_id, | ||
| order='ASC'): | ||
| print(self.generate_message_html(message), file=file) | ||
| print(self.generate_message_html(message, entity), file=file) | ||
| print(footer, file=file) | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,150 @@ | ||||||
| column_width = 480 | ||||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps a comment about what this controls?
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not totally necessary, just a thought. Of course, comments aren't the best solution as they can become outdated.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's a poor argument. Maybe telegram-export could support |
||||||
| styles = """ | ||||||
| body { | ||||||
| margin: 0; | ||||||
| font: 12px/18px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif; | ||||||
| } | ||||||
| .page_body { | ||||||
| padding-top: 64px; | ||||||
| width: %spx; | ||||||
| margin: 0 auto; | ||||||
| } | ||||||
| .history { | ||||||
| padding: 16px 0; | ||||||
| } | ||||||
| .message { | ||||||
| margin: 0 -10px; | ||||||
| transition: background-color 2.0s ease; | ||||||
| } | ||||||
| .default { | ||||||
| padding: 10px | ||||||
| } | ||||||
| .default .from_name { | ||||||
|
|
||||||
| color: #3892db; | ||||||
| font-weight: 700; | ||||||
| padding-bottom: 5px; | ||||||
|
|
||||||
| } | ||||||
| .details { | ||||||
|
|
||||||
| color: #70777b; | ||||||
|
|
||||||
| } | ||||||
| .pull_right { | ||||||
|
|
||||||
| float: right; | ||||||
|
|
||||||
| } | ||||||
| .photo { | ||||||
| max-width: %spx; | ||||||
| } | ||||||
| .body { | ||||||
| margin-left: 40px; | ||||||
| } | ||||||
|
|
||||||
| .page_header .content .text { | ||||||
|
|
||||||
| padding: 24px 24px 22px 24px; | ||||||
| font-size: 22px; | ||||||
| overflow: hidden; | ||||||
| text-overflow: ellipsis; | ||||||
| white-space: nowrap; | ||||||
|
|
||||||
| } | ||||||
| .bold { | ||||||
|
|
||||||
| color: #212121; | ||||||
| font-weight: 700; | ||||||
|
|
||||||
| } | ||||||
| .page_header .content { | ||||||
|
|
||||||
| width: 480px; | ||||||
| margin: 0 auto; | ||||||
| border-radius: 0 !important; | ||||||
|
|
||||||
| } | ||||||
| .page_header { | ||||||
|
|
||||||
| position: fixed; | ||||||
| z-index: 10; | ||||||
| background-color: #ffffff; | ||||||
| width: 100%%; | ||||||
| border-bottom: 1px solid #e3e6e8; | ||||||
|
|
||||||
| } | ||||||
| """ % (column_width, column_width - 20) | ||||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. % formatting |
||||||
|
|
||||||
| header = """ | ||||||
| <html lang="en"> | ||||||
| <head> | ||||||
| <meta charset="utf-8"> | ||||||
|
|
||||||
| <title>{}</title> | ||||||
| <meta name="description" content="The HTML5 Herald"> | ||||||
| <meta name="author" content="SitePoint"> | ||||||
| <style type="text/css">{}</style> | ||||||
|
|
||||||
| </head> | ||||||
|
|
||||||
| <body> | ||||||
| <div class="page_header"> | ||||||
|
|
||||||
| <div class="content"> | ||||||
|
|
||||||
| <div class="text bold"> | ||||||
| {} | ||||||
| </div> | ||||||
|
|
||||||
| </div> | ||||||
|
|
||||||
| </div> | ||||||
| <div class="page_body chat_page"> | ||||||
| <div class='history'> | ||||||
| """ | ||||||
|
|
||||||
| footer = """ | ||||||
| </div> | ||||||
| </div> | ||||||
| </body> | ||||||
| </html> | ||||||
| """ | ||||||
|
|
||||||
| basic_message_template = """ | ||||||
| <div class="message default clearfix" id="message{message_id}" > | ||||||
| <a name="message{message_id}"></a> | ||||||
| <div class="body"> | ||||||
| <div class="pull_right date details" title="{full_date}"> | ||||||
| {time} | ||||||
| </div> | ||||||
| <div class="from_name"> | ||||||
| {from_name} | ||||||
| </div> | ||||||
| {body} | ||||||
| </div> | ||||||
| </div> | ||||||
| """ | ||||||
|
|
||||||
| normal_body_template = """ | ||||||
| <div class="text">{text}</div> | ||||||
| """ | ||||||
| photo_body_template = """ | ||||||
| <div class="img_body"> | ||||||
| <a href="{img_path}"> <img class='photo' src="{img_path}"></img></a> | ||||||
| </div> | ||||||
| """ | ||||||
|
|
||||||
| forwaded_wrapper_template = """ | ||||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo here
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| <div class="body"> | ||||||
| <div class="from_name"> | ||||||
| {forward_from} <span class='details'>{date}</span> | ||||||
| </div> | ||||||
| {body} | ||||||
| </div> | ||||||
| """ | ||||||
| reply_template = """ | ||||||
| <div class="reply_to details"> | ||||||
| In reply to <a href="#message{message_id}">this message</a> | ||||||
| </div> | ||||||
| """ | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See how the other functions do this: they construct the namedtuple first, then use something like
_replace(original_date=datetime.datetime.fromtimestamp(original_date)