+++ /dev/null
-# -*- coding: utf-8 -*-
-
-"""
-Dboxswitch dropbox profile switcher
-
-license: Modified BSD License
-
-Copyright (c) 2012, <stack@inventati.org>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the <organization> nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""
-import platform
-import re
-import shutil
-import os
-import errno
-import signal
-
-from apperror import AppError
-from settings import appconf
-
-class ProfHandler():
-
- def __init__(self):
-
- #create profile directory if not exists
- try:
- os.makedirs(self.getProfileFolder())
- except OSError, e:
- if e.errno != errno.EEXIST:
- raise
-
- #compile regular expression for validating profile names
- self.reg = re.compile("[a-zA-Z0-9_-]+")
-
- #patch symlink on windows
- if platform.system() is 'Windows':
- os.symlink = winsymlink
-
- def getProfilesList(self):
- """ Generate and returns the profiles
- it assumes that self.pdir is defined """
- #this is generated every time to handle the case of the user renaming the directories by hand
- return sorted([os.path.join(self.pdir, f) for f in os.listdir(self.pdir)])
-
- def getProfileFolder(self):
- """ Generates, in a os dependant way, the local folder where all profiles are stored """
- try:
- #directory path is cached
- return self.pdir
- except AttributeError:
- pl = platform.system()
- if pl == "Linux":
- try:
- from xdg.BaseDirectory import xdf_data_home
- self.pdir = os.path.join(xdg_data_home, appconf.appname)
- except:
- self.pdir = os.path.join(os.path.expanduser('~'),".local/share",appconf.appname)
- elif pl == 'Windows':
- self.pdir = os.path.join(os.getenv("APPDATA"), appconf.appname)
- elif pl == 'Darwin':
- self.pdir = os.path.join(os.path.expanduser('~'),"."+appconf.appname)
- elif pl == None:
- raise AppError('Operative system NOT supported.')
-
- return self.pdir
-
- def addProfile(self, profileName):
- """ Create a profile """
-
- print("Creating a new profile")
- if self.isValidProfileName(profileName):
- try:
- os.makedirs(os.path.join(self.getProfileFolder(), profileName))
- except OSError,e:
- if e.errno == errno.EEXIST:
- raise AppError("Profile exists.")
- else:
- raise AppError(str(e))
- else:
- raise AppError('Profile Name not valid.\nAllowed only ascii characters.')
- print("Profile "+profileName+" created.")
-
- def delProfile(self, profileName):
- """ Delete a profile """
-
- print("Deleting profile")
- if self.isValidProfileName(profileName):
- try:
- #recursively delete the profile directory
- shutil.rmtree(os.path.join(self.pdir, profileName))
- except:
- raise AppError('Profile Name does not exists')
- else:
- raise AppError('Profile Name not valid')
- print("Profile "+profileName+" deleted.")
-
- def isCurrentProfile(self, ppath):
- """ Returns true if the current profile path is currently activated """
-
- pl = platform.system()
- if pl in ('Linux','Darwin'):
- if os.path.exists(self.getDropboxDirectory()):
- return True if os.readlink(self.getDropboxDirectory()) == ppath else False
- else:
- return False
-
- def isValidProfileName(self, pname):
-
- if self.reg.match(pname) is not None:
- return True
- else:
- return False
-
- def activateProfile(self, ppath):
- pl = platform.system()
- if ppath in self.getProfilesList():
- self.stopDropbox()
- try:
- if pl in ('Linux','Darwin'):
- if os.path.exists(self.getDropboxDirectory()):
- os.unlink(self.getDropboxDirectory())
- os.symlink(ppath, self.getDropboxDirectory())
- else:
- raise NotImplementedError, "Not implemented yet."
- except IOError as e:
- raise AppError('Error on activating Profile: '+ self.getBaseProfileName(ppath))
- self.startDropbox()
- else:
- raise AppError("Trying to acrivate non existant profile")
-
- def getBaseProfileName(self, ppath):
- """ Returns the base name given a profile returned by getProfilesList """
-
- return os.path.basename(ppath)
-
- def getDropboxDirectory(self):
- pl = platform.system()
- if pl in ('Linux', 'Darwin'):
- return os.path.join(os.path.expanduser('~'),".dropbox")
- elif pl == 'Windows':
- assert os.environ.has_key('APPDATA'), Exception('APPDATA env variable not found')
- return os.path.join(os.environ['APPDATA'],'Dropbox')
- else:
- raise NotImplementedError, "Not implemented yet."
-
- def stopDropbox(self):
- """ Stop dropbox Daemon """
- pl = platform.system()
- if pl == 'Linux':
- os.system("dropbox stop")
- if pl in ('Linux','Darwin'):
- pidfile = os.path.expanduser("~/.dropbox/dropbox.pid")
- try:
- with open(pidfile, "r") as f:
- pid = int(f.read())
- os.kill(pid, signal.SIGTERM)
- except:
- pass
-
- def startDropbox(self):
- """ Sart dropbox Daemon """
-
- pl = platform.system()
- if pl == 'Linux':
- try:
- os.system("dropbox start -i")
- except:
- raise AppError(u"Could not start dropbox.")
- elif pl == 'Darwin':
- os.system("/Applications/Dropbox.app/Contents/MacOS/Dropbox &")
-
-
-__CSL = None
-def winsymlink(source, link_name):
- '''symlink(source, link_name)
- Creates a symbolic link pointing to source named link_name.
- Used to patch the nonexistant version on windows for python 2.6'''
- global __CSL
- if __CSL is None:
- import ctypes
- csl = ctypes.windll.kernel32.CreateSymbolicLinkW
- csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
- csl.restype = ctypes.c_ubyte
- __CSL = csl
- flags = 0
- if source is not None and os.path.isdir(source):
- flags = 1
- if __CSL(link_name, source, flags) == 0:
- raise ctypes.WinError()
-