My First Python Script

I would like to introduce everyone to my first Python script. Just for the sake of full disclosure it was originally put together by a coworker and then passed off to me for completion. I haven't had much interest until recently to even touch Python. I guess all of us should be so lucky to have a job that forces us to grow in unexpected directions every once and a while.

The script itself is nothing overly complicated, but I'm still proud of it. The reason for that is because I had to dissect the language and semantics to figure out what functionality was still needed to be added to the script. As well as learn to read the language in order to work with the parts that were existing before I touched it.

Just a quick overview of what it actually does ( or is at least suppose to do ;) ). In a MySQL database somewhere in the world, there is a database that holds a schema that was created to try and allow for dynamic recreation of Apache virtualhosts config files at the push of a button. (I'm being a little terse regarding things because I really enjoy the project and have an upcoming blog post with more details. So I don't want to spoil all the fun now. :) )

  1. # -*- coding: utf-8 -*-
  2. import commands
  3. import datetime
  4. import unittest
  5. import MySQLdb
  6. import sys
  7.  
  8. ###################### Constants #############################
  9.  
  10. # What user should we connect to the database as, for updating tables and such?
  11. databaseUser = "******"
  12.  
  13. # What is the password to the database for the given user?
  14. databasePassword = "******"
  15.  
  16. # What is the name of the database that we are connected to?
  17. databaseName = "apache_config"
  18.  
  19. ##################### Begin Code Implementation ###################
  20.  
  21. # Returns a set containing all tuples satisfying the given query.
  22. def runQuery(query):
  23. db = MySQLdb.connect(user=databaseUser, passwd=databasePassword, db=databaseName)
  24. #db = MySQLdb.connect(host=host,user=databaseUser, passwd=databasePassword, db=databaseName)
  25.  
  26. # Execute the query and return the data.
  27. c = db.cursor()
  28. c.execute(query)
  29. return c.fetchall()
  30.  
  31. # Retrieves the master table that holds information on each of the virtualhosts currently being stored.
  32. def retrieveMasterVirtualhostTable(in_virtualhost):
  33. return runQuery("select name, ipaddress from virtualhosts WHERE name = \"" + in_virtualhost + "\"" )
  34.  
  35. #get all information for each virtualhosts based on virtualhost name
  36. def retrieveSitesbyVirtualhosts(in_virtualhost):
  37. return runQuery("SELECT virtualhosts.name, virtualhosts.ipaddress, site.site_name, site.docroot, site.admin_email, site.redirects, site.misc, site.site_id, site.misc FROM site,virtualhosts WHERE site.vhost_id = virtualhosts.id AND virtualhosts.name= \"" + in_virtualhost + "\"")
  38.  
  39. # retrieve all aliaeses for a particular site
  40. def retrieveAliasesbysite_id(in_aliases):
  41. return runQuery("SELECT alias_name FROM site_aliases WHERE site_id= " + in_aliases )
  42.  
  43. # Given a virtualhost entry, returns the header for the associated virtualhost.
  44. def formatVirtualhostHeader(virtualhost):
  45. return 'NameVirtualHost ' + virtualhost[1] + '\nLogFormat "%v %h %l %u %t \\\"%r\\\" %>s %b" vhost\n'
  46.  
  47. def convertWebsiteToVirtualhostEntry(site):
  48. if( not site[5] ):
  49. if ( site[4]):
  50. ret= "\n<VirtualHost " + site[1] + ">\n" + \
  51. " ServerAdmin " + "webmaster@" + site[2] + "\n" + \
  52. " DocumentRoot " + site[3] + "\n" + \
  53. " ServerName " + site[2] + "\n"
  54. else:
  55. ret= "\n<VirtualHost " + site[1] + ">\n" + \
  56. " DocumentRoot " + site[3] + "\n" + \
  57. " ServerName " + site[2] + "\n"
  58.  
  59. # Add in site aliases.
  60. for alias in retrieveAliasesbysite_id(str(site[7])):
  61. ret += " ServerAlias " + alias[0] + "\n"
  62.  
  63. ret+=\
  64. " ErrorLog /usr/local/var/apache/log/" + site[0] + ".error_log\n" + \
  65. " CustomLog /usr/local/var/apache/log/" + site[0] + ".access_log vhost\n"
  66.  
  67. if site[8]:
  68. ret += site[8] + "\n"
  69.  
  70. else:
  71. ret= "\n<VirtualHost " + site[1] + ">\n" + \
  72. " ServerName " + site[2] + "\n"
  73.  
  74. for alias in retrieveAliasesbysite_id(str(site[7])):
  75. ret += " ServerAlias " + alias[0] + "\n"
  76.  
  77. ret += " Redirect " + site[5] + "\n"
  78.  
  79. ret += "</Virtualhost>"
  80. return ret
  81.  
  82. # Execution begins here.
  83. def main():
  84.  
  85. # grab information pertaining
  86. virtualhost = retrieveMasterVirtualhostTable(sys.argv[1])
  87.  
  88. # print the format stuff out at the top of the file
  89. print formatVirtualhostHeader(virtualhost[0])
  90.  
  91. #now grab sites based on the virtualhost called
  92. virtualhostMaster = retrieveSitesbyVirtualhosts(virtualhost[0][0])
  93.  
  94. # For each site in the virtualhostMaster "list"..
  95. for v in virtualhostMaster:
  96.  
  97. ### Print entire output to the screen
  98. print convertWebsiteToVirtualhostEntry(v)
  99.  
  100. main()

I would just like to point out that although I'm proud of my work. I'm not sharing this to try and receive praise from the internet. I'd probably have better luck getting a STD from the internet than praise for this little script. On the contrary, I'm posting this because I'm new to Python, and I would like someone who has a little more experience to guide me in the places that I might not have used the best python methods to get things accomplished. For example, the line:

  1. virtualhostMaster = retrieveSitesbyVirtualhosts(virtualhost[0][0])

Although this works, my intuition tells me that this isn't a very python way of getting that data, using a double index like that. However I just haven't been able to find the correct way to do this. So if someone out there knows of a better way, I'm all eyes!

If you made it this far down into the article, hopefully you liked it enough to share it with your friends. Thanks if you do, I appreciate it.

Bookmark and Share