How to create an ldif from a python dict - python

i want to write a lot of data to an LDAP-Server (preferably using an ldif), but i also want that every insert/modify/delete in the ldif will be rolled back if there is an error. So basically, i need a function, that creates an ldif from a dict and then get the following behaviour.
Lets assume i have an ldif like this:
dn: uid=user,cn=testing,dc=foobar #Existing and valid entry so it should work
changeType: modify
replace: sn
sn: Alfred
dn: uid=user2,cn=testing,dc=foobar #Non-existent entry so it should fail
changeType: modify #Now because this fails, the first change
replace: sn #should be rolled back...
sn: Carl
So if the second ldif entry fails, i want to rollback the changes that were made previously to only create entries, if the whole ldif is correct.
There seems to be no kind of transactions for ldap which would be exactly what i am looking for. Till now i only found the deprecated ldif parser for python...but since its deprecated i do not want to use it anymore. So if any of you know an alternative please tell me.
Any help would be greatly appreciated

The LDAP client should consider using LDAP transactions as specified in RFC5805.

Related

How to store and get strings with concatenated variables from database without loosing variable value in python

I store in database a string with concatenated variables but when I fetch it, it behaves like string, and the variable values are not reflected.
Stored in database field I have:
"""\
Please visit the following link to grant or revoke your consent:
"""+os.environ.get("PROTOCOL")+"""://"""+os.environ.get("DOMAIN")+"""/consent?id="""+consentHash+""""""
I need to be able to fetch it in python and store it in a variable but have the concatenated variable values reflected:
someVariable = database['field']
But like this the concatenated variable values are not processed and the whole thing behaves like one string.
When I print(someVariable) I am expecting
Please visit the following link to grant or revoke your consent:
https://somedomain/consent?id=123
But instead I get the original stored string as in database field:
"""\
Please visit the following link to grant or revoke your consent:
"""+os.environ.get("PROTOCOL")+"""://"""+os.environ.get("DOMAIN")+"""/consent?id="""+consentHash+""""""
You can call eval on your string to have it, uh, evaluate the string as an expression.
Using eval is considered dangerous, because it can be used to do pretty much anything you could write code for, without knowing just what that code will be ahead of time. This is more of an issue when using it on strings provided from an outside source.

Checking for specific output from Python's DNS Resolver Query

I'm trying to write something that will ask users to input a specific domain (say, Google.com), and if _spf.google.com is in the SPF TXT record for Google.com, I want it to say "Yup". If not, I want it to say "Nope." Right now, the code will ask me for the domain, and it'll look up the SPF record, but I can't get it to say "yup." Why not? I've tried turning it into a string, but even that wouldn't get me what I wanted. What am I doing wrong here?
To add to that, what would you guys recommend is a good jumping off point for figuring out what code I'd need to write to figure out how many DNS lookups an SPF record is ultimately using?
import dns.resolver
question= raw_input("What domain do you want? ")
def PrintandGoogle(question):
answer=dns.resolver.query(question,"TXT")
for data in answer:
print data
if "_spf.google.com" in answer:
print "Yup."
else:
print "Nope."
printAndGoogle(question)
If your if is inside your loop:
if "_spf.google.com" in data.to_text():
If your if is outside your loop:
if any("_spf.google.com" in data.to_text() for data in answer):

using pull_all and push_all with python/mongoengine

I have this object in Mongo:
mystuff = ListField(ReferenceField(Asset, dbref=True))
I have a Python method that is supposed to update the Mongo object, prepending its mystuff Listfield value with a given value. Because Mongoengine doesn't yet have a way to insert an object into a certain point in a list (and has made it a low priority to add this function), I've tried to:
save the contents of the current list to a temporary variable (oldlist)
update the DB entry, emptying the mystuff list using the "pull_all" modifier (which is part of mongoengine)
update the DB entry again, pushing the newly added item to the mystuff list using update(push)
update the DB entry once again, using the "push_all" modifier and the oldlist variable to push the old stuff back onto the mystuff list.
It seems that "pull_all" requires some kind of modifier, but I'll be danged if I can figure out what it wants.
Anybody got any ideas? Of course the ideal situation would be to add an "insert_at" modifier to update(), but that's out of my hands. Life on the edge, etc.
The pull_all takes a list of elements you want to pull out of the list. In you're case I believe this will be oldlist.
However I think you're best bet is probably to retrieve the whole document with get, modify the mystuff field in the client code, and send it back with a save.
As you noted the tools for updating the document in place are limited.

dictionary key-call

im building a test program. its essentially a database of bugs and bug fixes. it may end up being an entire database for all my time working in python.
i want to create an effect of layers by using a dictionary.
here is the code as of april 29 2011:
modules=['pass']
syntax={'PRINT':''' in eclipse anthing which
you "PRINT" needs to be within a set of paranthesis''','StrRet':'anytime you need to use the return action in a string, you must use the triple quotes.'}
findinp= input('''where would you like to go?
Dir:''')
if findinp=='syntax':
print(syntax)
dir2= input('choose a listing')
if dir2=='print'or'PRINT'or'Print':
print('PRINT' in syntax)
now when i use this i get the ENTIRE dictionary, not just the first layer. how would i do something like this? do i need to just list links in the console? or is there a better way to do so?
thanks,
Pre.Shu.
I'm not quite sure what you want, but to print the content of a single key of dictionary you index it:
syntax['PRINT']
Maybe this help a bit:
modules=['pass']
syntax={
'PRINT':''' in eclipse anthing which
you "PRINT" needs to be within a set of paranthesis''',
'STRRET':'anytime you need to use the return action in a string, you must use the triple quotes.'}
choice = input('''where would you like to go?
Dir:''').upper()
if choice in syntax:
print syntax[choice]
else:
print "no data ..."

