Related
run python.py and show this error
import boto3, datetime, sys, getopt, re
from operator import itemgetter
from table_logger import TableLogger
class buck:
TARIFAWS = 0.023 # 0,023 USD por GB (Primeiros 50 TB por mês)
counter = 0
def __init__(self, s3bucket):
buck.counter = buck.counter + 1
self.name = s3bucket.name
self.creationdate = s3bucket.creation_date
self.size = self.metricCloudwatch(s3bucket,"BucketSizeBytes", "StandardStorage")
self.nbreObj = self.metricCloudwatch(s3bucket,"NumberOfObjects", "AllStorageTypes")
try:
boto3.client('s3').get_bucket_encryption(Bucket=s3bucket.name)
self.number = True
except:
self.number = False
self.region = (boto3.client('s3').get_bucket_location(Bucket=s3bucket.name))['LocationConstraint']
self.cout = round(self.size / 1024**3 * self.TARIFAWS,2)
try:
boto3.client('s3').get_bucket_replication(Bucket=s3bucket.name)
self.replica = True
except:
self.replica = False
def collObjInfo(self):
s3obj = (boto3.client('s3')).list_objects_v2(Bucket=self.name)
self.lastupdate = None
self.typeStorage = None
if s3obj['KeyCount'] != 0:
self.lastupdate = s3obj['Contents'][0]['LastModified']
self.typeStorage = s3obj['Contents'][0]['StorageClass']
collObjInfo(self)
self.public = False
def __str__(self):
return str(self.__class__) + ": " + str(self.__dict__)
def __getitem__(self, key):
if key == 'region':
return self.region
if key == 'typeStorage':
return self.typeStorage
def getSize(self, human=False):
if human:
return humanReadable(self.size)
else:
return self.size
def metricCloudwatch(self, bucket, nameMetric, storage):
cloudwatch = boto3.client('cloudwatch')
now = datetime.datetime.now()
try:
cloudwatch_size = cloudwatch.get_metric_statistics(
Namespace='AWS/S3',
MetricName=nameMetric,
Dimensions=[
{'Name': 'BucketName', 'Value': bucket.name},
{'Name': 'StorageType', 'Value': storage}
],
Statistics=['Maximum'],
Period=86400,
StartTime=(now - datetime.timedelta(days=1)).isoformat(),
EndTime=now.isoformat()
)
if cloudwatch_size["Datapoints"]:
return cloudwatch_size["Datapoints"][0]['Maximum']
else:
return 0
except:
return 0
def humanReadable(num, suffix='B'):
for unit in ['','K','M','G','T','P']:
if abs(num) < 1024.0:
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Yi', suffix)
def help():
print("Uso : bucket.py [OPTIONS]")
print("Exibe informações sobre buckets AWS S3, por padrão")
print("Argumentos : \n\
--help \t\t\t ajuda\n\
--crypted-only \t\t mostra apenas buckets criptografados\n\
-c, --csv \t\t mostra o resultado em CSV\n\
-s, --sorted \t\t agrupar resultados por região e grupo de armazenamento\n\
-h, --human-readable \t exibem tamanhos de 1024\n\
-f, --filter=filter \t filtra a lista de buckets com base na expressão regular FILTER")
def main():
csv=False
human = False
group = False
filterCrpt = False
filter = None
try:
opts, args = getopt.getopt(sys.argv[1:], "shcf:", ["sorted", "help", "csv", "human-readable", "crypted-only", "filter:"])
except:
print("Comando incorreto, aqui está a ajuda: ")
help()
sys.exit(2)
for opts, args in opts:
if opts == "--help":
help()
sys.exit()
elif opts == "--crypted-only":
filterCrpt = True
elif opts in ("-c", "--csv"):
csv = True
elif opts in ("-s", "--sorted"):
group = True
elif opts in ("-h", "--human-readable"):
human = True
elif opts in ("-f", "--filter"):
if len(args):
filter = args
else:
help()
sys.exit(2)
s3 = boto3.resource('s3')
bucks = []
listeS3Bucks = s3.buckets.all()
for bucket in listeS3Bucks:
try:
if filter:
re.match(filter,"Test chain")
except:
print("Regular expression error")
sys.exit(2)
if (filter and re.match(filter,bucket.name)) or not filter:
try:
bucks.append(buck(bucket))
except:
print("Erro ao conectar ao AWS, verifique suas configurações")
print("Para obter mais informações: https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html")
sys.exit(2)
if group:
bucks = sorted(bucks, key=itemgetter('region'))
bucks = sorted(bucks, key=itemgetter('typeStorage'))
tbl = TableLogger(columns='name,creation date,last update,size,number of objects,number,storage,public,region,cost,replica',
csv=csv, border=False)
for cBuck in bucks:
if (filterCrpt and cBuck.number) or not filterCrpt:
tbl(cBuck.name, cBuck.creationdate, cBuck.lastupdate, cBuck.getSize(human), str(cBuck.nbreObj),
cBuck.number,cBuck.typeStorage, cBuck.public, cBuck.region, "$"+str(cBuck.cout),cBuck.replica)
if __name__ == "__main__":
main()
when trying to run the script in python, it gives this error:
TypeError: unsupported format string passed to NoneType.format
can someone help me? is a script that pulls information from aws s3 bucket.
Bucket is a python script to extract statistics from S3 buckets. It is based on Cloudwatch monitoring metrics.
Help plis
File "C:\Python39\lib\site-packages\table_logger\table_logger.py", line 203, in __call__
line = self.format_row(*row_cells)
File "C:\Python39\lib\site-packages\table_logger\table_logger.py", line 207, in format_row
vals = [self.format_column(value, col) for col, value in enumerate(args)]
File "C:\Python39\lib\site-packages\table_logger\table_logger.py", line 207, in <listcomp>
vals = [self.format_column(value, col) for col, value in enumerate(args)]
File "C:\Python39\lib\site-packages\table_logger\table_logger.py", line 212, in format_column
return self.formatters[col](value)
File "C:\Python39\lib\site-packages\table_logger\fmt.py", line 40, in __call__
fmt = self.fmt(value)
TypeError: unsupported format string passed to NoneType.__format__
I've been struglying to convert my .py file in to a working .exe file. This is my first time doing it and I can't seem to find my mistake.
I've tryed two methods, pyinstaller and cx_Freeze, and both times the conversion would occur without any error, but when I try to open the .exe file, it blinks a CMD window and nothing happens.
Can any one, please, help me?
my program:
import numpy as np
import pandas as pd
verde='\033[1;32m'
vermelho='\033[1;31m'
preto='\033[0;30m'
'DATA FRAME FROTA'
Empilhadeiras={'Paletrans':['PR20','PR16'],'STILL':['FMX','EGU'], 'Ameise':['EJC','X']}
Modelos= pd.DataFrame(Empilhadeiras, columns=['Paletrans','STILL','Ameise'])
print(Modelos)
Custos={'Impostos':[]}
print()
print()
'VALOR DO MAQUINÁRIO'
num_maquinário = float(input("Digite o valor do maquinário: "))
str(float(num_maquinário))
print('R$'+str(float(num_maquinário)))
print()
'VALOR DOS IMPOSTOS'
num_txs = float(input("Digite a alíquota (sem %): "))
print(str(float(num_txs)) + '%')
txs=num_maquinário*(num_txs/100)
str(txs)
print('R$'+ str(txs))
print()
'DEPRECIAÇÃO DO MAQUINÁRIO'
num_depre = float(input("Digite o percentual de depreciação por ano (sem %): "))
print(str(float(num_depre)) + '%')
depre=num_maquinário*(num_depre/100)
str(depre)
print('R$'+ str(depre))
print()
'VALOR DO FRETE'
num_frete = float(input("Digite o valor do frete: "))
str(float(num_frete))
print('Frete trajeto único: R$'+ str(float(num_frete)))
num_frete*2
str(num_frete*2)
print('Frete ida e volta: R$' + str(num_frete*2))
print()
'DURAÇÃO DO CONTRATO'
num_dur = float(input("Digite o tempo de duração do contrato em meses( de 12 a 60): "))
str(float(num_dur))
print(str(float(num_dur))+' meses')
print()
'CUSTO COM SUBSTITUIÇÃO DE PEÇAS'
num_pec = float(input("Digite o custo médio para substituição de peças por mês: "))
str(float(num_pec))
print('R$'+str(float(num_pec)))
num_peças= num_pec*num_dur
print('Custo total com peças ao longo do contrato:R$'+str(num_peças))
print()
'NÚMERO DE VISITAS TÉCNICAS'
num_vis= float(input("Digite o número de visitas técnicas mensais planejadas: "))
str(float(num_vis))
print('R$'+str(float(num_vis)))
num_visit = num_vis*num_dur
print('Custo total com visitas ao longo do contrato: R$'+str(num_visit))
print()
'NÚMERO DE HORAS TÉCNICAS'
num_htec = float(input("Número médio de horas técnicas por atendimento: "))
if num_htec < 4:
if num_htec < 4:
print("R$100,00")
elif 8> num_htec >4:
print("R$200,00")
elif 12> num_htec >8:
print("R$300,00")
else:
print("R$500,00")
else:
print("R$100,00")
m = num_htec*num_vis
def totTec(m):
m = num_htec*num_vis
if m < 4:
if m < 4:
htec = 100
elif 8> m>4:
htec = 200
elif 12> m>8:
htec = 300
elif 16> m>=12:
htec = 500
elif 20> m>16:
htec = 750
elif 24> m>20:
htec = 1200
else:
htec = 1500
else:
htec = 250
return htec
print('Valor Tempo total: R$'+str(totTec(m)))
print()
'CUSTO DAS HORAS DE DESLOCAMENTO'
num_dtemp = float(input("Tempo de deslocamento em horas até o cliente: "))
if num_dtemp < 4:
if num_dtemp < 4:
print("R$100,00")
elif 8> num_dtemp >4:
print("R$200,00")
elif 12> num_dtemp >8:
print("R$300,00")
else:
print("R$400,00")
else:
print("R$100,00")
str(num_dtemp*num_vis)
print('Total de horas:'+str(num_dtemp*num_vis))
a=num_dtemp*num_vis
def totTemp(a):
a=num_dtemp*num_vis
if a < 4:
if a < 4:
temp= 100
elif 8> a>4:
temp= 200
elif 12> a>8:
temp= 300
elif 16> a>12:
temp= 400
elif 20> a>16:
temp= 500
elif 24> a>20:
temp= 600
else:
temp= 400
else:
temp= 100
return temp
print('Valor Tempo total: R$'+str(totTemp(a))+',00')
print()
'CUSTO DA DISTÂNCIA DE DESLOCAMENTO ATÉ O CLIENTE'
num_distância = float(input("Digite a distância até o cliente em KM: "))
if num_distância*2 < 100:
if num_distância*2 < 100:
print("R$40,00")
elif 250> num_distância*2 >100:
print("R$100,00")
elif 400> num_distância*2 >250:
print("R$160,00")
elif 550> num_distância*2 >400:
print("R$220,00")
elif 700> num_distância*2 >550:
print("R$500,00")
else:
print("R$750,00")
else:
print("R$50,00")
k = (num_distância*2)*num_vis
def distTot(k):
k = (num_distância*2)*num_vis
if k < 100:
if k < 100:
dist = 40
elif 250> k>100:
dist = 160
elif 400> k>250:
dist = 220
elif 550> k>400:
dist = 280
elif 700> k>550:
dist = 340
elif 1000>= k>850:
dist = 400
else:
dist = 500
else:
dist = 40
return dist
print('Valor Distância total: R$'+str(distTot(k))+',00')
print()
'CUSTO COM PEDÁGIO'
num_pedágio = float(input("Digite o gasto com pedágio: "))
str(float(num_pedágio))
print('Pedágios por visita: R$'+str(float(num_pedágio)))
num_tped = num_pedágio*num_vis
print('Gasto total com pedágio: R$'+str(num_tped))
print()
'CUSTO COM HOSPEDAGEM'
num_hospedagem = float(input("Digite o gasto com hospedagem: "))
str(float(num_hospedagem))
print('Hospedagem por visita: R$'+str(float(num_hospedagem)))
num_thost = num_hospedagem*num_vis
print('Gasto total com hospedagem: R$'+str(num_thost))
print()
'CUSTO COM ALIMENTAÇÃO'
num_alimentação = float(input("Digite o gasto com alimentação: "))
str(float(num_alimentação))
print('Gasto com alimentação por vista: R$'+str(float(num_alimentação)))
num_tal= num_alimentação*num_vis
print('Gasto total com alimentação: R$'+str(num_tal))
print()
'CUSTO TOTAL INICIAL'
cti= num_maquinário + txs + num_frete
print('Custo inicial: R$'+str(cti))
print()
'CUSTO TOTAL ANUAL'
cta= totTec(m) + num_pec + distTot(k) + totTemp(a) + num_tped + num_thost + num_tal
print('Custo anual: R$'+str(cta))
print()
'CUSTO TOTAL'
CustoTotal= num_maquinário + txs + depre + + (num_frete*2) + totTec(m) + num_pec + distTot(k) + totTemp(a) + num_tped + num_thost + num_tal
print('Custo total: R$'+str(CustoTotal))
'VALOR DO ALUGUEL'
num_alg = float(input("Digite o valor da Parcela Aluguel: "))
str(float(num_alg))
print('R$'+str(float(num_alg)))
rend_anual= num_alg*12
print('Receita Anual:R$'+ str(rend_anual))
print()
'TAXA MÍNIMA DE ATRATIVIDADE'
num_tma = float(input("Digite a Taxa Mínima de Atratividade: "))
str(float(num_tma))
print(str(float(num_tma))+'%')
num_TMA=num_tma/100
print()
dep1= num_maquinário - depre
dep2=dep1 - (dep1*num_depre)
dep3=dep2 - (dep2*num_depre)
dep4=dep3 - (dep3*num_depre)
dep5=dep4 - (dep4*num_depre)
ano_X=(rend_anual- cta)
ano_1=(rend_anual- cta + dep1 + num_frete)
ano_2=(rend_anual- cta + dep2 + num_frete)
ano_3=(rend_anual- cta + dep3 + num_frete)
ano_4=(rend_anual- cta + dep4 + num_frete)
ano_5=(rend_anual- cta + dep5 + num_frete)
n_1=12
n_2=24
n_3=36
n_4=48
n_5=60
Hipotese_1 = np.array([-cti,ano_1])
Hipotese_2 = np.array([-cti,ano_X,ano_2])
Hipotese_3 = np.array([-cti,ano_X,ano_X,ano_3])
Hipotese_4 = np.array([-cti,ano_X,ano_X,ano_X,ano_4])
Hipotese_5 = np.array([-cti,ano_X,ano_X,ano_X,ano_X,ano_5])
VPL_1=np.npv(rate=num_TMA, values=Hipotese_1)
VPL_2=np.npv(rate=num_TMA, values=Hipotese_2)
VPL_3=np.npv(rate=num_TMA, values=Hipotese_3)
VPL_4=np.npv(rate=num_TMA, values=Hipotese_4)
VPL_5=np.npv(rate=num_TMA, values=Hipotese_5)
print(VPL_1)
print(VPL_2)
print(VPL_3)
print(VPL_4)
print(VPL_5)
vpla_1=(VPL_1)*((num_TMA*(1+num_TMA)**n_1)/((1+num_TMA)**(n_1-1)))
vpla_2=(VPL_2)*((num_TMA*(1+num_TMA)**n_2)/((1+num_TMA)**(n_2-1)))
vpla_3=(VPL_3)*((num_TMA*(1+num_TMA)**n_3)/((1+num_TMA)**(n_3-1)))
vpla_4=(VPL_4)*((num_TMA*(1+num_TMA)**n_4)/((1+num_TMA)**(n_4-1)))
vpla_5=(VPL_5)*((num_TMA*(1+num_TMA)**n_5)/((1+num_TMA)**(n_5-1)))
print()
print('vpla_1 (12 meses)')
print(vpla_1)
if vpla_1>0:
print(verde+'Viável')
else:
print(vermelho+'Inviável')
print(preto+'vpla_2 (24 meses)')
print(vpla_2)
if vpla_2>0:
print(verde+'Viável')
else:
print(vermelho+'Inviável')
print(preto+'vpla_3 (36 meses)')
print(vpla_3)
if vpla_3>0:
print(verde+'Viável')
else:
print(vermelho+'Inviável')
print(preto+'vpla_4 (48 meses)')
print(vpla_4)
if vpla_4>0:
print(verde+'Viável')
else:
print(vermelho+'Inviável')
print(preto+'vpla_5 (60 meses)')
print(vpla_5)
if vpla_5>0:
print(verde+'Viável')
else:
print(vermelho+'Inviável')
How I tried to convert it from cx:
from cx_Freeze import setup, Executable
setup(name='VPLA',
version='0.1',
description='Análise de viabilidade para aluguel de empilhadeiras
elétricas',
executables= [Executable("VPLA.py")])
Then went to the Anaconda CMD and typed:
python setup.py build
I currently host the English Amiga Board (EAB) FTP, a FTP server filled with the classic Amiga computer goodies. It is open to everyone but users can also register their own account. I got help in creating a python script that checks that the username being registered at the FTP is a valid account on the EAB forums and that it has at least 50 posts.
However, I've now updated the server (fedora server) and the Python version was updated to 3.7.6. The script have now stopped working and I'm unable to reach the original author.
# python ./eab_post_count.py -u Turran
Traceback (most recent call last):
File "./eab_post_count.py", line 3, in <module>
import sys, re, urllib2
ModuleNotFoundError: No module named 'urllib2'
This script should return "0" if the user exists and have 50 posts.
While I script in some languages, python is not one of them so I would be grateful for any help to modify it to not use urllib2, which I understand is no longer valid for Python 3.
The script:
#!/usr/bin/env python
import sys, re, urllib2
titlecmd = "eab_post_count.py"
version = "1.15"
ignorecase = 0
lastpost = 0
userfound = False
if len(sys.argv) == 1: sys.argv[1:] = ["-h"]
def parseurl(url):
if not url:
print("Empty URL!")
sys.exit(3)
headers = { 'User-Agent' : 'Mozilla/5.0' }
request = urllib2.Request(url, None, headers)
try:
response = urllib2.urlopen(request)
except Exception:
print('URL open failed, EAB down?')
sys.exit(2)
content = response.read()
return content
def pagesearch(content, trigger, start, end):
sane = 0
needlestack = []
while sane == 0:
curpos = content.find(trigger)
if curpos >= 0:
testlen = len(content)
content = content[curpos:testlen]
curpos = content.find('"')
testlen = len(content)
content = content[curpos+1:testlen]
curpos = content.find(end)
needle = content[0:curpos]
result = content[len(start):curpos]
if needle.startswith(start):
needlestack.append(result)
else:
sane = 1
return needlestack
def unescape(s):
s = s.replace("<", "<")
s = s.replace(">", ">")
# this has to be last:
s = s.replace("&", "&")
return s
for idx, arg in enumerate(sys.argv):
if arg == '-h':
print(titlecmd + ' v' + version +' by modrobert in 2017')
print('Function: Returns the number of posts for a given EAB forum user.')
print('Syntax : ' + titlecmd + ' -u <username> [-i] [-l YYYY-MM-DD]')
print('Options : -h this help text.')
print(' : -i ignore case sensivity in user name.')
print(' -l last post after YYYY-MM-DD required.')
print(' -u followed by user name.')
print('Result : 0 = user found, 1 = user not found, 2 = EAB down, 3 = other fail.')
sys.exit(3)
if arg == '-u':
try:
username = sys.argv[idx+1]
except IndexError:
print('Missing username.')
sys.exit(3)
usernameurl = re.sub('[ ]', '%20', username)
if arg == '-i':
ignorecase = 1
if arg == '-l':
lastpost = 1
try:
lpdate = sys.argv[idx+1]
except IndexError:
print('Missing date.')
sys.exit(3)
try:
username
except NameError:
print('Username -u option required.')
sys.exit(3)
if lastpost:
eaburl = "http://eab.abime.net/memberlist.php?do=getall&pp=100&lastpostafter=" + lpdate + "&ausername=" + usernameurl
else:
eaburl = "http://eab.abime.net/memberlist.php?do=getall&pp=100&ausername=" + usernameurl
eabcontent = parseurl(eaburl)
countlist = pagesearch(eabcontent, 'td class', 'alt2">', '</td>')
userlist = pagesearch(eabcontent, 'member.php?', '>', '</a>')
for idx, item in enumerate(userlist):
# lets strip those fancy moderators and admins
userstr = re.sub('<[^<]+?>', '', item)
if ignorecase:
if unescape(str.lower(userstr)) == str.lower(username):
userfound = True;
break
else:
if unescape(str(userstr)) == username:
userfound = True;
break
if userfound == False:
print("User not found: " + username)
sys.exit(1)
usercount = idx
for idx, item in enumerate(countlist):
# hairy stuff below ;)
if idx < (3 * usercount):
continue
stripitem = re.sub('[,]', '', item)
try:
print(int(stripitem))
sys.exit(0)
except Exception:
continue
Thanks in advance!
Can some help me. I heave this code:
#Replace Incident Discription
def replace(line):
#Vul hier in waar je op zoekt, waar je het naar verandert wilt hebben, en hoever daarna de tekst moet beginnen die uit de FLEX gehaald word.
rename01 = "AUT.BR","Automatische brandmelding. ",71
rename02 = "BR GEBOUW","Brand gebouw. ",74
rename03 = "BR INDUSTRIE","Brand industrie. ",77
rename04 = "BR CONTROLE","Brand controle. ",76
rename05 = "BR BUITEN","Brand buiten. ",74
rename06 = "BR WEGVERVOER","Brand wegvervoerder. ",78
rename07 = "BR WONING","Brand woning. ",74
rename08 = "BR SPOORVERVOER","Brand spoorvervoerder. ",80
rename09 = "ONG WATER","Ongeval water. ",74
rename10 = "ONG LUCHTVAART","Ongeval luchtvaart. ",79
rename11 = "ONG SPOOR","Ongeval spoor. ",74
rename12 = "ONG WEG","Ongeval wegvervoerder. ",72
# Zoek de term op die gebruikt word in de melding. Vervang deze term en plak vanaf een bepaalde offset de melding tekst er achter.
if rename01[0].lower() in line.lower():
return rename01[1] + line[rename01[2]:]
elif rename02[0].lower() in line.lower():
return rename02[1] + line[rename02[2]:],
elif rename03[0].lower() in line.lower():
return rename03[1] + line[rename03[2]:]
elif rename04[0].lower() in line.lower():
return rename04[1] + line[rename04[2]:]
elif rename05[0].lower() in line.lower():
return rename05[1] + line[rename05[2]:]
elif rename06[0].lower() in line.lower():
return rename06[1] + line[rename06[2]:]
elif rename07[0].lower() in line.lower():
return rename07[1] + line[rename07[2]:]
elif rename08[0].lower() in line.lower():
return rename08[1]+ line[rename08[2]:]
elif rename09[0].lower() in line.lower():
return rename09[1] + line[rename09[2]:]
elif rename10[0].lower() in line.lower():
return rename10[1] + line[rename10[2]:]
elif rename11[0].lower() in line.lower():
return rename11[1] + line[rename11[2]:]
elif rename12[0].lower() in line.lower():
return rename12[1] + line[rename12[2]:]
elif rename13[0].lower() in line.lower():
return rename13[1] + line[rename13[2]:]
else:
return(line[63:])
I use this def to find a special text in a string that looks like:
"FLEX: 2017-07-10 07:45:34 1600/2/A 11.059 [001201972] ALN P 1 BR WONING Warwickstraat Steenbergen NB 201634 (inci-02)"
I search for "BR WONING" and want to change this is Brand woning. it wil return the text Brand woning. and then the rest of the sting that starts with flex with a different offset.
Wenn i test this def all seems to be good. But wenn a call this function an it is used in a other python project I get the fault: TypeError: can only concatenate tuple (not “str”) to tuple Error
second Python project:
print("Uitruk STB " + curtime()+replace(line)+groupid+' '),
I m looking for a easy fix so I can keep the code and only change small things.
Also ways to do it better is nice but first I would like to know what is going wrong.
Thank y
I'm trying to develop some kind of terminal user interface in python3
with threading and ncurse and some weird characters appear.
Based on the answer in this post:
Threading with Python Curses giving me weird characters?
which is exactly my problem, i tried to implement locking the maj() function (and also tested with rlock) in my code .
But it seams the lock does not block other thread .
Is my lock misplaced ?? or am i hitting a technical limit ?
here after is an example my code :
import threading
from time import sleep
import curses
import logging
from curses.textpad import Textbox, rectangle
from datetime import datetime
class GenericTUI(threading.Thread):
def __init__(self,textmode=False, messageBoxSize=10, logger=logging.getLogger()):
threading.Thread.__init__(self)
self.keyPressedList = list()
self.alive = True
self.myStdscr = None
self.title = ""
self.messageList = list()
self.messageBoxSize = messageBoxSize
self.subTitle = ""
self.priceInfo = ""
self.progInfo = ""
self.textMode = textmode
self.logger = logger
self.lock = threading.Lock()
def run(self):
if self.textMode :
with open('/tmp/genericTUI.command','w+') as f:
# command file in text mode
pass
while self.alive :
print("Program :"+ self.title)
print("sub"+self.subTitle)
print("Prices : "+self.priceInfo)
print("ProgInfos :"+self.progInfo)
for m in self.messageList :
print(m)
with open('/tmp/genericTUI.command','r+') as f:
c = f.read(1)
if c:
self.keyPressedList.append(c)
f.truncate(0)
sleep(5)
else :
curses.wrapper(self.main)
def maj(self):
'''
mise a jour de l ecran
au sujet du thread lock :
https://stackoverflow.com/questions/46773577/threading-with-python-curses-giving-me-weird-characters
'''
# determine la taille de l ecran
max_y, max_x = self.myStdscr.getmaxyx()
# reecriture
with self.lock :
try :
self.myStdscr.clear()
for x in range(max_x):
self.myStdscr.addch(0,x,curses.ACS_HLINE)
self.myStdscr.addstr(1, 2, "Program :"+ self.title, curses.color_pair(1) )
self.myStdscr.addstr(2, 2, self.subTitle)
for x in range(max_x):
self.myStdscr.addch(3,x,curses.ACS_HLINE)
self.myStdscr.addstr(4, 2, "Prices : "+self.priceInfo, curses.color_pair(2))
for x in range(max_x):
self.myStdscr.addch(5,x,curses.ACS_HLINE)
self.myStdscr.addstr(6, 2, "ProgInfos :"+self.progInfo, curses.color_pair(5))
for x in range(max_x):
self.myStdscr.addch(7,x,curses.ACS_HLINE)
indent =0
for m in self.messageList :
self.myStdscr.addstr(8+indent, 3,m)
indent+=1
for y in range(max_y):
self.myStdscr.addch(y,0,curses.ACS_VLINE)
self.myStdscr.refresh()
except Exception as e:
self.logger.error(repr(e))
self.myStdscr.clear()
def main(self,stdscr):
# color definition
if curses.has_colors():
curses.start_color()
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED)
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_YELLOW)
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_BLUE)
curses.init_pair(5, curses.COLOR_BLACK, curses.COLOR_GREEN)
## NE SURTOUT PAS METTRE keypad(false) GENERE DES CARACTERES AU HASARD .. DANGEREUX
self.myStdscr = stdscr
self.myStdscr.nodelay(True)
self.myStdscr.keypad(True)
self.myStdscr.box()
counter = 0
while self.alive:
try :
key = self.myStdscr.getkey()
self.keyPressedList.append(key)
except Exception as e:
## le nodelay rend l interface reactive mais ,le getkey genere un noinput error
## si pas de touche pressée d ou le pass
pass
sleep(0.1)
counter +=1
def getKeyPressed(self):
if self.keyPressedList :
return self.keyPressedList.pop()
else :
return None
def stop(self):
self.alive = False
def updatePriceInfo(self,priceDict,maj=False):
result = " ".join(str(key) +":"+ str(value)+"|" for key, value in priceDict.items())
self.priceInfo = result
if maj :
self.maj()
def updateTitle(self,title, maj=False):
self.title = str(title)
if maj :
self.maj()
def updateSubTitle(self,subtitleDict, maj=False):
result = " ".join(str(key) +":"+ str(value)+"|" for key, value in subtitleDict.items())
self.subTitle = str(result)
if maj :
self.maj()
def updateProgInfo(self,messDict, maj=False):
result = " ".join(str(key) +":"+ str(value)+"|" for key, value in messDict.items())
self.progInfo = result
if maj :
self.maj()
def addMessage(self,mess, maj=False):
self.messageList.append(repr(mess))
if len(self.messageList) > self.messageBoxSize : self.messageList.pop(0)
if maj :
self.maj()
def getValue(self, mess="Enter Value: (hit Ctrl-G to send)"):
self.myStdscr.addstr(0, 0, mess)
editwin = curses.newwin(1,7, 2,1)
rectangle(self.myStdscr, 1,0, 1+1+1, 1+7+1)
self.myStdscr.refresh()
box = Textbox(editwin)
box.stripspaces = True
# Let the user edit until Ctrl-G is struck.
box.edit()
# Get resulting contents
return(box.gather().strip())
if __name__ == "__main__":
## the main is used for some test when the lib is called directly
testGUI = GenericTUI()
alive = True
testGUI.logger.addHandler(logging.StreamHandler())
testGUI.logger.setLevel(logging.DEBUG)
testGUI.start()
while alive :
testGUI.updateTitle('time %s'%str(datetime.now() ))
k = testGUI.getKeyPressed()
if k is not None:
if k=='Q' :
alive = False
elif k=='M' :
mess = testGUI.getValue()
testGUI.addMessage(mess,maj=True)
else :
testGUI.addMessage('unknown key %s'%k , maj=True)
sleep(0.1)
testGUI.stop()
as you can see there is a with self.lock statement in the maj()function o the class, but
in my log i still get a lot of errors like :
alphanumeric key ? pressed
unknown key press : ?
alphanumeric key [ pressed
unknown key press : [
alphanumeric key pressed
unknown key press :
alphanumeric key ? pressed
where should i place my lock to avoid that ??
I answer my own question, but I think it will be hepfull for others :
The trick is in the ncurses wrapper which have is own thread . So If i want the lock to work I have to put it in the main loop .
Below is the code modified :
import threading
from time import sleep
import curses
import logging
from curses.textpad import Textbox, rectangle
from datetime import datetime
import re
class GenericTUI(threading.Thread):
def __init__(self,textmode=False, messageBoxSize=10, logger=logging.getLogger()):
threading.Thread.__init__(self)
self.keyPressedList = list()
self.alive = True
self.myStdscr = None
self.title = ""
self.messageList = list()
self.messageBoxSize = messageBoxSize
self.subTitle = ""
self.priceInfo = ""
self.progInfo = ""
self.textMode = textmode
self.logger = logger
self.lock = threading.Lock()
self.refreshFlag = True
def run(self):
if self.textMode :
with open('/tmp/genericTUI.command','w+') as f:
# command file in text mode
pass
while self.alive :
print("Program :"+ self.title)
print("sub"+self.subTitle)
print("Prices : "+self.priceInfo)
print("ProgInfos :"+self.progInfo)
for m in self.messageList :
print(m)
with open('/tmp/genericTUI.command','r+') as f:
c = f.read(1)
if c:
self.keyPressedList.append(c)
f.truncate(0)
sleep(5)
else :
curses.wrapper(self.main)
def main(self,stdscr):
# color definition
if curses.has_colors():
curses.start_color()
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED)
curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_YELLOW)
curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_BLUE)
curses.init_pair(5, curses.COLOR_BLACK, curses.COLOR_GREEN)
## NE SURTOUT PAS METTRE keypad(false) GENERE DES CARACTERES AU HASARD .. DANGEREUX
self.myStdscr = stdscr
self.myStdscr.nodelay(True)
self.myStdscr.keypad(True)
self.myStdscr.box()
counter = 0
while self.alive:
try :
key = self.myStdscr.getkey()
#workaround to avoid multi thread escape character
if re.match('[A-Z_\+\-\*/]', key) :
self.keyPressedList.append(key)
except Exception as e:
## le nodelay rend l interface reactive mais ,le getkey genere un noinput error
## si pas de touche pressée d ou le pass
pass
'''
screen update in the mail loop
to be able to thread lock :
https://stackoverflow.com/questions/46773577/threading-with-python-curses-giving-me-weird-characters
'''
# determine la taille de l ecran
max_y, max_x = self.myStdscr.getmaxyx()
# reecriture
if self.refreshFlag:
try :
with self.lock :
self.myStdscr.clear()
for x in range(max_x):
self.myStdscr.addch(0,x,curses.ACS_HLINE)
self.myStdscr.addstr(1, 2, "Program :"+ self.title, curses.color_pair(1) )
self.myStdscr.addstr(2, 2, self.subTitle)
for x in range(max_x):
self.myStdscr.addch(3,x,curses.ACS_HLINE)
self.myStdscr.addstr(4, 2, "Prices : "+self.priceInfo, curses.color_pair(2))
for x in range(max_x):
self.myStdscr.addch(5,x,curses.ACS_HLINE)
self.myStdscr.addstr(6, 2, "ProgInfos :"+self.progInfo, curses.color_pair(5))
for x in range(max_x):
self.myStdscr.addch(7,x,curses.ACS_HLINE)
indent =0
for m in self.messageList :
self.myStdscr.addstr(8+indent, 3,m)
indent+=1
for y in range(max_y):
self.myStdscr.addch(y,0,curses.ACS_VLINE)
self.myStdscr.refresh()
except Exception as e:
self.logger.error(repr(e))
self.myStdscr.clear()
finally:
self.refreshFlag = False
sleep(0.1)
counter +=1
def getKeyPressed(self):
if self.keyPressedList :
return self.keyPressedList.pop()
else :
return None
def stop(self):
self.alive = False
def updatePriceInfo(self,priceDict,maj=False):
result = " ".join(str(key) +":"+ str(value)+"|" for key, value in priceDict.items())
self.priceInfo = result
self.refreshFlag = maj
def updateTitle(self,title, maj=False):
self.title = str(title)
self.refreshFlag = maj
def updateSubTitle(self,subtitleDict, maj=False):
result = " ".join(str(key) +":"+ str(value)+"|" for key, value in subtitleDict.items())
self.subTitle = str(result)
self.refreshFlag = maj
def updateProgInfo(self,messDict, maj=False):
result = " ".join(str(key) +":"+ str(value)+"|" for key, value in messDict.items())
self.progInfo = result
self.refreshFlag = maj
def addMessage(self,mess, maj=False):
self.messageList.append(repr(mess))
if len(self.messageList) > self.messageBoxSize : self.messageList.pop(0)
self.refreshFlag = maj
def getValue(self, mess="Enter Value: (hit Ctrl-G to send)"):
with self.lock :
self.myStdscr.addstr(0, 0, mess)
editwin = curses.newwin(1,7, 2,1)
rectangle(self.myStdscr, 1,0, 1+1+1, 1+7+1)
box = Textbox(editwin)
box.stripspaces = True
self.myStdscr.refresh()
# Let the user edit until Ctrl-G is struck.
box.edit()
# Get resulting contents
return(box.gather().strip())
if __name__ == "__main__":
## the main is used for some test when the lib is called directly
testGUI = GenericTUI()
alive = True
testGUI.logger.addHandler(logging.StreamHandler())
testGUI.logger.setLevel(logging.DEBUG)
testGUI.start()
while alive :
testGUI.updateTitle('time %s'%str(datetime.now() ))
k = testGUI.getKeyPressed()
if k is not None:
if k=='Q' :
alive = False
elif k=='M' :
mess = testGUI.getValue()
testGUI.addMessage(mess,maj=True)
else :
testGUI.addMessage('unknown key %s'%k , maj=True)
sleep(0.1)
testGUI.stop()
```
you may also notice there is another lock in the getvalue function to avoid the main thread to erase the textbox .
Hope this help others.