OSDN Git Service

Re implement cachefile.py
authorAiwota Programmer <aiwotaprog@tetteke.tk>
Sun, 24 Sep 2006 07:02:33 +0000 (16:02 +0900)
committerAiwota Programmer <aiwotaprog@tetteke.tk>
Sun, 24 Sep 2006 07:02:33 +0000 (16:02 +0900)
src/FukuiNoNamari/board_data.py
src/FukuiNoNamari/cachefile.py
src/FukuiNoNamari/misc.py

index 767f7fc..83231d0 100644 (file)
@@ -121,11 +121,17 @@ class BoardData:
 
     def load_idxfiles(self):
         print "load_cache"
-        datalist = self._load_cache()
+        try:
+            datalist = self._load_cache()
+        except IOError:
+            datalist = {}
         print "load_idx"
         self._load_modified_idxfiles(datalist)
         print "save_cache"
-        cachefile.save_cache(self.bbs_type, datalist)
+        try:
+            self._save_cache(datalist)
+        except IOError:
+            traceback.print_exc()
 
         status = "Complete index files."
         gobject.idle_add(self.set_status, status)
@@ -137,12 +143,13 @@ class BoardData:
         except OSError:
             total = -1
 
-        iterable = cachefile.load_cache(self.bbs_type)
+        iterable = file(misc.get_board_cache_path(self.bbs_type))
 
         # split
         iterable_dic, iterable_line = itertools.tee(iterable)
-        iterable_dic = itertools.starmap(lambda x, y: x, iterable_dic)
-        iterable_line = itertools.starmap(lambda x, y: y, iterable_line)
+
+        iterable_dic = itertools.imap(lambda l: l.rstrip(), iterable_dic)
+        iterable_dic = cachefile.formatted_to_dict(iterable_dic)
 
         iterable_line = itertools.imap(lambda x :len(x), iterable_line)
         iterable_line = accumulate(iterable_line)
@@ -225,6 +232,19 @@ class BoardData:
             del datalist[key]
             print "del", key
 
+    def _save_cache(self, datalist):
+        def save(f, data):
+            f.write(data)
+            return data
+
+        iterable = datalist.iteritems()
+        iterable = cachefile.dict_to_formatted(iterable)
+        c_file = misc.FileWrap(misc.get_board_cache_path(self.bbs_type), "w")
+        iterable = itertools.imap(lambda data: save(c_file, data), iterable)
+
+        for i in iterable:
+            pass
+
     def _split_record(self, line_encoded):
         line = line_encoded.decode(self.bbs_type.encoding, "replace")
         m = self.bbs_type.subject_reg.match(line)
index 0b042f4..8077d81 100644 (file)
@@ -15,8 +15,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-import os
-import traceback
+import itertools
 
 import misc
 
@@ -33,86 +32,62 @@ def _empty_generator():
 
 default_dict = dict([pair for pair in _empty_generator()])
 
+def _tabbed_to_dict(tabbed):
 
-def _tabbed_to_key_value_generator(line):
-    for key_equal_value in line.split("\t"):
-        try:
-            index = key_equal_value.index("=")
-        except ValueError:
-            pass
-        else:
-            key = key_equal_value[:index]
-            if key in recorded_data:
-                value = key_equal_value[index+1:]
-                if key in int_data:
-                    try:
-                        value = int(value)
-                    except:
-                        value = 0
-                yield key, value
-
-def _dict_to_tabbed(dic):
-    line = ""
-    for name, value in dic.iteritems():
-
-        # save metadata only if its name exists in metadata_namelist
-        if name not in metadata_namelist:
-            continue
+    def adjust_type(key, value):
+        if key in int_data:
+            try:
+                value = int(value)
+            except:
+                value = 0
+        return key, value
 
-        # no need to save an empty or invalid field
-        if name in int_data and value > 0:
-            line += name + "=" + str(value) + "\t"
-        elif name not in int_data and value:
-            line += name + "=" + value + "\t"
-
-    return line
+    iterable = misc.tabbed_to_dict_generator(tabbed)
+    iterable = misc.unpack_ifilter(lambda k, v: k in recorded_data, iterable)
+    iterable = itertools.starmap(adjust_type, iterable)
 