How do I create a list or set object in a class in Python?

For my project, the role of the Lecturer (defined as a class) is to offer projects to students. Project itself is also a class. I have some global dictionaries, keyed by the unique numeric id's for lecturers and projects that map to objects.
Thus for the "lecturers" dictionary (currently):
lecturer[id] = Lecturer(lec_name, lec_id, max_students)
I'm currently reading in a white-space delimited text file that has been generated from a database. I have no direct access to the database so I haven't much say on how the file is formatted. Here's a fictionalised snippet that shows how the text file is structured. Please pardon the cheesiness.
0001 001 "Miyamoto, S." "Even Newer Super Mario Bros"
0002 001 "Miyamoto, S." "Legend of Zelda: Skies of Hyrule"
0003 002 "Molyneux, P." "Project Milo"
0004 002 "Molyneux, P." "Fable III"
0005 003 "Blow, J." "Ponytail"
The structure of each line is basically proj_id, lec_id, lec_name, proj_name.
Now, I'm currently reading the relevant data into the relevant objects. Thus, proj_id is stored in class Project whereas lec_name is a class Lecturer object, et al. The Lecturer and Project classes are not currently related.
However, as I read in each line from the text file, for that line, I wish to read in the project offered by the lecturer into the Lecturer class; I'm already reading the proj_id into the Project class. I'd like to create an object in Lecturer called offered_proj which should be a set or list of the projects offered by that lecturer. Thus whenever, for a line, I read in a new project under the same lec_id, offered_proj will be updated with that project. If I wanted to get display a list of projects offered by a lecturer I'd ideally just want to use print lecturers[lec_id].offered_proj.
My Python isn't great and I'd appreciate it if someone could show me a way to do that. I'm not sure if it's better as a set or a list, as well.
Update
After the advice from Alex Martelli and Oddthinking I went back and made some changes and tried to print the results.
Here's the code snippet:
for line in csv_file:
proj_id = int(line[0])
lec_id = int(line[1])
lec_name = line[2]
proj_name = line[3]
projects[proj_id] = Project(proj_id, proj_name)
lecturers[lec_id] = Lecturer(lec_id, lec_name)
if lec_id in lecturers.keys():
lecturers[lec_id].offered_proj.add(proj_id)
print lec_id, lecturers[lec_id].offered_proj
The print lecturers[lec_id].offered_proj line prints the following output:
001 set([0001])
001 set([0002])
002 set([0003])
002 set([0004])
003 set([0005])
It basically feels like the set is being over-written or somesuch. So if I try to print for a specific lecturer print lec_id, lecturers[001].offered_proj all I get is the last the proj_id that has been read in.
set is better since you don't care about order and have no duplicate.
You can parse the file easily with the csv module (with a delimiter of ' ').
Once you have the lec_name you must check if that lecturer's already know; for that purpose, keep a dictionary from lec_name to lecturer objects (that's just another reference to the same lecturer object which you also refer to from the lecturer dictionary). On finding a lec_name that's not in that dictionary you know it's a lecturer not previously seen, so make a new lecturer object (and stick it in both dicts) in that case only, with an empty set of offered courses. Finally, just .add the course to the current lecturer's offered_proj. It's really a pretty smooth flow.
Have you tried implementing this flow? If so, what problems have you had? Can you show us the relevant code -- should be a dozen lines or so, at most?
Edit: since the OP has posted code now, I can spot the bug -- it's here:
lecturers[lec_id] = Lecturer(lec_id, lec_name)
if lec_id in lecturers.keys():
lecturers[lec_id].offered_proj.add(proj_id)
this is unconditionally creating a new lecturer object (trampling over the old one in the lecturers dict, if any) so of course the previous set gets tossed away. This is the code you need: first check, and create only if needed! (also, minor bug, don't check in....keys(), that's horribly inefficient - just check for presence in the dict). As follows:
if lec_id in lecturers:
thelec = lecturers[lec_id]
else:
thelec = lecturers[lec_id] = Lecturer(lec_id, lec_name)
thelec.offered_proj.add(proj_id)
You could express this in several different ways, but I hope this is clear enough. Just for completeness, the way I would normally phrase it (to avoid two lookups into the dictionary) is as follows:
thelec = lecturers.get(lec_id)
if thelec is None:
thelec = lecturers[lec_id] = Lecturer(lec_id, lec_name)
thelec.offered_proj.add(proj_id)
Sets are useful when you want to guarantee you only have one instance of each item. They are also faster than a list at calculating whether an item is present in the collection.
Lists are faster at adding items, and also have an ordering.
This sounds like you would like a set. You sound like you are very close already.
in Lecturer.init, add a line:
self.offered_proj = set()
That will make an empty set.
When you read in the project, you can simply add to that set:
lecturer.offered_proj.add(project)
And you can print, just as you suggest (although you may like to pretty it up.)
Thanks for the help Alex and Oddthinking! I think I've figured out what was going on:
I modified the code snippet that I added to the question. Basically, every time it read the line I think it was recreating the lecturer object. Thus I put in another if statement that checks if lec_id already exists in the dictionary. If it does, then it skips the object creation and simply moves onto adding projects to the offered_proj set.
The change I made is:
if not lec_id in lecturers.keys():
projects[proj_id] = Project(proj_id, proj_name)
lecturers[lec_id] = Lecturer(lec_id, lec_name)
lecturers[lec_id].offered_proj.add(proj_id)
I only recently discovered the concept behind if not thanks to my friend Samir.
Now I get the following output:
001 set([0001])
001 set([0001, 0002])
002 set([0003])
002 set([0003, 0004])
003 set([0005])
If I print for a chosen lec_id I get the fully updated set. Glee.

Categories

Resources