Bladeren bron

add time in html

ppwwyyxx 11 jaren geleden
bovenliggende
commit
f03eb9b5bd
9 gewijzigde bestanden met toevoegingen van 89 en 41 verwijderingen
  1. 31 0
      lib/msgslice.py
  2. 2 3
      lib/parser.py
  3. 37 22
      lib/render.py
  4. 2 2
      lib/static/TP_EMOJI.html
  5. 2 2
      lib/static/TP_IMG.html
  6. 2 2
      lib/static/TP_MSG.html
  7. 2 2
      lib/static/TP_SPEAK.html
  8. 5 0
      lib/static/TP_TIME.html
  9. 6 8
      lib/static/template.html

+ 31 - 0
lib/msgslice.py

@@ -0,0 +1,31 @@
+#!/usr/bin/env python2
+# -*- coding: UTF-8 -*-
+# File: msgslice.py
+# Date: Mon Dec 22 22:24:32 2014 +0800
+# Author: Yuxin Wu <[email protected]>
+
+class MessageSlicer(object):
+    """ Separate messages into slices by time.
+        A new day always begins a new slice.
+    """
+    def __init__(self, diff_thres=5 * 60):
+        self.diff_thres = diff_thres
+
+    def slice(self, msgs):
+        ret = []
+        now = []
+        for m in msgs:
+            if len(now) == 0:
+                now.append(m)
+                continue
+            nowtime, lasttime = m.createTime, now[-1].createTime
+            if nowtime.date() == lasttime.date() and \
+               (nowtime - lasttime).seconds < self.diff_thres:
+                now.append(m)
+                continue
+
+            ret.append(now)
+            now = []
+        return ret
+
+

+ 2 - 3
lib/parser.py

@@ -1,7 +1,7 @@
 #!/usr/bin/env python2
 # -*- coding: UTF-8 -*-
 # File: parser.py
-# Date: Mon Dec 22 21:59:26 2014 +0800
+# Date: Mon Dec 22 22:14:18 2014 +0800
 # Author: Yuxin Wu <[email protected]>
 
 import sqlite3
@@ -76,7 +76,7 @@ SELECT {} FROM message
         imginfo_q = self.cc.execute("""SELECT msgSvrId, bigImgPath FROM ImgInfo2""")
         self.imginfo = {k: v for (k, v) in imginfo_q
                              if not v.startswith('SERVERID://')}
-        logger.info("Found {} big images records.".format(len(self.imginfo)))
+        logger.info("Found {} hd image records.".format(len(self.imginfo)))
 
     def _find_msg_by_type(self, msgs=None):
         ret = []
@@ -103,7 +103,6 @@ SELECT {} FROM message
             if catalog not in NEEDED_EMOJI_CATALOG:
                 continue
             self.internal_emojis[md5] = name
-        print self.internal_emojis
 
 
     def parse(self):

+ 37 - 22
lib/render.py

@@ -1,7 +1,7 @@
 #!/usr/bin/env python2
 # -*- coding: UTF-8 -*-
 # File: render.py
-# Date: Mon Dec 22 16:52:48 2014 +0800
+# Date: Mon Dec 22 22:48:32 2014 +0800
 # Author: Yuxin Wu <[email protected]>
 
 import os
@@ -11,7 +11,8 @@ import logging
 logger = logging.getLogger(__name__)
 
 LIB_PATH = os.path.dirname(os.path.abspath(__file__))
-HTML_FILE = os.path.join(LIB_PATH, 'static/template.html')
+HTML_FILE = os.path.join(LIB_PATH, 'static', 'template.html')
+TIME_HTML_FILE = os.path.join(LIB_PATH, 'static', 'TP_TIME.html')
 
 try:
     from csscompressor import compress as css_compress
@@ -20,7 +21,8 @@ except:
 
 from .msg import *
 from .utils import ensure_unicode
