OSDN Git Service

Multithreads are abandoned. Alternatly, The asyncore substitutes.(#16776)
[fukui-no-namari/fukui-no-namari.git] / src / FukuiNoNamari / misc.py
1 # Copyright (C) 2006 by Aiwota Programmer
2 # aiwotaprog@tetteke.tk
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 import pygtk
19 pygtk.require('2.0')
20 import gtk
21 import gobject
22 import os.path
23 import re
24 from datetime import tzinfo, timedelta, datetime
25 import itertools
26 import traceback
27
28 import config
29 from BbsType import bbs_type_exception
30
31 REG_EXPR_HTTPDATE = re.compile("[^ ,]{3}, (?P<day>\d{2}) (?P<month>(?:Jan)|(?:Feb)|(?:Mar)|(?:Apr)|(?:May)|(?:Jun)|(?:Jul)|(?:Aug)|(?:Sep)|(?:Oct)|(?:Nov)|(?:Dec)) (?P<year>\d{4}) (?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2}) GMT")
32 MON_DICT = {"Jan":1, "Feb":2, "Mar":3, "Apr":4, "May":5, "Jun":6, "Jul":7,
33             "Aug":8, "Sep":9, "Oct":10, "Nov":11, "Dec":12}
34
35 def _check_thread(bbs_type):
36     """if bbs_type is not thread, raise BbsTypeError"""
37
38     if not bbs_type.is_thread():
39         raise bbs_type_exception.BbsTypeError, \
40               "the bbs_type does not represent thread: " + bbs_type.uri
41
42 def get_logs_dir_path():
43     return os.path.join(config.get_config_dir_path(), "logs")
44
45 def get_thread_dat_dir_path(bbs_type):
46     """Returns dir path for saving thread dat file"""
47
48     return os.path.join(get_board_dir_path(bbs_type), "dat")
49
50 def get_thread_idx_dir_path(bbs_type):
51     """Returns dir path for saving thread index file"""
52
53     return os.path.join(get_board_dir_path(bbs_type), "idx")
54
55 def get_thread_states_dir_path(bbs_type):
56     """Returns dir path for saving thread states file"""
57
58     return os.path.join(get_board_dir_path(bbs_type), "states")
59
60 def get_thread_dat_path(bbs_type):
61     """Returns thread dat file path"""
62
63     _check_thread(bbs_type)
64
65     return os.path.join(get_thread_dat_dir_path(bbs_type),
66                         bbs_type.thread + ".dat")
67
68 def get_board_subjecttxt_path(bbs_type):
69     """Returns subject.txt file path"""
70
71     return os.path.join(get_board_dir_path(bbs_type), "subject.txt")
72
73 def get_thread_states_path(bbs_type):
74     """Returns thread states file path"""
75
76     _check_thread(bbs_type)
77
78     return os.path.join(get_thread_states_dir_path(bbs_type),
79                         bbs_type.thread + ".states")
80
81 def get_board_states_path(bbs_type):
82     """Returns board states file path"""
83
84     return os.path.join(get_board_dir_path(bbs_type), "board.states")
85
86 def get_board_idx_path(bbs_type):
87     """Returns board idx file path"""
88
89     return os.path.join(get_board_dir_path(bbs_type), "subject.idx")
90
91 def get_board_dir_path(bbs_type):
92     """Returns board dir path"""
93
94     return os.path.join(get_logs_dir_path(), bbs_type.get_board_dir_path())
95
96 def get_thread_idx_path(bbs_type):
97     """Returns idx file path of thread"""
98
99     _check_thread(bbs_type)
100
101     return os.path.join(get_thread_idx_dir_path(bbs_type),
102                         bbs_type.thread + ".idx")
103
104 def get_board_cache_path(bbs_type):
105     """Returns .cache file path of board"""
106
107     return os.path.join(get_thread_idx_dir_path(bbs_type), ".cache")
108
109 ZERO = timedelta(0)
110 HOUR = timedelta(hours=1)
111 class UTC(tzinfo):
112     """UTC"""
113
114     def utcoffset(self, dt):
115         return ZERO
116
117     def tzname(self, dt):
118         return "UTC"
119
120     def dst(self, dt):
121         return ZERO
122
123 utc = UTC()
124
125 epoch = datetime(1970, 1, 1, 0, 0, 0, 0, utc)
126
127 def httpdate_to_secs(httpdate):
128     """Returns the seconds since the epoch"""
129
130     if not httpdate:
131         return 0
132
133     m = REG_EXPR_HTTPDATE.match(httpdate)
134     if m:
135         tm_day = int(m.group("day"))
136         tm_mon = MON_DICT[m.group("month")]
137         tm_year = int(m.group("year"))
138         tm_hour = int(m.group("hour"))
139         tm_min = int(m.group("minute"))
140         tm_sec = int(m.group("second"))
141         
142         d = datetime(tm_year, tm_mon, tm_day, tm_hour, tm_min, tm_sec, 0, utc)
143         delta = d - epoch
144         return delta.days*24*60*60 + delta.seconds
145     else:
146         raise ValueError
147
148
149 class FileWrap:
150     def __init__(self, path, mode="a+"):
151         self.__file = None
152         self.__path = path
153         self.__mode = mode
154     def __del__(self):
155         self.close()
156     def seek(self, size):
157         self.file().seek(size)
158     def write(self, data):
159         self.file().write(data)
160     def writelines(self, sequence):
161         self.file().writelines(sequence)
162     def close(self):
163         if self.__file:
164             self.__file.close()
165             self.__file = None
166     def file(self):
167         if not self.__file:
168             basedir = os.path.dirname(self.__path)
169             if not os.path.isdir(basedir):
170                 os.makedirs(basedir)
171             self.__file = file(self.__path, self.__mode)
172         return self.__file
173
174 def unpack_ifilter(predicate, iterable):
175     """For multiple argument"""
176     for item in iterable:
177         if predicate(*item):
178             yield item
179
180 def split_key_and_value(key_equal_value):
181     try:
182         index = key_equal_value.index("=")
183     except ValueError:
184         pass
185     else:
186         key = key_equal_value[:index]
187         value = key_equal_value[index+1:]
188         return key, value
189
190 def tabbed_to_dict_generator(tabbed, sep="\t"):
191     iterable = tabbed.rstrip().split(sep)
192     iterable = itertools.imap(split_key_and_value, iterable)
193     iterable = itertools.ifilter(None, iterable)
194     return iterable
195
196 def tabbed_to_dict(tabbed, sep="\t"):
197     """Creates a dict from key equal value pairs seperated with tab"""
198     return dict([pair for pair in tabbed_to_dict_generator(tabbed, sep)])
199
200
201 class StopChainException: pass
202
203 def _do_chain(function, on_end, iterable):
204     try:
205         value = iterable.next()
206         function(value)
207     except StopIteration:
208         # normal end.
209         on_end()
210     except StopChainException:
211         # normal end.
212         on_end()
213     except:
214         # an error is occurred.
215         on_end()
216         traceback.print_exc()
217     else:
218         gobject.idle_add(_do_chain, function, on_end, iterable)
219
220 def chain(function, on_end, iterable):
221     gobject.idle_add(_do_chain, function, on_end, iterable)