How to delete from webapp2 extras appengine auth models Unique? - google-app-engine

I reviewed how to delete from webapp2_extras.appengine.auth.models.Unique
This solution worked with:
Unique.delete_multi( map(lambda s: 'User.auth_id:' + s,user.auth_ids))
Problem is that there is a second record. The following statement has no effect:
Unique.delete_multi( map(lambda s: 'User.email:' + s,user.email))
No error in the log. Nothing happens.
The record I'm trying to delete has the value in field "Key Name" in Unique is "User.email:test#example.com"
When the user is created, the unique_properties is as follows:
unique_properties = ['email']
Thinking it was some kind of lock, I tried logging user out first, then deleting user (saved user.email to a temp var). No dice.

solution was found in using delete_multi differently for auth_ids and email:
for user.email (note in OP the way email was created):
unique_email = ['User.email:%s' % user.email]
Unique.delete_multi(unique_email)
for user.auth_ids:
Unique.delete_multi( map(lambda s: 'User.auth_id:' + s,user.auth_ids))

Related

Discord py, How to remove permissions using role metnion

I want to remove the the role from the users in the server who have the corresponding role by using the role mention.
For example, '%remove_role#TEAM_A' removes 'TEAM_A' from the roles of people who have the role 'TEAM_A'.
I searched hard on Google, but I couldn't find an answer or a way to do it, so I made it myself, but I failed to complete it, so I wrote a question here.
1st. %rmrole team name
2nd. Check if the team name you entered is in 'role_list'.
3rd. Remove the role of the team name entered from users on the server.
this is my code.
#bot.command()
async def rmrole(ctx, team_name):
key = 0
role = get(ctx.guild.roles, name=team_name)
team_list = []
print(role)
# typo check
role_list = ["TEAM_A", "TEAM_B", "TEAM_C", "TEAM_D"]
if role in role_list:
type_error = 1
else:
type_error = 0
# remove_role
empty = True
if type_error == 1:
for member in ctx.guild.members:
if role in member.roles:
await member.remove_roles(role)
empty = False
if empty:
await ctx.send("anyone has this role.")
else:
await ctx.send("check the typos."
async def remove_role(ctx, role: discord.Role)
I was worried that if I write like this, users would get a lot of alarms.
Thus, in the body, I enter the name of the role in text, and I write it in a way that scans the role in the code.
The '#remove_role' part was searched and found.
The code was executed, but the role was not removed.
I wonder where the wrong part is, and I need help to make what I want.
Your mistake is simple:
role_list = ["TEAM_A", "TEAM_B", "TEAM_C", "TEAM_D"]
if role in role_list:
type_error = 1
else:
type_error = 0
This code will always fail and lead to type_error = 0, as role is a discord.role.Role class and not a string. This means comparing the role you got via get and a string representing its name will always fail : and so, that the second part of your code that removes the role is never accessed. It works otherwise.
Instead, you want:
if role.name in role_list:
type_error = 1
else:
type_error = 0
Or better yet, this instead:
if role is None:
return await ctx.send("Role doesn't exist")
...since I don't quite see the point of your code personally: if role = get(ctx.guild.roles, name=team_name) fails (i.e the role doesn't exist), role will be None, and you can easily check for it instead of comparing it against a hardcoded list.

How can I store empty value in GAE LinkProperty?

By default LinkProperty() is empty. But let us say I submit a form that stores site link in the DB field with the property LinkProperty(). This works fine so far.
Next, I want to delete that link stored in the DB by resubmitting the form with empty site link. At this time, I get database error as follows:
"BadValueError: link must not be empty."
Can anyone please help with this? Code below.
###Database
class MyDatabase(db.Model):
site = db.LinkProperty()
###Trying to store form data in the database
mydb_obj = MyDatabase.get_or_insert('abc')
#above line works fine
mydb_obj.site = self.request.get('form_site') #works fine.
#Above form_site is read from form submission. It can be 'www.google.com' or it can be
#empty as in ''
mydb_obj.put() #I GET ERROR WHEN form_site = ''.
#"BadValueError: link must not be empty"
I have not tried to replicate this error. It could be possible that the when the link input is empty, the value requested is None. Perhaps this might work:
mydb_obj.site = self.request.get('form_site')
if mydb_obj.site is None:
mydb_obj.site = '' # value is empty string instead of None.
The following works
mydb_obj.site = self.request.get('form_site')
if not mydb_obj.site:
mydb_obj.site = None
mydb_obj.put()

ndb query by KeyProperty

