Hi,

we have been developing a small desktop toy as a plasmoid for the last
few days and now tried to add notifications for events.

We already limited the botification number to one event per minute,
however, the code still freezes KDE.

The moment a notification is emitted, the notification sound is played
and then KDE becomes unresponsive until the closing of the plasmoid is
registered. I somehow have the impression that the code displays more
than one notification at a time, but I do not have any idea why.

Attached is the plasmoid code that crashes, removing the comment sign at
the beginning of line 317 introduces notifications and the freeze.

The working plasmoid is at
http://kde-look.org/content/download.php?content=158609&id=1&tan=93512101,
the broken code can be tested by replacing contents/code/main.py inside
the pasmoid with the attached script.

Can anyone give a hint on why this is misbehaving?

Cheers,
Nik

-- 
PGP-Fingerprint: 3C9D 54A4 7575 C026 FB17  FD26 B79A 3C16 A0C4 F296
# ~*~ coding: utf-8 ~*~
#-
# desKoala - Tamagotchi with a Koala as KDE Plasmoid
#
# Copyright 2013 Dominik George <n...@naturalnet.de>
# Copyright 2013 Tim Huppertz <mitro...@naturalnet.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyKDE4.plasma import Plasma
from PyKDE4.kdeui import KDialog, KPageDialog
from PyKDE4 import plasmascript
from datetime import datetime
from PyQt4 import uic
from ConfigParser import ConfigParser
from koalaConfig import KoalaConfig
from random import randint
import os
import dbus
import time

