Submitting a HIT with external URL throws error - python

I am trying to submit a hit using the example provided in mturk example
Here is my question.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd">
<ExternalURL>https://tictactoe.amazon.com/gamesurvey.cgi?gameid=01523</ExternalURL>
<FrameHeight>750</FrameHeight>
</ExternalQuestion>
and here is my submit_hit.py:
import boto3
from dateutil.parser import *
MTURK_SANDBOX = 'https://mturk-requester-sandbox.us-east-1.amazonaws.com'
mturk = boto3.client('mturk',
aws_access_key_id = "....",
aws_secret_access_key = "....",
region_name='us-east-1',
endpoint_url = MTURK_SANDBOX
)
print "I have $" + mturk.get_account_balance()['AvailableBalance'] + " in my Sandbox account"
question = open(name='question.xml',mode='r').read()
new_hit = mturk.create_hit(
Title = 'Here comes the title',
Description = 'Here comes description'
Keywords = 'game, quick',
Reward = '0.15',
MaxAssignments = 1,
LifetimeInSeconds = 172800,
AssignmentDurationInSeconds = 600,
AutoApprovalDelayInSeconds = 14400,
Question = question,
)
print "A new HIT has been created. You can preview it here:"
print "https://workersandbox.mturk.com/mturk/preview?groupId=" + new_hit['HIT']['HITGroupId']
print "HITID = " + new_hit['HIT']['HITId'] + " (Use to Get Results)"
And here is the error I am receiving:
botocore.exceptions.ClientError: An error occurred (ParameterValidationError) when calling the CreateHIT operation: There was an error parsing the XML question or answer data in your request. Please make sure the data is well-formed and validates against the appropriate schema. Details: cvc-elt.1: Cannot find the declaration of element 'ExternalQuestion'. (1579649552886 s)
I need to use external url(i.e. I can not copy my html file in .xml) since my html content is web-based tool and not a simple questionare.
I am using python 2.7 if that matters.
Any help would be very much appreciated.

Turned out I was using tag <ExternalQuestion>, BUT I was using the http link for <HTMLQuestion>! make sure you're using the right link.
So, instead of this:
<ExternalQuestion
xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2011-11-11/HTMLQuestion.xsd">
it should be this:
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">

Related

How to get the latest cloudwatch log stream URL using Python Lambda?

I'm deploying some lambda functions and at the end, I need to print the complete URL of the latest CloudWatch log stream. So that other users can view the log directly by clicking the URL.
I've tried the below, but I need to print the complete URL.
print("CloudWatch log stream name:", context.log_stream_name)
I believe this can be done by using describe_log_streams along with some tweaks. But I'm helpless where to start.
I tried the below code and its working as expected, please comment for any improvement.
def multiple_replace(text, adict):
rx = re.compile('|'.join(map(re.escape, adict)))
def one_xlat(match):
return adict[match.group(0)]
return rx.sub(one_xlat, text)
def main(event, context):
region = context.invoked_function_arn.split(':')[3]
replace_map = {}
replace_map['/']='$252F'
replace_map['[']='$255B'
replace_map['$']='$2524'
replace_map[']']='$255D'
cw_logs = 'https://' + region + '.console.aws.amazon.com/cloudwatch/home?region=' + region + '#logsV2:log-groups/log-group/' + context.log_group_name.replace('/', '%252F') + '/log-events/' + multiple_replace(context.log_stream_name,replace_map)

How to add .htm to email body using win32com

I need to use win32com.client to make an email where I add a signature with the .htm extension to the mail.HtmlBody. However, each time I do this, I get UnicodeDecodeError.
In other words, how do I correct the UnicodeDecodeError problem and add my string & htm file to the HtmlBody?
self.mail = win32.Dispatch('outlook.application').CreateItem(0)
self.curText = str(self.email.currentText())
self.projectNameT = ' '.join(self.curText.split(' ')[7:])
self.mail.To = 'ABC#XYZ.com'
self.mail.Subject = "Subject: " + str(self.projectNameT)
self.someStr = 'Hello '
self.html_url = open("SomePath//Signature.htm",encoding = 'utf16')
self.data = self.html_url.read()
self.mail.HtmlBody = self.someStr + ('<p>self.data</p>')
If you want to insert a signature in using python and fully programatically, Redemption exposes the RDOSignature object which implements ApplyTo method (it deals with signature image files and merges HTML styles). Because with the outlook security patch, a lot is unable to be done inherrently, so you must work around this before you can procede as normal

Parsing outlook .msg files with python

