def commitChanges(self):
        GenericSchemaEditor.commitChanges(self)
        if len(self._addedProps):
            # we must reload the class module
            oMod = misc.getCallableByName(self._class.__module__)
            reload(oMod)
            from porcupine.oql.command import OqlCommand

            db = offlinedb.getHandle()
            oql_command = OqlCommand()
            rs = oql_command.execute("select * from deep('/') where instanceof('%s')" % self._instance.contentclass)
            try:
                if len(rs):
                    txn = offlinedb.OfflineTransaction()
                    try:
                        for item in rs:
                            for name in self._addedProps:
                                if not hasattr(item, name):
                                    setattr(item, name, self._addedProps[name])
                            db.putItem(item, txn)
                        txn.commit()
                    except Exception, e:
                        txn.abort()
                        raise e
                        sys.exit(2)
            finally:
                offlinedb.close()
 def removeProperty(self, name):
     from porcupine.oql.command import OqlCommand
     db = offlinedb.getHandle()
     oql_command = OqlCommand()
     rs = oql_command.execute(
         "select * from deep('/') where instanceof('%s')" %
         self._instance.contentclass)
     try:
         if len(rs):
             txn = offlinedb.OfflineTransaction()
             try:
                 for item in rs:
                     if hasattr(item, name):
                         delattr(item, name)
                     db.putItem(item, txn)
                 txn.commit()
             except Exception, e:
                 txn.abort()
                 raise e
                 sys.exit(2)
     finally:
         offlinedb.close()
     
     if self._attrs.has_key(name):
         del self._attrs[name]
    def commitChanges(self, generate_code=True):
        from porcupine.oql.command import OqlCommand

        if self._setProps or self._removedProps:
            if generate_code:
                GenericSchemaEditor.commitChanges(self)
                # we must reload the class module
                oMod = misc.get_rto_by_name(self._class.__module__)
                reload(oMod)

            db = offlinedb.getHandle()
            oql_command = OqlCommand()
            rs = oql_command.execute("select * from deep('/') where instanceof('%s')" % self._instance.contentclass)
            try:
                if len(rs):
                    try:
                        for item in rs:
                            txn = db.get_transaction()
                            for name in self._removedProps:
                                if hasattr(item, name):
                                    delattr(item, name)
                            for name in self._setProps:
                                if not hasattr(item, name):
                                    # add new
                                    setattr(item, name, self._setProps[name])
                                else:
                                    # replace property
                                    old_value = getattr(item, name).value
                                    setattr(item, name, self._setProps[name])
                                    new_attr = getattr(item, name)
                                    if isinstance(new_attr, datatypes.Password):
                                        new_attr._value = old_value
                                    else:
                                        new_attr.value = old_value
                            if self.xform:
                                item = self.xform(item)
                            db.put_item(item, txn)
                            txn.commit()
                    except Exception, e:
                        txn.abort()
                        raise e
                        sys.exit(2)
            finally:
                offlinedb.close()
    def create(self):
        # registrations
        conf_file = configfiles.ConfigFileManager('conf/store.xml')
        pkgnode = conf_file.getPackageNode(self.name)
        if pkgnode:
            print 'INFO: extracting package registrations'
            regsFile = file(serverSettings.temp_folder + '/_regs.xml', 'w')
            regsFile.write('<config>\n' + pkgnode.toxml('utf-8') + '\n</config>')
            regsFile.close()
            self.package_files.append(
                (
                    self.package_file.gettarinfo(
                        regsFile.name, os.path.basename(regsFile.name)
                    ),
                    regsFile.name
                )
            )
        else:
            print 'WARNING: Package "' + self.name + '" has no registrations'
        
        # files
        files = self.config_file.options('files')
        for fl in files:
            fname = self.config_file.get('files', fl)
            print 'INFO: adding file ' + fname
            self.package_files.append(
                (self.package_file.gettarinfo(fname, fname), fname)
            )
    
        # directories
        dirs = self.config_file.options('dirs')
        for dir in dirs:
            dirname = self.config_file.get('dirs', dir)
            print 'INFO: adding directory ' + dirname
            self._addtree(dirname)
        
        # published directories
        if self.config_file.has_section('pubdir'):
            pubdirs = self.config_file.options('pubdir')
            dirsConfig = configfiles.PubDirManager()
            
            dir_nodes = []
            for dir in pubdirs:
                dirname = self.config_file.get('pubdir', dir)
                print 'INFO: adding published directory "%s"' % dirname
                dir_node = dirsConfig.getDirNode(dirname)
                if dir_node:
                        dir_nodes.append(dir_node)
                        dir_location = dir_node.getAttribute('path')
                        self._addtree(dir_location)
                else:
                    print 'WARNING: published directory "%s" does not exist' % appname
            
            if dir_nodes:
                dirsFile = file(serverSettings.temp_folder + '/_pubdir.xml', 'w')
                dirsFile.write('<?xml version="1.0" encoding="utf-8"?><dirs>')
                for dir_node in dir_nodes:
                    dirsFile.write(dir_node.toxml('utf-8'))
                dirsFile.write('</dirs>')
                dirsFile.close()
                self.package_files.append(
                    (
                        self.package_file.gettarinfo(
                            dirsFile.name, os.path.basename(dirsFile.name)
                        ),
                        dirsFile.name
                    )
                )
            dirsConfig.close(False)
        
        # database items
        items = self.config_file.options('items')
        itemids = [self.config_file.get('items', x) for x in items]
        self.db = offlinedb.getHandle()
        try:
            for itemid in itemids:
                self._exportItem(itemid)
        finally:
            offlinedb.close()
                
        # scripts
        if self.config_file.has_option('scripts', 'preinstall'):
            preinstall = self.config_file.get('scripts', 'preinstall')
            print 'INFO: adding pre-install script "%s"' % preinstall
            self.package_files.append(
                (
                    self.package_file.gettarinfo(preinstall, '_pre.py'),
                    preinstall
                )
            )

        if self.config_file.has_option('scripts', 'postinstall'):
            postinstall = self.config_file.get('scripts', 'postinstall')
            print 'INFO: adding post-install script "%s"' % postinstall
            self.package_files.append(
                (
                    self.package_file.gettarinfo(postinstall, '_post.py'),
                    postinstall
                )
            )
                
        if self.config_file.has_option('scripts', 'uninstall'):
            uninstall = self.config_file.get('scripts', 'uninstall')
            print 'INFO: adding uninstall script "%s"' % uninstall
            self.package_files.append(
                (
                    self.package_file.gettarinfo(uninstall, '_uninstall.py'),
                    uninstall
                )
            )
            
        # definition file
        self.package_files.append(
            (
                self.package_file.gettarinfo(definition, '_pkg.ini'),
                definition
            )
        )
    
        # compact files
        print 'INFO: compacting...'
        for tarinfo, fname in self.package_files:
            if tarinfo.isfile():
                self.package_file.addfile(tarinfo, file(fname, 'rb'))
                # remove temporary
                if fname[:len(serverSettings.temp_folder)] == \
                serverSettings.temp_folder:
                    os.remove(fname)
            else:
                self.package_file.add(fname)
    def uninstall(self):
        print 'INFO: uninstalling [%s-%s] package...' % (self.name, self.version)
        
        # registrations
        conf_file = configfiles.ConfigFileManager('conf/store.xml')
        pkgnode = conf_file.getPackageNode(self.name)
        if pkgnode:
            print 'INFO: removing package registrations'
            conf_file.removePackageNode(pkgnode)
            conf_file.close()
        
        # database items
        items = self.config_file.options('items')
        itemids = [self.config_file.get('items', x) for x in items]
        self.db = offlinedb.getHandle()
        txn = offlinedb.OfflineTransaction()
        try:
            try:
                for itemid in itemids:
                    print 'INFO: removing object %s' % itemid
                    try:
                        oItem = self.db.getItem(itemid, txn)
                    except:
                        pass
                    else:
                        oItem.delete(txn)
                txn.commit()
            except Exception, e:
                txn.abort()
                raise e
                sys.exit(2)
        finally:
            offlinedb.close()
            
        # uninstall script
        contents = self.package_file.getnames()
        if '_uninstall.py' in contents:
            print 'INFO: running uninstallation script...'
            self.package_file.extract('_uninstall.py', serverSettings.temp_folder)
            execfile(serverSettings.temp_folder + '/_uninstall.py')
            os.remove(serverSettings.temp_folder + '/_uninstall.py')
        
        # files
        files = self.config_file.options('files')
        for fl in files:
            fname = self.config_file.get('files', fl)
            print 'INFO: removing file ' + fname
            if os.path.exists(fname):
                os.remove(fname)
            # check if it is a python file
            if fname[-3:] == '.py':
                dummy = [
                    os.remove(fname + x)
                    for x in ('c', 'o')
                    if os.path.exists(fname + x)
                ]
    
        # directories
        dirs = self.config_file.options('dirs')
        for dir in dirs:
            dirname = self.config_file.get('dirs', dir)
            if os.path.exists(dirname):
                print 'INFO: removing directory ' + dirname
                self._deltree(dirname)
                
        # published dirs
        if '_pubdir.xml' in contents:
            print 'INFO: uninstalling web apps...'
            dirsfile = self.package_file.extractfile('_pubdir.xml')
            _dom = minidom.parse(dirsfile)
            dirsConfig = configfiles.PubDirManager()
            dir_nodes = _dom.getElementsByTagName('dir')
            for dir_node in dir_nodes:
                #app_node = app_node.cloneNode(True)
                dir_name = dir_node.getAttribute('name')
                print 'INFO: uninstalling published directory "%s"' % dir_name
                old_node = dirsConfig.getDirNode(dir_name)
                if old_node:
                    dirsConfig.removeDirNode(old_node)
                else:
                    print 'WARNING: published directory "%s" does not exist' % app_name
                dirname = dir_node.getAttribute('path')
                if os.path.exists(dirname):
                    self._deltree(dirname)

            _dom.unlink()
            dirsConfig.close(True)
    def install(self):
        print 'INFO: installing [%s-%s] package...' % (self.name, self.version)
        contents = self.package_file.getnames()
        
        # pre-install script
        if '_pre.py' in contents:
            print 'INFO: running pre installation script...'
            self.package_file.extract('_pre.py', serverSettings.temp_folder)
            execfile(serverSettings.temp_folder + '/_pre.py')
            os.remove(serverSettings.temp_folder + '/_pre.py')
        
        # registrations
        if '_regs.xml' in contents:
            print 'INFO: installing package registrations...'
            regsfile = self.package_file.extractfile('_regs.xml')
            _dom = minidom.parse(regsfile)
            package_node = _dom.getElementsByTagName('package')[0]
            package_node = package_node.cloneNode(True)
            conf_file = configfiles.ConfigFileManager('conf/store.xml')
            old_node = conf_file.getPackageNode(self.name)
            if old_node:
                conf_file.replacePackageNode(package_node, old_node)
            else:
                conf_file.addPackageNode(package_node)
            _dom.unlink()
            conf_file.close()

        # published directories
        if '_pubdir.xml' in contents:
            print 'INFO: installing published directories...'
            dirsfile = self.package_file.extractfile('_pubdir.xml')
            _dom = minidom.parse(dirsfile)
            dirsConfig = configfiles.PubDirManager()
            dir_nodes = _dom.getElementsByTagName('dir')
            for dir_node in dir_nodes:
                dir_node = dir_node.cloneNode(True)
                dir_name = dir_node.getAttribute('name')
                print 'INFO: installing published directory "%s"' % dir_name
                old_node = dirsConfig.getDirNode(dir_name)
                if old_node:
                    dirsConfig.replaceDirNode(dir_node, old_node)
                else:
                    dirsConfig.addDirNode(dir_node)
            _dom.unlink()
            dirsConfig.close(True)
                
        # files and dirs
        for pfile in [x for x in contents if x[0] != '_']:
            print 'INFO: extracting ' + pfile
            self.package_file.extract(pfile)
                
        # database
        dbfiles = [x for x in contents if x[:4] == '_db/']
        if dbfiles:
            self.db = offlinedb.getHandle()
            txn = offlinedb.OfflineTransaction()
            try:
                for dbfile in dbfiles:
                    print 'INFO: importing object ' + os.path.basename(dbfile)
                    actual_fn = serverSettings.temp_folder + '/' + dbfile
                    objfile = None
                    try:
                        try:
                            self.package_file.extract(dbfile, serverSettings.temp_folder)
                            objfile = file(actual_fn, 'rb')
                            self._importItem(objfile, txn)
                        except Exception, e:
                            txn.abort()
                            raise e
                            sys.exit(2)
                    finally:
                        if objfile:
                            objfile.close()
                        if os.path.exists(actual_fn):
                            os.remove(actual_fn)
                txn.commit()
            finally:
                offlinedb.close()
                if os.path.exists(serverSettings.temp_folder + '/_db'):
                    os.rmdir(serverSettings.temp_folder + '/_db')
            
        # post-install script
        if '_post.py' in contents:
            print 'INFO: running post installation script...'
            self.package_file.extract('_post.py', serverSettings.temp_folder)
            execfile(serverSettings.temp_folder + '/_post.py')
            os.remove(serverSettings.temp_folder + '/_post.py')
)

