Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

beebox / crossover   deb

Repository URL to install this package:

Version: 18.5.0-1 

/ opt / cxoffice / lib / python / bottlecollection.py

# (c) Copyright 2009-2011, 2015. CodeWeavers, Inc.

import os

import gobject

import cxdecorators
import cxproduct
import cxutils

import bottlequery
import bottlewrapper
import bottlemanagement

import pyop

ALL_INFO = ("basic", "controlpanel", "applications", "csmt", "dxvk")

focused_bottle = None

def sharedCollection(infoToTrack=()):
    global sharedBottleCollection
    try:
        sharedBottleCollection.track_info(infoToTrack)
    except NameError:
        sharedBottleCollection = BottleCollection(infoToTrack)

    return sharedBottleCollection


class BottleCollection(object):

    bottleCollectionDict = None

    def __init__(self, infoToTrack=ALL_INFO):
        self.bottleCollectionDict = {}
        self.ignored_bottles = []
        self.defaultBottleName = ""

        self._infoToTrack = set(infoToTrack)
        self.changeDelegates = []
        self.bottleChangeDelegates = []
        self.refresh()
        # Set up a timer so we can poll for newly-created bottles.
        gobject.timeout_add(2000, self.refresh)

    def queue_bottle_updates(self, bottles, info):
        if 'basic' in info:
            for bottle in bottles:
                updateOp = RefreshBasicInfoOperation(bottle)
                pyop.sharedOperationQueue.enqueue(updateOp)
        if 'applications' in info or 'controlpanel' in info or 'csmt' in info or 'dxvk' in info:
            for bottle in bottles:
                #pylint: disable=R0204
                updateOp = RefreshExtraInfoOperation(bottle, info)
                pyop.sharedOperationQueue.enqueue(updateOp)

    def refresh(self):
        bottleList = bottlequery.get_bottle_list()
        changes = False
        removeList = []

        # Handle renames
        for bottleNameKey in self.bottleCollectionDict:
            newName = self.bottleCollectionDict[bottleNameKey].name
            if newName != bottleNameKey:
                self.bottleCollectionDict[newName] = self.bottleCollectionDict.pop(bottleNameKey)
                changes = True

        # Remove deleted bottles
        for bottleNameKey in self.bottleCollectionDict:
            bottle = self.bottleCollectionDict[bottleNameKey]
            bottleName = bottle.name
            if bottleName not in bottleList and \
                bottlewrapper.BottleWrapper.STATUS_RENAMING not in bottle.status_overrides:
                changes = True
                removeList.append(bottleNameKey)

        for bottleNameKey in removeList:
            self._removeBottle(bottleNameKey)

        # Check for updates
        bottles_to_update = []
        for bottleNameKey in self.bottleCollectionDict:
            if self.bottleCollectionDict[bottleNameKey].get_needs_update(updating=True):
                bottles_to_update.append(self.bottleCollectionDict[bottleNameKey])

        # Add new bottles
        for bottleName in bottleList:
            if bottleName not in self.bottleCollectionDict and \
               bottleName not in self.ignored_bottles:
                self._addBottle(bottleName)
                self.bottleCollectionDict[bottleName].get_needs_update(updating=True)
                bottles_to_update.append(self.bottleCollectionDict[bottleName])
                changes = True

        if bottles_to_update:
            # FIXME:  We don't really need to reload 'basic' info
            #         if this bottle was just added.
            self.queue_bottle_updates(bottles_to_update, self._infoToTrack)

        if changes:
            for delegate in self.changeDelegates:
                delegate.bottleCollectionChanged()

        return True

    def track_info(self, new_info):
        if not self._infoToTrack.issuperset(new_info):
            new_info = set(new_info)
            new_info.difference_update(self._infoToTrack)
            self._infoToTrack.update(new_info)
            self.queue_bottle_updates(self.bottleCollectionDict.values(), self._infoToTrack)

    def add_ignored_bottle(self, newname):
        self.ignored_bottles.append(cxutils.expect_unicode(newname))

    def remove_ignored_bottle(self, newname):
        self.ignored_bottles.remove(cxutils.expect_unicode(newname))

    def refreshDefaultBottle(self):
        self.defaultBottleName = bottlequery.get_default_bottle()
        for bottle in self.bottleCollectionDict.itervalues():
            bottle.is_default = (bottle.name == self.defaultBottleName)

    def getDefaultBottle(self):
        return self.defaultBottleName

    def bottleObject(self, inBottleName):
        return self.bottleCollectionDict[cxutils.expect_unicode(inBottleName)]

    def bottleList(self):
        return self.bottleCollectionDict.keys()

    def bottles(self):
        return self.bottleCollectionDict.values()

    def bottleCount(self):
        return len(self.bottleCollectionDict)

    def _addBottle(self, inBottleName):
        inBottleName = cxutils.expect_unicode(inBottleName)
        # Make sure this isn't already in the list.
        for bottle in self.bottles():
            if bottle.name == inBottleName:
                return
        bottleobj = bottlewrapper.BottleWrapper(inBottleName)
        self.bottleCollectionDict[inBottleName] = bottleobj
        for delegate in self.bottleChangeDelegates:
            bottleobj.add_change_delegate(delegate)

        self.refreshDefaultBottle()

    def _removeBottle(self, inBottleName):
        self.bottleCollectionDict.pop(cxutils.expect_unicode(inBottleName), None)
        self.refreshDefaultBottle()

    def addChangeDelegate(self, inDelegate):
        self.changeDelegates.append(inDelegate)

    def removeChangeDelegate(self, inDelegate):
        self.changeDelegates.remove(inDelegate)

    def addBottleChangeDelegate(self, inDelegate):
        self.bottleChangeDelegates.append(inDelegate)
        for bottleobj in self.bottles():
            bottleobj.add_change_delegate(inDelegate)

    def removeBottleChangeDelegate(self, inDelegate):
        self.bottleChangeDelegates.remove(inDelegate)
        for bottleobj in self.bottles():
            bottleobj.remove_change_delegate(inDelegate)

    def archiveBottle(self, inBottleName, inArchivePath):
        inBottleName = cxutils.expect_unicode(inBottleName)
        bottle_obj = self.bottleObject(inBottleName)
        bottle_obj.add_status_override(bottle_obj.STATUS_ARCHIVING)
        try:
            rVal = bottlemanagement.archive_bottle(inBottleName, inArchivePath)
        finally:
            bottle_obj.remove_status_override(bottle_obj.STATUS_ARCHIVING)
        return rVal

