Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-04-14 17:06:17 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-04-14 17:06:17 (GMT)
commita4c97e5c60d93cf7ce42ccf6b191dc376df383d1 (patch)
tree1cade1001a40cb7d223c607a99a8c24fb187ece4
parent73619fff09a27ee8f0f7d72c5acd7703af33d58d (diff)
Do not store image thoughts on disk
-rw-r--r--labyrinthactivity.py52
-rw-r--r--src/BaseThought.py4
-rw-r--r--src/DrawingThought.py4
-rw-r--r--src/ImageThought.py112
-rw-r--r--src/MMapArea.py31
-rw-r--r--src/PeriodicSaveThread.py37
-rw-r--r--src/TextThought.py4
7 files changed, 86 insertions, 158 deletions
diff --git a/labyrinthactivity.py b/labyrinthactivity.py
index 45242ff..e90450e 100644
--- a/labyrinthactivity.py
+++ b/labyrinthactivity.py
@@ -19,9 +19,9 @@ import sys
import os
import logging
from gettext import gettext as _
-import tarfile
import tempfile
import xml.dom.minidom as dom
+from zipfile import ZipFile
import gobject
import gtk
@@ -141,7 +141,6 @@ class LabyrinthActivity(activity.Activity):
tool.connect('clicked', self.__zoom_original_cb)
view_toolbar.insert(tool, -1)
- self._save_file = None
self._mode = MMapArea.MODE_TEXT
self._undo = UndoManager.UndoManager (self,
@@ -149,7 +148,6 @@ class LabyrinthActivity(activity.Activity):
edit_toolbar.redo.child)
self._undo.block ()
self._main_area = MMapArea.MMapArea (self._undo)
- self._main_area.connect ("doc_save", self.__doc_save_cb)
self._main_area.connect ("set_focus", self.__main_area_focus_cb)
self._main_area.connect ("button-press-event", self.__main_area_focus_cb)
self._main_area.connect ("expose_event", self.__expose)
@@ -286,19 +284,16 @@ class LabyrinthActivity(activity.Activity):
self._main_area.grab_focus ()
def read_file(self, file_path):
- tar_file = tarfile.open(file_path)
- map_name = tar_file.getnames()[0]
- tar_file.extractall(tempfile.gettempdir())
- tar_file.close()
+ zip = ZipFile(file_path, 'r')
- f = file (os.path.join(tempfile.gettempdir(), map_name), 'r')
- doc = dom.parse (f)
+ doc = dom.parseString (zip.read('MANIFEST'))
top_element = doc.documentElement
+
self.set_title(top_element.getAttribute ("title"))
self._mode = int (top_element.getAttribute ("mode"))
self._main_area.set_mode (self._mode)
- self._main_area.load_thyself (top_element, doc)
+ self._main_area.load_thyself (top_element, doc, zip)
if top_element.hasAttribute("scale_factor"):
self._main_area.scale_fac = float (top_element.getAttribute ("scale_factor"))
if top_element.hasAttribute("translation"):
@@ -308,35 +303,19 @@ class LabyrinthActivity(activity.Activity):
self.mods[self._mode].set_active(True)
+ zip.close()
+
def write_file(self, file_path):
logging.debug('write_file')
- self._main_area.save_thyself ()
-
- if self._save_file is None:
- # FIXME: Create an empty file because the Activity superclass
- # always requires one
- fd, self._save_file = tempfile.mkstemp(suffix='.map')
- del fd
-
- tf = tarfile.open (file_path, "w")
- tf.add (self._save_file, os.path.split(self._save_file)[1])
- for t in self._main_area.thoughts:
- if isinstance(t, ImageThought.ImageThought):
- tf.add (t.filename, 'images/' + os.path.split(t.filename)[1])
-
- tf.close()
- os.unlink(self._save_file)
+ zip = ZipFile(file_path, 'w')
- def __doc_save_cb (self, widget, doc, top_element):
- logging.debug('doc_save_cb')
- save_string = self.serialize_to_xml(doc, top_element)
+ self._main_area.update_save(zip)
+ manifest = self.serialize_to_xml(self._main_area.save,
+ self._main_area.element)
+ zip.writestr('MANIFEST', manifest)
- fd, self._save_file = tempfile.mkstemp(suffix='.map')
- del fd
-
- self.save_map(self._save_file, save_string)
- #self.emit ('file_saved', self._save_file, self)
+ zip.close()
def serialize_to_xml(self, doc, top_element):
top_element.setAttribute ("title", self.props.title)
@@ -351,11 +330,6 @@ class LabyrinthActivity(activity.Activity):
string = doc.toxml ()
return string.encode ("utf-8" )
- def save_map(self, filename, string):
- f = file (filename, 'w')
- f.write (string)
- f.close ()
-
def __link_cb(self, widget):
self._main_area.link_menu_cb()
diff --git a/src/BaseThought.py b/src/BaseThought.py
index 6e15497..4279d49 100644
--- a/src/BaseThought.py
+++ b/src/BaseThought.py
@@ -186,10 +186,10 @@ class BaseThought (gobject.GObject):
def draw (self, context):
pass
- def load (self, node):
+ def load (self, node, zip):
pass
- def update_save (self):
+ def update_save (self, zip):
pass
def copy_text (self, clip):
diff --git a/src/DrawingThought.py b/src/DrawingThought.py
index 357d72f..5a8448c 100644
--- a/src/DrawingThought.py
+++ b/src/DrawingThought.py
@@ -334,7 +334,7 @@ class DrawingThought (ResizableThought):
map(lambda p : p.move_by(x,y), self.points)
ResizableThought.move_content_by(self, x, y)
- def update_save (self):
+ def update_save (self, zip):
next = self.element.firstChild
while next:
m = next.nextSibling
@@ -383,7 +383,7 @@ class DrawingThought (ResizableThought):
elem.setAttribute ("color", p.color.to_string())
return
- def load (self, node):
+ def load (self, node, zip):
tmp = node.getAttribute ("ul-coords")
self.ul = utils.parse_coords (tmp)
tmp = node.getAttribute ("lr-coords")
diff --git a/src/ImageThought.py b/src/ImageThought.py
index cb21c0d..78bba20 100644
--- a/src/ImageThought.py
+++ b/src/ImageThought.py
@@ -26,6 +26,9 @@ import gettext
_ = gettext.gettext
import cairo
import os
+import logging
+import tempfile
+import cStringIO
from sugar import mime
@@ -50,49 +53,37 @@ class ImageThought (ResizableThought):
# FIXME: Work in progress, needs at least activity self to create
# tmp files/links in the right places and reference the window.
- def journal_open_image (self, filename=None):
- if not filename:
- self.object_chooser_active = True
- if hasattr(mime, 'GENERIC_TYPE_IMAGE'):
- chooser = ObjectChooser(_('Choose image'),
- what_filter=mime.GENERIC_TYPE_IMAGE)
- else:
- chooser = ObjectChooser(_('Choose image'))
-
- try:
- result = chooser.run()
- if result == gtk.RESPONSE_ACCEPT and chooser.get_selected_object():
- jobject = chooser.get_selected_object()
- else:
- return False
-
- if jobject and jobject.file_path:
- fname = os.path.join(get_activity_root(), 'tmp',
- os.path.basename(jobject.file_path))
- os.rename(jobject.file_path, fname)
- else:
- return False
- finally:
- chooser.destroy()
- del chooser
- self.object_chooser_active = False
+ def journal_open_image (self):
+ self.object_chooser_active = True
+ if hasattr(mime, 'GENERIC_TYPE_IMAGE'):
+ chooser = ObjectChooser(_('Choose image'),
+ what_filter=mime.GENERIC_TYPE_IMAGE)
else:
- fname = filename
-
- print "fname =",fname
+ chooser = ObjectChooser(_('Choose image'))
try:
- self.orig_pic = gtk.gdk.pixbuf_new_from_file (fname)
- except:
- try:
- # lets see if file was imported and is already extracted
- fname = utils.get_save_dir() + 'images/' + utils.strip_path_from_file_name(filename)
- self.orig_pic = gtk.gdk.pixbuf_new_from_file (fname)
- except:
+ result = chooser.run()
+ if result == gtk.RESPONSE_ACCEPT and chooser.get_selected_object():
+ jobject = chooser.get_selected_object()
+ else:
return False
- self.filename = fname
- self.text = fname[fname.rfind('/')+1:fname.rfind('.')]
+ if jobject and jobject.file_path:
+ logging.debug("journal_open_image: fname=%s" % jobject.file_path)
+ try:
+ self.orig_pic = gtk.gdk.pixbuf_new_from_file (jobject.file_path)
+ self.filename = os.path.basename(jobject.file_path)
+ except Exception, e:
+ logging.error("journal_open_image: %s" % e)
+ return False
+ else:
+ return False
+ finally:
+ chooser.destroy()
+ del chooser
+ self.object_chooser_active = False
+
+ self.text = self.filename[0:self.filename.rfind('.')]
self.recalc_edges(True)
return True
@@ -167,7 +158,7 @@ class ImageThought (ResizableThought):
return False
- def update_save (self):
+ def update_save (self, zip):
text = self.extended_buffer.get_text ()
if text:
self.extended_buffer.update_save()
@@ -197,9 +188,12 @@ class ImageThought (ResizableThought):
self.element.removeAttribute ("primary_root")
except xml.dom.NotFoundErr:
pass
- return
- def load (self, node):
+ arcname = self.filename.encode('cp437')
+ if not [i for i in zip.namelist() if i == arcname]:
+ zip.writestr(arcname, pixbuf2str(self.orig_pic))
+
+ def load (self, node, zip):
tmp = node.getAttribute ("ul-coords")
self.ul = utils.parse_coords (tmp)
tmp = node.getAttribute ("lr-coords")
@@ -223,20 +217,30 @@ class ImageThought (ResizableThought):
print "Unknown: "+n.nodeName
margin = utils.margin_required (utils.STYLE_NORMAL)
self.pic_location = (self.ul[0]+margin[0], self.ul[1]+margin[1])
- self.okay = self.journal_open_image (self.filename)
+ self.orig_pic = str2pixbuf(zip.read(self.filename.encode('cp437')))
self.lr = (self.pic_location[0]+self.width+margin[2], self.pic_location[1]+self.height+margin[3])
- if not self.okay:
- dialog = gtk.MessageDialog (None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE,
- _("Error loading file"))
- dialog.format_secondary_text (_("%s could not be found. Associated thought will be empty."%self.filename))
- dialog.run ()
- dialog.hide ()
- self.pic = None
- self.orig_pic = None
- else:
- self.recalc_edges()
- return
+ self.recalc_edges()
def enter (self):
self.editing = True
+
+def pixbuf2str(pixbuf):
+ def push(data, buffer):
+ buffer.write(data)
+
+ buffer = cStringIO.StringIO()
+ pixbuf.save_to_callback(push, 'png', user_data=buffer)
+
+ return buffer.getvalue()
+
+def str2pixbuf(data):
+ fd, path = tempfile.mkstemp()
+
+ f = os.fdopen(fd, 'w')
+ f.write(data)
+ f.close()
+
+ out = gtk.gdk.pixbuf_new_from_file(path)
+ os.unlink(path)
+
+ return out
diff --git a/src/MMapArea.py b/src/MMapArea.py
index 0a127cc..dccc2e7 100644
--- a/src/MMapArea.py
+++ b/src/MMapArea.py
@@ -85,12 +85,6 @@ class MMapArea (gtk.DrawingArea):
__gsignals__ = dict (title_changed = (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
(gobject.TYPE_STRING, )),
- doc_save = (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
- doc_delete = (gobject.SIGNAL_RUN_FIRST,
- gobject.TYPE_NONE,
- ()),
change_mode = (gobject.SIGNAL_RUN_LAST,
gobject.TYPE_NONE,
(gobject.TYPE_INT, )),
@@ -1012,10 +1006,10 @@ class MMapArea (gtk.DrawingArea):
self.invalidate ()
return True
- def load_thought (self, node, type):
+ def load_thought (self, node, type, zip):
thought = self.create_new_thought (None, type, loading = True)
thought.creating = False
- thought.load (node)
+ thought.load (node, zip)
def load_link (self, node):
link = Link (self.save)
@@ -1025,16 +1019,16 @@ class MMapArea (gtk.DrawingArea):
element = link.get_save_element ()
self.element.appendChild (element)
- def load_thyself (self, top_element, doc):
+ def load_thyself (self, top_element, doc, zip):
for node in top_element.childNodes:
if node.nodeName == "thought":
- self.load_thought (node, MODE_TEXT)
+ self.load_thought (node, MODE_TEXT, zip)
elif node.nodeName == "image_thought":
- self.load_thought (node, MODE_IMAGE)
+ self.load_thought (node, MODE_IMAGE, zip)
elif node.nodeName == "drawing_thought":
- self.load_thought (node, MODE_DRAW)
+ self.load_thought (node, MODE_DRAW, zip)
elif node.nodeName == "res_thought":
- self.load_thought (node, MODE_RESOURCE)
+ self.load_thought (node, MODE_RESOURCE, zip)
elif node.nodeName == "link":
self.load_link (node)
else:
@@ -1085,19 +1079,12 @@ class MMapArea (gtk.DrawingArea):
for l in del_links:
self.delete_link (l)
- def prepare_save(self):
+ def update_save(self, zip):
for t in self.thoughts:
- t.update_save ()
+ t.update_save (zip)
for l in self.links:
l.update_save ()
- def save_thyself (self):
- self.prepare_save()
- if len(self.thoughts) > 0:
- self.emit ("doc_save", self.save, self.element)
- else:
- self.emit ("doc_delete")
-
def text_selection_cb (self, thought, start, end, text):
self.emit ("text_selection_changed", start, end, text)
diff --git a/src/PeriodicSaveThread.py b/src/PeriodicSaveThread.py
deleted file mode 100644
index 1747e90..0000000
--- a/src/PeriodicSaveThread.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# PeriodicSaveThread.py
-# This file is part of Labyrinth
-#
-# Copyright (C) 2008 - Labyrinth-Dev-Team
-#
-# Labyrinth 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.
-#
-# Labyrinth 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 Labyrinth; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor,
-# Boston, MA 02110-1301 USA
-#
-
-import threading
-import time
-
-class PeriodicSaveThread(threading.Thread):
-
- def __init__(self, main_area):
- threading.Thread.__init__(self)
- self.main_area = main_area
- self.cancel = False
-
- def run (self):
- time.sleep (60)
- while not self.cancel:
- self.main_area.save_thyself ()
- time.sleep (60)
-
diff --git a/src/TextThought.py b/src/TextThought.py
index 38b0ca7..3bb0599 100644
--- a/src/TextThought.py
+++ b/src/TextThought.py
@@ -790,7 +790,7 @@ class TextThought (ResizableThought):
context.set_source_rgb (0,0,0)
context.stroke ()
- def update_save (self):
+ def update_save (self, zip):
next = self.element.firstChild
while next:
m = next.nextSibling
@@ -886,7 +886,7 @@ class TextThought (ResizableThought):
self.bindex = self.b_f_i (self.index)
self.text = tmp
- def load (self, node):
+ def load (self, node, zip):
self.index = int (node.getAttribute ("cursor"))
self.end_index = self.index
tmp = node.getAttribute ("ul-coords")