Exemple #1
0
    def __init__(self, sysPropsFileName):
        # create a lock for thread synchronization
        self.lock = ZMutex(u"ZSystemProperties")  #$NON-NLS-1$
        self.listeners = ZListenerSet()

        self.sysPropsFileName = sysPropsFileName
        self.sysPropsDoc = ZDom()

        self.reloadProperties()
Exemple #2
0
    def __init__(self, parentModel, task, parent):
        self.parentModel = parentModel
        self.model = ZBackgroundTaskPanelModel()
        self.mutex = ZMutex()
        self.task = task

        ZTransparentPanel.__init__(self, parent, wx.ID_ANY)
        self.task.attachListener(self)

        self._initPanel()
        self.refresh()
Exemple #3
0
    def __init__(self, sysPropsFileName):
        # create a lock for thread synchronization
        self.lock = ZMutex(u"ZSystemProperties") #$NON-NLS-1$
        self.listeners = ZListenerSet()

        self.sysPropsFileName = sysPropsFileName
        self.sysPropsDoc = ZDom()

        self.reloadProperties()
Exemple #4
0
class ZSystemProperties:
    u"""Use this class to get and set System Properties.""" #$NON-NLS-1$

    def __init__(self, sysPropsFileName):
        # create a lock for thread synchronization
        self.lock = ZMutex(u"ZSystemProperties") #$NON-NLS-1$
        self.listeners = ZListenerSet()

        self.sysPropsFileName = sysPropsFileName
        self.sysPropsDoc = ZDom()

        self.reloadProperties()
    # end __init__()

    def addListener(self, listener):
        self.listeners.append(listener)
    # end addListener()

    def removeListener(self, listener):
        self.listeners.remove(listener)
    # end removeListener

    def _fireEvent(self, key, value):
        for listener in self.listeners:
            listener.onSystemPropertyChange(key, value)
    # end _fireEvent()

    def reloadProperties(self):
        self.lock.acquire()
        try:
            # Open and parse the system properties file
            self.sysPropsDoc.load(self.sysPropsFileName)
        finally:
            self.lock.release()
    # end reloadProperties()

    # Public method - call this to save the system properties.
    def save(self):
        u"Public method - call this to save the system properties." #$NON-NLS-1$
        self.lock.acquire()
        self.saveProperties()
        self.lock.release()
        self._fireEvent(None, None)
    # end save()

    # Note that locking is required prior to calling saveProperties()
    def saveProperties(self):
        try:
            tempSysPropsFileName = self.sysPropsFileName + u".t" #$NON-NLS-1$
            self.sysPropsDoc.save(tempSysPropsFileName, True)
            deleteFile(self.sysPropsFileName)
            renameFile(tempSysPropsFileName, self.sysPropsFileName)
        except Exception, e:
            raise ZException(_extstr(u"sysprops.ErrorSavingPropsFile") % self.sysPropsFileName, e) #$NON-NLS-1$
Exemple #5
0
    def __init__(self, parentModel, task, parent):
        self.parentModel = parentModel
        self.model = ZBackgroundTaskPanelModel()
        self.mutex = ZMutex()
        self.task = task

        ZTransparentPanel.__init__(self, parent, wx.ID_ANY)
        self.task.attachListener(self)

        self._initPanel()
        self.refresh()
Exemple #6
0
    def __init__(self, parent):
        applicationModel = getApplicationModel()
        userProfile = applicationModel.getUserProfile()
        debugFilePath = os.path.join(userProfile.getLogDirectory(), u"ZRavenApplicationStatusBar.log") #$NON-NLS-1$
        self.debugFile = open(debugFilePath, u"wa") #$NON-NLS-1$
        self._debugMsg(u"== New Debug Session ==") #$NON-NLS-1$

        self.progressCtrl = None
        self.model = ZRavenApplicationStatusBarModel()
        self.mutex = ZMutex(u"ZAppStatusBarMTX") #$NON-NLS-1$
        self._debugMsg(u"Begin Call Super ZStatusBar.__init__") #$NON-NLS-1$
        ZStatusBar.__init__(self, parent, self.model.createStatusBarProvider())
        self._debugMsg(u"Done Call Super ZStatusBar.__init__") #$NON-NLS-1$
        # Attach to any already-running tasks.
        for task in self.model.getTaskService().getTasks():
            if task.isRunning():
                self._debugMsg(u"Attaching self as listner to task %s - %s" % (task.getId(), task.getName()) ) #$NON-NLS-1$
                task.attachListener(self)
        # Listen for new tasks that may show up.
        self._debugMsg(u"Attaching self as listner to task service") #$NON-NLS-1$
        self.model.getTaskService().addListener(self)
        self._debugMsg(u"End  ZRavenApplicationStatusBar.__init__") #$NON-NLS-1$
Exemple #7
0
    def __init__(self, parent, bgTask, title, description, imagePath):
        self.title = title
        self.description = description
        self.bgTask = bgTask
        self.imagePath = imagePath

        # This is here for intellisense purposes.
        if self.bgTask is None and False:
            self.bgTask = IZBackgroundTask()

        self.mutex = ZMutex(u"BGTaskDialogMTX")  #$NON-NLS-1$

        # Dialog state - can be modified by multiple threads and should
        # be protected by the above mutex.
        self.model = ZBackgroundTaskProgressDialogModel()

        ZHeaderDialog.__init__(self, parent, wx.ID_ANY, title)

        size = self.GetBestSize()
        if size.GetWidth() < 500:
            size.SetWidth(500)
        self.SetSize(size)

        self.bgTask.attachListener(self)
Exemple #8
0
class ZRavenApplicationStatusBar(ZStatusBar, IZBackgroundTaskServiceListener, IZBackgroundTaskListener):

    def __init__(self, parent):
        applicationModel = getApplicationModel()
        userProfile = applicationModel.getUserProfile()
        debugFilePath = os.path.join(userProfile.getLogDirectory(), u"ZRavenApplicationStatusBar.log") #$NON-NLS-1$
        self.debugFile = open(debugFilePath, u"wa") #$NON-NLS-1$
        self._debugMsg(u"== New Debug Session ==") #$NON-NLS-1$

        self.progressCtrl = None
        self.model = ZRavenApplicationStatusBarModel()
        self.mutex = ZMutex(u"ZAppStatusBarMTX") #$NON-NLS-1$
        self._debugMsg(u"Begin Call Super ZStatusBar.__init__") #$NON-NLS-1$
        ZStatusBar.__init__(self, parent, self.model.createStatusBarProvider())
        self._debugMsg(u"Done Call Super ZStatusBar.__init__") #$NON-NLS-1$
        # Attach to any already-running tasks.
        for task in self.model.getTaskService().getTasks():
            if task.isRunning():
                self._debugMsg(u"Attaching self as listner to task %s - %s" % (task.getId(), task.getName()) ) #$NON-NLS-1$
                task.attachListener(self)
        # Listen for new tasks that may show up.
        self._debugMsg(u"Attaching self as listner to task service") #$NON-NLS-1$
        self.model.getTaskService().addListener(self)
        self._debugMsg(u"End  ZRavenApplicationStatusBar.__init__") #$NON-NLS-1$
    # end __init__()

    def _debugMsg(self, msg):
        try:
            self.debugFile.write(u"*****>>>>> %s\n" % msg) #$NON-NLS-1$
            self.debugFile.flush()
        except:
            pass
    # end _debugMsg()

    def _debugProgressCtrl(self):
        if not self.progressCtrl:
            stack = traceback.extract_stack()
            self._debugMsg( unicode(stack) )
        return self.progressCtrl is not None
    # end _debugProgressCtrl()

    def _createCustomWidgets(self):
        self.progressCtrl = ZProgressLabelCtrl(self, u"", True) #$NON-NLS-1$
        self._debugMsg(u"Done _createCustomWidgets") #$NON-NLS-1$
    # end _createCustomWidgets()

    def _bindCustomWidgets(self):
        self.Bind(ZEVT_REFRESH, self.onRefresh, self)
        self._debugMsg(u"Done _bindCustomWidgets") #$NON-NLS-1$
    # end _bindCustomWidgets()

    def _refreshPane(self, paneIdx):
        if not self._debugProgressCtrl():
            return
        if paneIdx == 0:
            numTasks = self.model.getNumRunningTasks()
            progressText = u"%d %s" % (numTasks, _extstr(u"appstatusbar.RunningTasks")) #$NON-NLS-1$ #$NON-NLS-2$
            if numTasks == 0:
                progressText = _extstr(u"appstatusbar.NoRunningTasks") #$NON-NLS-1$
            self.progressCtrl.setLabel(progressText)
    # end _refreshPane()

    def _repositionPane(self, paneIdx, rect):
        if not self._debugProgressCtrl():
            return
        if paneIdx == 0:
            self.progressCtrl.SetPosition( (rect.x + 4, rect.y + 1) )
            self.progressCtrl.SetSize( (rect.width - 5, rect.height - 2) )
    # end _repositionPane()

    def onRefresh(self, event):
        self.mutex.acquire()
        try:
            if self._debugProgressCtrl() and self.model.isDirty():
                if self.model.isRunning():
                    self.progressCtrl.start()
                else:
                    self.progressCtrl.stop()
                self.refresh()
                self.model.setDirty(False)
        finally:
            self.mutex.release()
        event.Skip()
    # end onRefresh()

    def onTaskAdded(self, task):
        self.mutex.acquire()
        try:
            task.attachListener(self)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onTaskAdded()

    def onTaskRemoved(self, task):
        self.mutex.acquire()
        try:
            self.model.removeTask(task)
            task.detachListener(self)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onTaskRemoved()

    def onAttached(self, task, numCompletedWorkUnits): #@UnusedVariable
        self.mutex.acquire()
        try:
            if task.isRunning():
                self.model.addTask(task)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onAttached()

    def onStarted(self, task, workAmount): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.addTask(task)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onStarted()

    def onComplete(self, task):
        self.mutex.acquire()
        try:
            self.model.removeTask(task)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onComplete()

    def onStop(self, task):
        self.mutex.acquire()
        try:
            self.model.removeTask(task)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onStop()

    def onCancel(self, task):
        self.mutex.acquire()
        try:
            self.model.removeTask(task)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onCancel()

    def onError(self, task, errorMessage, errorDetails): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.removeTask(task)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onError()

    def reposition(self):
        self._debugMsg(u"start 'reposition()'") #$NON-NLS-1$
        try:
            ZStatusBar.reposition(self)
        finally:
            self._debugMsg(u"end 'reposition()'") #$NON-NLS-1$
