root/lang/python/twopy/trunk/twopy/comment.py @ 34396

Revision 34396, 4.4 kB (checked in by rezoo, 4 years ago)

2chライブラリ'twopy' version 0.4.0を新規にリリース

Line 
1#!/usr/bin/env python
2#-*- coding:utf-8 -*-
3
4import re, datetime
5import xml.sax.saxutils
6import unicodedata
7
8class Comment (object):
9        """
10        スレッド上のコメントを管理するクラスです.
11        """
12       
13        __delete_tag = re.compile(r"<.+?>")
14        __date_and_id = re.compile(r"(?P<date>.*) ID:(?P<id>\S*)")
15        __be = re.compile(r"BE:(?P<be>.*)")
16        __datetime = re.compile(r"(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})\(.*\) (?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})(\.(?P<csec>\d+)|)")
17        __urls = re.compile(r"(ttps?:\/\/[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+)")
18        __response = re.compile(r">>(\d{1,4}|>>[0-9]{1,4})")
19       
20        def __init__(self, thread, line, number):
21                """
22                オブジェクトのコンストラクタです.
23               
24                thread : コメントが保存されている親スレッドのインスタンス
25                line   : 初期化に用いられる、datファイルの一行.
26                         この引数はunicode型でなければなりません.
27                number : スレッドからの、コメント位置.
28                """
29                self.thread = thread
30                self.number = number
31                self.line   = line
32               
33                self.__datetime_cache = None
34                self.__urls_cache = None
35                if type(line) == unicode:
36                        columns = line.split("<>")
37                elif type(line) == str:
38                        columns = unicode(line, "Shift-JIS", "replace").split("<>")
39                else: raise TypeError("the type of the argument 'line' is not unicode or str.")
40                if len(columns) < 5 : raise TypeError
41                self.__name = Comment.__delete_tag.sub("", columns[0])
42                self.__mailaddr = columns[1]
43                raw_body = Comment.__delete_tag.sub("", columns[3].replace(" <br> ", "\n"))
44                self.__body = xml.sax.saxutils.unescape(raw_body)[1:-1] # 余分なスペースの削除
45                di_result = Comment.__date_and_id.search(columns[2])
46                if di_result:
47                        self.__date = di_result.group("date") or ""
48                        self.__id   = di_result.group("id") or ""
49                be_result = Comment.__be.search(columns[2])
50                self.__be = None
51                if be_result:   self.__be = be_result.group("be")
52               
53                self.__responses_cache = None
54               
55        def getName(self): return self.__name
56        name = property(getName)
57       
58        def getMailAddr(self): return self.__mailaddr
59        mailaddr = property(getMailAddr)
60       
61        def getDate(self): return self.__date
62        date = property(getDate)
63       
64        def getBody(self): return self.__body
65        body = property(getBody)
66       
67        def getDatetime(self):
68                if self.__datetime_cache: return self.__datetime_cache
69               
70                result = Comment.__datetime.search(self.__date)
71                if result:
72                        year  = int(result.group("year"))
73                        month = int(result.group("month"))
74                        day   = int(result.group("day"))
75                        hour  = int(result.group("hour"))
76                        m     = int(result.group("min"))
77                        sec   = int(result.group("sec"))
78                        c     = result.group("csec")
79                        csec  = c == None and 0 or int(c)
80                       
81                        d = datetime.datetime(year, month, day, hour, m, sec, csec*10000)
82                        self.__datetime_cache = d
83                        return d
84                else: return None
85        datetime = property(getDatetime)
86       
87        def getID(self): return self.__id
88        ID = property(getID)
89       
90        def getBe(self): return self.__be
91        be = property(getBe)
92       
93        def extractUrls(self):
94                """
95                コメントの内容から、URLの一覧を抽出して返します.
96                """
97                if self.__urls_cache: return self.__urls_cache
98                result = Comment.__urls.finditer(self.body)
99                l = ["".join( ("h", r.group(0)) ) for r in result]
100                self.__urls_cache = l
101                return l
102        urls = property(extractUrls)
103       
104        def extractResponses(self, returnType="str"):
105                """
106                コメントの内容から、レスポンスの一覧を抽出して返します.
107                """
108                if self.__responses_cache == None:
109                        result = Comment.__response.finditer(self.body)
110                        l = [r.group(0) for r in result]
111                        self.__responses_cache = l
112               
113                l = self.__responses_cache
114                if returnType == "str": return l
115                elif returnType == "int":
116                        ld = [int(unicodedata.normalize("NFKC", m[2:])) for m in l]
117                        return ld
118                if returnType == "comment":
119                        ld = [int(unicodedata.normalize("NFKC", m[2:])) for m in l]
120                        lc = [self.thread[i] for i in ld if 0 < i <= self.thread.res]
121                        return lc
122                else: raise TypeError
123                       
124        res = property(extractResponses)
125        responses = property(extractResponses)
126       
127        def render(self):
128                """
129                取得したコメントから、整形された文章を返します.
130                """
131                if self.be:
132                        header = u"%i 名前:%s [%s]: %s ID:%s BE:%s" % \
133                                (self.number, self.name, self.mailaddr, self.date, self.ID, self.be)
134                else:
135                        header = u"%i 名前:%s [%s]: %s ID:%s" % \
136                                (self.number, self.name, self.mailaddr, self.date, self.ID)
137                return u"%s\n%s\n" % (header, self.body)
138       
139        def __unicode__(self): return self.render()
Note: See TracBrowser for help on using the browser.