Editing the Windows Registry with winreg in Python had a strange result - python

New to Python, was trying to figure if it's possible to modify an existing registry value, things turned out quite odd as the script keeps returning that the value was indeed modified, but when I go to Regedit everything is the same.
First I ran this test:
with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as hkey:
with winreg.OpenKey(hkey, r"SOFTWARE\\GUU\\", 0, winreg.KEY_ALL_ACCESS) as guu:
Client = winreg.QueryValueEx(guu, "Client")
print(Client[0])
That resulted in the expected output "qBitTorrent" which was the data within the Client value.
Then I run this code in hopes to modify it:
with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as hkey:
with winreg.OpenKey(hkey, r"SOFTWARE\\GUU\\", 0, winreg.KEY_ALL_ACCESS) as guu:
new_path_value = "Hiiiii"
winreg.SetValue(guu, "Client", winreg.REG_SZ, new_path_value)
if guu:
winreg.CloseKey(guu)
The code ended with no errors. Re-running the previous test now outputs "Hiiiii" as the new data for Client, but on Regedit it still shows up as qBitTorrent, but still whenever I print the "Client" data the output is always "Hiiiii" as if the alteration actually happened succesfully.

Related

Replace mysql.connector-function with reading csv/tsv data

I would like to run a large python script programmed by someone else (https://github.com/PatentsView/PatentsView-Disambiguation to be precise). At numerous times during the execution of this code, python connects to a mysql database in order to read some data. The problem is that I
a) cannot get a mysql installation on the server I use. Being only a guest at the institution whose computers I use, I cannot really influence IT to change this
b) would like to alter the code as little as possible, since I have very little python experience
The original code uses a function granted_table() that returns a mysql.connector.connect(...), where host, user, password etc. are given in the dots. My idea is to switch out this function with one that reads in TSV files instead, which I have all stored on my machine. This way, I do not have to go over the long script and fiddle around with it (I have almost no experience with python and might mess something up without realizing it).
I have tried a few things already and it almost works, but not quite. The reproducible example follows:
First, there is the original function that accesses mysql, which has to go
def granted_table(config):
if config['DISAMBIGUATION']['granted_patent_database'].lower() == 'none':
logging.info('[granted_table] no db given')
return None
else:
logging.info('[granted_table] trying to connect to %s', config['DISAMBIGUATION']['granted_patent_database'])
return mysql.connector.connect(host=config['DATABASE']['host'],
user=config['DATABASE']['username'],
password=config['DATABASE']['password'],
database=config['DISAMBIGUATION']['granted_patent_database'])
Second, the function that tries to call the above function to read in data (I shortened and simplified it but kept the structure as I understand it. This version of the function actually only prints whatever data it receives): I do not want to change this if at all possible
def build_granted(config):
cnx = granted_table(config)
cursor = cnx.cursor()
query = "SELECT uuid, patent_id, assignee_id, rawlocation_id, type, name_first, name_last, organization, sequence FROM rawassignee"
cursor.execute(query)
for rec in cursor:
print(rec)
Third, there is my attempt at a new function granted_table(config) which will behave like the old one but not access mysql
def granted_table(config):
return(placeholder())
class placeholder:
def cursor(self):
return conn_to_data()
class conn_to_data:
def execute(self,query): # class method
#define folder etc
print(query)
filename = "foo.tsv"
path ="/share/bar/"
file=open((path+filename))
print(file.read(100))
return file
Now, if I execute all of the above and then run
config="test"
build_granted(config)
the code breaks with
"Type Error: conn_to_data object is not iterable",
so it does not access the actual data as intended. However, if I change the line cursor.execute(query) to cursor=cursor.execute(query) it works as intended. I could do that if there is really no better solution, but it seems like there must be. I am a python newb, so maybe there even is a simple function/class that is intended for this and one of you can point it out. You might realize that the code currently always opens the same file, without actually interpreting the query. This is something I will still have to fix later, once it even works at all. It seems to me to be a somewhat messy but conceptually simple string-parsing problem, but if some of you have a smart idea, it would also be a huge help.
Thanks in advance!

ReceivedTime of the mail is not showing in python