Exemple #9
0
class ZBackgroundTaskPanel(ZTransparentPanel, IZBackgroundTaskListener):

    def __init__(self, parentModel, task, parent):
        self.parentModel = parentModel
        self.model = ZBackgroundTaskPanelModel()
        self.mutex = ZMutex()
        self.task = task

        ZTransparentPanel.__init__(self, parent, wx.ID_ANY)
        self.task.attachListener(self)

        self._initPanel()
        self.refresh()
    # end __init__()

    def _initPanel(self):
        self._createPanelWidgets()
        self._layoutPanelWidgets()
        self._bindWidgetEvents()
        self._populatePanelWidgets()
    # end _initPanel()

    def _createPanelWidgets(self):
        self.titleText = wx.StaticText(self, wx.ID_ANY, self.task.getName())
        self.titleText.SetFont(getDefaultFontBold())

        startTime = u"    %s %s" % (_extstr(u"bgtaskpanel.StartedOn"), self.task.getStartTime().toString(u"%c", True)) #$NON-NLS-2$ #$NON-NLS-1$ #$NON-NLS-3$
        self.startTimeText = wx.StaticText(self, wx.ID_ANY, startTime)

        errorBmp = getResourceRegistry().getBitmap(u"images/dialogs/bgtasks/manager/error-glyph.png") #$NON-NLS-1$
        self.errorGlyph = ZImageButton(self, errorBmp, True)
        infoBmp = getResourceRegistry().getBitmap(u"images/dialogs/bgtasks/manager/info-glyph.png") #$NON-NLS-1$
        self.infoGlyph = ZImageButton(self, infoBmp, True)
        stopBmp = getResourceRegistry().getBitmap(u"images/dialogs/bgtasks/manager/stop-glyph.png") #$NON-NLS-1$
        self.stopGlyph = ZImageButton(self, stopBmp, True)

        # Progress widgets - only visible while task is running.
        self.progressGauge = wx.Gauge(self, wx.ID_ANY, self.task.getNumWorkUnits())
        self.progressGauge.SetSizeHints(-1, 14)
        self.progressText = wx.StaticText(self, wx.ID_ANY, u"") #$NON-NLS-1$
        self.statusText = wx.StaticText(self, wx.ID_ANY, u"") #$NON-NLS-1$

        self.cancelButton = ZImageButton(self, getResourceRegistry().getBitmap(u"images/dialogs/bgtasks/manager/cancel.png")) #$NON-NLS-1$
        self.cancelButton.SetToolTipString(_extstr(u"bgtaskpanel.CancelTask")) #$NON-NLS-1$
        self.pauseButton = ZImageButton(self, getResourceRegistry().getBitmap(u"images/dialogs/bgtasks/manager/pause.png")) #$NON-NLS-1$
        self.pauseButton.SetToolTipString(_extstr(u"bgtaskpanel.PauseTask")) #$NON-NLS-1$

        # Widgets that are only shown when the task is complete
        self.endTimeText = wx.StaticText(self, wx.ID_ANY, u"") #$NON-NLS-1$

        self.removeButton = ZImageButton(self, getResourceRegistry().getBitmap(u"images/dialogs/bgtasks/manager/remove.png")) #$NON-NLS-1$
        self.removeButton.SetToolTipString(_extstr(u"bgtaskpanel.RemoveTask")) #$NON-NLS-1$

        self.staticLine = wx.StaticLine(self)
    # end _createPanelWidgets()

    def _layoutPanelWidgets(self):
        leftSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer = wx.BoxSizer(wx.HORIZONTAL)

        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
        titleSizer.Add(self.errorGlyph, 0, wx.EXPAND | wx.RIGHT, 5)
        titleSizer.Add(self.infoGlyph, 0, wx.EXPAND | wx.RIGHT, 5)
        titleSizer.Add(self.stopGlyph, 0, wx.EXPAND | wx.RIGHT, 5)
        titleSizer.Add(self.titleText, 1, wx.ALIGN_CENTER_VERTICAL)

        leftSizer.AddSizer(titleSizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 2)
        leftSizer.Add(self.startTimeText, 0, wx.EXPAND | wx.TOP, 2)
        leftSizer.Add(self.progressGauge, 0, wx.EXPAND | wx.ALL, 2)
        leftSizer.Add(self.progressText, 0, wx.EXPAND | wx.ALL, 2)
        leftSizer.Add(self.statusText, 0, wx.EXPAND | wx.ALL, 2)
        leftSizer.Add(self.endTimeText, 0, wx.EXPAND | wx.BOTTOM, 2)

        rightSizer.Add(self.pauseButton, 0, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.cancelButton, 0, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.removeButton, 0, wx.EXPAND | wx.ALL, 2)

        horSizer = wx.BoxSizer(wx.HORIZONTAL)
        horSizer.AddSizer(leftSizer, 1, wx.EXPAND | wx.ALL, 5)
        horSizer.AddSizer(rightSizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.AddSizer(horSizer, 0, wx.EXPAND | wx.ALL, 5)

        panelSizer = wx.BoxSizer(wx.VERTICAL)
        panelSizer.AddSizer(sizer, 0, wx.EXPAND)
        panelSizer.Add(self.staticLine, 0, wx.EXPAND)

        self.SetSizer(panelSizer)
        self.SetAutoLayout(True)
    # end _layoutPanelWidgets()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_BUTTON, self.onCancelButton, self.cancelButton)
        self.Bind(wx.EVT_BUTTON, self.onPauseButton, self.pauseButton)
        self.Bind(wx.EVT_BUTTON, self.onRemoveButton, self.removeButton)
        self.Bind(wx.EVT_BUTTON, self.onInfoGlyphButton, self.infoGlyph)
        self.Bind(wx.EVT_BUTTON, self.onErrorGlyphButton, self.errorGlyph)
        self.Bind(wx.EVT_BUTTON, self.onStopGlyphButton, self.stopGlyph)
        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)
    # end _bindWidgetEvents()

    def _populatePanelWidgets(self):
        pass
    # ene _populatePanelWidgets()

    def refresh(self):
        self.statusText.SetLabel(self.model.getCurrentWorkText())
        self.progressText.SetLabel(self._formatProgressText())
        self.progressGauge.SetValue(self.model.getCurrentWorkAmount())

        if self.model.hasError():
            self.errorGlyph.SetToolTipString(getSafeString(self.model.getError()[0]))

        endTime = u"" #$NON-NLS-1$
        if self.model.isComplete() and self.task.getEndTime() is not None:
            endTime = u"%s %s" % (_extstr(u"bgtaskpanel.EndedOn"), self.task.getEndTime().toString(u"%c", True)) #$NON-NLS-1$ #$NON-NLS-2$ #$NON-NLS-3$
        elif self.model.isCancelled():
            endTime = u"(%s)" % _extstr(u"bgtaskpanel.Cancelled") #$NON-NLS-1$ #$NON-NLS-2$
        endTime = u"    %s" % endTime #$NON-NLS-1$
        self.endTimeText.SetLabel(endTime)

        self._hideShowWidgets()

        self.Layout()
        self.GetParent().Layout()
    # end refresh()

    def _hideShowWidgets(self):
        self.errorGlyph.Show(self.model.hasError())
        self.stopGlyph.Show(self.model.isCancelled())
        self.infoGlyph.Show(not self.model.hasError() and not self.model.isRunning() and not self.model.isCancelled())

        self.endTimeText.Show(self.model.isComplete())

        self.progressGauge.Show(self.model.isRunning())
        self.progressText.Show(self.model.isRunning())
        self.statusText.Show(self.model.isRunning())
        self.pauseButton.Show(self.model.isRunning())
        self.cancelButton.Show(self.model.isRunning())
        self.removeButton.Show(self._shouldShowRemoveButton())
        self.pauseButton.Show(self.model.isRunning() and self.task.isResumable())
    # end _hideShowWidgets()
    
    def _shouldShowRemoveButton(self):
        if self.model.isComplete() or self.model.hasError():
            return True
        if not self.model.isRunning() and not self.task.isResumable():
            return True
        return False
    # end _shouldShowRemoveButton()

    def onPauseButton(self, event):
        ZShowNotYetImplementedMessage(self)
        event.Skip()
    # end onPauseButton()

    def onCancelButton(self, event):
        ZShowNotYetImplementedMessage(self)
        event.Skip()
    # end onCancelButton()

    def onRemoveButton(self, event):
        self.parentModel.removeTask(self.task)
        event.Skip()
    # end onRemoveButton()

    def onInfoGlyphButton(self, event):
        menuNode = createBackgroundTaskInfoMenuNode(self.task)
        self._popupGlyphMenu(menuNode, self.infoGlyph)
        event.Skip()
    # end onInfoGlyphButton()

    def onErrorGlyphButton(self, event):
        menuNode = createBackgroundTaskErrorMenuNode(self.task)
        self._popupGlyphMenu(menuNode, self.errorGlyph)
        event.Skip()
    # end onErrorGlyphButton()

    def onStopGlyphButton(self, event):
        menuNode = createBackgroundTaskInfoMenuNode(self.task)
        self._popupGlyphMenu(menuNode, self.stopGlyph)
        event.Skip()
    # end onInfoGlyphButton()
    
    def onZoundryRefresh(self, event):
        self.refresh()
        event.Skip()
    # end onZoundryRefresh()

    def _popupGlyphMenu(self, menuNode, glyph):
        context = ZMenuActionContext(self)
        provider = ZActiveModelBasedMenuContentProvider(menuNode, context)
        handler = ZActiveModelBasedMenuEventHandler(context)
        menu = ZMenu(self, menuNode, provider, handler)
        (x, y) = glyph.GetPositionTuple() #@UnusedVariable
        (w, h) = glyph.GetSizeTuple() #@UnusedVariable
        self.PopupMenuXY(menu, x, y + h - 1)
    # end _popupGlyphMenu()

    def onAttached(self, task, numCompletedWorkUnits): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.init(task)
        finally:
            self.mutex.release()
    # end onAttached()

    def onWorkDone(self, task, amount, text): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.incrementWorkAmount(amount)
            self.model.setCurrentWorkText(text)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onWorkDone()

    def onComplete(self, task): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.setComplete(True)
            self.model.setRunning(False)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onComplete()

    def onStop(self, task):
        self.onComplete(task)
    # end onStop()

    def onCancel(self, task): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.setCanceled(True)
            self.model.setRunning(False)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onCancel()

    def onError(self, task, errorMessage, errorDetails): #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.setError( (errorMessage, errorDetails) )
            self.model.setRunning(False)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)
    # end onError()

    def _formatProgressText(self):
        # Avoid possible divide by 0 error
        if self.model.getCurrentWorkAmount() == 0:
            perc = 0
        else:
            perc = (self.model.getCurrentWorkAmount() * 100) / self.task.getNumWorkUnits()
        return _extstr(u"bgtaskpanel.RunningPercent") % perc #$NON-NLS-1$
    # end _formatProgressText()

    def destroy(self):
        self.task.detachListener(self)
