OSDN Git Service

Add some fundamental functions for thread and small html parser
authorAiwota Programmer <aiwotaprog@tetteke.tk>
Sun, 13 Aug 2006 05:20:45 +0000 (14:20 +0900)
committerAiwota Programmer <aiwotaprog@tetteke.tk>
Sun, 13 Aug 2006 05:20:45 +0000 (14:20 +0900)
src/Hage1/barehtmlparser.py [new file with mode: 0644]
src/Hage1/datfile.py [new file with mode: 0644]
src/Hage1/misc.py

diff --git a/src/Hage1/barehtmlparser.py b/src/Hage1/barehtmlparser.py
new file mode 100644 (file)
index 0000000..e025f6c
--- /dev/null
@@ -0,0 +1,78 @@
+# Copyright (C) 2006 by Aiwota Programmer
+# aiwotaprog@tetteke.tk
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+from HTMLParser import HTMLParser
+import htmlentitydefs
+
+
+class BareHTMLParser(HTMLParser):
+    """Parses html by the minimal necessity
+
+    to_out_func format is:
+    def some_func(untied_data, is_bold, href):
+    where untied_data is non markuped string
+    and is_bold is whether untied_data is bold or not
+    and href is url anchor if exists
+    """
+
+    def __init__(self, to_out_func):
+        HTMLParser.__init__(self)
+        self.to_out_func = to_out_func
+        self.bold = False
+        self.href = None
+
+    def reset_func(self, to_out_func):
+        self.to_out_func = to_out_func
+
+    def to_out(self, data):
+        self.to_out_func(data, self.bold, self.href)
+
+    # handle_* are overriden methods
+
+    def handle_starttag(self, tag, attr):
+        if tag == "b":
+            self.bold = True
+        elif tag == "br":
+            self.to_out("\n")
+        elif tag == "a":
+            for item in attr:
+                if item[0] == "href":
+                    self.href = item[1]
+
+    def handle_endtag(self, tag):
+        if tag == "b":
+            self.bold = False
+        elif tag == "a":
+            self.href = None
+
+    def handle_data(self, data):
+        self.to_out(data)
+
+    def handle_charref(self, ref):
+        data = None
+        try:
+            data = unichr(int(ref))
+        except:
+            data = "&#"+ref+";"
+        self.to_out(data)
+
+    def handle_entityref(self, name):
+        if name in htmlentitydefs.name2codepoint:
+            codepoint = htmlentitydefs.name2codepoint[name]
+            self.to_out(unichr(codepoint))
+        else:
+            self.to_out("&"+name+";")
diff --git a/src/Hage1/datfile.py b/src/Hage1/datfile.py
new file mode 100644 (file)
index 0000000..e4bf2eb
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright (C) 2006 by Aiwota Programmer
+# aiwotaprog@tetteke.tk
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+import re
+import os.path
+import codecs
+
+import misc
+
+REG_EXPR_TITLE = re.compile(".*<>.*<>.*<>.*<>(.*)")
+REG_EXPR_ELEM = re.compile( \
+    "(?P<name>.*)<>(?P<mail>.*)<>(?P<date>.*)<>(?P<msg>.*)<>")
+
+def get_title_from_dat(bbs, board, thread):
+    """Returns thread title in dat file
+
+    bbs: bbs id
+
+    board: board id
+
+    thread: thread id
+
+    If failed, return None
+    """
+    dat_path = misc.get_thread_dat_path(bbs, board, thread)
+    if not os.path.exists(dat_path):
+        return None
+
+    f = open(dat_path, "r")
+    try:
+        line = f.readline()
+        if line:
+            m = REG_EXPR_TITLE.match(line.decode("cp932", "replace"))
+            if m:
+                return m.group(1)
+    finally:
+        f.close()
+
+def split_line_to_elems(line, func):
+    """Splits a line to elements and invokes func
+
+    line: represents one res
+
+    func: is invoked after splitting
+    format of user functon is:
+    def some_func(name, mail, date, msg):
+    where parameters represent corresponding elements of the res
+    """
+    m = REG_EXPR_ELEM.match(line)
+    if m:
+        name = m.group("name")
+        mail = m.group("mail")
+        date = m.group("date")
+        msg = m.group("msg")
+        func(name, mail, date, msg)
+
+def load_dat(bbs, board, thread, func):
+    """Loads entire dat and invokes func per one res
+
+    bbs: bbs id
+
+    board: board id
+
+    thread: thread id
+
+    func: is invoked per one res
+    format of user function is:
+    def some_func(num, line):
+    where num is the number of the res and line is raw body of the res
+    """
+    dat_path = misc.get_thread_dat_path(bbs, board, thread)
+    if not os.path.exists(dat_path):
+        return
+
+    f = open(dat_path, "r")
+    num = 1
+    try:
+        line = f.readline()
+        while line:
+            line = line.decode("cp932", "replace")
+            func(num, line)
+            line = f.readline()
+            num += 1
+    finally:
+        f.close()
index 9fc98bc..ab8269e 100644 (file)
@@ -34,6 +34,22 @@ def get_board_base_url(bbs, board):
 
     return "http://" + brdlist.get(bbs, board, "host") + "/" + board + "/"
 
+def get_thread_dat_path(bbs, board, thread):
+    """Returns thread dat file path
+
+    bbs: bbs id
+
+    board: board id
+
+    thread: thread id
+    """
+
+    # if parameter is empty, raise ValueError
+    if not bbs or not board or not thread:
+        raise ValueError, "parameter must not be empty"
+
+    return os.path.join(get_board_dir_path(bbs, board), thread + ".dat")
+
 def get_board_subjecttxt_url(bbs, board):
     """Returns subject.txt file url