Looked around and couldn't find a satisfactory answer. Does anyone know how to parse .msg files from outlook with Python?
I've tried using mimetools and email.parser with no luck. Help would be greatly appreciated!
This works for me:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
msg = outlook.OpenSharedItem(r"C:\test_msg.msg")
print msg.SenderName
print msg.SenderEmailAddress
print msg.SentOn
print msg.To
print msg.CC
print msg.BCC
print msg.Subject
print msg.Body
count_attachments = msg.Attachments.Count
if count_attachments > 0:
for item in range(count_attachments):
print msg.Attachments.Item(item + 1).Filename
del outlook, msg
Please refer to the following post regarding methods to access email addresses and not just the names (ex. "John Doe") from the To, CC and BCC properties - enter link description here
I succeeded extracting relevant fields from MS Outlook files (.msg) using msg-extractor utilitity by Matt Walker.
Prerequesites
pip install extract-msg
Note, it may require to install additional modules, in my case, it required to install imapclient:
pip install imapclient
Usage
import extract_msg
f = r'MS_Outlook_file.msg' # Replace with yours
msg = extract_msg.Message(f)
msg_sender = msg.sender
msg_date = msg.date
msg_subj = msg.subject
msg_message = msg.body
print('Sender: {}'.format(msg_sender))
print('Sent On: {}'.format(msg_date))
print('Subject: {}'.format(msg_subj))
print('Body: {}'.format(msg_message))
There are many other goodies in MsgExtractor utility, to be explored, but this is good to start with.
Note
I had to comment out lines 3 to 8 within the file C:\Anaconda3\Scripts\ExtractMsg.py:
#"""
#ExtractMsg:
# Extracts emails and attachments saved in Microsoft Outlook's .msg files
#
#https://github.com/mattgwwalker/msg-extractor
#"""
Error message was:
line 3
ExtractMsg:
^
SyntaxError: invalid syntax
After blocking those lines, the error message disappeared and the code worked just fine.
Even though this is an old thread, I hope this information might help someone who is looking for a solution to what the thread subject exactly says. I strongly advise using the solution of mattgwwalker in github, which requires OleFileIO_PL module to be installed externally.
I was able to parse it similar way as Vladimir mentioned above. However I needed to make small change by adding a for loop. The glob.glob(r'c:\test_email*.msg') returns a list whereas the Message(f) expect a file or str.
f = glob.glob(r'c:\test_email\*.msg')
for filename in f:
msg = ExtractMsg.Message(filename)
msg_sender = msg.sender
msg_date = msg.date
msg_subj = msg.subject
msg_message = msg.body
I found on the net a module called MSG PY.
This is Microsoft Outlook .msg file module for Python.
The module allows you to easy create/read/parse/convert Outlook .msg files.
The module does not require Microsoft Outlook to be installed on the machine or any other third party application or library in order to work.
For example:
from independentsoft.msg import Message
appointment = Message("e:\\appointment.msg")
print("subject: " + str(appointment.subject))
print("start_time: " + str(appointment.appointment_start_time))
print("end_time: " + str(appointment.appointment_end_time))
print("location: " + str(appointment.location))
print("is_reminder_set: " + str(appointment.is_reminder_set))
print("sender_name: " + str(appointment.sender_name))
print("sender_email_address: " + str(appointment.sender_email_address))
print("display_to: " + str(appointment.display_to))
print("display_cc: " + str(appointment.display_cc))
print("body: " + str(appointment.body))
I've tried the python email module and sometimes that doesn't successfully parse the msg file.
So, in this case, if you are only after text or html, the following code worked for me.
start_text = "<html>"
end_text = "</html>"
def parse_msg(msg_file,start_text,end_text):
with open(msg_file) as f:
b=f.read()
return b[b.find(start_text):b.find(end_text)+len(end_text)]
print parse_msg(path_to_msg_file,start_text,end_text)
The extract-msg Python module (pip install extract-msg) is also extremely useful because it allows quick access to the full headers from the message, something that Outlook makes much harder than necessary to get hold of.
My modification of Vladimir's code that shows full headers is:
#!/usr/bin/env python3
import extract_msg
import sys
msg = extract_msg.Message(sys.argv[1])
msg_sender = msg.sender
msg_date = msg.date
msg_subj = msg.subject
print('Sender: {}'.format(msg_sender))
print('Sent On: {}'.format(msg_date))
print('Subject: {}'.format(msg_subj))
print ("=== Details ===")
for k, v in msg.header.items():
print("{}: {}".format(k, v))
print(msg.body)

Amazon Product API for python - A strange error that I can't figure out