if answer.upper() == "Y":
    import org.innoscript.desktop.schema.common
    import org.innoscript.desktop.schema.security

    # create system user
    system = org.innoscript.desktop.schema.security.SystemUser()
    system._id = "system"
    system.displayName.value = "SYSTEM"
    system._isSystem = True
    system.description.value = "System account"

    try:
        # get offline db handle
        db = offlinedb.getHandle(system)
    except Exception, e:
        sys.exit(e)

    # truncate database
    sys.stdout.write("Deleting existing database...")
    db.truncate()
    sys.stdout.write("[OK]\n")

    # modify containment at run-time
    org.innoscript.desktop.schema.common.RootFolder.containment = (
        "org.innoscript.desktop.schema.common.Category",
        "org.innoscript.desktop.schema.common.PersonalFolders",
        "org.innoscript.desktop.schema.common.AdminTools",
    )
    org.innoscript.desktop.schema.common.AdminTools.containment = (
if command in ('DB_BACKUP', 'DB_RESTORE'):
    if not(file):
        usage()
    msg = management.MgtMessage(command, file)
elif command == 'DB_RECOVER' and not address:
    answer = raw_input('''
WARNING: You are about to perform an offline recovery.
Please ensure that all Porcupine services are stopped,
since database recovery requires a single-threaded environment.

Are you sure you want proceed(Y/N)?''')
    if (answer.upper() == 'Y'):
        try:
            from porcupine.administration import offlinedb
            print 'Recovering database. Please wait...'
            db = offlinedb.getHandle(recover=2)
            db.close()
            print 'Database recovery completed successfully.'
        except Exception, e:
            sys.exit(e)
    sys.exit()
else:
    msg = management.MgtMessage(command, '')

request = management.MgtRequest(msg.serialize())

try:
    response = request.get_response(address)
except socket.error:
    sys.exit('The host is unreachable...')