Add module progressbar

develop
Самоукин Алексей 14 years ago
parent 82fbe6b9e1
commit 63cbc852ca

@ -0,0 +1,228 @@
#-*- coding: utf-8 -*-
# Copyright 2008-2010 Mir Calculate Ltd. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
import subprocess
import time
class NoneProgressBar:
"""Abstract class of progress bar. It do nothing."""
def __init__(self,title,dialog=None):
pass
def openDialog(self,title,max=None):
"""Create dialog with progress bar, prepare date"""
pass
def shutdownDialog(self):
"""Destroy dialog"""
pass
def setValue(self,value):
"""Set value of progress bar relative of maximum"""
pass
def setMaximum(self,max):
"""Set maximum value of progress bar"""
pass
def setTitle(self,title):
"""Set title of progress dialog"""
pass
class GProgressBar(NoneProgressBar):
"""GProgressBar uses Xdialog program for display progressbar."""
def __init__(self,title,xdialog=None):
self.title = title
self.bgPID = 0
self.value = 0
self.pipein = None
if xdialog == None:
self.openDialog(self.title)
def openDialog(self,title,max=None):
if max != None:
self.setMaximum(max)
title = re.sub("<[^>]+>", "", title)
self.title = title
if os.system('which Xdialog &>/dev/null') == 0:
pipe = subprocess.Popen('/usr/bin/Xdialog --progress "%s" 6 80'\
%(self.title),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
env=os.environ, shell=True)
self.pipein = pipe.stdin
self._set(1)
pipe.stdout.close()
pipe.stderr.close()
def shutdownDialog(self):
'''Принудительно уничтожить процесс dialog'''
if self.pipein:
self._set(100)
time.sleep(0.1)
self.pipein.close()
self.pipein = None
def _set(self,value):
if self.pipein:
self.pipein.write("%02d\n"%value)
self.pipein.flush()
def setValue(self,value):
'''Установить текущее значения для прогресса'''
if self.pipein and value <= self.max:
progress_value = int(value / self.kmax)
if progress_value > int(self.value / self.kmax) and progress_value < 100:
self._set(progress_value)
self.value = value
def setMaximum(self,max):
'''Установить максимальное значения для прогресса'''
self.max = max
self.kmax = max / 100.0
def setTitle(self,title):
'''Установить описания прогресса'''
pass
class KProgressBar(NoneProgressBar):
"""KProgressBar uses kdialog program and dbus for display progressbar."""
suffixSet = 'org.freedesktop.DBus.Properties.Set \
org.kde.kdialog.ProgressDialog'
execenv = {"HOME":"/root"}
max = 100
kdialog = None
label = None
def __init__(self,title,kdialog=None):
self.title = title
self.value = 0
if kdialog is None:
self.openDialog(self.title)
def openDialog(self,title,max=None):
if max != None:
self.max = max
self.title = title
if os.system('which kdialog >/dev/null') == 0:
self.label ="LOGINKDIALOG=%d" % os.getpid()
env = {}
env.update(os.environ.items() + self.execenv.items() +\
[tuple(self.label.split("="))])
pipe = subprocess.Popen('/usr/bin/kdialog --progressbar "%s" %d'\
%(" "*(len(title)+20), self.max),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
env=env, shell=True)
pipe.stdin.close()
# wait for terminate kdialog, which say dbus dialog id
if pipe.poll() is None:
# ожидание в 5 сек
for t in range(500):
time.sleep(0.01)
if pipe.poll() != None:
break
# waiting is ok
if pipe.poll() == 0:
self.kdialog = pipe.stdout.readline().strip()
while not "org.kde.kdialog" in self.kdialog:
s = pipe.stdout.readline()
# if bad result of kdialog then shutdown dialog
if s == "":
pipe.stdout.close()
pipe.stderr.close()
self.shutdownDialog()
break
self.kdialog = s.strip()
self.setTitle(self.title)
pipe.stdout.close()
pipe.stderr.close()
# waiting is failed
else:
pipe.stdout.close()
pipe.stderr.close()
self.shutdownDialog()
def shutdownDialog(self):
'''Принудительно уничтожить процесс kdialog'''
self.kdialog = None
pipe = subprocess.Popen("/bin/ps axeo pid,cmd",
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True, shell=True)
if self.label != None:
for s in pipe.stdout.readlines():
if self.label in s:
try:
os.kill( int(s.split()[0]), 9 )
except (OSError,ValueError):
pass
self.label = None
def setValue(self,value):
'''Установить текущее значения для прогресса'''
if self.kdialog and value <= self.max:
env = ""
if self.execenv:
env = " ".join(map(lambda x: '%s="%s"'%(x[0],x[1]),\
self.execenv)) + " "
oldperc = int(self.value / self.kmax)
newperc = int(value / self.kmax)
if newperc > oldperc:
os.system(env + '/usr/bin/qdbus %s %s value %d >/dev/null'\
%(self.kdialog,self.suffixSet, newperc))
self.value = value
def setMaximum(self,max):
'''Установить максимальное значения для прогресса'''
if self.kdialog and self.max == 0 and max != 0:
env = ""
if self.execenv:
env = " ".join(map(lambda x: '%s="%s"'%(x[0],x[1]),\
self.execenv)) + " "
os.system(env + '/usr/bin/qdbus %s %s maximum %d >/dev/null'\
%(self.kdialog,self.suffixSet, 100))
self.max = max
self.kmax = max / 100.0
def setTitle(self,title):
'''Установить описания прогресса'''
self.title = title
if self.kdialog:
env = ""
if self.execenv:
env = " ".join(map(lambda x: '%s="%s"'%(x[0],x[1]),\
self.execenv)) + " "
os.system(env + '/usr/bin/qdbus %s setLabelText "%s" >/dev/null'\
%(self.kdialog,self.title))
def ProgressBar(*args,**kwarg):
"""Return instance of object for progress bar"""
if os.system('which kdialog &>/dev/null') == 0:
return KProgressBar(*args,**kwarg)
elif os.system('which Xdialog &>/dev/null') == 0:
return GProgressBar(*args,**kwarg)
return NoneProgressBar(*args,**kwarg)

@ -32,7 +32,8 @@ setup(
package_dir = {'calculate-lib': "."}, package_dir = {'calculate-lib': "."},
packages = ['calculate-lib.pym', packages = ['calculate-lib.pym',
'calculate-lib.pym.format', 'calculate-lib.pym.format',
'calculate-lib.pym.server'], 'calculate-lib.pym.server',
'calculate-lib.pym.client'],
data_files = [("/usr/share/calculate-2.2/i18n",['i18n/cl_lib_ru.mo']), data_files = [("/usr/share/calculate-2.2/i18n",['i18n/cl_lib_ru.mo']),
("/var/calculate/remote",[])], ("/var/calculate/remote",[])],
) )

Loading…
Cancel
Save