Changeset 36521

Show
Ignore:
Timestamp:
01/24/10 21:01:45 (3 years ago)
Author:
rezoo
Message:

203レスポンスコードをDat落ちと判断. タブをホワイトスペースに変更.

Location:
lang/python/twopy/trunk/twopy
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • lang/python/twopy/trunk/twopy/board.py

    r34400 r36521  
    66 
    77class Board (object): 
    8         """ 
    9         2chの板全般を管理するクラスです。 
    10         """ 
    11          
    12         __tr_re     = re.compile(r"(?P<title>.*) \((?P<res>\d*)\)") 
    13         __server_re = re.compile(r"http://.+?/") 
    14         __name_re = re.compile(r"http://.+?/(.+?)/") 
    15          
    16         def __init__(self, url, user=None): 
    17                 """ 
    18                 オブジェクトのコンストラクタです。 
    19                  
    20                 url  : 対象の2ch板のURL 
    21                 user : 通信に用いるtwopy.Userクラスのインスタンス 
    22                 """ 
    23                 u = url.endswith("/") and url or url + "/" 
    24                 self.__url  = u 
    25                 self.__user = user or twopy.User.anonymouse() 
    26                 self.__isRetrieved = False 
    27                  
    28                 self.__index = 0 
    29                 self.__threads = [] 
    30          
    31         def getUrl(self): return self.__url 
    32         def setUrl(self, url): 
    33                 if type(url) == str: 
    34                         self.__url = url 
    35                 else: raise AttributeError 
    36         url = property(getUrl, setUrl) 
    37          
    38         def getConfig(self): return self.__conf 
    39         def setConfig(self, conf): self__conf = conf 
    40         config = property(getConfig, setConfig) 
    41          
    42         def getSubject(self): 
    43                 su = self.url.endswith("/") and \ 
    44                      self.url + "subject.txt" or self.url + "/subject.txt" 
    45                 return su 
    46         subject_url = property(getSubject) 
    47          
    48         def getBBS(self): 
    49                 b = self.url.endswith("/") and \ 
    50                     self.url + "test/bbs.cgi" or self.url + "/test/bbs.cgi" 
    51          
    52         def get_isRetrieved(self): return self.__isRetrieved 
    53         isRetrieved = property(get_isRetrieved) 
    54          
    55         def getUser(self): return self.__user 
    56         user = property(getUser) 
    57          
    58         def getServer(self): 
    59                 return Board.__server_re.search(self.url).group(0) 
    60         server = property(getServer) 
    61          
    62         def getName(self): 
    63                 return Board.__name_re.search(self.url).group(1) 
    64         name = property(getName) 
    65          
    66         def __init_threads(self): 
    67                 self.__threads = [] 
    68                 self.__isRetrieved = False 
    69          
    70         def retrieve(self): 
    71                 """ 
    72                 対象の板からスレッド一覧を取得します。 
    73                 """ 
    74                 self.__init_threads() 
    75                  
    76                 try: 
    77                         response = self.user.urlopen(self.subject_url, gzip=False) 
    78                 except urllib2.HTTPError, e: 
    79                         return e.code 
    80                 if response.code == 200: 
    81                         rawdata = unicode(response.read(), 'Shift_JIS', 'ignore') 
    82                         dat = rawdata.split("\n") 
    83                         for thread_str in dat: 
    84                                 columns = thread_str.split("<>") 
    85                                 if len(columns) < 2 : continue 
    86                                 r = Board.__tr_re.search(columns[1]) 
    87                                 title = r.group("title") 
    88                                 res   = int(r.group("res")) 
    89                                 th = twopy.Thread(self, columns[0], self.user, title, res) 
    90                                 self.__threads.append(th) 
    91                         self.__isRetrieved = True 
    92                  
    93                 return response.code 
    94          
    95         def createNewThread(self, subject=u"", name=u"", mailaddr=u"", message=u"", 
    96                             submit=u"新規スレッド作成", hidden={}, delay=5): 
    97                 """ 
    98                 新しくスレッドを生成します. 
    99                  
    100                 引数: 
    101                 subject  : スレッドのタイトル 
    102                 name     : 名前 
    103                 mailaddr : メールアドレス 
    104                 message  : 本文の文章 
    105                 submit   : 書き込みボタンのキャプション 
    106                 hidden   : hidden属性の値 
    107                 delay    : 本来の時間から何秒だけ後戻りさせるか(未来の時間に書き込むのを防ぐ) 
    108                  
    109                 返り値: 
    110                 レスポンスコードと受信した文章の本文のタプル. 
    111                 レスポンスコード: 
    112                 twopy.STATUS_TRUE   書き込み成功 
    113                 twopy.STATUS_FALSE  書き込み成功&警告 
    114                 twopy.STATUS_ERROR  書き込み失敗 
    115                 twopy.STATUS_CHECK  書き込み警告 
    116                 twopy.STATUS_COOKIE 書き込み確認 
    117                  
    118                 ただし、レスポンスコードがtwopy.STATUS_COOKIEの場合、 
    119                 返り値はレスポンスコード、受信した文章の本文、input->hidden属性の辞書が返されます. 
    120                 """ 
    121                 referer = self.url 
    122                 send_dict = { "bbs" : self.name, 
    123                               "subject" : subject.encode("Shift_JIS"), 
    124                               "time" : int(time.time())-delay, 
    125                               "FROM" : name.encode("Shift_JIS"), 
    126                               "mail" : mailaddr.encode("Shift_JIS"), 
    127                               "MESSAGE" : message.encode("Shift_JIS"), 
    128                               "submit" : submit.encode("Shift_JIS")} 
    129                 send_dict.update(hidden) 
    130                 params = urllib.urlencode(send_dict) 
    131                  
    132                 return utility.bbsPost(self.user, self, params, referer) 
    133          
    134         def __len__(self): 
    135                 if not self.isRetrieved: raise twopy.NotRetrievedError 
    136                 return len(self.__threads) 
    137          
    138         def __iter__(self): 
    139                 if not self.isRetrieved: raise twopy.NotRetrievedError 
    140                 for thread in self.__threads: 
    141                         yield thread 
    142          
    143         def __getitem__(self, i): 
    144                 if not self.isRetrieved: raise twopy.NotRetrievedError 
    145                 return self.__threads[i] 
     8  """ 
     9  2chの板全般を管理するクラスです。 
     10  """ 
     11   
     12  __tr_re     = re.compile(r"(?P<title>.*) \((?P<res>\d*)\)") 
     13  __server_re = re.compile(r"http://.+?/") 
     14  __name_re = re.compile(r"http://.+?/(.+?)/") 
     15   
     16  def __init__(self, url, user=None): 
     17    """ 
     18    オブジェクトのコンストラクタです。 
     19     
     20    url  : 対象の2ch板のURL 
     21    user : 通信に用いるtwopy.Userクラスのインスタンス 
     22    """ 
     23    u = url.endswith("/") and url or url + "/" 
     24    self.__url  = u 
     25    self.__user = user or twopy.User.anonymouse() 
     26    self.__isRetrieved = False 
     27     
     28    self.__index = 0 
     29    self.__threads = [] 
     30   
     31  def getUrl(self): return self.__url 
     32  def setUrl(self, url): 
     33    if type(url) == str: 
     34      self.__url = url 
     35    else: raise AttributeError 
     36  url = property(getUrl, setUrl) 
     37   
     38  def getConfig(self): return self.__conf 
     39  def setConfig(self, conf): self__conf = conf 
     40  config = property(getConfig, setConfig) 
     41   
     42  def getSubject(self): 
     43    su = self.url.endswith("/") and \ 
     44         self.url + "subject.txt" or self.url + "/subject.txt" 
     45    return su 
     46  subject_url = property(getSubject) 
     47   
     48  def getBBS(self): 
     49    b = self.url.endswith("/") and \ 
     50        self.url + "test/bbs.cgi" or self.url + "/test/bbs.cgi" 
     51   
     52  def get_isRetrieved(self): return self.__isRetrieved 
     53  isRetrieved = property(get_isRetrieved) 
     54   
     55  def getUser(self): return self.__user 
     56  user = property(getUser) 
     57   
     58  def getServer(self): 
     59    return Board.__server_re.search(self.url).group(0) 
     60  server = property(getServer) 
     61   
     62  def getName(self): 
     63    return Board.__name_re.search(self.url).group(1) 
     64  name = property(getName) 
     65   
     66  def __init_threads(self): 
     67    self.__threads = [] 
     68    self.__isRetrieved = False 
     69   
     70  def retrieve(self): 
     71    """ 
     72    対象の板からスレッド一覧を取得します。 
     73    """ 
     74    self.__init_threads() 
     75     
     76    try: 
     77      response = self.user.urlopen(self.subject_url, gzip=False) 
     78    except urllib2.HTTPError, e: 
     79      return e.code 
     80    if response.code == 200: 
     81      rawdata = unicode(response.read(), 'Shift_JIS', 'ignore') 
     82      dat = rawdata.split("\n") 
     83      for thread_str in dat: 
     84        columns = thread_str.split("<>") 
     85        if len(columns) < 2 : continue 
     86        r = Board.__tr_re.search(columns[1]) 
     87        title = r.group("title") 
     88        res   = int(r.group("res")) 
     89        th = twopy.Thread(self, columns[0], self.user, title, res) 
     90        self.__threads.append(th) 
     91      self.__isRetrieved = True 
     92     
     93    return response.code 
     94   
     95  def createNewThread(self, subject=u"", name=u"", mailaddr=u"", message=u"", 
     96                      submit=u"新規スレッド作成", hidden={}, delay=5): 
     97    """ 
     98    新しくスレッドを生成します. 
     99     
     100    引数: 
     101    subject  : スレッドのタイトル 
     102    name     : 名前 
     103    mailaddr : メールアドレス 
     104    message  : 本文の文章 
     105    submit   : 書き込みボタンのキャプション 
     106    hidden   : hidden属性の値 
     107    delay    : 本来の時間から何秒だけ後戻りさせるか(未来の時間に書き込むのを防ぐ) 
     108     
     109    返り値: 
     110    レスポンスコードと受信した文章の本文のタプル. 
     111    レスポンスコード: 
     112    twopy.STATUS_TRUE   書き込み成功 
     113    twopy.STATUS_FALSE  書き込み成功&警告 
     114    twopy.STATUS_ERROR  書き込み失敗 
     115    twopy.STATUS_CHECK  書き込み警告 
     116    twopy.STATUS_COOKIE 書き込み確認 
     117     
     118    ただし、レスポンスコードがtwopy.STATUS_COOKIEの場合、 
     119    返り値はレスポンスコード、受信した文章の本文、input->hidden属性の辞書が返されます. 
     120    """ 
     121    referer = self.url 
     122    send_dict = { "bbs" : self.name, 
     123                  "subject" : subject.encode("Shift_JIS"), 
     124                  "time" : int(time.time())-delay, 
     125                  "FROM" : name.encode("Shift_JIS"), 
     126                  "mail" : mailaddr.encode("Shift_JIS"), 
     127                  "MESSAGE" : message.encode("Shift_JIS"), 
     128                  "submit" : submit.encode("Shift_JIS")} 
     129    send_dict.update(hidden) 
     130    params = urllib.urlencode(send_dict) 
     131     
     132    return utility.bbsPost(self.user, self, params, referer) 
     133   
     134  def __len__(self): 
     135    if not self.isRetrieved: raise twopy.NotRetrievedError 
     136    return len(self.__threads) 
     137   
     138  def __iter__(self): 
     139    if not self.isRetrieved: raise twopy.NotRetrievedError 
     140    for thread in self.__threads: 
     141      yield thread 
     142   
     143  def __getitem__(self, i): 
     144    if not self.isRetrieved: raise twopy.NotRetrievedError 
     145    return self.__threads[i] 
  • lang/python/twopy/trunk/twopy/comment.py

    r34425 r36521  
    77 
    88class 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})(-\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(1),r.group(2)) for r in result] 
    111                         self.__responses_cache = l 
    112                  
    113                 l = self.__responses_cache 
    114                 if returnType == "str": return ["".join(i) for i in l] 
    115                 elif returnType == "int": return self.__makeIntegerLists(l) 
    116                 elif returnType == "comment": 
    117                         rl  = self.__makeIntegerLists(l) 
    118                         rl2 = [] 
    119                         for i in rl: 
    120                                 if type(i) == int: 
    121                                         if 0<i<=self.thread.res: rl2.append(self.thread[i]) 
    122                                 else: rl2.append([self.thread[j] for j in i if 0<j<=self.thread.res]) 
    123                         return rl2 
    124                                          
    125                 else: raise TypeError 
    126                          
    127         res = property(extractResponses) 
    128         responses = property(extractResponses) 
    129          
    130         def __makeIntegerLists(self, l): 
    131                 rl = [] 
    132                 for i in l: 
    133                         start = int(unicodedata.normalize("NFKC", i[0][2:])) 
    134                         if i[1] == "": rl.append(start) 
    135                         else: 
    136                                 end   = int(unicodedata.normalize("NFKC", i[1][1:])) 
    137                                 rl.append(range(start, end+1)) 
    138                 return rl 
    139          
    140         def render(self): 
    141                 """ 
    142                 取得したコメントから、整形された文章を返します. 
    143                 """ 
    144                 if self.be: 
    145                         header = u"%i 名前:%s [%s]: %s ID:%s BE:%s" % \ 
    146                                 (self.number, self.name, self.mailaddr, self.date, self.ID, self.be) 
    147                 else: 
    148                         header = u"%i 名前:%s [%s]: %s ID:%s" % \ 
    149                                 (self.number, self.name, self.mailaddr, self.date, self.ID) 
    150                 return u"%s\n%s\n" % (header, self.body) 
    151          
    152         def __unicode__(self): return self.render() 
     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})(-\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(1),r.group(2)) for r in result] 
     111      self.__responses_cache = l 
     112     
     113    l = self.__responses_cache 
     114    if returnType == "str": return ["".join(i) for i in l] 
     115    elif returnType == "int": return self.__makeIntegerLists(l) 
     116    elif returnType == "comment": 
     117      rl  = self.__makeIntegerLists(l) 
     118      rl2 = [] 
     119      for i in rl: 
     120        if type(i) == int: 
     121          if 0<i<=self.thread.res: rl2.append(self.thread[i]) 
     122        else: rl2.append([self.thread[j] for j in i if 0<j<=self.thread.res]) 
     123      return rl2 
     124           
     125    else: raise TypeError 
     126       
     127  res = property(extractResponses) 
     128  responses = property(extractResponses) 
     129   
     130  def __makeIntegerLists(self, l): 
     131    rl = [] 
     132    for i in l: 
     133      start = int(unicodedata.normalize("NFKC", i[0][2:])) 
     134      if i[1] == "": rl.append(start) 
     135      else: 
     136        end   = int(unicodedata.normalize("NFKC", i[1][1:])) 
     137        rl.append(range(start, end+1)) 
     138    return rl 
     139   
     140  def render(self): 
     141    """ 
     142    取得したコメントから、整形された文章を返します. 
     143    """ 
     144    if self.be: 
     145      header = u"%i 名前:%s [%s]: %s ID:%s BE:%s" % \ 
     146        (self.number, self.name, self.mailaddr, self.date, self.ID, self.be) 
     147    else: 
     148      header = u"%i 名前:%s [%s]: %s ID:%s" % \ 
     149        (self.number, self.name, self.mailaddr, self.date, self.ID) 
     150    return u"%s\n%s\n" % (header, self.body) 
     151   
     152  def __unicode__(self): return self.render() 
  • lang/python/twopy/trunk/twopy/errors.py

    r34396 r36521  
    55 
    66class DatoutError (Exception): 
    7         """ 
    8         対象のURLがdat落ちとなった場合に送出されるエラーです. 
    9         """ 
    10         def __init__(self, value): 
    11                 self.value = value 
    12          
    13         def __str__(self): 
    14                 return "DatoutError: %s" % (self.value) 
     7  """ 
     8  対象のURLがdat落ちとなった場合に送出されるエラーです. 
     9  """ 
     10  def __init__(self, value): 
     11    self.value = value 
     12   
     13  def __str__(self): 
     14    return "DatoutError: %s" % (self.value) 
    1515 
    1616class NotRetrievedError (Exception): 
    17         """ 
    18         対象のオブジェクトがまだ取得されていない場合に送出されるエラーです. 
    19         """ 
    20         def __init__(self, value="an object is not retrieved."): 
    21                 self.value = value 
    22          
    23         def __str__(self): 
    24                 return "NotRetrievedError: %s" % (self.value) 
     17  """ 
     18  対象のオブジェクトがまだ取得されていない場合に送出されるエラーです. 
     19  """ 
     20  def __init__(self, value="an object is not retrieved."): 
     21    self.value = value 
     22   
     23  def __str__(self): 
     24    return "NotRetrievedError: %s" % (self.value) 
    2525 
    2626class Message (object): 
    27          
    28         __title_re = re.compile("<title>(?P<title>.*?)</title>") 
    29         __body_re  = re.compile("<body>(?P<body>.*?)</body>") 
    30          
    31         def __init__(self, dat): 
    32                 self.__title = Message.__title_re.search(dat).group("title") 
    33                 self.__body = Message.__body_re.search(dat).group("body") 
    34          
    35         def getTitle(self): return self.__title 
    36         title = property(getTitle) 
    37          
    38         def getBody(self): return self.__body 
    39         body = property(getBody) 
     27   
     28  __title_re = re.compile("<title>(?P<title>.*?)</title>") 
     29  __body_re  = re.compile("<body>(?P<body>.*?)</body>") 
     30   
     31  def __init__(self, dat): 
     32    self.__title = Message.__title_re.search(dat).group("title") 
     33    self.__body = Message.__body_re.search(dat).group("body") 
     34   
     35  def getTitle(self): return self.__title 
     36  title = property(getTitle) 
     37   
     38  def getBody(self): return self.__body 
     39  body = property(getBody) 
  • lang/python/twopy/trunk/twopy/thread.py

    r34400 r36521  
    66 
    77class Thread (object): 
    8         """ 
    9         2chのスレッドを管理するクラスです. 
    10         """ 
    11          
    12         __url  = re.compile(r"http://(.+?)/test/read.cgi/(.+?)/(\d+)") 
    13         __etag = re.compile(r'".*"') 
    14          
    15         __hidden = re.compile(r'input type=hidden name="(.+?)" value="(.+?)"') 
    16          
    17         @classmethod 
    18         def initWithUrl(cls, url, user=None): 
    19                 """ 
    20                 スレッドを示すURLから、対象のThreadクラスを生成します. 
    21          
    22                 url  : 対象となるURL 
    23                 user : 通信に用いるtwopy.Userクラスのインスタンス 
    24                 """ 
    25                 rs = Thread.__url.search(url) 
    26                 if rs == None: raise TypeError 
    27                  
    28                 server     = rs.group(1) 
    29                 board_name = rs.group(2) 
    30                 dat_number = rs.group(3) 
    31                  
    32                 board_url = "http://%s/%s/" % (server, board_name) 
    33                 u = user or twopy.User.anonymouse() 
    34                 b = twopy.Board(board_url, u) 
    35                 filename = "%s.dat" % dat_number  
    36                 return Thread(b, filename, u) 
    37          
    38         def __init__(self, board, filename, user=None, title="", res=0): 
    39                 """ 
    40                 オブジェクトのコンストラクタです. 
    41          
    42                 board    : 対象となる板のインスタンス 
    43                 filename : datファイル名 
    44                 user     : 通信に用いるtwopy.Userクラスのインスタンス 
    45                 title    : スレッドのタイトルが判明している場合は別途指定. 
    46                                  retrieve()が呼び出された場合は、取得したスレッド名で上書きされる. 
    47                 res      : スレッドのレス数が判明している場合は別途指定. 
    48                                  retrieve()が呼び出された場合は、取得したレス数で上書きされる. 
    49                 """ 
    50                 self.__board = board 
    51                 self.__filename = filename 
    52                 self.__user = user or twopy.User.anonymouse() 
    53                 self.__title = title 
    54                 self.__res = res 
    55                 self.__rawdat = "" 
    56                 self.__comments = [] 
    57                  
    58                 self.__isRetrieved = False 
    59                 self.__isBroken   = False 
    60                 self.__last_modified = None 
    61                 self.__etag  = None 
    62          
    63         def __init_thread(self): 
    64                 self.__rawdat = "" 
    65                 self.__comments = [] 
    66                 self.__isRetrieved = False 
    67          
    68         def getBoard(self): return self.__board 
    69         board = property(getBoard) 
    70          
    71         def getFilename(self): return self.__filename 
    72         filename = property(getFilename) 
    73          
    74         def getUser(self): return self.__user 
    75         user = property(getUser) 
    76          
    77         def getConfig(self): return self.__conf 
    78         def setConfig(self, conf): self__conf = conf 
    79         config = property(getConfig, setConfig) 
    80          
    81         def getTitle(self): return self.__title 
    82         title = property(getTitle) 
    83          
    84         def getResponse(self): return self.__res 
    85         response = property(getResponse) 
    86         res      = property(getResponse) 
    87          
    88         def getDatNumber(self): 
    89                 return int(self.filename[:-4]) 
    90         dat_number = property(getDatNumber) 
    91          
    92         def get_isRetrieved(self): return self.__isRetrieved 
    93         isRetrieved = property(get_isRetrieved) 
    94          
    95         def get_isBroken(self): return self.__isBroken 
    96         isBroken = property(get_isBroken) 
    97          
    98         def getUrl(self): 
    99                 u = "%sdat/%s" % (self.board.url, self.filename) 
    100                 return u 
    101         url = property(getUrl) 
    102          
    103         def getSince(self): 
    104                 return datetime.datetime.fromtimestamp(self.dat_number) 
    105         since = property(getSince) 
    106          
    107         def getVelocity(self, t=None): 
    108                 tp = t or time.time() 
    109                 now = int(tp) 
    110                 delta = now - self.dat_number 
    111                 return self.response / float(delta)*3600 
    112         velocity = property(getVelocity) 
    113          
    114         def retrieve(self): 
    115                 """ 
    116                 スレッドからdatファイルを読み込み、その内容を取得します. 
    117                 """ 
    118                 self.__init_thread() 
    119                 response = self.user.urlopen(self.url, gzip=True) 
    120                  
    121                 if response.code == 200: 
    122                         headers = response.info() 
    123                         self.__last_modified = headers["Last-Modified"] 
    124                         self.__etag = Thread.__etag.search(headers["ETag"]).group(0) 
    125                         gzip_str = StringIO.StringIO(response.read()) 
    126                         self.__rawdat = gzip.GzipFile(fileobj=gzip_str).read() 
    127                         if self.__rawdat.startswith("<html>"): 
    128                                 # Dat落ちと判断 
    129                                 raise twopy.DatoutError, twopy.Message(self.__rawdat) 
    130                         self.__appendComments(unicode(self.__rawdat, "Shift_JIS", "replace")) 
    131                         self.__isRetrieved = True 
    132                         self.__isBroken   = False 
    133                         self.__res = len(self.__comments) 
    134                 return response.code 
    135          
    136         def __appendComments(self, dat): 
    137                 no_tag = re.compile("<.*?>") 
    138                 nt = re.compile("(?P<name>.*)</b>(?P<trip>.*)<b>") 
    139                 di = re.compile("(?P<date>.*) ID:(?P<id>.*)") 
    140                  
    141                 for (i, line) in enumerate(dat.split("\n")): 
    142                         if len(self.__comments) == 0 : 
    143                                 columns = line.split("<>") 
    144                                 self.__title = columns[4] 
    145                         if line != "": 
    146                                 self.__comments.append( twopy.Comment(self, line, i+1) ) 
    147  
    148         def update(self): 
    149                 """ 
    150                 スレッドの内容を更新します. 
    151                  
    152                 返り値: HTTPステータスコード 
    153                 """ 
    154                 if len(self.__comments) == 0: # 未取得だった場合 
    155                         self.retrieve() 
    156                         return 
    157                  
    158                 try: 
    159                         response = self.user.urlopen(self.url, gzip=False, bytes=len(self.__rawdat), 
    160                                                if_modified_since=self.__last_modified, 
    161                                                if_none_match=self.__etag) 
    162                         if response.code == 206: 
    163                                 # datが更新されていた場合 
    164                                 headers = response.info() 
    165                                 self.__last_modified = headers["Last-Modified"] 
    166                                 self.__etag = Thread.__etag.search(headers["ETag"]).group(0) 
    167                                 newdat = response.read() 
    168                                 self.__rawdat += newdat 
    169                                 self.__appendComments(newdat) 
    170                                 self.__res = len(self.__comments) 
    171                         elif response.code == 416: 
    172                                 # datが壊れている場合 
    173                                 self.__isBroken = True 
    174                         else: raise TypeError 
    175                          
    176                         return response.code 
    177                  
    178                 except urllib2.HTTPError, e: 
    179                         if e.code == 304: 
    180                                 # datが更新されていない場合 
    181                                 pass 
    182                         return e.code 
    183          
    184         def autopost(self, name=u"", mailaddr=u"", message=u"", 
    185                      submit=u"書き込む", delay=5): 
    186                 """ 
    187                 書き込みの確認をすべてスキップして書き込みます. 
    188                 """ 
    189                 r1 = self.post(name, mailaddr, message, submit, delay=delay) 
    190                 if r1[0] == twopy.STATUS_COOKIE: 
    191                         r2 = self.post(name, mailaddr, message, submit, hidden=r1[2], delay=delay) 
    192                         return r2 
    193                 else: 
    194                         return r1 
    195          
    196         def post(self, name=u"", mailaddr=u"", message=u"", 
    197                  submit=u"書き込む", hidden={}, delay=5): 
    198                 """ 
    199                 コメントの書き込みを試みます. 
    200                  
    201                 引数: 
    202                 name     : 名前 
    203                 mailaddr : メールアドレス 
    204                 message  : 本文の文章 
    205                 submit   : 書き込みボタンのキャプション 
    206                 hidden   : hidden属性の値 
    207                 delay    : 本来の時間から何秒だけ後戻りさせるか(未来の時間に書き込むのを防ぐ) 
    208                  
    209                 返り値: 
    210                 レスポンスコードと受信した文章の本文のタプル. 
    211                 レスポンスコード: 
    212                 twopy.STATUS_TRUE   書き込み成功 
    213                 twopy.STATUS_FALSE  書き込み成功&警告 
    214                 twopy.STATUS_ERROR  書き込み失敗 
    215                 twopy.STATUS_CHECK  書き込み警告 
    216                 twopy.STATUS_COOKIE 書き込み確認 
    217                  
    218                 ただし、レスポンスコードがtwopy.STATUS_COOKIEの場合、 
    219                 返り値はレスポンスコード、受信した文章の本文、input->hidden属性の辞書が返されます. 
    220                 """ 
    221                 referer = "%stest/read.cgi/%s/%i/" % (self.board.server, self.board.name, self.dat_number) 
    222                 send_dict = { "bbs"  : self.board.name, 
    223                               "key"  : self.dat_number, 
    224                               "time" : int(time.time())-delay, 
    225                               "FROM" : name.encode("Shift_JIS"), 
    226                               "mail" : mailaddr.encode("Shift_JIS"), 
    227                               "MESSAGE" : message.encode("Shift_JIS"), 
    228                               "submit"  : submit.encode("Shift_JIS")} 
    229                 send_dict.update(hidden) 
    230                 params = urllib.urlencode(send_dict) 
    231                  
    232                 return utility.bbsPost(self.user, self.board, params, referer) 
    233          
    234         def __iter__(self): 
    235                 if not self.isRetrieved: raise twopy.NotRetrievedError 
    236                 for comment in self.__comments: 
    237                         yield comment 
    238          
    239         def __len__(self): 
    240                 if not self.isRetrieved: raise twopy.NotRetrievedError 
    241                 return len(self.__comments) 
    242          
    243         def __getitem__(self, i): 
    244                 if not self.isRetrieved: raise twopy.NotRetrievedError 
    245                 return self.__comments[i-1] 
     8  """ 
     9  2chのスレッドを管理するクラスです. 
     10  """ 
     11   
     12  __url  = re.compile(r"http://(.+?)/test/read.cgi/(.+?)/(\d+)") 
     13  __etag = re.compile(r'".*"') 
     14   
     15  __hidden = re.compile(r'input type=hidden name="(.+?)" value="(.+?)"') 
     16   
     17  @classmethod 
     18  def initWithUrl(cls, url, user=None): 
     19    """ 
     20    スレッドを示すURLから、対象のThreadクラスを生成します. 
     21   
     22    url  : 対象となるURL 
     23    user : 通信に用いるtwopy.Userクラスのインスタンス 
     24    """ 
     25    rs = Thread.__url.search(url) 
     26    if rs == None: raise TypeError 
     27     
     28    server     = rs.group(1) 
     29    board_name = rs.group(2) 
     30    dat_number = rs.group(3) 
     31     
     32    board_url = "http://%s/%s/" % (server, board_name) 
     33    u = user or twopy.User.anonymouse() 
     34    b = twopy.Board(board_url, u) 
     35    filename = "%s.dat" % dat_number  
     36    return Thread(b, filename, u) 
     37   
     38  def __init__(self, board, filename, user=None, title="", res=0): 
     39    """ 
     40    オブジェクトのコンストラクタです. 
     41   
     42    board    : 対象となる板のインスタンス 
     43    filename : datファイル名 
     44    user     : 通信に用いるtwopy.Userクラスのインスタンス 
     45    title    : スレッドのタイトルが判明している場合は別途指定. 
     46               retrieve()が呼び出された場合は、取得したスレッド名で上書きされる. 
     47    res      : スレッドのレス数が判明している場合は別途指定. 
     48               retrieve()が呼び出された場合は、取得したレス数で上書きされる. 
     49    """ 
     50    self.__board = board 
     51    self.__filename = filename 
     52    self.__user = user or twopy.User.anonymouse() 
     53    self.__title = title 
     54    self.__res = res 
     55    self.__rawdat = "" 
     56    self.__comments = [] 
     57     
     58    self.__isRetrieved = False 
     59    self.__isBroken   = False 
     60    self.__last_modified = None 
     61    self.__etag  = None 
     62   
     63  def __init_thread(self): 
     64    self.__rawdat = "" 
     65    self.__comments = [] 
     66    self.__isRetrieved = False 
     67   
     68  def getBoard(self): return self.__board 
     69  board = property(getBoard) 
     70   
     71  def getFilename(self): return self.__filename 
     72  filename = property(getFilename) 
     73   
     74  def getUser(self): return self.__user 
     75  user = property(getUser) 
     76   
     77  def getConfig(self): return self.__conf 
     78  def setConfig(self, conf): self__conf = conf 
     79  config = property(getConfig, setConfig) 
     80   
     81  def getTitle(self): return self.__title 
     82  title = property(getTitle) 
     83   
     84  def getResponse(self): return self.__res 
     85  response = property(getResponse) 
     86  res      = property(getResponse) 
     87   
     88  def getDatNumber(self): 
     89    return int(self.filename[:-4]) 
     90  dat_number = property(getDatNumber) 
     91   
     92  def get_isRetrieved(self): return self.__isRetrieved 
     93  isRetrieved = property(get_isRetrieved) 
     94   
     95  def get_isBroken(self): return self.__isBroken 
     96  isBroken = property(get_isBroken) 
     97   
     98  def getUrl(self): 
     99    u = "%sdat/%s" % (self.board.url, self.filename) 
     100    return u 
     101  url = property(getUrl) 
     102   
     103  def getSince(self): 
     104    return datetime.datetime.fromtimestamp(self.dat_number) 
     105  since = property(getSince) 
     106   
     107  def getVelocity(self, t=None): 
     108    tp = t or time.time() 
     109    now = int(tp) 
     110    delta = now - self.dat_number 
     111    return self.response / float(delta)*3600 
     112  velocity = property(getVelocity) 
     113   
     114  def retrieve(self): 
     115    """ 
     116    スレッドからdatファイルを読み込み、その内容を取得します. 
     117    """ 
     118    self.__init_thread() 
     119    response = self.user.urlopen(self.url, gzip=True) 
     120     
     121    if response.code == 200: 
     122      headers = response.info() 
     123      self.__last_modified = headers["Last-Modified"] 
     124      self.__etag = Thread.__etag.search(headers["ETag"]).group(0) 
     125      gzip_str = StringIO.StringIO(response.read()) 
     126      self.__rawdat = gzip.GzipFile(fileobj=gzip_str).read() 
     127      if self.__rawdat.startswith("<html>"): 
     128        # Dat落ちと判断 
     129        raise twopy.DatoutError, twopy.Message(self.__rawdat) 
     130      self.__appendComments(unicode(self.__rawdat, "Shift_JIS", "replace")) 
     131      self.__isRetrieved = True 
     132      self.__isBroken   = False 
     133      self.__res = len(self.__comments) 
     134    if response.code == 203: 
     135      # Dat落ちと判断(10/01/24現在のanydat.soモジュールの仕様より) 
     136      raise twopy.DatoutError, twopy.Message(self.__rawdat) 
     137     
     138    return (response.code, self.__res) 
     139   
     140  def __appendComments(self, dat): 
     141    no_tag = re.compile("<.*?>") 
     142    nt = re.compile("(?P<name>.*)</b>(?P<trip>.*)<b>") 
     143    di = re.compile("(?P<date>.*) ID:(?P<id>.*)") 
     144     
     145    num = 0 
     146    for (i, line) in enumerate(dat.split("\n")): 
     147      if len(self.__comments) == 0 : 
     148        columns = line.split("<>") 
     149        self.__title = columns[4] 
     150      if line != "": 
     151        self.__comments.append( twopy.Comment(self, line, i+1) ) 
     152        num += 1 
     153    return num 
     154 
     155  def update(self): 
     156    """ 
     157    スレッドの内容を更新します. 
     158     
     159    返り値: HTTPステータスコード 
     160    """ 
     161    if not self.isRetrieved: # 未取得だった場合 
     162      return self.retrieve() 
     163 
     164    num = 0     
     165    try: 
     166      response = self.user.urlopen(self.url, gzip=False, bytes=len(self.__rawdat), 
     167                                   if_modified_since=self.__last_modified, 
     168                                   if_none_match=self.__etag) 
     169      if response.code == 206: 
     170        # datが更新されていた場合 
     171        headers = response.info() 
     172        self.__last_modified = headers["Last-Modified"] 
     173        self.__etag = Thread.__etag.search(headers["ETag"]).group(0) 
     174        newdat = response.read() 
     175        self.__rawdat += newdat 
     176        num = self.__appendComments(newdat) 
     177        self.__res = len(self.__comments) 
     178      elif response.code == 416: 
     179        # datが壊れている場合 
     180        self.__isBroken = True 
     181      else: raise TypeError 
     182       
     183      return (response.code, num) 
     184     
     185    except urllib2.HTTPError, e: 
     186      if e.code == 304: 
     187        # datが更新されていない場合 
     188        pass 
     189      return (e.code, num) 
     190   
     191  def autopost(self, name=u"", mailaddr=u"", message=u"", 
     192               submit=u"書き込む", delay=5): 
     193    """ 
     194    書き込みの確認をすべてスキップして書き込みます. 
     195    """ 
     196    r1 = self.post(name, mailaddr, message, submit, delay=delay) 
     197    if r1[0] == twopy.STATUS_COOKIE: 
     198      r2 = self.post(name, mailaddr, message, submit, hidden=r1[2], delay=delay) 
     199      return r2 
     200    else: 
     201      return r1 
     202   
     203  def post(self, name=u"", mailaddr=u"", message=u"", 
     204           submit=u"書き込む", hidden={}, delay=5): 
     205    """ 
     206    コメントの書き込みを試みます. 
     207     
     208    引数: 
     209    name     : 名前 
     210    mailaddr : メールアドレス 
     211    message  : 本文の文章 
     212    submit   : 書き込みボタンのキャプション 
     213    hidden   : hidden属性の値 
     214    delay    : 本来の時間から何秒だけ後戻りさせるか(未来の時間に書き込むのを防ぐ) 
     215     
     216    返り値: 
     217    レスポンスコードと受信した文章の本文のタプル. 
     218    レスポンスコード: 
     219    twopy.STATUS_TRUE   書き込み成功 
     220    twopy.STATUS_FALSE  書き込み成功&警告 
     221    twopy.STATUS_ERROR  書き込み失敗 
     222    twopy.STATUS_CHECK  書き込み警告 
     223    twopy.STATUS_COOKIE 書き込み確認 
     224     
     225    ただし、レスポンスコードがtwopy.STATUS_COOKIEの場合、 
     226    返り値はレスポンスコード、受信した文章の本文、input->hidden属性の辞書が返されます. 
     227    """ 
     228    referer = "%stest/read.cgi/%s/%i/" % (self.board.server, self.board.name, self.dat_number) 
     229    send_dict = { "bbs"  : self.board.name, 
     230                  "key"  : self.dat_number, 
     231                  "time" : int(time.time())-delay, 
     232                  "FROM" : name.encode("Shift_JIS"), 
     233                  "mail" : mailaddr.encode("Shift_JIS"), 
     234                  "MESSAGE" : message.encode("Shift_JIS"), 
     235                  "submit"  : submit.encode("Shift_JIS")} 
     236    send_dict.update(hidden) 
     237    params = urllib.urlencode(send_dict) 
     238     
     239    return utility.bbsPost(self.user, self.board, params, referer) 
     240   
     241  def __iter__(self): 
     242    if not self.isRetrieved: raise twopy.NotRetrievedError 
     243    for comment in self.__comments: 
     244      yield comment 
     245   
     246  def __len__(self): 
     247    if not self.isRetrieved: raise twopy.NotRetrievedError 
     248    return len(self.__comments) 
     249   
     250  def __getitem__(self, i): 
     251    if not self.isRetrieved: raise twopy.NotRetrievedError 
     252    return self.__comments[i-1] 
  • lang/python/twopy/trunk/twopy/user.py

    r34396 r36521  
    55 
    66class User (object): 
    7         """ 
    8         クッキーの管理や、ユーザーエージェントなどのヘッダ全般を管理するクラスです. 
    9         """ 
    10         @classmethod 
    11         def anonymouse(cls): 
    12                 return User() 
    13          
    14         def __init__(self, 
    15                      user_agent = "Monazilla 1.00", 
    16                      language   = "ja", 
    17                      keep_alive = 300): 
    18                 self.user_agent = user_agent 
    19                 self.language   = language 
    20                 self.keep_alive = keep_alive 
    21                  
    22                 cj = cookielib.CookieJar() 
    23                 self.__cookie = cj 
    24                 self.__opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
    25          
    26         def getOpener(self): return self.__opener 
    27         opener = property(getOpener) 
    28          
    29         def getCookie(self): return self.__cookie 
    30         cookie = property(getCookie) 
    31          
    32         def getRequest(self, url, gzip=False, bytes=0, 
    33                        if_modified_since=None, if_none_match=None): 
    34                 headers = { 
    35                         "User-Agent" : self.user_agent, 
    36                         "Accept-Language" : self.language, 
    37                         "Keep-Alive" : str(self.keep_alive), 
    38                         "Connection" : "close", 
    39                 } 
    40                 if gzip: headers["Accept-Encoding"] = "gzip" 
    41                 if bytes > 0 : 
    42                         headers["If-Modified-Since"] = if_modified_since 
    43                         headers["If-None-Match"]     = if_none_match 
    44                         headers["Range"]             = "bytes= %i-" % bytes 
    45                 req = urllib2.Request(url, None, headers) 
    46                 return req 
    47          
    48         def urlopen(self, url, gzip=False, bytes=0, 
    49                     if_modified_since=None, if_none_match=None): 
    50                 req = self.getRequest(url, gzip, bytes, if_modified_since, if_none_match) 
    51                 return self.opener.open(req) 
    52          
    53         def urlpost(self, url, param, referer): 
    54                 headers = { 
    55                         "User-Agent" : self.user_agent, 
    56                         "Accept" : "*/*", 
    57                         "Accept-Language" : self.language, 
    58                         "Keep-Alive" : str(self.keep_alive), 
    59                         "Referer" : referer, 
    60                         "Connection" : "close", 
    61                 } 
    62                 req = urllib2.Request(url, None, headers) 
    63                 self.__cookie.add_cookie_header(req) 
    64                 return self.opener.open(req, param) 
     7  """ 
     8  クッキーの管理や、ユーザーエージェントなどのヘッダ全般を管理するクラスです. 
     9  """ 
     10  @classmethod 
     11  def anonymouse(cls): 
     12    return User() 
     13   
     14  def __init__(self, 
     15               user_agent = "Monazilla 1.00", 
     16               language   = "ja", 
     17               keep_alive = 300): 
     18    self.user_agent = user_agent 
     19    self.language   = language 
     20    self.keep_alive = keep_alive 
     21     
     22    cj = cookielib.CookieJar() 
     23    self.__cookie = cj 
     24    self.__opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
     25   
     26  def getOpener(self): return self.__opener 
     27  opener = property(getOpener) 
     28   
     29  def getCookie(self): return self.__cookie 
     30  cookie = property(getCookie) 
     31   
     32  def getRequest(self, url, gzip=False, bytes=0, 
     33                 if_modified_since=None, if_none_match=None): 
     34    headers = { 
     35      "User-Agent" : self.user_agent, 
     36      "Accept-Language" : self.language, 
     37      "Keep-Alive" : str(self.keep_alive), 
     38      "Connection" : "close", 
     39    } 
     40    if gzip: headers["Accept-Encoding"] = "gzip" 
     41    if bytes > 0 : 
     42      headers["If-Modified-Since"] = if_modified_since 
     43      headers["If-None-Match"]     = if_none_match 
     44      headers["Range"]             = "bytes= %i-" % bytes 
     45    req = urllib2.Request(url, None, headers) 
     46    return req 
     47   
     48  def urlopen(self, url, gzip=False, bytes=0, 
     49              if_modified_since=None, if_none_match=None): 
     50    req = self.getRequest(url, gzip, bytes, if_modified_since, if_none_match) 
     51    return self.opener.open(req) 
     52   
     53  def urlpost(self, url, param, referer): 
     54    headers = { 
     55      "User-Agent" : self.user_agent, 
     56      "Accept" : "*/*", 
     57      "Accept-Language" : self.language, 
     58      "Keep-Alive" : str(self.keep_alive), 
     59      "Referer" : referer, 
     60      "Connection" : "close", 
     61    } 
     62    req = urllib2.Request(url, None, headers) 
     63    self.__cookie.add_cookie_header(req) 
     64    return self.opener.open(req, param) 
  • lang/python/twopy/trunk/twopy/utility.py

    r34396 r36521  
    1919 
    2020def bbsPost(user, board, params, referer): 
    21         """ 
    22         サーバーの/test/bbs.cgiを呼び出して、書き込みやスレッド作成などの処理を行います. 
    23         """ 
    24         url = "%stest/bbs.cgi" % (board.server) 
    25          
    26         try: 
    27                 response = user.urlpost(url, params, referer) 
    28                 if response.code == 200: 
    29                         body = unicode(response.read(), "Shift_JIS", "ignore") 
    30                         code = __detectStatusCode(body) 
    31                         if code == STATUS_COOKIE: 
    32                                 r = __hidden.search(body) 
    33                                 d = {r.group(1):r.group(2)} 
    34                                 return (code, body, d) 
    35                         else: return (code, body) 
    36                 else: 
    37                         raise TypeError 
    38         except urllib2.HTTPError, e: 
    39                 print e.code 
     21  """ 
     22  サーバーの/test/bbs.cgiを呼び出して、書き込みやスレッド作成などの処理を行います. 
     23  """ 
     24  url = "%stest/bbs.cgi" % (board.server) 
     25   
     26  try: 
     27    response = user.urlpost(url, params, referer) 
     28    if response.code == 200: 
     29      body = unicode(response.read(), "Shift_JIS", "ignore") 
     30      code = __detectStatusCode(body) 
     31      if code == STATUS_COOKIE: 
     32        r = __hidden.search(body) 
     33        d = {r.group(1):r.group(2)} 
     34        return (code, body, d) 
     35      else: return (code, body) 
     36    else: 
     37      raise TypeError 
     38  except urllib2.HTTPError, e: 
     39    print e.code 
    4040 
    4141def __detectStatusCode(body): 
    42         """ 
    43         与えられた引数からステータスコードを返します. 
    44         """ 
    45         if __status_false.search(body): return STATUS_FALSE 
    46         elif __status_true.search(body): return STATUS_TRUE 
    47         elif __status_error.search(body): return STATUS_ERROR 
    48         elif __status_check.search(body): return STATUS_CHECK 
    49         elif __status_cookie.search(body): return STATUS_COOKIE 
    50         else: raise TypeError, "twopy can't detect the status code."  
     42  """ 
     43  与えられた引数からステータスコードを返します. 
     44  """ 
     45  if __status_false.search(body): return STATUS_FALSE 
     46  elif __status_true.search(body): return STATUS_TRUE 
     47  elif __status_error.search(body): return STATUS_ERROR 
     48  elif __status_check.search(body): return STATUS_CHECK 
     49  elif __status_cookie.search(body): return STATUS_COOKIE 
     50  else: raise TypeError, "twopy can't detect the status code."