You have no info on your profile so I have to post it here.
Note change the prt statements as that is a private library we use. also need all the paths marked fixthis. must also install ArcRest
'''-------------------------------------------------------------------------------
Purpose: Reads in all the form maps, creates PDFs for the forms, emails them out, then updates the FormEmailed field in the HFS.
The HFS MUST be the first layer in the map and MUST be part of a group layer (this is how it normally comes in).
The HFS MUST have a field called FormEmailed that is yes or no (in lowercase).
The form map mxd MUST have a form element with the name FormName.
The form map mxd MUST have a form element with the name PDFTitle and that should be a field from the HFS.
-------------------------------------------------------------------------------'''
import arcpy, os, string , urllib, urllib2, json, contextlib, smtplib, mimetypes, datetime, sys, time, traceback
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from arcrest.security import AGOLTokenSecurityHandler
from arcrest.agol import FeatureLayer
from arcrest.common.filters import LayerDefinitionFilter
# Testing flags
sendEmailsFlag = 1
markAsEmailed = 1
deleteTempPDF = 1
# login info
AGOusername = "put here"
AGOpassword = "put here"
emailSMTP = "fixthis.smtp.com"
#smtpusername = ""
#smtppassword = ""
# Temp area to store pdfs to email. script then deletes them for cleanup. could keep if wanted just set flag above
pdfBase = r"fixthis"
# Directory of DDP maps
mapsDir = r"fixthis"
prt("---Start of Daily Forms Email Log File---\n")
prt("Forms Email Started: " + time.asctime())
prt ("\n====================================================================================================\n")
try:
# Run for each Form map in the Dir
mapsList = os.listdir(mapsDir)
for mapToUse in mapsList:
if mapToUse.endswith(".mxd"):
# Get map and ddp links
mxd = arcpy.mapping.MapDocument(os.path.join(mapsDir, mapToUse))
prt("Running map " + os.path.join(mapsDir, mapToUse))
ddp = mxd.dataDrivenPages
# Kick out a pdf for each record in the HFS. Note this assumes a definition query was set for formemailed=no
if ddp.pageCount > 0:
for i in range(1, ddp.pageCount + 1):
ddp.currentPageID = i
row = ddp.pageRow
elm = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "FormName")
formName = elm[0].text
fixDate = row.CreationDate
fixedDate = str(fixDate.month) + "-" + str(fixDate.day) + "-" + str(fixDate.year)
# There is not always a JobName so had to make a form element called PDFTitle that is used to name forms and subject lines
# This gives back
elm2 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "PDFTitle")
titleName = elm2[0].text
fieldStart = titleName.find("field") + 7
fieldEnd = titleName.find('"', fieldStart)
findField = titleName[fieldStart:fieldEnd]
nameToUse = row.getValue(findField)
if nameToUse:
baseName = formName + " " + nameToUse + " " + fixedDate
else:
baseName = formName + " " + "Blank Name Given" + " " + fixedDate
pdfName = pdfBase + "\\" + baseName + ".pdf"
ddp.exportToPDF(pdfName, "RANGE", str(i))
if sendEmailsFlag == 1:
# Email the pdf
emailfrom = row.Creator
# email a copy to the creator always plus the field they picked
# Gets mad if a null, so check for empty field
# Weird but the msg["To"] must be a string but the call to the smtp server must be a list
emailto = row.Creator
emailRecList = row.Creator
if row.EmailCopyTo:
emailto = row.Creator + "," + row.EmailCopyTo
emailRecList = emailto.split(',')
# this is full path to pdf to attach
fileToSend = pdfName
# this is just the name without path which becomes the actual name of the attached file
justfileName = baseName + ".pdf"
msg = MIMEMultipart()
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = baseName + " Attached"
msg.preamble = "Where is this"
ctype, encoding = mimetypes.guess_type(fileToSend)
if ctype is None or encoding is not None:
ctype = "application/octet-stream"
maintype, subtype = ctype.split("/", 1)
fp = open(fileToSend, "rb")
attachment = MIMEBase(maintype, subtype)
attachment.set_payload(fp.read())
fp.close()
encoders.encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment", filename=justfileName)
msg.attach(attachment)
server = smtplib.SMTP(emailSMTP)
#server.starttls()
#server.login(smtpusername,smtppassword) # password not needed for here
server.sendmail(emailfrom, emailRecList, msg.as_string())
server.quit()
prt("Sent email " + baseName + " to " + emailto)
# Delete the temp PDF for cleanup
if deleteTempPDF == 1:
os.remove(pdfName)
if markAsEmailed == 1:
# Update the formemailed flag to yes
# Get url of HFS from the layer in the map. Assumes first layer is group of HFS then second is HFS
hfsLayer = arcpy.mapping.ListLayers(mxd)[1]
hfsURL = hfsLayer.dataSource + "/" + "updateFeatures"
# Get token
agolSH = AGOLTokenSecurityHandler(username=AGOusername,password=AGOpassword)
updateAttr = [{"attributes" : {"objectid": row.objectid ,"formemailed" : "yes"}}]
data = {'f': 'json', 'features': updateAttr, 'token' : agolSH.token}
encodedData = urllib.urlencode(data)
request = urllib2.Request(hfsURL, encodedData)
response = urllib2.urlopen(request)
readResponse = response.read()
jsonResponse = json.loads(readResponse)
if not jsonResponse['updateResults'][0]['success']:
prt("FormEmailed field for form " + formName + " at ObjectID " + row.objectid + " was NOT updated successfully!")
ScriptFailed=True
else:
prt( "No recrods found in the Hosted Feature Service. There are no forms to email or not signed in to AGO.\n\n")
ScriptFailed=True
prt("\n")
prt("\n" + "Daily Forms Email Complete: " + time.asctime())
del mxd
except:
PythonMessages("Daily Forms Email Failed")
prt(traceback.format_exc())
prt(arcpy.GetMessages(2))
ScriptFailed=True