Here is the situation, I'm trying to get this API to work for me, but I can't seem to figure out all of its quirks. Even when I run the example below (taken from https://bitbucket.org/basti/python-amazon-product-api/src/2b6b628300c4/examples/all-galileo-titles.py) I get random errors. Now I'm getting an error that says the __init__() takes 4 arguments, and I'm only feeding it two. I put all of the credentials in the correct place, though, and I can't find anywhere in the modules where __init__() is demanding extra arguments. Anyone have any thoughts?
Here is what I was running. More details about the program can be found at that link above.
from amazonproduct.api import API
import lxml
if __name__ == '__main__':
# Don't forget to create file ~/.amazon-product-api
# with your credentials (see docs for details)
api = API(locale = 'uk')
result = api.item_search('Books', Publisher= 'RosettaBooks',
ResponseGroup='Large')
# extract paging information
total_results = result.results
total_pages = len(result) # or result.pages
for book in result:
print 'page %d of %d' % (result.current, total_pages)
#~ from lxml import etree
#~ print etree.tostring(book, pretty_print=True)
print book.ASIN,
print unicode(book.ItemAttributes.Author), ':',
print unicode(book.ItemAttributes.Title),
if hasattr(book.ItemAttributes, 'ListPrice'):
print unicode(book.ItemAttributes.ListPrice.FormattedPrice)
elif hasattr(book.OfferSummary, 'LowestUsedPrice'):
print u'(used from %s)' % book.OfferSummary.LowestUsedPrice.FormattedPrice
I had the same problem, I found on the bitbucket site for python-amazon-product-api a question from a couple of years ago that enabled me to work around the problem. See 11/1/2011 new requirement AssociateTag -- update required?
What I did to work around is not use the .amazon-product-api file to specify the credentials but instead pass them as part of the API call:
AWS_KEY = '……….'
SECRET_KEY = '……………'
ASSOCIATE_TAG = '…………….'
api = API(access_key_id=AWS_KEY, secret_access_key=SECRET_KEY, locale="us", associate_tag=ASSOCIATE_TAG)

Invalid request URI while adding a video to playlist via youtube api

I have been unable to overcome this error while trying to add a video to my playlist using the youtube gdata python api.
gdata.service.RequestError: {'status':
400, 'body': 'Invalid request URI',
'reason': 'Bad Request'}
This seems to be the same error, but there are no solutions as yet. Any help guys?
import getpass
import gdata.youtube
import gdata.youtube.service
yt_service = gdata.youtube.service.YouTubeService()
# The YouTube API does not currently support HTTPS/SSL access.
yt_service.ssl = False
yt_service = gdata.youtube.service.YouTubeService()
yt_service.email = #myemail
yt_service.password = getpass.getpass()
yt_service.developer_key = #mykey
yt_service.source = #text
yt_service.client_id= #text
yt_service.ProgrammaticLogin()
feed = yt_service.GetYouTubePlaylistFeed(username='default')
# iterate through the feed as you would with any other
for entry in feed.entry:
if (entry.title.text == "test"):
lst = entry;
print entry.title.text, entry.id.text
custom_video_title = 'my test video on my test playlist'
custom_video_description = 'this is a test video on my test playlist'
video_id = 'Ncakifd_16k'
playlist_uri = lst.id.text
playlist_video_entry = yt_service.AddPlaylistVideoEntryToPlaylist(playlist_uri, video_id, custom_video_title, custom_video_description)
if isinstance(playlist_video_entry, gdata.youtube.YouTubePlaylistVideoEntry):
print 'Video added'
The confounding thing is that updating the playlist works, but adding a video does not.
playlist_entry_id = lst.id.text.split('/')[-1]
original_playlist_description = lst.description.text
updated_playlist = yt_service.UpdatePlaylist(playlist_entry_id,'test',original_playlist_description,playlist_private=False)
The video_id is not wrong because its the video from the sample code. What am I missing here? Somebody help!
Thanks.
Gdata seems to use v1 API. So, the relevant documentation is here: http://code.google.com/apis/youtube/1.0/developers_guide_protocol.html#Retrieving_a_playlist
This means, your "playlist_uri" should not take the value of "lst.id.text", but should take the "feedLink" element's "href" attribute in order to be used with "AddPlaylistVideoEntryToPlaylist"
Even if you happen to use v2 API, you should take the URI from the "content" element's "src" attribute as explained in the documentation, you get by substituting 2.0, in the above URL! (SO doesn't allow me to put two hyperlinks because i don't have enough reputations! :))

Categories