I am trying to read my mail and see the received time in outlook 2016 using MAPI.
I am able to see the subject of the mail not able to see the receivedTime of the mail. I know that "Receivedtime" is there to get the received time of the mail, but while the program is executed,
a popup is coming, telling that python has stopped working
I know it is not due to any machine problem rather some problem in my code.
Here is my code.
def arrange(mailbox):
global spam
timeperiod() # stores required date in spam[] list
msgs=mailbox.Items
msgs.Sort("[ReceivedTime]", True)
p=msgs.restrict(" [ReceivedTime] >= '"+spam[2]+"'") #and [ReceivedTime] >= '" +spam[1]+"'
print(len(p))
'''
for m in list1:
if m.Unread:
m.Unread=False
'''
return p
#Calling it
ctm1=arrange(ctm)
print(len(ctm1)) #Working fine
for message in ctm1:
print (message.subject) #Also works good
print (message.receivedTime) # Here is the problem, it's not showing
]1
i have tried Senton property as well, but it's not working . So any guesses why the senton or receivedTime properties are not working???
updated code :
def printlist(box1) :
print(len(box1))
for message in box1:
if message.Class==43 :
# print('true')
print (message)
#.senderEmailAddress) #working
#print(message.SentOn.strftime("%d-%m-%y")) #not working
#print(message.body)
#print(message.UnRead)
#print (message.receivedTime) #not working
#print('-----------')
I was also having trouble with the .ReceivedTime breaking the program when I compile the .py script to an .exe using auto-py-to-exe.
Here's where the error occurs underneath this try: statement
try:
received_year = str(email.ReceivedTime)[0:4]
received_month = str(email.ReceivedTime)[5:7]
received_day = str(email.ReceivedTime)[8:10]
This works PERFECTLY well inside of my IDE (PyCharm), but once I've compiled it to .exe, it breaks here.
I've updated pywin32 to the most up-to-date version (228) and also tried using 224 to see if it was a version issue (it wasn't).
BUT!! Going through this, I FOUND THE BUG! When you compile to .exe with auto-py-to-exe, it does not include the package "win32timezone" which the .ReceivedTime portion needs to run correctly. So you need to import this package for it to work.
All you have to do to fix this is include this at the top of your .py script before compiling to .exe:
import win32timezone
Let me know if this works for anyone else facing this issue!
Most likely you run into an item other than MailItem - you can also have ReportItem and MeetingItem objects in your Inbox; none of them expose the ReceivedTime property.
Check that message.Class property == 43 (olMail) before accessing any other MailItem specific properties.
Please try the below:
print([x.ReceivedTime for x in messages])

win32com.client.Dispatch works, win32com.client.GetActiveObject doesnt

Im using python 2.7.9, windows 7...
The overall goal: Have another application access our custom com server (already running at this point) and send it a message to be displayed. Obviously, there needs to be a single server, multiple clients.
Im trying to use some custom code as a com server. The class was created as:
class StatusServerClass:
_public_methods_ = ...
_reg_progid_ = "CseStatusServerLib.CseStatusServer"
_reg_verprogid_ = "CseStatusServerLib.CseStatusServer"
_reg_progid_ = "CseStatusServerLib.CseStatusServer"
_reg_clsid_ = "{<GUID here>}"
_reg_desc_ = 'CSE Status Server'
_typelib_guid_ = "{<typelib GUID here>}"
_typelib_version_ = 1, 0 # Version 1.0
_reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
_reg_threading_ = "Apartment" # Not used?
def __init__.....
and registered using:
win32com.server.register.UseCommandLine(StatusServerClass)
I can see it in regedit and as far as i know, it looks ok.
The GUID is right, name is right.
Now when i go to use it, this works just fine:
self.StatusClient = Dispatch('CseStatusServerLib.CseStatusServer')
but when i want to attach to a running instance from another exe (or even another python window for debug) using:
win32com.client.GetActiveObject("CseStatusServerLib.CseStatusServer")
it just gives me:
dispatch = pythoncom.GetActiveObject(resultCLSID)
com_error: (-2147221021, 'Operation unavailable', None, None)
Tells me that its not registered?
Ive tried using the GUID, Ive tried using pythoncom.GetObject with both the ID and the GUID... no luck.
Ive tried comtypes package and get the same thing.
Any ideas on what im doing wrong? Why does Dispatch find it by name, but GetActiveObject gets mad?
Seems that Dispatch working by name would suggest that the registering worked?
What else can i verify in the regedit?
thanks!!!
UPDATED 6/6/2016
In case you haven't realized yet, I know very little about this. But I have read that for win32com.client.GetActiveObject() to work, the server needs to be in the "running object table"... and its not.
So, I found some more example code that i used to register the class this way:
import win32com.server.util
wrapped = win32com.server.util.wrap(StatusServerClass)
flags = pythoncom.REGCLS_MULTIPLEUSE|pythoncom.REGCLS_SUSPENDED
handle = pythoncom.RegisterActiveObject(wrapped,
StatusServerClass._reg_clsid_,flags)
and that does allow the server to show in the running object table, and i can get this:
testSW = win32com.client.GetActiveObject("CseStatusServerLib.CseStatusServer")
to return without error.
So now, I can use Dispatch or GetActiveObject just fine in python, pythonWin, and even interact with the server in Excel/VB <-> python and it appears to share namespsace.
BUT...
I still cant get this IE-based third party app to use the existing server... even with GetActiveObject. Always wants to create new instance and use its own namespace... not good
Is there something with IE or Chrome that would prevent the existing server from being used? Again, it works fine in Excel/VB. The application is supposed to execute "python myscript.py" (which works fine in idle, pythonwin and cmdline), but doesnt execute the com server stuff when called from IE/Chrome App (although other python functions like file writing work just fine).
Also, seeing as how i know very little about this, by all means, suggest a better way of doing this: starting a server in python as a singleton and then accessing it from another application.
thanks!!