-def load_cache(bbs_type):
-    """ Loads metadata from .cache file. This is generator.
+    dic = default_dict.copy()
+    for key, value in iterable:
+        dic[key] = value
 
-    loads metadata and yield per one thread
+    return dic
 
-    metadata dic key is in metadata_namelist
-    """
-
-    cachefile_path = misc.get_board_cache_path(bbs_type)
-    try:
-        for line in file(cachefile_path):
-
-            dic = default_dict.copy()
-            for key, value in _tabbed_to_key_value_generator(line.rstrip()):
-                dic[key] = value
-
-            # only if id exists
-            if "id" in dic and dic["id"]:
-                yield dic, line
+def _dict_to_tabbed(dic):
 
-    except IOError:
-        traceback.print_exc()
+    def validate(name, value):
+        if name in int_data and value > 0:
+            return True
+        elif name not in int_data and value:
+            return True
+        return False
+        
+    iterable = dic.iteritems()
 
-def save_cache(bbs_type, dic):
-    """ Saves metadata list to .cache file
+    # save metadata only if its name exists in metadata_namelist
+    iterable = misc.unpack_ifilter(lambda n,v: n in metadata_namelist,iterable)
 
-    dic: dictionary of thread id and metadata dictionary
-    which key is in metadata_namelist
-    """
-    # nothing to do if dic is empty
-    if not dic:
-        return
+    # no need to save an empty or invalid field
+    iterable = misc.unpack_ifilter(validate, iterable)
 
-    cachefile_path = misc.get_board_cache_path(bbs_type)
+    iterable = itertools.starmap(lambda n,v: "%s=%s\t" % (n, str(v)), iterable)
 
-    # create a directroy where .cache file is if not exists
-    basedir = os.path.dirname(cachefile_path)
-    if not os.path.isdir(basedir):
-        os.makedirs(basedir)
+    line = ""
+    for tabbed in iterable:
+        line += tabbed
+    return line
 
-    f = open(cachefile_path, "w")
-    for id, metadata_list in dic.iteritems():
-        # save only if id is not empty
-        if id:
-            line = "id=" + id + "\t"
-            line += _dict_to_tabbed(metadata_list)
-            line += "\n"
-            f.write(line)
-    f.close()
+def do_formatted_to_dict(formatted):
+    dic = _tabbed_to_dict(formatted)
+    if "id" in dic and dic["id"]:
+        return dic
+    
+def formatted_to_dict(iterable):
+    iterable = itertools.imap(do_formatted_to_dict, iterable)
+    iterable = itertools.ifilter(None, iterable)
+    return iterable
+
+def do_dict_to_formatted(thread_id, dic):
+    return "id=%s\t%s\n" % (thread_id, _dict_to_tabbed(dic))
+
+def dict_to_formatted(iterable):
+    return itertools.starmap(do_dict_to_formatted, iterable)
index eb29558..27ebbed 100644 (file)
@@ -19,6 +19,7 @@ import os.path
 import re
 import threading
 from datetime import tzinfo, timedelta, datetime
+import itertools
 
 import config
 from BbsType import bbs_type_exception
@@ -176,3 +177,29 @@ class FileWrap:
                 os.makedirs(basedir)
             self.__file = file(self.__path, self.__mode)
         return self.__file
+
+def unpack_ifilter(predicate, iterable):
+    """For multiple argument"""
+    for item in iterable:
+        if predicate(*item):
+            yield item
+
+def split_key_and_value(key_equal_value):
+    try:
+        index = key_equal_value.index("=")
+    except ValueError:
+        pass
+    else:
+        key = key_equal_value[:index]
+        value = key_equal_value[index+1:]
+        return key, value
+
+def tabbed_to_dict_generator(tabbed, sep="\t"):
+    iterable = tabbed.rstrip().split(sep)
+    iterable = itertools.imap(split_key_and_value, iterable)
+    iterable = itertools.ifilter(None, iterable)
+    return iterable
+
+def tabbed_to_dict(tabbed, sep="\t"):
+    """Creates a dict from key equal value pairs seperated with tab"""
+    return dict([pair for pair in tabbed_to_dict_generator(tabbed, sep)])