Skip to content
This repository has been archived by the owner on Nov 5, 2020. It is now read-only.

Commit

Permalink
Add autosave capability and update changelog (close #99, close #97)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmueller committed Nov 12, 2016
1 parent 6e0dc2c commit 159821f
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 122 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
@@ -1,3 +1,7 @@
0.6.5
- Sessions are now autosaved every 60s (#97)
- Bugfixes:
- Loading of sessions with hierarchy children failed (#99)
0.6.4
- Bugfixes:
- Batch analysis: Individual measurement parameters not preserved (#96)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -43,7 +43,7 @@
'GUI': ["wxPython", "chaco", "opencv"],
# kiwisolver?
},
install_requires=["dclab", "NumPy>=1.7.0", "SciPy>=0.10.0",
install_requires=["appdirs", "dclab", "NumPy>=1.7.0", "SciPy>=0.10.0",
"pyper"],
setup_requires=['pytest-runner'],
tests_require=["pytest", "urllib3"],
Expand Down
76 changes: 76 additions & 0 deletions shapeout/gui/autosave.py
@@ -0,0 +1,76 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
""" ShapeOut - autosaving of sessions
"""
from __future__ import division, print_function

import appdirs
import os
import shutil
import time
import wx
import wx.lib.delayedresult as delayedresult

from . import session

cache_dir = appdirs.user_cache_dir(appname="ShapeOut")
autosave_file = os.path.join(cache_dir, "autosave.zmso")


def mkdir_p(adir):
"""Recursively create a directory"""
adir = os.path.abspath(adir)
if not os.path.exists(adir):
try:
os.mkdir(adir)
except:
mkdir_p(os.path.dirname(adir))


def _autosave_consumer(delayedresult, parent):
parent.StatusBar.SetStatusText("Autosaving...")
tempname = autosave_file+".tmp"
mkdir_p(cache_dir)
session.save_session(tempname, parent.analysis)
try:
session.save_session(tempname, parent.analysis)
except:
parent.StatusBar.SetStatusText("Autosaving failed!")
shutil.rmtree(tempname, ignore_errors=True)
else:
os.rename(tempname, autosave_file)
parent.StatusBar.SetStatusText("")
autosave_run(parent)


def _autosave_worker(parent, interval):
"""Runs in the background and performs autosaving"""
time.sleep(interval)


def autosave_run(parent, interval=60):
"""Runs in the background and performs autosaving"""
delayedresult.startWorker(_autosave_consumer,
_autosave_worker,
wargs=(parent, interval,),
cargs=(parent,))


def check_recover(parent):
"""Check for a recovery file and ask if user wants to restore
Returns True if a session was restored. False otherwise.
"""
if os.path.exists(autosave_file):
message="Autosaved session found. Restore?"
dlg = wx.MessageDialog(parent,
caption=_("Missing tdms files for session"),
message=message,
style=wx.YES|wx.NO,
)
mod = dlg.ShowModal()
dlg.Destroy()
if mod != wx.YES:
session.open_session(autosave_file, parent)
return True
return False
123 changes: 17 additions & 106 deletions shapeout/gui/frontend.py
Expand Up @@ -11,12 +11,9 @@
import numpy as np
import os
import platform
import shutil
import sys
import tempfile
import traceback
import wx
import zipfile

import dclab

Expand All @@ -27,13 +24,16 @@
import gaugeframe
from .. import analysis
from .. import tlabwrap
from . import autosave
from . import update
from . import plot_main
from . import misc
from . import video
from . import export
from . import batch
from . import plot_export
from . import session


########################################################################
class ExceptionDialog(wx.MessageDialog):
Expand Down Expand Up @@ -125,11 +125,18 @@ def __init__(self, version, session_file=None):
self.spright.SetMinimumPaneSize(100)
self.sptop.SetMinimumPaneSize(100)

if session_file is not None:
# Check if we have an autosaved session that we did not delete
recover = autosave.check_recover(self)

# Load session file if provided
if session_file is not None and not recover:
self.OnMenuLoad(session_file=session_file)

# Search for updates
update.Update(self)

# Start autosaving
autosave.autosave_run(self)

# Set window icon
try:
Expand All @@ -138,6 +145,7 @@ def __init__(self, version, session_file=None):
except:
self.MainIcon = None


def InitUI(self):
"""Menus, Toolbar, Statusbar"""

Expand Down Expand Up @@ -454,91 +462,8 @@ def OnMenuLoad(self, e=None, session_file=None):

dirname = os.path.dirname(fname)
self.config.SetWorkingDirectory(dirname)
Arc = zipfile.ZipFile(fname, mode='r')
tempdir = tempfile.mkdtemp()
Arc.extractall(tempdir)
Arc.close()

indexfile = os.path.join(tempdir, "index.txt")

delist = [self, self.PanelTop, self.PlotArea]
for item in delist:
if hasattr(item, "analysis"):
del item.analysis

# check session integrity
messages = analysis.session_check_index(indexfile, search_path=dirname)

while len(messages["missing tdms"]):
# There are missing tdms files. We need to modify the extracted
# index file with a folder.
missing = messages["missing tdms"]
directories = [] # search directories
updict = {} # new dicts for individual measurements
# Ask user for directory
miss = os.path.basename(missing[0][1])

message = _("ShapeOut could not find the following measurements:")+\
"\n\n".join([""]+[m[1] for m in missing]) +"\n\n"+\
_("Please select a directory that contains these.")

dlg = wx.MessageDialog(self,
caption=_("Missing tdms files for session"),
message=message,
style=wx.CANCEL|wx.OK,
)
mod = dlg.ShowModal()
dlg.Destroy()
if mod != wx.ID_OK:
break

dlg = wx.DirDialog(self,
message=_(
"Please select directory containing {}"
).format(miss),
)
mod = dlg.ShowModal()
path = dlg.GetPath()
dlg.Destroy()
if mod != wx.ID_OK:
break

# Add search directory
directories.insert(0, path)

# Try to find all measurements with that directory (also relative)
wx.BeginBusyCursor()
remlist = []
for m in missing:
key, tdms, thash = m
newfile = tlabwrap.search_hashed_tdms(tdms, thash, directories)
if newfile is not None:
newdir = os.path.dirname(newfile)
updict[key] = {"fdir": newdir}
directories.insert(0, os.path.dirname(newdir))
directories.insert(0, os.path.dirname(os.path.dirname(newdir)))
remlist.append(m)
for m in remlist:
missing.remove(m)
wx.EndBusyCursor()

# Update the extracted index file.
analysis.session_update_index(indexfile, updict)

self.NewAnalysis(indexfile, search_path=dirname)

directories = list()
for mm in self.analysis.measurements:
if os.path.exists(mm.fdir):
directories.append(mm.fdir)

bolddirs = self.analysis.GetTDMSFilenames()

self.OnMenuSearchPathAdd(add=False, path=directories,
marked=bolddirs)

# Remove all temporary files
shutil.rmtree(tempdir, ignore_errors=True)
session.open_session(fname, self)


def OnMenuSearchPath(self, e=None):
Expand Down Expand Up @@ -599,10 +524,9 @@ def OnMenuQuit(self, e=None):
if filename is None:
# User did not save session - abort
return
#self.Close()
#self.Destroy()
#sys.exit()
# Force Exit without cleanup

# remove the autosaved file
os.remove(autosave.autosave_file)
os._exit(0)


Expand All @@ -619,20 +543,7 @@ def OnMenuSaveSimple(self, e=None):
path += ".zmso"
dirname = os.path.dirname(path)
self.config.SetWorkingDirectory(dirname, name="Session")
# Begin saving
returnWD = os.getcwd()
tempdir = tempfile.mkdtemp()
os.chdir(tempdir)
Arc = zipfile.ZipFile(path, mode='w')
## Dump data into directory
self.analysis.DumpData(tempdir, rel_path=os.path.dirname(path))
for root, _dirs, files in os.walk(tempdir):
for f in files:
fw = os.path.join(root,f)
Arc.write(os.path.relpath(fw,tempdir))
os.remove(fw)
Arc.close()
os.chdir(returnWD)
session.save_session(path, self.analysis)
return path
else:
dirname = dlg.GetDirectory()
Expand Down

0 comments on commit 159821f

Please sign in to comment.