Exemple #10
0
import random
import socket
import sys
import time

# The size of the circular queue.    Larger sizes give more assurance for uniqueness.
# Smaller sizes take less memory and are a tiny bit faster
QUEUE_SIZE = 100

#############################
###     global module variables

MAX_RANDOM = sys.maxint  # converted to hex goes to 8 chars (at least, in Python 2.3)
rand = random.Random()
ip = u""  #$NON-NLS-1$
lock = ZMutex(u"guidMTX")  #$NON-NLS-1$
lastguid = u""  #$NON-NLS-1$
try:
    ip = socket.gethostbyname(socket.gethostname())
except (
        socket.gaierror
):  # if we don't have an ip, default to someting in the 10.x.x.x private range
    ip = u'10'  #$NON-NLS-1$
    for i in range(3):
        ip += u'.' + str(rand.randrange(1, 254))  #$NON-NLS-1$
hexip = u"".join(
    [u"%04x" % long(i) for i in ip.split(u'.')]
)  # leave space for ip v6 (65K in each sub) #$NON-NLS-1$ #$NON-NLS-2$ #$NON-NLS-3$

#######################################
###     A simple circular set
Exemple #11
0
 def __init__(self):
     self.userProfile = None
     self.dbLock = ZMutex(u"ZPySQLIndexProviderMTX") #$NON-NLS-1$
Exemple #12
0
 def __init__(self):
     self.userProfile = None
     self.dbLock = ZMutex(u"ZPySQLIndexProviderMTX") #$NON-NLS-1$