class Koala():
    def __init__(self):
        self.dir = os.path.join(os.path.expanduser('~'), ".deskoala")
        if not os.path.exists(self.dir):
            os.mkdir(self.dir)

        self.happiness = 50
        self.hunger = 10
        self.exhaustion = 10
        self.brushed = datetime.now()
        self.brushtime = "22:15"
        self.dirtiness = 0
        self.loneliness = 0
        self.weight = 10
        self.name = "Tim"
        self.animal = "koala"
        self.timeout = 60000
        self.sickness = 0

        self.load()

    def get_mood(self):
        if datetime.now() > datetime.strptime(datetime.now().strftime("%d.%m.%Y") + " " + self.brushtime, "%d.%m.%Y %H:%M") and self.brushed < datetime.strptime(datetime.now().strftime("%d.%m.%Y") + " " + self.brushtime, "%d.%m.%Y %H:%M"):
            return "dirty-teeth"

        if self.sickness >= 20:
            return "sick"

        if self.hunger >= 10:
            return "hungry"

        if self.dirtiness >= 10:
            return "dirty"

        if self.loneliness >= 10:
            return "lonely"

        if self.weight >= 40:
            return "fat"

        if self.exhaustion >= 20:
            return "tired"

        if self.happiness >= 70:
            return "happy"
        elif self.happiness >= 50:
            return "neutral"
        else:
            return "unhappy"

    def update(self):
        if self.happiness > 20:
            self.happiness -= 1

        if self.hunger < 20:
            self.hunger += 1

        if self.dirtiness < 20:
            self.dirtiness += 0.5

        if self.loneliness < 20:
            self.loneliness += 0.5

        if self.exhaustion < 30:
            self.exhaustion += 0.5

        if self.get_mood() == "dirty-teeth":
            self.happiness -= 1
            self.sickness += 0.5

        if self.get_mood() == "hungry":
            self.happiness -= 1

        if self.get_mood() == "fat":
            self.happiness -= 1
            self.loneliness += 2
            self.sickness += 0.5

        if self.get_mood() == "dirty":
            self.sickness += 0.5

        if self.get_mood() == "sick":
            self.loneliness += 2
            self.happiness -= 2
            self.dirtiness += 2

        if randint(0, 100) % 4 == 0:
            self.sickness += 1

        self.save()

    def save(self):
        cfg = os.path.join(self.dir, "koala.ini")

        cfgParser = ConfigParser()
        cfgParser.add_section('koala')
        cfgParser.add_section('behaviour')
        cfgParser.add_section('state')

        cfgParser.set('koala', 'name', self.name)
        cfgParser.set('koala', 'animal', self.animal)
        cfgParser.set('behaviour', 'brushtime', self.brushtime)
        cfgParser.set('behaviour', 'timeout', self.timeout)

        cfgParser.set('state', 'happiness', self.happiness)
        cfgParser.set('state', 'hunger', self.hunger)
        cfgParser.set('state', 'exhaustion', self.exhaustion)
        cfgParser.set('state', 'brushed', self.brushed.strftime("%d.%m.%Y %H:%M:%S"))
        cfgParser.set('state', 'dirtiness', self.dirtiness)
        cfgParser.set('state', 'loneliness', self.loneliness)
        cfgParser.set('state', 'weight', self.weight)

        cfgFile = open(cfg, "w")
        cfgParser.write(cfgFile)
        cfgFile.close()        

    def load(self):
        cfg = os.path.join(self.dir, "koala.ini")
        if os.path.exists(cfg):
            cfgParser = ConfigParser()
            cfgFile = open(cfg)
            cfgParser.readfp(cfgFile)

            self.name = cfgParser.get('koala', 'name')
            self.animal = cfgParser.get('koala', 'animal')
            self.brushtime = cfgParser.get('behaviour', 'brushtime')
            self.timeout = int(cfgParser.get('behaviour', 'timeout'))

            self.happiness = float(cfgParser.get('state', 'happiness'))
            self.hunger = float(cfgParser.get('state', 'hunger'))
            self.exhaustion = float(cfgParser.get('state', 'exhaustion'))
            self.brushed = datetime.strptime(cfgParser.get('state', 'brushed'), "%d.%m.%Y %H:%M:%S")
            self.dirtiness = float(cfgParser.get('state', 'dirtiness'))
            self.loneliness = float(cfgParser.get('state', 'loneliness'))
            self.weight = float(cfgParser.get('state', 'weight'))

            cfgFile.close()
        else:
            self.save()

    def feed(self):
        self.hunger -= 2
        self.dirtiness += 0.5
        self.weight += 1

    def turn(self):
        self.happiness += 3

    def brush(self):
        self.brushed = datetime.now()

    def excercise(self):
        self.hunger += 2
        self.happiness += 1
        self.exhaustion += 2
        self.dirtiness += 0.5
        self.weight -= 1

    def soap(self):
        self.dirtiness -= 5

    def medicine(self):
        self.happiness += 5
        self.hunger -= 1
        self.loneliness -= 5
        self.sickness -= 5

    def bonbon(self):
        self.weight += 2
        self.happiness += 5
        self.hunger -= 1
        self.dirtiness += 0.5

    def hug(self):
        self.happiness += 2
        self.loneliness -= 2
        self.sickness -= 0.5

    def walk(self):
        self.happiness += 5
        self.loneliness -= 5
        self.hunger += 5
        self.weight -= 5

    def sleep(self):
        self.exhaustion -= 20
        self.dirtiness += 1
        self.sickness -= 0.5