-from smiley import SmileyProvider
+from .smiley import SmileyProvider
+from .msgslice import MessageSlicer
 
 TEMPLATES_FILES = {TYPE_MSG: "TP_MSG",
                    TYPE_IMG: "TP_IMG",
@@ -33,11 +35,13 @@ TEMPLATES = {k: ensure_unicode(open(os.path.join(LIB_PATH, 'static/{}.html'.form
 class HTMLRender(object):
     def __init__(self, parser, res=None):
         self.html = ensure_unicode(open(HTML_FILE).read())
+        self.time_html = open(TIME_HTML_FILE).read()
         self.parser = parser
         self.res = res
         if self.res is None:
             logger.warn("Resource Directory not given. Images / Voice Message won't be displayed.")
         self.smiley = SmileyProvider()
+        self.slicer = MessageSlicer()
 
         csss = glob.glob(os.path.join(LIB_PATH, 'static/*.css'))
         css_string = []
@@ -69,21 +73,23 @@ class HTMLRender(object):
     def render_msg(self, msg):
         """ render a message, return the html block"""
         sender = 'you' if not msg.isSend else 'me'
+        format_dict = {'sender_label': sender,
+                       'time': msg.createTime }
         def fallback():
             template = TEMPLATES[TYPE_MSG]
             content = msg.msg_str()
-            content = self.smiley.replace_smileycode(content)
-            return template.format(sender_label=sender,
-                                   content=content)
+            format_dict['content'] = self.smiley.replace_smileycode(content)
+            return template.format(**format_dict)
+
         if msg.type not in TEMPLATES:
             return fallback()
 
         template = TEMPLATES[msg.type]
         if msg.type == TYPE_SPEAK:
             audio_str, duration = self.res.get_voice_mp3(msg.imgPath)
-            return template.format(sender_label=sender,
-                                   voice_duration=duration,
-                                   voice_str=audio_str)
+            format_dict['voice_duration'] = duration
+            format_dict['voice_str'] = audio_str
+            return template.format(**format_dict)
         elif msg.type == TYPE_IMG:
             # imgPath was original THUMBNAIL_DIRPATH://th_xxxxxxxxx
             imgpath = msg.imgPath.split('_')[-1]
@@ -94,9 +100,9 @@ class HTMLRender(object):
                 logger.warn("No image thumbnail found for {}".format(imgpath))
                 return fallback()
             # TODO do not show fancybox when no bigimg found
-            return template.format(sender_label=sender,
-                                   small_img=smallimg,
-                                   big_img=bigimg)
+            format_dict['small_img'] = smallimg
+            format_dict['big_img'] = bigimg
+            return template.format(**format_dict)
         elif msg.type == TYPE_EMOJI:
             imgpath = msg.imgPath
             if imgpath in self.parser.internal_emojis:
@@ -107,33 +113,42 @@ class HTMLRender(object):
                 else:
                     group = None
                 emoji_img, format = self.res.get_emoji(imgpath, group)
-            #assert emoji_img
-            return template.format(sender_label=sender,
-                                  emoji_format=format,
-                                  emoji_img=emoji_img)
+            format_dict['emoji_format'] = format
+            format_dict['emoji_img'] = emoji_img
+            return template.format(**format_dict)
         elif msg.type == TYPE_LINK:
             content = msg.msg_str()
             if content.startswith(u'URL:'):
                 url = content[4:]
                 content = u'URL:<a target="_blank" href="{0}">{0}</a>'.format(url)
-                return template.format(sender_label=sender,
-                                       content=content)
+                format_dict['content'] = content
+                return template.format(**format_dict)
         return fallback()
 
     def render_msgs(self, msgs):
-        """ render msgs of the same friend"""
+        """ render msgs of one friend"""
         talker_name = msgs[0].talker
         logger.info(u"Rendering {} messages of {}({})".format(
             len(msgs), self.parser.contacts[talker_name], talker_name))
         avatars = self.get_avatar_pair(talker_name)
-        blocks = [self.render_msg(m) for m in msgs]
+        slices = self.slicer.slice(msgs)
+
+        blocks = []
+        for idx, slice in enumerate(slices):
+            nowtime = slice[0].createTime
+            if idx == 0 or \
+               slices[idx - 1][0].createTime.date() != nowtime.date():
+                timestr = nowtime
+            else:
+                timestr = nowtime.strftime("%H:%M:%S")
+            blocks.append(self.time_html.format(time=timestr))
+            blocks.extend([self.render_msg(m) for m in slice])
 
         return self.html.format(extra_css=self.css_string,
                                 extra_js=self.js_string,
                                 talker=msgs[0].talker_name,
                                 messages=u''.join(blocks),
-                                avatar_me=avatars[0],
-                                avatar_you=avatars[1])
+                                avatars=avatars)
 
 if __name__ == '__main__':
     r = HTMLRender()

+ 2 - 2
lib/static/TP_EMOJI.html

@@ -1,8 +1,8 @@
 <div class="chatItem {sender_label}">
   <div class="chatItemContent">
-    <img class="avatar" src="">
+    <img class="avatar">
     <div class="cloud cloudImg">
-      <div class="cloudPannel">
+      <div class="cloudPannel" title="{time}">
         <div class="cloudBody">
           <div class="cloudContent">
             <span class="img_wrap">

+ 2 - 2
lib/static/TP_IMG.html

@@ -1,8 +1,8 @@
 <div class="chatItem {sender_label}">
   <div class="chatItemContent">
-    <img class="avatar" src="">
+    <img class="avatar">
     <div class="cloud cloudImg">
-      <div class="cloudPannel">
+      <div class="cloudPannel" title="{time}">
         <div class="cloudBody">
           <div class="cloudContent">
             <span class="img_wrap">

+ 2 - 2
lib/static/TP_MSG.html

@@ -1,8 +1,8 @@
 <div class="chatItem {sender_label}">
   <div class="chatItemContent">
-    <img class="avatar" src="">
+    <img class="avatar">
     <div class="cloud cloudText">
-      <div class="cloudPannel">
+      <div class="cloudPannel" title="{time}">
         <div class="cloudBody">
           <div class="cloudContent">
             <pre style="white-space:pre-wrap">{content}</pre>

+ 2 - 2
lib/static/TP_SPEAK.html

@@ -1,8 +1,8 @@
 <div class="chatItem {sender_label}">
   <div class="chatItemContent">
-    <img class="avatar" src="">
+    <img class="avatar">
     <div class="cloud cloudVoice" onclick="playVoice(event)" style="width:80px">
-      <div class="cloudPannel" style="">
+      <div class="cloudPannel" title="{time}">
         <div class="sendStatus">
           <span class="second">{voice_duration}"</span>
         </div>

+ 5 - 0
lib/static/TP_TIME.html

@@ -0,0 +1,5 @@
+<div class="time">
+  <span class="timeBg left"> </span>
+  {time}
+  <span class="timeBg right"> </span>
+</div>

+ 6 - 8
lib/static/template.html

@@ -2,16 +2,15 @@
 <head>
   <meta http-equiv="Content-Type" content="text/html;charset=utf8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <title>WeChat</title>
-  <link rel="stylesheet" type="text/css" href="http://localhost:8000/wx.css">
+  <title>Chat with {talker}</title>
   <style type="text/css">
   .me .avatar {{
     background-size: 100%;
-    background-image: url("data:image/jpeg;base64,{avatar_me}");
+    background-image: url("data:image/jpeg;base64,{avatars[0]}");
   }}
   .you .avatar {{
     background-size: 100%;
-    background-image: url("data:image/jpeg;base64,{avatar_you}");
+    background-image: url("data:image/jpeg;base64,{avatars[1]}");
   }}
   </style>
   {extra_css}
@@ -33,8 +32,7 @@
       </div>
     </div>
   </div>
-  <script type='text/javascript'>
-
+<script type='text/javascript'>
 var playVoice = function(event) {{
   var target = event.target;
   while (!target.classList.contains('cloud'))
@@ -45,10 +43,10 @@ var playVoice = function(event) {{
 
 $(document).ready(function() {{
     $(".fancybox").fancybox({{
-        // fancybox will otherwise scroll page to top
+    // fancybox will otherwise scroll page to top
     helpers: {{ overlay : {{ locked : false}}}}
    }});
  }});
-  </script>
+</script>
 </body>
 </html>