I'm struggling with a KeyProperty query, and can't see what's wrong.
My model is
class MyList(ndb.Model):
user = ndb.KeyProperty(indexed=True)
status = ndb.BooleanProperty(default=True)
items = ndb.StructuredProperty(MyRef, repeated=True, indexed=False)
I create an instance of MyList with the appropriate data and can run the following properly
cls = MyList
lists = cls.query().fetch()
Returns
[MyList(key=Key('MyList', 12), status=True, items=..., user=Key('User', 11))]
But it fails when I try to filter by user, i.e. finding lists where the user equals a particular entity; even when using the one I've just used for insert, or from the previous query result.
key = lists[0].user
lists = cls.query(cls.user=key).fetch()
Returns
[]
But works fine with status=True as the filter, and I can't see what's missing?
I should add it happens in a unit testing environment with the following v3_stub
self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)
self.testbed.init_datastore_v3_stub(
require_indexes=True,
root_path="%s/../"%(os.path.dirname(__file__)),
consistency_policy=self.policy
)
user=Key('User', 11) is a key to a different class: User. Not MyList
Perhaps you meant:
user = ndb.KeyProperty(kind='User', indexed=True)
Your code looks fine, but I have noticed some data integrity issues when developing locally with NDB. I copied your model and code, and I also got the empty list at first, but then after a few more attempts, the data is there.
Try it a few times?
edit: possibly related?
google app engine ndb: put() and then query(), there is always one less item

why is my key_name value not as i set it?

First off, I'm relatively new to Google App Engine, so I'm probably doing something silly.
I want the username to be set as key in model User
class User(db.Model):
#username is key
password = db.StringProperty(required = True)
type = db.StringProperty(required = True)
approved = db.BooleanProperty(required = True)
To insert i do this
user = User(key_name = self.request.get('username'), password = password, type = type, approved = False)
user.put()
I believe that when you set key_name manually it should be exactly what you set it to be but when i query user modle
users = db.GqlQuery("SELECT * FROM User")
for(user in users):
self.response.write(user.key())
I got the output as agxkZXZ-dmhvc3RlbDNyEQsSBFVzZXIiB2JodXNoYW4M
Please someone help!!
To start with you should read the docs on the Key class https://developers.google.com/appengine/docs/python/datastore/keyclass and how keys a structured - https://developers.google.com/appengine/docs/python/datastore/#Python_Kinds_keys_and_identifiers
Any way to your problem, note that the output of self.response.write(user.key()) is giving you the string agxkZXZ-dmhvc3RlbDNyEQsSBFVzZXIiB2JodXNoYW4M which is correct behaviour.
This is a URL safe form of the key which encodes all artifacts that make up the key.
This means you can round trip
user.key() = db.Key(encoded=str(user.key())
This allows you to use keys as part of URL. Whether that's wise or not is another discussion.
If you want to just show the name you used as the key_name then the docs for the Key class show you that the method name() will return the name.
As in user.key().name() or you could use id_or_name method which does what the name implies.
Perhaps self.request.get('username') is returning Null or None, and that results in the Datastore generating a default entry. According to the Users Service documentation it might need users.get_current_user().nickname() instead. Check by logging the values.
As Tim says you retrieve the name from the key using user.key().name().

GqlQuery Results Only for Session?

My app, Datastore, webapp2, and form-specific "responses" are all working :) but I need the page to load without displaying previous visitor's query results. I need query results only for current form-submitter, after they submit form. Is this a session or headers solution, or can I edit the GqlQuery to accomplish this?
messages = db.GqlQuery("SELECT * "
"FROM Visitor "
"ORDER BY date DESC LIMIT 1") #obviously shows previous form submit
for message in messages:
if message.name == "" or message.mood == "":
self.response.out.write("<div class='textright'>Type name and select.</div>")
self.response.out.write("</body></html>")
elif message.mood == "bad" and message.name != "":
self.response.out.write("<body><html>")
self.response.out.write("<div class='textright'>Stay the course
^ ^ this last section is my "response" that needs to appear only after current visitor submits form.
I would strongly recommend you to go through the Getting Started and especially the templates section, until you will understand how it works.
But you if you just want to see your example in action try this (read more):
class Process(webapp.RequestHandler):
def post(self):
name = self.request.get("name")
mood = self.request.get("mood")
if mood == "bad" and name != "":
self.response.out.write("<html><body>")
self.response.out.write("<h1>Welcome to the Internet!</h1>")
self.response.out.write("<p>My mood is %s and my name is %s</p>" % (mood, name))
self.response.out.write("</body></html>")
else:
self.response.out.write("<html><body>")
self.response.out.write("<h1>Welcome to the Internet anyway!</h1>")
self.response.out.write("</body></html>")
Also never use print in your GAE applications, use the logger instead for debugging and more.
If you want to emit values for debugging purposes, particularly if you want that before an <html> tag is written, try
self.response.out.write("<!-- name: %s -->" % self.request.get("name"))
Otherwise, the browser might get confused.
print from a handler will never to what you expect.
In your snippet, you haven't shown where var7 and var9 come from.
I do realize that post/.put form values to Datastore automatically redirects user to new page
I think you misunderstand. You haven't shown us where your code does a put() or a redirect. A post() handler does not automatically do either.
Which tutorial are you looking at? Perhaps we need to tighten up vague wording.

Resources