pdfquery/PyQuery: example code shows no AttributeError but mine does...why?

I'm following the example code found here. The author has some documentation where he list some steps that used to write the program. When I run the whole program together it runs perfectly but when I follow the steps he's put I get an AttributeError.
Here's my code
pdf = pdfquery.PDFQuery("Aberdeen_2015_1735t.pdf")
pdf.load()
pdf.tree.write("test3.xml", pretty_print=True, encoding="utf-8")
sept = pdf.pq('LTPage[pageid=\'1\'] LTTextLineHorizontal:contains("SEPTEMBER")')
print(sept.text())
x = float(sept.get('x0'))
y = float(sept.get('y0'))
cells = pdf.extract( [
('with_parent','LTPage[pageid=\'1\']'),
('cells', 'LTTextLineHorizontal:in_bbox("%s,%s,%s,%s")' % (x, y, x+600, y+20))
])
Everything runs fine until it gets to "sept.get" where it says that "'PyQuery' object has no attribute 'get'." Does anyone know why the program wouldn't encounter this error when it's run all together but it occurs when a piece of the code is run?
According to the PyQuery API reference, a PyQuery object indeed doesn't have a get member. The code example must be obsolete.
According to https://pypi.python.org/pypi/pdfquery, attributes are retrieved with .attr:
x = float(sept.attr('x0'))
Judging by the history of pyquery's README.rst, get was never documented and only worked due to some side effect (some delegation to a dict, perhaps).

Using libsecret I can't get to the label of an unlocked item

