How to find uid of existing python email object - python

I have been reading through this document. Most of the document is based on finding an email's uid. From the article:
"The way this works is pretty simple: use the uid function, and pass in the string of the command in as the first argument. The rest behaves exactly the same.
result, data = mail.uid('search', None, "ALL") # search and return uids instead
latest_email_uid = data[0].split()[-1]
result, data = mail.uid('fetch', latest_email_uid, '(RFC822)')
raw_email = data[0][1]
I'm working with a django app called django-mailbox (http://django-mailbox.readthedocs.org/en/latest/index.html) the purpose of which is to consume emails.
The app creates a "Message" model that looks like:
u'django_mailbox.message': {
'Meta': {'object_name': 'Message'},
'body': ('django.db.models.fields.TextField', [], {}),
'encoded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'from_header': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': u"orm['django_mailbox.Message']"}),
'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': u"orm['django_mailbox.Mailbox']"}),
'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'read': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'to_header': ('django.db.models.fields.TextField', [], {})
using the python "email" library I can select a record from a django queryset and turn it into an email object:
qs = Message.objects.filter("my criteria")
first = qs[0]
one = first.get_email_object() // one is an email object
Does the existing data in the db have a uid, and if so how can I grab it.

The strict answer to your question is "no". The document you quote is about looping through an IMAP folder (in this case, a Gmail account), which will certainly get a unique ID (uid) from the server which tracks the unique message ID for each Email message.
Because you are constructing a mail message object using Django, you won't have such a UID. The "ID" field you do get from django.db.models.fields.AutoField is the sequential auto-increment ID that the Gmail/IMAP web page you quote says is "unacceptable".
You may want to look at the "uuid" library (http://docs.python.org/2/library/uuid.html) to generate unique ID values for your messages, but unless you also store those in your database, you'll be re-generating them over and over.
If you care to share more exact information about what you're trying to build (a web-based Email reader, perhaps?) then we as a community might have some better ideas for you.

you will get the uid of your mail in response
email_user = 'your gmail'
email_pass = 'your app password'
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login(email_user, email_pass)
mail.select('inbox')
status, response = mail.uid('search', None, r'(X-GM-RAW "subject:\"your latest mail subject\"")')
response = response[0].decode('utf-8').split()
response.reverse()
response = response[:min(10, len(response))]
print (response)

Related

How to take from key value and take from this value another value

How can i get needed value, because i send post request to other site and cant edit answer from site.
I have this dict from responded content:
{'username': 'DeadFinder', 'subscriptions': [{'subscription': 'default', 'expiry': '1635683460'}], 'ip': 'not at this life'}
How you can see in this dict there is a key subscriptions, i'm need value expiry(this is timestamp) but how can i get this value if when i'm trying to call this value i'm not see any results (code not gives needed value), maybe any variants how to get this value? I'm not finded anything like this.
Maybe my small part of code can smally help you but i doubt.
data1 = {f"hwid":"", "type":"login", "username": {username}, "pass": {password},
"sessionid":f"{response_cut2}", "name":"test_app", "ownerid":"5OLbm5S3fS"}
url1 = "nope"
response1 = requests.post(url1, data1)
data = response1.json()
#get = data.get('expiry')
file_write = open("test.txt", "w")
file_write.write(str(data))
file_write.close()
for key in data.keys():
if key == 'info':
print (data[key])
Are you trying to achieve this as result ?
data = {'username': 'DeadFinder', 'subscriptions': [{'subscription': 'default', 'expiry': '1635683460'}], 'ip': 'not at this life'}
print(data['subscriptions'][0]['expiry'])
# first get 'subscriptions' which returns an array,
# so use [0] to get this dict {'subscription': 'default', 'expiry': '1635683460'}
# then get 'expiry'
EDIT : In case subscriptions has multiple values then use for loop
subscriptions = data['subscriptions']
for subscription in subscriptions:
print(subscription['expiry'])
Output
1635683460

Parse Nested Url Encoded Data from POST Request

I am currently creating a callback URL in Django for a webhook in Mailchimp where Mailchimp will send a POST request with urlencoded data in the form of application/x-www-form-urlencoded.
The issue I have run into is that the data returned contains nested data. Some of the data in this urlencoded string looks like its defining nested JSON, which I believe is non-standard (I could be mistaken, though).
For example, one POST request from Mailchimp, which is sent when a user changes their name, would look like:
type=profile&fired_at=2021-05-25+18%3A03%3A23&data%5Bid%5D=abcd1234&data%5Bemail%5D=test%40domain.com&data%5Bemail_type%5D=html&data%5Bip_opt%5D=0.0.0.0&data%5Bweb_id%5D=1234&data%5Bmerges%5D%5BEMAIL%5D=test%40domain.com&data%5Bmerges%5D%5BFNAME%5D=first_name&data%5Bmerges%5D%5BLNAME%5D=last_name&data%5Blist_id%5D=5678
Using Django's request.POST, the data is decoded into:
{
'type': 'profile',
'fired_at': '2021-05-25 18:03:23',
'data[id]': 'abcd1234',
'data[email]': 'test#domain.com',
'data[email_type]': 'html',
'data[ip_opt]': '0.0.0.0',
'data[web_id]': '1234',
'data[merges][EMAIL]': 'test#domain.com',
'data[merges][FNAME]': 'first_name',
'data[merges][LNAME]': 'last_name',
'data[list_id]': '5678'
}
This looks really ugly in practice, since to access the first name of the user from request.POST we would have to do
request.POST.get("data['merges']['FNAME']", None)
The data is obviously intended to look like
{
'type': 'profile',
'fired_at': '2021-05-25 18:03:23',
'data': {
'id': 'abcd1234',
'email': 'test#domain.com',
'email_type': 'html',
'ip_opt': '0.0.0.0',
'web_id': '1234',
'merges':{
'email': 'test#domain.com',
'fname': 'first_name',
'lname': 'last_name',
},
'list_id': '5678'
},
}
and be accessed like
data = request.POST.get('data', None)
first_name = data['merges']['FNAME']
I have looked for a Django/Python specific way to decode this nested URL-encoded data into more appropriate formats to work with it in Python, but have been unable to find anything. Python's urllib library provides methods such as urllib.parse.parse_qs() to decode urlencoded strings, but these methods do not handle this nested type data.
Is there a way to properly decode this nested urlencoded data using Django/Python?
There is no standard library nor Django utility function for this.
We can implement convert_form_dict_to_json_dict as such:
Initialise json_dict to an empty dict {}.
For each form_key, using the example 'data[merges][EMAIL]',
Use regex to obtain nested_keys, i.e. ('data', 'merges', 'EMAIL').
Determine last_nesting_level, i.e. 2 from nesting levels (0, 1, 2).
Initialise current_dict to json_dict.
For each nesting_level, current_key, i.e. 0, 'data', 1, 'merges', 2, 'EMAIL',
If it is before last_nesting_level, get next current_dict using current_key.
Else, set current_dict entry for current_key to value.
Return json_dict.
import re
def convert_form_dict_to_json_dict(form_dict):
json_dict = {}
for form_key, value in form_dict.items():
nested_keys = (re.match(r'\w+', form_key).group(0), *re.findall(r'\[(\w+)]', form_key))
last_nesting_level = len(nested_keys) - 1
current_dict = json_dict
for nesting_level, current_key in enumerate(nested_keys):
if nesting_level < last_nesting_level:
current_dict = current_dict.setdefault(current_key, {})
else:
current_dict[current_key] = value
return json_dict
Usage:
POST_dict = {
'type': 'profile',
'fired_at': '2021-05-25 18:03:23',
'data[id]': 'abcd1234',
'data[email]': 'test#domain.com',
'data[email_type]': 'html',
'data[ip_opt]': '0.0.0.0',
'data[web_id]': '1234',
'data[merges][EMAIL]': 'test#domain.com',
'data[merges][FNAME]': 'first_name',
'data[merges][LNAME]': 'last_name',
'data[list_id]': '5678'
}
from pprint import pprint
pprint(convert_form_dict_to_json_dict(POST_dict))

Google AdWords API v201802: fields selector not working with python libraries

I am connecting to Google AdWords via API v201802 and most recent Python3 googleads module. The connection works fine and I can retrieve data for Campaigns or Ad Groups but the fields selector seems not to work. I'd like to request only a few fields, but I receive all available fields. Am I overlooking something?
from googleads import adwords
adwords_client = adwords.AdWordsClient.LoadFromStorage()
ad_group_service = adwords_client.GetService('AdGroupService', version='v201802')
selector = {
'fields': ['Id', 'Name', 'Status', 'CampaignId'],
'paging': {
'startIndex': '0',
'numberResults': '500'
}
}
page = ad_group_service.get(selector)
print(page)
Result:
{
'totalNumEntries': 138,
'Page.Type': 'AdGroupPage',
'entries': [
{
'id': 44831117552,
'campaignId': 888843682,
'campaignName': None,
'name': '001_0001_BMM_xxx',
'status': 'ENABLED',
'settings': [],
'labels': [],
'forwardCompatibilityMap': [],
'biddingStrategyConfiguration': None,
'contentBidCriterionTypeGroup': None,
'baseCampaignId': None,
'baseAdGroupId': None,
'trackingUrlTemplate': None,
'finalUrlSuffix': None,
'urlCustomParameters': None,
'adGroupType': None,
'adGroupAdRotationMode': None
},
...
] }
Of course I can filter out the unneeded fields when processing the response, but I wonder why the fields selector is not working...
I just found an answer to this in adwords-api google groups:
Hi Kevin,
The API will always include the fields your are requesting in the
response, but it might also add other fields that will be grouped
together to some of your original fields.
Best,
David Torres - AdWords API Team

Unable to update data in pymongo

I have a JSON POST data that a user is going to send me every time to fetch some data from a third party service.I plan to cache the data based on a scope id so that I don't keep inserting the data each time the user requests for something.Futhermore I am keeping a time stamp for each user request.Below is the POST data that user is going to send me everytime.
{
"scope_id": "user1",
"tool_id": "appdynamics",
"api_id": "get metrics",
"input_params": {"user": "myuser", "pwd": "mypwd", "acc_id": "myaccount", "app_id": "TestApp", "metric-path": "ars",
"time-range-type": "BEFORE_NOW", "duration-in-mins": 10},
"output_filters": {}
}
Below is the code snippet to handle the insertion of data
def post(self):
data = ServiceAPI.parser.parse_args()
print("First data", data)
scope_id = data["scope_id"]
tool_id = data["tool_id"]
api_id = data["api_id"]
input_params = data["input_params"]
output_filter = data["output_filter"]
if all([scope_id, tool_id, api_id]) and all(input_params.values()):
check_id = [j for i in users.find({}) for j in i if j == scope_id]
if check_id and check_id[0] == scope_id:
users.update({scope_id: [tool_id, api_id, input_params]},
{scope_id: [tool_id, api_id, input_params],
"timestamp": datetime.now().strftime('%Y-%m-%d %H:%M:%S')}, upsert=True)
else:
users.insert_one(
{scope_id: [tool_id, api_id, input_params],
"timestamp": datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
Here the update statement works great if the user request is exactly the same as last time but makes a new entry if the user demands a new information for example in the POST request api_id = "get logs" when ideally it should have updated the user's data with the latest one.
For the first time when the user makes a POST request, below is the data that gets stored in my database
[{'user1': ['appdynamics', 'get metrics', {'pwd': 'mypwd', 'metric-path': 'ars', 'user': 'myuser', 'time-range-type': 'BEFORE_NOW', 'acc_id': 'myaccount', 'app_id': 'TestApp', 'duration-in-mins': 10}], 'timestamp': '2018-03-24 21:49:28', '_id': ObjectId('5ab67a901899db6d8a266558')}]
Now I make the same request again, it ensures no new entry is made since its made by the same scope id
However now if the user requests some new information for example
{
"scope_id": "user1",
"tool_id": "appdynamics",
"api_id": "get logs",
"input_params": {"user": "myuser", "pwd": "mypwd", "acc_id": "myaccount", "app_id": "TestApp", "metric-path": "ars",
"time-range-type": "BEFORE_NOW", "duration-in-mins": 10},
"output_filters": {}
}
Notice I have changed "api_id": "get logs", it makes a new entry instead of just modifying the existing data in my database.Here is the data now
[{'user1': ['appdynamics', 'get metrics', {'pwd': 'mypwd', 'metric-path': 'ars', 'user': 'myuser', 'time-range-type': 'BEFORE_NOW', 'acc_id': 'myaccount', 'app_id': 'TestApp', 'duration-in-mins': 10}], 'timestamp': '2018-03-24 21:49:28', '_id': ObjectId('5ab67a901899db6d8a266558')}, {'user1': ['appdynamics', 'get logs', {'pwd': 'mypwd', 'metric-path': 'ars', 'user': 'myuser', 'time-range-type': 'BEFORE_NOW', 'acc_id': 'myaccount', 'app_id': 'TestApp', 'duration-in-mins': 10}], 'timestamp': '2018-03-24 21:55:29', '_id': ObjectId('5ab67bf9089b16e9e77037f4')}]
So here the update seems to fail.What could be going wrong?
Note: This is a flask app and I suggest not to get into the details of the implementation.I just need to update the given data based on the scope id each time a user makes a request irrespective of whether it is the same request or a different one.
You are passing upsert=True to update(). Upsert tells MongoDB to update an existing document if one matching the query is found, insert a new document otherwise. The first parameter to update() is a query filter to find documents to apply the update to. The update query filter where api_id == "get logs" isn't matching any existing document, so a new document is being created.

How to send multiple messages to mandrill

I have around 1000 unique mails with unique content. I want to bulk send them to mandril i.e. I dont want to make individual network calls for every message I am sending. The following document shows the api. But it does not define what I want to.
https://mandrillapp.com/api/docs/messages.python.html
What I want
mandrill_client = mandrill.Mandrill('YOUR_API_KEY')
messages ={ message1, message2 ....}
result = mandrill_client.messages.send(messages=messages, async=True, ip_pool='Main Pool', send_at='example send_at')
I could not find the above. But this is what I want.
Try this
message = {
#other details
'from_email': 'message.from_email#example.com',
'from_name': 'Example Name',
'to': [{'email': 'recipient.email#example.com',
'name': 'Recipient Name',
'type': 'to'},2nd reciepient,....],
}
result = mandrill_client.messages.send(messages=messages, async=True)

Categories

Resources