def boost_priority(bottleobj):
    #pylint: disable=W0603
    global focused_bottle
    focused_bottle = bottleobj

class RefreshInfoOperation(pyop.PythonOperation):
    def __init__(self, inBottle):
        pyop.PythonOperation.__init__(self)
        self.bottleObject = inBottle

    def _get_priority(self):
        if self.bottleObject is focused_bottle:
            return 1
        return -1

    @cxdecorators.abstractmethod
    def main(self):
        # so pylint recognizes this as an abstract class
        raise NotImplementedError()

    priority = property(_get_priority)

class RefreshBasicInfoOperation(RefreshInfoOperation):
    def __unicode__(self):
        return " ".join("RefreshBasicInfoOperation for" + repr(self.bottleObject))

    def enqueued(self):
        pyop.PythonOperation.enqueued(self)
        self.bottleObject.pre_load_basic_info()

    def main(self):
        self.bottleObject.load_basic_info()

    def finish(self):
        self.bottleObject.post_load_basic_info()
        pyop.PythonOperation.finish(self)

class RefreshExtraInfoOperation(RefreshInfoOperation):
    def __init__(self, inBottle, info):
        RefreshInfoOperation.__init__(self, inBottle)
        self.info = info

    def __unicode__(self):
        return " ".join("RefreshExtraInfoOperation for" + repr(self.bottleObject))

    def enqueued(self):
        pyop.PythonOperation.enqueued(self)
        if 'applications' in self.info:
            self.bottleObject.pre_load_installed_applications()
        if 'controlpanel' in self.info:
            self.bottleObject.pre_load_control_panel_info()
        if 'csmt' in self.info:
            self.bottleObject.pre_load_is_csmt_disabled()
        if 'dxvk' in self.info:
            self.bottleObject.pre_load_is_dxvk_enabled()

    def main(self):
        if 'applications' in self.info:
            self.bottleObject.load_installed_applications()
        if 'controlpanel' in self.info:
            self.bottleObject.load_control_panel_info()
        if 'csmt' in self.info:
            self.bottleObject.load_is_csmt_disabled()
        if 'dxvk' in self.info:
            self.bottleObject.load_is_dxvk_enabled()

    def finish(self):
        if 'applications' in self.info:
            self.bottleObject.post_load_installed_applications()
        if 'controlpanel' in self.info:
            self.bottleObject.post_load_control_panel_info()
        if 'csmt' in self.info:
            self.bottleObject.post_load_is_csmt_disabled()
        if 'dxvk' in self.info:
            self.bottleObject.post_load_is_dxvk_enabled()
        pyop.PythonOperation.finish(self)


class QuitBottleOperation(pyop.PythonOperation):

    def __init__(self, inBottleList, inForce=False, inFinishDelegate=None):
        pyop.PythonOperation.__init__(self)
        self.bottleList = [cxutils.expect_unicode(x) for x in inBottleList]
        self.force = inForce
        self.finishDelegate = inFinishDelegate
        self.succeeded = True

    def __unicode__(self):
        return " ".join(["QuitBottleOperation for"] + self.bottleList)

    def main(self):
        for bottleName in self.bottleList:
            bottleObj = sharedCollection().bottleObject(bottleName)
            if self.force:
                if not bottleObj.force_quit():
                    self.succeeded = False
            else:
                if not bottleObj.quit():
                    self.succeeded = False
            bottleObj.cancelShutdown()


    def finish(self):
        if self.finishDelegate:
            self.finishDelegate.opFinished(self)
        pyop.PythonOperation.finish(self)


def unique_bottle_name(inBasename):
    collection = sharedCollection(('basic',))

    existingBottles = set()
    existingBottles.update(collection.bottleList())
    existingBottles.update(collection.ignored_bottles)

    collision = True
    candidate = inBasename
    i = 1

    while collision:
        collision = False
        for bottlename in existingBottles:
            if candidate.lower() == bottlename.lower():
                collision = True
                break
        if not collision:
            wineprefix = os.path.join(cxproduct.get_bottle_path().split(":")[0], candidate)
            if os.path.exists(wineprefix):
                collision = True
        if collision:
            i += 1
            candidate = inBasename + "-" + unicode(i)

    return candidate