I'm working on a little program that uses libsecret. This program should be able to create a Secret.Service...
from gi.repository import Secret
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
... get a specific Collection from that Service...
# 2 is the index of a custom collection I created, not the default one.
collection = service.get_collections()[2]
... and then list all the Items inside that Collection, this by just printing their labels.
# I'm just printing a single label here for testing, I'd need all of course.
print(collection.get_items()[0].get_label())
An important detail is that the Collecction may initially be locked, and so I need to include code that checks for that possibility, and tries to unlock the Collection.
# The unlock method returns a tuple (number_of_objs_unlocked, [list_of_objs])
collection = service.unlock_sync([collection])[1][0]
This is important because the code I currently have can do all I need when the Collection is initially unlocked. However if the Collection is initially locked, even after I unlock it, I can't get the labels from the Items inside. What I can do is disconnect() the Service, recreate the Service again, get the now unlocked Collection, and this way I am able to read the label on each Item. Another interesting detail is that, after the labels are read once, I no longer required the Service reconnection to access them. This seems quite inelegant, so I started looking for a different solution.
I realized that the Collection inherited from Gio.DBusProxy and this class caches the data from the object it accesses. So I'm assuming that is the problem for me, I'm not updating the cache. This is strange though because the documentation states that Gio.DBusProxy should be able to detect changes on the original object, but that's not happening.
Now I don't know how to update the cache on that class. I've taken a look at some seahorse(another application that uses libsecret) vala code, which I wasn't able to completely decipher, I can't code vala, but that mentioned the Object.emit() method, I'm still not sure how I could use that method to achieve my goal. From the documentation(https://lazka.github.io/pgi-docs/Secret-1/#) I found another promising method, Object.notify(), which seems to be able to send notifications of changes that would enable cache updates, but I also haven't been able to properly use it yet.
I also posted on the gnome-keyring mailing list about this...
https://mail.gnome.org/archives/gnome-keyring-list/2015-November/msg00000.html
... with no answer so far, and found a bugzilla report on gnome.org that mentions this issue...
https://bugzilla.gnome.org/show_bug.cgi?id=747359
... with no solution so far(7 months) either.
So if someone could shine some light on this problem that would be great. Otherwise some inelegant code will unfortunately find it's way into my little program.
Edit-0:
Here is some code to replicate the issue in Python3.
This snippet creates a collection 'test_col', with one item 'test_item', and locks the collection. Note libsecret will prompt you for the password you want for this new collection:
#!/usr/bin/env python3
from gi import require_version
require_version('Secret', '1')
from gi.repository import Secret
# Create schema
args = ['com.idlecore.test.schema']
args += [Secret.SchemaFlags.NONE]
args += [{'service': Secret.SchemaAttributeType.STRING,
'username': Secret.SchemaAttributeType.STRING}]
schema = Secret.Schema.new(*args)
# Create 'test_col' collection
flags = Secret.CollectionCreateFlags.COLLECTION_CREATE_NONE
collection = Secret.Collection.create_sync(None, 'test_col', None, flags, None)
# Create item 'test_item' inside collection 'test_col'
attributes = {'service': 'stackoverflow', 'username': 'xor'}
password = 'password123'
value = Secret.Value(password, len(password), 'text/plain')
flags = Secret.ItemCreateFlags.NONE
Secret.Item.create_sync(collection, schema, attributes,
'test_item', value, flags, None)
# Lock collection
service = collection.get_service()
service.lock_sync([collection])
Then we need to restart the gnome-keyring-daemon, you can just logout and back in or use the command line:
gnome-keyrin-daemon --replace
This will setup your keyring so we can try opening a collection that is initially locked. We can do that with this code snippet. Note that you will be prompted once again for the password you set previously:
#!/usr/bin/env python3
from gi import require_version
require_version('Secret', '1')
from gi.repository import Secret
# Get the service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Find the correct collection
for c in service.get_collections():
if c.get_label() == 'test_col':
collection = c
break
# Unlock the collection and show the item label, note that it's empty.
collection = service.unlock_sync([collection])[1][0]
print('Item Label:', collection.get_items()[0].get_label())
# Do the same thing again, and it works.
# It's necessary to disconnect the service to clear the cache,
# Otherwise we keep getting the same empty label.
service.disconnect()
# Get the service
service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
# Find the correct collection
for c in service.get_collections():
if c.get_label() == 'test_col':
collection = c
break
# No need to unlock again, just show the item label
print('Item Label:', collection.get_items()[0].get_label())
This code attempts to read the item label twice. One the normal way, which fails, you should see an empty string, and then using a workaround, that disconnects the service and reconnects again.
I came across this question while trying to update a script I use to retrieve passwords from my desktop on my laptop, and vice versa.
The clue was in the documentation for Secret.ServiceFlagsā€”there are two:
OPEN_SESSION = 2
establish a session for transfer of secrets while initializing the Secret.Service
LOAD_COLLECTIONS = 4
load collections while initializing the Secret.Service
I think for a Service that both loads collections and allows transfer of secrets (including item labels) from those collections, we need to use both flags.
The following code (similar to your mailing list post, but without a temporary collection set up for debugging) seems to work. It gives me the label of an item:
from gi.repository import Secret
service = Secret.Service.get_sync(Secret.ServiceFlags.OPEN_SESSION |
Secret.ServiceFlags.LOAD_COLLECTIONS)
collections = service.get_collections()
unlocked_collection = service.unlock_sync([collections[0]], None)[1][0]
unlocked_collection.get_items()[0].get_label()
I have been doing this
print(collection.get_locked())
if collection.get_locked():
service.unlock_sync(collection)
Don't know if it is going to work though because I have never hit a case where I have something that is locked. If you have a piece of sample code where I can create a locked instance of a collection then maybe I can help

Categories