Friday, April 27, 2012

Simple enum implementation in python

When using Arcpy, sometimes I always felts that the parameters that require specific entries, like workspace type for layer.replaceDataSource() would be best served if they were an enumerated value.
Python has rejected the enum type, but it does not mean you cannot create your own enum type. Let's get started:

 def __enum(**enums): 
    return type('Enum', (), enums)
Now we can define the enum values as needed.

WorkSpaceType = __enum(ACCESS_WORKSPACE="ACCESS_WORKSPACE",
                       ARCINFO_WORKSPACE="ARCINFO_WORKSPACE",
                       CAD_WORKSPACE="CAD_WORKSPACE",
                       EXCEL_WORKSPACE="EXCEL_WORKSPACE",
                       FILEGDB_WORKSPACE="FILEGDB_WORKSPACE",
                       NONE="NONE",
                       OLEDB_WORKSPACE="OLEDB_WORKSPACE",
                       PCCOVERAGE_WORKSPACE="PCCOVERAGE_WORKSPACE",
                       RASTER_WORKSPACE="RASTER_WORKSPACE",
                       SDE_WORKSPACE="SDE_WORKSPACE",
                       SHAPEFILE_WORKSPACE="SHAPEFILE_WORKSPACE",                     
                       TEXT_WORKSPACE="TEXT_WORKSPACE",
                       TIN_WORKSPACE="TIN_WORKSPACE",
                       VPF_WORKSPACE="VPF_WORKSPACE")

To use the newly created type, just call it like a property on any object.
>>> print WorkSpaceType.CAD_WORKSPACE
CAD_WORKSPACE

Enjoy

Friday, April 6, 2012

Snippet: Add a Spatial Index To All Feature Classes

Ever need to run a batch spatial index in a work space? Yes, well here is a snippet to help you out. import arcpy
from arcpy import env

env.workspace = arcpy.GetParameterAsText(0) # workspace parameter
fcs = arcpy.ListFeatureClasses()
for fc in fcs:
   arcpy.AddSpatialIndex_management(fc)
print 'fin'
Enjoy

Thursday, April 5, 2012

Python Snippet, Writing Text To A File

Let's say you have a program that runs a long process, and you want to write information to a text file. Using the file IO functions, you can easily do this:

data = ["a","b","c","d"]
myFile = open("info.dat", 'w',0)
for item in data:
    myFile.write("%s\n" % item)
myFile.flush()
myFile.close()
del myFile
del data


Now you have a text file where each item in the list is on a new line.

Enjoy

Wednesday, April 4, 2012

Adding Python Extensions to ArcCatalog File Types

When writing complex python processes, sometimes you do not want to put all the logic in a single python file.  This means if you need to make an edit during testing from ArcCatalog, you will have to have file explorer open and switch between screens.

As a programmer, this is unacceptable, so make life easier and add the PY extensions as a viewable file extension in ArcCatalog.
  1. To do this, bring up ArcCatalog and select Customize from the menu bar.
  2. Next, select 'ArcCatalog Options'
  3. Click on the 'File Types' tab
  4. For Standard Installations:
    • If you did a standard installation, the computer should already have python installed, so click on 'Import File Type From Registry'
    • Select the PY extension in the list
  5. For Non-Standard Installations, or Step 4 does not work:
    • For 'File Extension' type PY
    • 'Description Type' - Python File
    • Set the icon to: C:\Python26\ArcGIS10.0\DLLs\py.ic
  6. Press OK to save your changes
  7. Press Apply then OK one more time
  8. Now you can see your python files in ArcCatalog
Enjoy

Monday, March 12, 2012

Oracle's New Motto

My Suggestion for Oracle's Motto: "We're Not Happy Till You're Not Happy"

Tuesday, March 6, 2012

Sending Email At the End of Your Process

Here is a nice script that will allow you to send emails at the end of your python script, or where ever you want to.  Today I just posted a comment on my topic of long running scripts, and I am adding this component onto my workflow, so I know when processes finish or that they have completed.

Enjoy

import arcpy
import smtplib
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
def send_mail(send_from, send_to,
              subject, text,
              f="",server="THE SERVER URL"):
    assert type(send_to)==list
    # Provide the name of your email server below
    #
    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject
 
    msg.attach( MIMEText(text) )
    if os.path.isfile(f):
        part = MIMEBase('application', "zip")
        part.set_payload( open(f,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
        msg.attach(part)
    smtp = smtplib.SMTP(server)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.quit()
def trace():
    import traceback
    import inspect
    import sys
    '''
    trace finds the line, the filename and error message and returns it
    to the user
    '''
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    # script name + line number
    line = tbinfo.split(", ")[1]
    filename = inspect.getfile( inspect.currentframe() )
    # Get Python syntax error
    #
    synerror = traceback.format_exc().splitlines()[-1]
    return line, filename, synerror  
def main(*argv):
    try:
        #    User Inputs
        #
        server = argv[0]
        subject = argv[1]
        message = argv[2]
        recievers = str(argv[3]).split(';')
        #    Email Function
        #
        send_mail(
              "NOTIFICATION@DONOTREPLY.COM",
              recievers,
              subject,
              message,
              "",
              server)
        arcpy.SetParameterAsText(4,True)
    except:
        arcpy.AddError(arcpy.GetMessages(2))
        arcpy.AddError(str(trace()))
        arcpy.SetParameterAsText(4,False)
if __name__ == "__main__":
    argv = tuple(arcpy.GetParameterAsText(i)
            for i in range(arcpy.GetArgumentCount()))
    main(*argv)

Thursday, March 1, 2012

Clean Up Files - A Helpful Function

I've been developing window services using python (win32api), and often I find is necessary that I need to clean up files at the end of the process.  I developed a small function that is quite helpful for cleaning up files by extension:


def cleanUpFiles(directory,extension):
    dir = directory
    files = os.listdir(dir)
    for f in files:
      if not os.path.isdir(f) and extension in f:
        os.remove(dir + os.sep + f)


Enjoy