class Deskoala(plasmascript.Applet):
    def __init__(self,parent,args=None):
        plasmascript.Applet.__init__(self,parent)

        self.koala = Koala()
        self.lastnotifytime = time.time()
        self.knotify = dbus.SessionBus().get_object("org.kde.knotify", "/Notify")

    def init(self):
        self.setHasConfigurationInterface(True)
        self.resize(320, 260)
        self.layout = QGraphicsLinearLayout(Qt.Horizontal,self.applet)
        self.label = Plasma.Label(self.applet)
        self.layout.addItem(self.label)
        self.show_mood()
        self.buttons = []

        for g in [
                  [("feed", self.feed, "Feed the animal"), ("turn", self.turn, "Make the animal happy by turning upside down"), ("excercise", self.excercise, "Make sports with the animal"), ("brush", self.brush, "Brush the animal's teeth"), ("soap", self.soap, "Wash the animal")],
                  [("medicine", self.medicine, "Heal the animal"), ("bonbon", self.bonbon, "Give the animal a bonbon"), ("hug", self.hug, "Hug the animal"), ("walk", self.walk, "Take the animal for a walk"), ("sleep", self.sleep, "Let the animal sleep")]
                 ]:
            buttons = QGraphicsLinearLayout(Qt.Vertical, self.layout)

            for b in g:
                button = Plasma.PushButton(self.applet)
                button.setImage(self.package().filePath('images', 'button_' + b[0] + '.gif'))
                button.setToolTip(b[2])
                self.connect(button, SIGNAL("clicked()"), b[1])
                buttons.addItem(button)

            self.buttons.append(buttons)
            self.layout.addItem(buttons)

        self.startTimer(self.koala.timeout)

    def createConfigurationInterface(self,parent):
        self.koalaConfig = KoalaConfig(self)
        page = parent.addPage(self.koalaConfig,"")

        self.connect(parent, SIGNAL("okClicked()"), self.configAccepted)
        self.connect(parent, SIGNAL("cancelClicked()"), self.configDenied)

        self.koalaConfig.linName.setText(self.koala.name)
        self.koalaConfig.timBrushtime.setTime(QTime.fromString(self.koala.brushtime, "h:m"))
        self.koalaConfig.spnTimeout.setValue(self.koala.timeout / 1000)

        animals = ["koala", "kangaroo"]
        for i in animals:
            self.koalaConfig.cmbAnimal.addItem(i)
            if i == self.koala.animal:
                self.koalaConfig.cmbAnimal.setCurrentIndex(animals.index(i))
    
    def showConfigurationInterface(self):
        dialog = KPageDialog()
        dialog.setFaceType(KPageDialog.Plain)
        dialog.setButtons(KDialog.ButtonCode(KDialog.Ok | KDialog.Cancel))
        self.createConfigurationInterface(dialog)
        dialog.resize(400,300)
        dialog.exec_()

    def configAccepted(self):
        self.koala.name = self.koalaConfig.linName.text()
        self.koala.brushtime = str(self.koalaConfig.timBrushtime.time().toString("h:m"))
        self.koala.animal = self.koalaConfig.cmbAnimal.currentText()
        self.koala.timeout = self.koalaConfig.spnTimeout.value() * 1000
        self.koala.save()

        self.startTimer(self.koala.timeout)

    def configDenied(self):
        pass

    def show_mood(self, notify = False):
        mood = self.koala.get_mood()
        self.label.setImage(self.package().filePath('images', self.koala.animal + '_' + mood + '.gif'))

        notifications = [
                         ("dirty-teeth", "needs to brush its teeth!"),
                         ("tired", "is tired!"),
                         ("lonely", "is lonely!"),
                         ("dirty", "needs to take a bath!"),
                         ("sick", "is very sick!")
                        ]

        if notify:
            for n in notifications:
                if mood == n[0]:
                    self.notify(n[1])

        self.update()

    def notify(self, message):
        if time.time() - self.lastnotifytime > 60:
#            self.knotify.event("warning", "kde", [], str(self.koala.name + " needs you!"), str(self.koala.name + " " + message), [], [], 0, 0, dbus_interface="org.kde.KNotify")
            self.lastnotifytime = time.time()

    def timerEvent(self, event):
        self.koala.update()
        self.show_mood(True)

    def feed(self):
        self.koala.feed()
        self.show_mood()

    def turn(self):
        self.koala.turn()
        self.show_mood()

    def excercise(self):
        self.koala.excercise()
        self.show_mood()

    def brush(self):
        self.koala.brush()
        self.show_mood()

    def soap(self):
        self.koala.soap()
        self.show_mood()

    def medicine(self):
        self.koala.medicine()
        self.show_mood()

    def bonbon(self):
        self.koala.bonbon()
        self.show_mood()

    def hug(self):
        self.koala.hug()
        self.show_mood()

    def walk(self):
        self.koala.walk()
        self.show_mood()

    def sleep(self):
        self.koala.sleep()
        self.show_mood()

def CreateApplet(parent):
    return Deskoala(parent)

Attachment: signature.asc
Description: Digital signature

>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

Reply via email to