Exemple #13
0
class ZPySQLIndexProvider(IZIndexProvider):

    def __init__(self):
        self.userProfile = None
        self.dbLock = ZMutex(u"ZPySQLIndexProviderMTX") #$NON-NLS-1$
    # end __init__()

    def _lockDatabase(self):
        self.dbLock.acquire()
    # end _lockDatabase()

    def _unlockDatabase(self):
        self.dbLock.release()
    # end _unlockDatabase()

    def create(self, applicationModel):
        self.userProfile = applicationModel.getUserProfile()
        self.dataStoreDirectory = self.userProfile.getDirectory(u"datastore") #$NON-NLS-1$
        self.indexFile = os.path.join(self.dataStoreDirectory, u"index.db") #$NON-NLS-1$
        self.connectionFactory = ZPySQLConnectionFactory(self.indexFile)

        if not os.path.isfile(self.indexFile):
            self._createNewIndex()
    # end create()

    def clear(self):
        self._createNewIndex()
    # end clear()

    def findDocuments(self, documentFilter):
        queryBuilder = ZDocumentQueryBuilder(documentFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZDocumentIDOListQueryHandler())
    # end findDocuments()

    def findLinks(self, linkFilter):
        queryBuilder = ZLinkQueryBuilder(linkFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZLinkIDOListQueryHandler())
    # end findLinks()

    def findTags(self, tagFilter):
        queryBuilder = ZTagQueryBuilder(tagFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZTagIDOListQueryHandler())
    # end findTags()

    def findImages(self, imageFilter):
        queryBuilder = ZImageQueryBuilder(imageFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZImageIDOListQueryHandler())
    # end findImages()

    def getDocumentCount(self, filter):
        queryBuilder = ZDocumentQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getDocumentCount()

    def getTagCount(self, filter):
        queryBuilder = ZTagQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getTagCount()

    def getLinkCount(self, filter):
        queryBuilder = ZLinkQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getLinkCount()

    def getImageCount(self, filter):
        queryBuilder = ZImageQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getImageCount()

    def addDocument(self, document, listeners):
        self._lockDatabase()
        try:
            self._addDocument(document, listeners)
        finally:
            self._unlockDatabase()
    # end addDocument()

    def _addDocument(self, document, listeners):
        documentIDO = None
        pubDataIDOs = []
        linkIDOs = []
        imageIDOs = []
        tagIDOs = []

        connection = self._createConnection()
        try:
            # First, store the document itself.
            self._storeDocument(document, connection)
            documentIDO = self._createDocumentIDO(document)

            # Now write out the pub-info.
            blogInfoList = document.getBlogInfoList()
            for blogInfo in blogInfoList:
                self._storeBlogInfo(document.getId(), blogInfo, connection)
                pubDataIDO = self._createPubDataIDO(blogInfo)
                documentIDO.addPubDataIDO(pubDataIDO)
                pubDataIDOs.append(pubDataIDO)

            # Now write out the links, images and tags
            content = document.getContent()
            if content:
                xhtmlDoc = content.getXhtmlDocument()
                links = xhtmlDoc.getLinks()
                for link in links:
                    self._storeLink(document.getId(), link, connection)
                    linkIDOs.append(self._createLinkIDO(document, link, pubDataIDOs))

                images = xhtmlDoc.getImages()
                for image in images:
                    self._storeImage(document.getId(), image, connection)
                    imageIDOs.append(self._createImageIDO(document, image, pubDataIDOs))
            # end writing out the links and images

            # build a map of tags
            tagMap = self._getTagsMap(document)
            # write out the taxonomy.
            for (tagId, tag) in tagMap.iteritems():
                self._storeTag(document.getId(), tagId, tag, connection)
                tagIDOs.append( self._createTagIDO(document, tagId, tag, pubDataIDOs) )

            connection.commit()
        finally:
            connection.close()

        # Now, fire an "index changed" event for the document and each link and image IDO added to the index.
        self._fireIndexChangeEvent(listeners, ZDocIndexDocumentAddEvent, [documentIDO])
        self._fireIndexChangeEvent(listeners, ZDocIndexLinkAddEvent, linkIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexImageAddEvent, imageIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexTagAddEvent, tagIDOs)
    # end addDocument()

    def _getTagsMap(self, document):
        # temp list containing tag and category strings
        tags = []
        # Collect list of tags from document meta data
        if document.getTagwordsList and document.getTagwordsList():
            wordSet = ZTagwordsSet()
            wordSet.addZTagwordObjectList( document.getTagwordsList() )
            tags.extend( wordSet.getTagwords() )

        # Get document (blog info) categories for tags/taxanomy.
        if document.getBlogInfoList and document.getBlogInfoList():
            for blogInfo in document.getBlogInfoList():
                for category in blogInfo.getCategories():
                    tags.append( category.getName() )

        # Also use document (pub meta data) categories for tags/taxanomy.
        if document.getPubMetaDataList and document.getPubMetaDataList():
            for metaData in document.getPubMetaDataList(): #@UnusedVariable
                pass # FIXME (PJ) add meta data categories?  Same as blog infor categories?


        # get list of tags found in xhtml content document embedded in links with rel = tag
        if document.getContent() and document.getContent().getXhtmlDocument():
            tagwordsInLinks = document.getContent().getXhtmlDocument().getTagwords()
            if tagwordsInLinks:
                tags.extend(tagwordsInLinks)

        # build a map of tags to eliminate duplicates
        # map key: tagId, value: tag word
        tagMap = {}
        for tag in tags:
            tagId = tag.lower().strip().replace(u" ", u"_") #$NON-NLS-1$ #$NON-NLS-2$
            tagId = tagId.replace(u"'", u"_") #$NON-NLS-1$ #$NON-NLS-2$
            tagId = tagId.replace(u'"', u"_") #$NON-NLS-1$ #$NON-NLS-2$
            if not tagId:
                continue
            if not tagMap.has_key(tagId):
                tagMap[tagId] = tag.strip()
        return tagMap

    def updateDocument(self, document, listeners):
        self._lockDatabase()
        try:
            self._updateDocument(document, listeners)
        finally:
            self._unlockDatabase()
    # end updateDocument()

    def _updateDocument(self, document, listeners):
        docId = document.getId()
        # FIXME (EPW) change to actually update the document, rather than remove/add
        self._removeDocument(docId, listeners)
        self._addDocument(document, listeners)
    # end _updateDocument()

    def removeDocument(self, docId, listeners):
        self._lockDatabase()
        try:
            self._removeDocument(docId, listeners)
        finally:
            self._unlockDatabase()
    # end removeDocument()

    def _removeDocument(self, docId, listeners):
        # Get the IDOs being removed (for event firing purposes)
        connection = self._createConnection()
        # FIXME (EPW) remove these if not needed (since pySQL cascade/trigger is used).
        documentIDOs = self._getDocumentIDO(docId, connection)
        linkIDOs = self._getLinkIDOs(docId, connection)
        imageIDOs = self._getImageIDOs(docId, connection)
        tagIDOs = self._getTagIDOs(docId, connection)

        try:
            self._delete(u"DELETE FROM Document WHERE Document.DocumentId = ?", [ docId ], connection) #$NON-NLS-1$
            connection.commit()
        finally:
            connection.close()

        # Now, fire an "index changed" event for the document and each link and image IDO removed
        self._fireIndexChangeEvent(listeners, ZDocIndexDocumentRemoveEvent, documentIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexLinkRemoveEvent, linkIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexImageRemoveEvent, imageIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexTagRemoveEvent, tagIDOs)
    # end _removeDocument()

    def getNumDocuments(self):
        return self._select(u"SELECT count(DocumentId) FROM Document", None, ZSingleItemQueryHandler()) #$NON-NLS-1$
    # end getNumDocuments()

    def requiresReindex(self):
        providerVersion = self._getProviderVersion()
        dbVersion = self._getDBVersion()
        return providerVersion != dbVersion
    # end requiresReindex()

    def destroy(self):
        pass
    # end destroy()

    def _createConnection(self):
        return self.connectionFactory.createConnection()
    # end _createConnection()

    def _createNewIndex(self):
        self._lockDatabase()
        try:
            if os.path.exists(self.indexFile):
                os.remove(self.indexFile)
            self._createDB()
        finally:
            self._unlockDatabase()
    # end _createNewIndex()

    def _createDB(self):
        connection = self._createConnection()
        try:
            cursor = connection.cursor()
            try:
                cursor.executescript(PYSQL_DOCINDEX_DDL)
                connection.commit()
            finally:
                cursor.close()
            cursor.close()
        finally:
            connection.close()
    # end _createDB()

    def _getProviderVersion(self):
        return PYSQL_INDEX_VERSION
    # end _getProviderVersion()

    def _getDBVersion(self):
        return self._select(u"SELECT Value FROM MetaData WHERE Name = 'Version'", None, ZSingleItemQueryHandler()) #$NON-NLS-1$
    # end _getDBVersion()

    def _storeDocument(self, document, connection):
        params = [
              document.getId(),
              document.getTitle(),
              getNoneString(document.getCreationTime()),
              getNoneString(document.getLastModifiedTime())
        ]
        self._insert(u"INSERT INTO Document (DocumentId, Title, CreationTime, LastModifiedTime) values (?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeDocument()

    def _storeBlogInfo(self, documentId, blogInfo, connection):
        pubInfo = blogInfo.getPublishInfo()
        draft = 0
        if pubInfo.isDraft():
            draft = 1
        params = [
              documentId,
              blogInfo.getAccountId(),
              blogInfo.getBlogId(),
              pubInfo.getBlogEntryId(),
              getNoneString(pubInfo.getPublishedTime()),
              getNoneString(pubInfo.getSynchTime()),
              draft,
              pubInfo.getUrl()
        ]
        self._insert(u"INSERT INTO PublishedData (DocumentId, AccountId, BlogId, BlogEntryId, IssuedTime, SynchTime, Draft, Permalink) values (?, ?, ?, ?, ?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeBlogInfo()

    def _createPubDataIDO(self, blogInfo):
        pubInfo = blogInfo.getPublishInfo()
        accountId = blogInfo.getAccountId()
        blogId = blogInfo.getBlogId()
        blogEntryId = pubInfo.getBlogEntryId()
        issuedTime = pubInfo.getPublishedTime()
        synchTime = pubInfo.getSynchTime()
        draft = pubInfo.isDraft()
        permaLink = pubInfo.getUrl()

        return ZPubDataIDO(accountId, blogId, blogEntryId, issuedTime, synchTime, draft, permaLink)
    # end _createPubDataIDO()

    # Creates a ZDocumentIDO object from the IZDocument and pub data IDO objects.
    def _createDocumentIDO(self, document):
        id = document.getId()
        title = document.getTitle()
        creationTime = document.getCreationTime()
        lastModifiedTime = document.getLastModifiedTime()

        return ZDocumentIDO(None, id, title, creationTime, lastModifiedTime)
    # end _createDocumentIDO()

    def _storeLink(self, documentId, link, connection):
        url = link.getUrl()
        params = [
              documentId,
              url.toString(),
              url.getHost(),
              url.getPath(),
              link.getRel(),
              link.getTitle(),
              link.getText(),
              link.getHitCount()
        ]
        self._insert(u"INSERT INTO Link (DocumentId, Url, Host, Path, Rel, Title, Content, HitCount) values (?, ?, ?, ?, ?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeLink()

    def _createLinkIDO(self, document, link, pubDataIDOs):
        url = link.getUrl()
        return ZLinkIDO(pubDataIDOs, document.getId(), url.toString(), url.getHost(), url.getPath(), link.getRel(), link.getTitle(), link.getText())
    # end _createLinkIDO()

    def _storeImage(self, documentId, image, connection):
        url = image.getUrl()
        params = [
              documentId,
              url.toString(),
              url.getHost(),
              url.getPath(),
              image.getTitle(),
              image.getHitCount()
        ]
        self._insert(u"INSERT INTO Image (DocumentId, Url, Host, Path, Title, HitCount) values (?, ?, ?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeImage()

    def _createImageIDO(self, document, image, pubDataIDOs):
        url = image.getUrl()
        return ZImageIDO(pubDataIDOs, document.getId(), url.toString(), url.getHost(), url.getPath(), image.getTitle())
    # end _createImageIDO()

    def _storeTag(self, documentId, tagId, tag, connection):
        params = [
              documentId,
              tagId,
              tag
        ]
        self._insert(u"INSERT INTO Tag (DocumentId, TagId, TagWord) values (?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeTag()

    def _createTagIDO(self, document, tagId, tag, pubDataIDOs):
        ido = ZTagIDO(pubDataIDOs, document.getId(), tagId, tag)
        return ido
    # end _createTagIDO()

    def _getDocumentIDO(self, docId, connection):
        return self._select(u"SELECT * FROM Document AS doc LEFT JOIN PublishedData AS pd ON doc.DocumentId = pd.DocumentId WHERE doc.DocumentId = ?", [ docId ], ZDocumentIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getDocumentIDO()

    def _getLinkIDOs(self, docId, connection):
        return self._select(u"SELECT * FROM Link AS link LEFT JOIN PublishedData AS pd ON link.DocumentId = pd.DocumentId WHERE link.DocumentId = ?", [ docId ], ZLinkIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getLinkIDOs()

    def _getImageIDOs(self, docId, connection):
        return self._select(u"SELECT * FROM Image AS image LEFT JOIN PublishedData AS pd ON image.DocumentId = pd.DocumentId WHERE image.DocumentId = ?", [ docId ], ZImageIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getImageIDOs()

    def _getTagIDOs(self, docId, connection):
        return self._select(u"SELECT * FROM Tag AS tag WHERE tag.DocumentId = ?", [ docId ], ZTagIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getTagIDOs()

    # Fires an 'onIndexChange' event to all the listeners.
    def _fireIndexChangeEvent(self, listeners, eventClass, IDOs):
        for ido in IDOs:
            for listener in listeners:
                try:
                    listener.onIndexChange(eventClass(ido))
                except Exception, e:
                    getLoggerService().exception(e)
Exemple #14
0
class ZBackgroundTaskPanel(ZTransparentPanel, IZBackgroundTaskListener):
    def __init__(self, parentModel, task, parent):
        self.parentModel = parentModel
        self.model = ZBackgroundTaskPanelModel()
        self.mutex = ZMutex()
        self.task = task

        ZTransparentPanel.__init__(self, parent, wx.ID_ANY)
        self.task.attachListener(self)

        self._initPanel()
        self.refresh()

    # end __init__()

    def _initPanel(self):
        self._createPanelWidgets()
        self._layoutPanelWidgets()
        self._bindWidgetEvents()
        self._populatePanelWidgets()

    # end _initPanel()

    def _createPanelWidgets(self):
        self.titleText = wx.StaticText(self, wx.ID_ANY, self.task.getName())
        self.titleText.SetFont(getDefaultFontBold())

        startTime = u"    %s %s" % (_extstr(u"bgtaskpanel.StartedOn"),
                                    self.task.getStartTime().toString(
                                        u"%c", True)
                                    )  #$NON-NLS-2$ #$NON-NLS-1$ #$NON-NLS-3$
        self.startTimeText = wx.StaticText(self, wx.ID_ANY, startTime)

        errorBmp = getResourceRegistry().getBitmap(
            u"images/dialogs/bgtasks/manager/error-glyph.png")  #$NON-NLS-1$
        self.errorGlyph = ZImageButton(self, errorBmp, True)
        infoBmp = getResourceRegistry().getBitmap(
            u"images/dialogs/bgtasks/manager/info-glyph.png")  #$NON-NLS-1$
        self.infoGlyph = ZImageButton(self, infoBmp, True)
        stopBmp = getResourceRegistry().getBitmap(
            u"images/dialogs/bgtasks/manager/stop-glyph.png")  #$NON-NLS-1$
        self.stopGlyph = ZImageButton(self, stopBmp, True)

        # Progress widgets - only visible while task is running.
        self.progressGauge = wx.Gauge(self, wx.ID_ANY,
                                      self.task.getNumWorkUnits())
        self.progressGauge.SetSizeHints(-1, 14)
        self.progressText = wx.StaticText(self, wx.ID_ANY, u"")  #$NON-NLS-1$
        self.statusText = wx.StaticText(self, wx.ID_ANY, u"")  #$NON-NLS-1$

        self.cancelButton = ZImageButton(
            self,
            getResourceRegistry().getBitmap(
                u"images/dialogs/bgtasks/manager/cancel.png"))  #$NON-NLS-1$
        self.cancelButton.SetToolTipString(
            _extstr(u"bgtaskpanel.CancelTask"))  #$NON-NLS-1$
        self.pauseButton = ZImageButton(
            self,
            getResourceRegistry().getBitmap(
                u"images/dialogs/bgtasks/manager/pause.png"))  #$NON-NLS-1$
        self.pauseButton.SetToolTipString(
            _extstr(u"bgtaskpanel.PauseTask"))  #$NON-NLS-1$

        # Widgets that are only shown when the task is complete
        self.endTimeText = wx.StaticText(self, wx.ID_ANY, u"")  #$NON-NLS-1$

        self.removeButton = ZImageButton(
            self,
            getResourceRegistry().getBitmap(
                u"images/dialogs/bgtasks/manager/remove.png"))  #$NON-NLS-1$
        self.removeButton.SetToolTipString(
            _extstr(u"bgtaskpanel.RemoveTask"))  #$NON-NLS-1$

        self.staticLine = wx.StaticLine(self)

    # end _createPanelWidgets()

    def _layoutPanelWidgets(self):
        leftSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer = wx.BoxSizer(wx.HORIZONTAL)

        titleSizer = wx.BoxSizer(wx.HORIZONTAL)
        titleSizer.Add(self.errorGlyph, 0, wx.EXPAND | wx.RIGHT, 5)
        titleSizer.Add(self.infoGlyph, 0, wx.EXPAND | wx.RIGHT, 5)
        titleSizer.Add(self.stopGlyph, 0, wx.EXPAND | wx.RIGHT, 5)
        titleSizer.Add(self.titleText, 1, wx.ALIGN_CENTER_VERTICAL)

        leftSizer.AddSizer(titleSizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 2)
        leftSizer.Add(self.startTimeText, 0, wx.EXPAND | wx.TOP, 2)
        leftSizer.Add(self.progressGauge, 0, wx.EXPAND | wx.ALL, 2)
        leftSizer.Add(self.progressText, 0, wx.EXPAND | wx.ALL, 2)
        leftSizer.Add(self.statusText, 0, wx.EXPAND | wx.ALL, 2)
        leftSizer.Add(self.endTimeText, 0, wx.EXPAND | wx.BOTTOM, 2)

        rightSizer.Add(self.pauseButton, 0, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.cancelButton, 0, wx.EXPAND | wx.ALL, 2)
        rightSizer.Add(self.removeButton, 0, wx.EXPAND | wx.ALL, 2)

        horSizer = wx.BoxSizer(wx.HORIZONTAL)
        horSizer.AddSizer(leftSizer, 1, wx.EXPAND | wx.ALL, 5)
        horSizer.AddSizer(rightSizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.AddSizer(horSizer, 0, wx.EXPAND | wx.ALL, 5)

        panelSizer = wx.BoxSizer(wx.VERTICAL)
        panelSizer.AddSizer(sizer, 0, wx.EXPAND)
        panelSizer.Add(self.staticLine, 0, wx.EXPAND)

        self.SetSizer(panelSizer)
        self.SetAutoLayout(True)

    # end _layoutPanelWidgets()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_BUTTON, self.onCancelButton, self.cancelButton)
        self.Bind(wx.EVT_BUTTON, self.onPauseButton, self.pauseButton)
        self.Bind(wx.EVT_BUTTON, self.onRemoveButton, self.removeButton)
        self.Bind(wx.EVT_BUTTON, self.onInfoGlyphButton, self.infoGlyph)
        self.Bind(wx.EVT_BUTTON, self.onErrorGlyphButton, self.errorGlyph)
        self.Bind(wx.EVT_BUTTON, self.onStopGlyphButton, self.stopGlyph)
        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)

    # end _bindWidgetEvents()

    def _populatePanelWidgets(self):
        pass

    # ene _populatePanelWidgets()

    def refresh(self):
        self.statusText.SetLabel(self.model.getCurrentWorkText())
        self.progressText.SetLabel(self._formatProgressText())
        self.progressGauge.SetValue(self.model.getCurrentWorkAmount())

        if self.model.hasError():
            self.errorGlyph.SetToolTipString(
                getSafeString(self.model.getError()[0]))

        endTime = u""  #$NON-NLS-1$
        if self.model.isComplete() and self.task.getEndTime() is not None:
            endTime = u"%s %s" % (_extstr(u"bgtaskpanel.EndedOn"),
                                  self.task.getEndTime().toString(u"%c", True)
                                  )  #$NON-NLS-1$ #$NON-NLS-2$ #$NON-NLS-3$
        elif self.model.isCancelled():
            endTime = u"(%s)" % _extstr(
                u"bgtaskpanel.Cancelled")  #$NON-NLS-1$ #$NON-NLS-2$
        endTime = u"    %s" % endTime  #$NON-NLS-1$
        self.endTimeText.SetLabel(endTime)

        self._hideShowWidgets()

        self.Layout()
        self.GetParent().Layout()

    # end refresh()

    def _hideShowWidgets(self):
        self.errorGlyph.Show(self.model.hasError())
        self.stopGlyph.Show(self.model.isCancelled())
        self.infoGlyph.Show(not self.model.hasError()
                            and not self.model.isRunning()
                            and not self.model.isCancelled())

        self.endTimeText.Show(self.model.isComplete())

        self.progressGauge.Show(self.model.isRunning())
        self.progressText.Show(self.model.isRunning())
        self.statusText.Show(self.model.isRunning())
        self.pauseButton.Show(self.model.isRunning())
        self.cancelButton.Show(self.model.isRunning())
        self.removeButton.Show(self._shouldShowRemoveButton())
        self.pauseButton.Show(self.model.isRunning()
                              and self.task.isResumable())

    # end _hideShowWidgets()

    def _shouldShowRemoveButton(self):
        if self.model.isComplete() or self.model.hasError():
            return True
        if not self.model.isRunning() and not self.task.isResumable():
            return True
        return False

    # end _shouldShowRemoveButton()

    def onPauseButton(self, event):
        ZShowNotYetImplementedMessage(self)
        event.Skip()

    # end onPauseButton()

    def onCancelButton(self, event):
        ZShowNotYetImplementedMessage(self)
        event.Skip()

    # end onCancelButton()

    def onRemoveButton(self, event):
        self.parentModel.removeTask(self.task)
        event.Skip()

    # end onRemoveButton()

    def onInfoGlyphButton(self, event):
        menuNode = createBackgroundTaskInfoMenuNode(self.task)
        self._popupGlyphMenu(menuNode, self.infoGlyph)
        event.Skip()

    # end onInfoGlyphButton()

    def onErrorGlyphButton(self, event):
        menuNode = createBackgroundTaskErrorMenuNode(self.task)
        self._popupGlyphMenu(menuNode, self.errorGlyph)
        event.Skip()

    # end onErrorGlyphButton()

    def onStopGlyphButton(self, event):
        menuNode = createBackgroundTaskInfoMenuNode(self.task)
        self._popupGlyphMenu(menuNode, self.stopGlyph)
        event.Skip()

    # end onInfoGlyphButton()

    def onZoundryRefresh(self, event):
        self.refresh()
        event.Skip()

    # end onZoundryRefresh()

    def _popupGlyphMenu(self, menuNode, glyph):
        context = ZMenuActionContext(self)
        provider = ZActiveModelBasedMenuContentProvider(menuNode, context)
        handler = ZActiveModelBasedMenuEventHandler(context)
        menu = ZMenu(self, menuNode, provider, handler)
        (x, y) = glyph.GetPositionTuple()  #@UnusedVariable
        (w, h) = glyph.GetSizeTuple()  #@UnusedVariable
        self.PopupMenuXY(menu, x, y + h - 1)

    # end _popupGlyphMenu()

    def onAttached(self, task, numCompletedWorkUnits):  #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.init(task)
        finally:
            self.mutex.release()

    # end onAttached()

    def onWorkDone(self, task, amount, text):  #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.incrementWorkAmount(amount)
            self.model.setCurrentWorkText(text)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)

    # end onWorkDone()

    def onComplete(self, task):  #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.setComplete(True)
            self.model.setRunning(False)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)

    # end onComplete()

    def onStop(self, task):
        self.onComplete(task)

    # end onStop()

    def onCancel(self, task):  #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.setCanceled(True)
            self.model.setRunning(False)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)

    # end onCancel()

    def onError(self, task, errorMessage, errorDetails):  #@UnusedVariable
        self.mutex.acquire()
        try:
            self.model.setError((errorMessage, errorDetails))
            self.model.setRunning(False)
        finally:
            self.mutex.release()
        fireRefreshEvent(self)

    # end onError()

    def _formatProgressText(self):
        # Avoid possible divide by 0 error
        if self.model.getCurrentWorkAmount() == 0:
            perc = 0
        else:
            perc = (self.model.getCurrentWorkAmount() *
                    100) / self.task.getNumWorkUnits()
        return _extstr(u"bgtaskpanel.RunningPercent") % perc  #$NON-NLS-1$

    # end _formatProgressText()

    def destroy(self):
        self.task.detachListener(self)
Exemple #15
0
class ZPySQLIndexProvider(IZIndexProvider):

    def __init__(self):
        self.userProfile = None
        self.dbLock = ZMutex(u"ZPySQLIndexProviderMTX") #$NON-NLS-1$
    # end __init__()

    def _lockDatabase(self):
        self.dbLock.acquire()
    # end _lockDatabase()

    def _unlockDatabase(self):
        self.dbLock.release()
    # end _unlockDatabase()

    def create(self, applicationModel):
        self.userProfile = applicationModel.getUserProfile()
        self.dataStoreDirectory = self.userProfile.getDirectory(u"datastore") #$NON-NLS-1$
        self.indexFile = os.path.join(self.dataStoreDirectory, u"index.db") #$NON-NLS-1$
        self.connectionFactory = ZPySQLConnectionFactory(self.indexFile)

        if not os.path.isfile(self.indexFile):
            self._createNewIndex()
    # end create()

    def clear(self):
        self._createNewIndex()
    # end clear()

    def findDocuments(self, documentFilter):
        queryBuilder = ZDocumentQueryBuilder(documentFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZDocumentIDOListQueryHandler())
    # end findDocuments()

    def findLinks(self, linkFilter):
        queryBuilder = ZLinkQueryBuilder(linkFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZLinkIDOListQueryHandler())
    # end findLinks()

    def findTags(self, tagFilter):
        queryBuilder = ZTagQueryBuilder(tagFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZTagIDOListQueryHandler())
    # end findTags()

    def findImages(self, imageFilter):
        queryBuilder = ZImageQueryBuilder(imageFilter)
        sql = queryBuilder.build()
        return self._select(sql, None, ZImageIDOListQueryHandler())
    # end findImages()

    def getDocumentCount(self, filter):
        queryBuilder = ZDocumentQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getDocumentCount()

    def getTagCount(self, filter):
        queryBuilder = ZTagQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getTagCount()

    def getLinkCount(self, filter):
        queryBuilder = ZLinkQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getLinkCount()

    def getImageCount(self, filter):
        queryBuilder = ZImageQueryBuilder(filter)
        sql = queryBuilder.build(True)
        return self._select(sql, None, ZSingleItemQueryHandler())
    # end getImageCount()

    def addDocument(self, document, listeners):
        self._lockDatabase()
        try:
            self._addDocument(document, listeners)
        finally:
            self._unlockDatabase()
    # end addDocument()

    def _addDocument(self, document, listeners):
        documentIDO = None
        pubDataIDOs = []
        linkIDOs = []
        imageIDOs = []
        tagIDOs = []

        connection = self._createConnection()
        try:
            # First, store the document itself.
            self._storeDocument(document, connection)
            documentIDO = self._createDocumentIDO(document)

            # Now write out the pub-info.
            blogInfoList = document.getBlogInfoList()
            for blogInfo in blogInfoList:
                self._storeBlogInfo(document.getId(), blogInfo, connection)
                pubDataIDO = self._createPubDataIDO(blogInfo)
                documentIDO.addPubDataIDO(pubDataIDO)
                pubDataIDOs.append(pubDataIDO)

            # Now write out the links, images and tags
            content = document.getContent()
            if content:
                xhtmlDoc = content.getXhtmlDocument()
                links = xhtmlDoc.getLinks()
                for link in links:
                    self._storeLink(document.getId(), link, connection)
                    linkIDOs.append(self._createLinkIDO(document, link, pubDataIDOs))

                images = xhtmlDoc.getImages()
                for image in images:
                    self._storeImage(document.getId(), image, connection)
                    imageIDOs.append(self._createImageIDO(document, image, pubDataIDOs))
            # end writing out the links and images

            # build a map of tags
            tagMap = self._getTagsMap(document)
            # write out the taxonomy.
            for (tagId, tag) in tagMap.iteritems():
                self._storeTag(document.getId(), tagId, tag, connection)
                tagIDOs.append( self._createTagIDO(document, tagId, tag, pubDataIDOs) )

            connection.commit()
        finally:
            connection.close()

        # Now, fire an "index changed" event for the document and each link and image IDO added to the index.
        self._fireIndexChangeEvent(listeners, ZDocIndexDocumentAddEvent, [documentIDO])
        self._fireIndexChangeEvent(listeners, ZDocIndexLinkAddEvent, linkIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexImageAddEvent, imageIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexTagAddEvent, tagIDOs)
    # end addDocument()

    def _getTagsMap(self, document):
        # temp list containing tag and category strings
        tags = []
        # Collect list of tags from document meta data
        if document.getTagwordsList and document.getTagwordsList():
            wordSet = ZTagwordsSet()
            wordSet.addZTagwordObjectList( document.getTagwordsList() )
            tags.extend( wordSet.getTagwords() )

        # Get document (blog info) categories for tags/taxanomy.
        if document.getBlogInfoList and document.getBlogInfoList():
            for blogInfo in document.getBlogInfoList():
                for category in blogInfo.getCategories():
                    tags.append( category.getName() )

        # Also use document (pub meta data) categories for tags/taxanomy.
        if document.getPubMetaDataList and document.getPubMetaDataList():
            for metaData in document.getPubMetaDataList(): #@UnusedVariable
                pass # FIXME (PJ) add meta data categories?  Same as blog infor categories?


        # get list of tags found in xhtml content document embedded in links with rel = tag
        if document.getContent() and document.getContent().getXhtmlDocument():
            tagwordsInLinks = document.getContent().getXhtmlDocument().getTagwords()
            if tagwordsInLinks:
                tags.extend(tagwordsInLinks)

        # build a map of tags to eliminate duplicates
        # map key: tagId, value: tag word
        tagMap = {}
        for tag in tags:
            tagId = tag.lower().strip().replace(u" ", u"_") #$NON-NLS-1$ #$NON-NLS-2$
            tagId = tagId.replace(u"'", u"_") #$NON-NLS-1$ #$NON-NLS-2$
            tagId = tagId.replace(u'"', u"_") #$NON-NLS-1$ #$NON-NLS-2$
            if not tagId:
                continue
            if not tagMap.has_key(tagId):
                tagMap[tagId] = tag.strip()
        return tagMap

    def updateDocument(self, document, listeners):
        self._lockDatabase()
        try:
            self._updateDocument(document, listeners)
        finally:
            self._unlockDatabase()
    # end updateDocument()

    def _updateDocument(self, document, listeners):
        docId = document.getId()
        # FIXME (EPW) change to actually update the document, rather than remove/add
        self._removeDocument(docId, listeners)
        self._addDocument(document, listeners)
    # end _updateDocument()

    def removeDocument(self, docId, listeners):
        self._lockDatabase()
        try:
            self._removeDocument(docId, listeners)
        finally:
            self._unlockDatabase()
    # end removeDocument()

    def _removeDocument(self, docId, listeners):
        # Get the IDOs being removed (for event firing purposes)
        connection = self._createConnection()
        # FIXME (EPW) remove these if not needed (since pySQL cascade/trigger is used).
        documentIDOs = self._getDocumentIDO(docId, connection)
        linkIDOs = self._getLinkIDOs(docId, connection)
        imageIDOs = self._getImageIDOs(docId, connection)
        tagIDOs = self._getTagIDOs(docId, connection)
        
        try:
            self._delete(u"DELETE FROM Document WHERE Document.DocumentId = ?", [ docId ], connection) #$NON-NLS-1$
            connection.commit()
        finally:
            connection.close()

        # Now, fire an "index changed" event for the document and each link and image IDO removed
        self._fireIndexChangeEvent(listeners, ZDocIndexDocumentRemoveEvent, documentIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexLinkRemoveEvent, linkIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexImageRemoveEvent, imageIDOs)
        self._fireIndexChangeEvent(listeners, ZDocIndexTagRemoveEvent, tagIDOs)
    # end _removeDocument()

    def getNumDocuments(self):
        return self._select(u"SELECT count(DocumentId) FROM Document", None, ZSingleItemQueryHandler()) #$NON-NLS-1$
    # end getNumDocuments()

    def requiresReindex(self):
        providerVersion = self._getProviderVersion()
        dbVersion = self._getDBVersion()
        return providerVersion != dbVersion
    # end requiresReindex()

    def destroy(self):
        pass
    # end destroy()

    def _createConnection(self):
        return self.connectionFactory.createConnection()
    # end _createConnection()

    def _createNewIndex(self):
        self._lockDatabase()
        try:
            if os.path.exists(self.indexFile):
                os.remove(self.indexFile)
            self._createDB()
        finally:
            self._unlockDatabase()
    # end _createNewIndex()

    def _createDB(self):
        connection = self._createConnection()
        try:
            cursor = connection.cursor()
            try:
                cursor.executescript(PYSQL_DOCINDEX_DDL)
                connection.commit()
            finally:
                cursor.close()
            cursor.close()
        finally:
            connection.close()
    # end _createDB()

    def _getProviderVersion(self):
        return PYSQL_INDEX_VERSION
    # end _getProviderVersion()

    def _getDBVersion(self):
        return self._select(u"SELECT Value FROM MetaData WHERE Name = 'Version'", None, ZSingleItemQueryHandler()) #$NON-NLS-1$
    # end _getDBVersion()

    def _storeDocument(self, document, connection):
        params = [
              document.getId(),
              document.getTitle(),
              getNoneString(document.getCreationTime()),
              getNoneString(document.getLastModifiedTime())
        ]
        self._insert(u"INSERT INTO Document (DocumentId, Title, CreationTime, LastModifiedTime) values (?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeDocument()

    def _storeBlogInfo(self, documentId, blogInfo, connection):
        pubInfo = blogInfo.getPublishInfo()
        draft = 0
        if pubInfo.isDraft():
            draft = 1
        params = [
              documentId,
              blogInfo.getAccountId(),
              blogInfo.getBlogId(),
              pubInfo.getBlogEntryId(),
              getNoneString(pubInfo.getPublishedTime()),
              getNoneString(pubInfo.getSynchTime()),
              draft,
              pubInfo.getUrl()
        ]
        self._insert(u"INSERT INTO PublishedData (DocumentId, AccountId, BlogId, BlogEntryId, IssuedTime, SynchTime, Draft, Permalink) values (?, ?, ?, ?, ?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeBlogInfo()

    def _createPubDataIDO(self, blogInfo):
        pubInfo = blogInfo.getPublishInfo()
        accountId = blogInfo.getAccountId()
        blogId = blogInfo.getBlogId()
        blogEntryId = pubInfo.getBlogEntryId()
        issuedTime = pubInfo.getPublishedTime()
        synchTime = pubInfo.getSynchTime()
        draft = pubInfo.isDraft()
        permaLink = pubInfo.getUrl()

        return ZPubDataIDO(accountId, blogId, blogEntryId, issuedTime, synchTime, draft, permaLink)
    # end _createPubDataIDO()

    # Creates a ZDocumentIDO object from the IZDocument and pub data IDO objects.
    def _createDocumentIDO(self, document):
        id = document.getId()
        title = document.getTitle()
        creationTime = document.getCreationTime()
        lastModifiedTime = document.getLastModifiedTime()

        return ZDocumentIDO(None, id, title, creationTime, lastModifiedTime)
    # end _createDocumentIDO()

    def _storeLink(self, documentId, link, connection):
        url = link.getUrl()
        params = [
              documentId,
              url.toString(),
              url.getHost(),
              url.getPath(),
              link.getRel(),
              link.getTitle(),
              link.getText(),
              link.getHitCount()
        ]
        self._insert(u"INSERT INTO Link (DocumentId, Url, Host, Path, Rel, Title, Content, HitCount) values (?, ?, ?, ?, ?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeLink()

    def _createLinkIDO(self, document, link, pubDataIDOs):
        url = link.getUrl()
        return ZLinkIDO(pubDataIDOs, document.getId(), url.toString(), url.getHost(), url.getPath(), link.getRel(), link.getTitle(), link.getText())
    # end _createLinkIDO()

    def _storeImage(self, documentId, image, connection):
        url = image.getUrl()
        params = [
              documentId,
              url.toString(),
              url.getHost(),
              url.getPath(),
              image.getTitle(),
              image.getHitCount()
        ]
        self._insert(u"INSERT INTO Image (DocumentId, Url, Host, Path, Title, HitCount) values (?, ?, ?, ?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeImage()

    def _createImageIDO(self, document, image, pubDataIDOs):
        url = image.getUrl()
        return ZImageIDO(pubDataIDOs, document.getId(), url.toString(), url.getHost(), url.getPath(), image.getTitle())
    # end _createImageIDO()

    def _storeTag(self, documentId, tagId, tag, connection):
        params = [
              documentId,
              tagId,
              tag
        ]
        self._insert(u"INSERT INTO Tag (DocumentId, TagId, TagWord) values (?, ?, ?)", params, connection) #$NON-NLS-1$
    # end _storeTag()

    def _createTagIDO(self, document, tagId, tag, pubDataIDOs):
        ido = ZTagIDO(pubDataIDOs, document.getId(), tagId, tag)
        return ido
    # end _createTagIDO()

    def _getDocumentIDO(self, docId, connection):
        return self._select(u"SELECT * FROM Document AS doc LEFT JOIN PublishedData AS pd ON doc.DocumentId = pd.DocumentId WHERE doc.DocumentId = ?", [ docId ], ZDocumentIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getDocumentIDO()

    def _getLinkIDOs(self, docId, connection):
        return self._select(u"SELECT * FROM Link AS link LEFT JOIN PublishedData AS pd ON link.DocumentId = pd.DocumentId WHERE link.DocumentId = ?", [ docId ], ZLinkIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getLinkIDOs()

    def _getImageIDOs(self, docId, connection):
        return self._select(u"SELECT * FROM Image AS image LEFT JOIN PublishedData AS pd ON image.DocumentId = pd.DocumentId WHERE image.DocumentId = ?", [ docId ], ZImageIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getImageIDOs()

    def _getTagIDOs(self, docId, connection):
        return self._select(u"SELECT * FROM Tag AS tag WHERE tag.DocumentId = ?", [ docId ], ZTagIDOListQueryHandler(), connection) #$NON-NLS-1$
    # end _getTagIDOs()

    # Fires an 'onIndexChange' event to all the listeners.
    def _fireIndexChangeEvent(self, listeners, eventClass, IDOs):
        for ido in IDOs:
            for listener in listeners:
                try:
                    listener.onIndexChange(eventClass(ido))
                except Exception, e:
                    getLoggerService().exception(e)
Exemple #16
0
 def __init__(self):
     self.mutex = ZMutex(u"ZListenerSetMTX")  #$NON-NLS-1$
     self.head = None
Exemple #17
0
class ZSystemProperties:
    u"""Use this class to get and set System Properties."""  #$NON-NLS-1$

    def __init__(self, sysPropsFileName):
        # create a lock for thread synchronization
        self.lock = ZMutex(u"ZSystemProperties")  #$NON-NLS-1$
        self.listeners = ZListenerSet()

        self.sysPropsFileName = sysPropsFileName
        self.sysPropsDoc = ZDom()

        self.reloadProperties()

    # end __init__()

    def addListener(self, listener):
        self.listeners.append(listener)

    # end addListener()

    def removeListener(self, listener):
        self.listeners.remove(listener)

    # end removeListener

    def _fireEvent(self, key, value):
        for listener in self.listeners:
            listener.onSystemPropertyChange(key, value)

    # end _fireEvent()

    def reloadProperties(self):
        self.lock.acquire()
        try:
            # Open and parse the system properties file
            self.sysPropsDoc.load(self.sysPropsFileName)
        finally:
            self.lock.release()

    # end reloadProperties()

    # Public method - call this to save the system properties.
    def save(self):
        u"Public method - call this to save the system properties."  #$NON-NLS-1$
        self.lock.acquire()
        self.saveProperties()
        self.lock.release()
        self._fireEvent(None, None)

    # end save()

    # Note that locking is required prior to calling saveProperties()
    def saveProperties(self):
        try:
            tempSysPropsFileName = self.sysPropsFileName + u".t"  #$NON-NLS-1$
            self.sysPropsDoc.save(tempSysPropsFileName, True)
            deleteFile(self.sysPropsFileName)
            renameFile(tempSysPropsFileName, self.sysPropsFileName)
        except Exception, e:
            raise ZException(
                _extstr(u"sysprops.ErrorSavingPropsFile") %
                self.sysPropsFileName, e)  #$NON-NLS-1$