Browse Source

Added config parser and .conf file ability.

mike 5 years ago
parent
commit
88e45fee6e
1 changed files with 54 additions and 32 deletions
  1. 54 32
      index.py

+ 54 - 32
index.py

@@ -28,7 +28,9 @@ from os import path
 #  Add database column to hold parcel number.  Make links to GIS servers 
 #  Add database column to hold parcel number.  Make links to GIS servers 
 #
 #
 #  IDENTIFY NEW PROPERTIES!!
 #  IDENTIFY NEW PROPERTIES!!
-
+#
+#  Automate db opening and closing when calling dbinsert()
+#
 #############
 #############
 
 
 class Property:
 class Property:
@@ -62,26 +64,33 @@ class Search:
 #  def __init__(self, county: list, lower_price=0, upper_price=500000, \
 #  def __init__(self, county: list, lower_price=0, upper_price=500000, \
 #    lower_acres=5, upper_acres=15, type=['farm','land','home'], lower_sqft='', upper_sqft='', \
 #    lower_acres=5, upper_acres=15, type=['farm','land','home'], lower_sqft='', upper_sqft='', \
 #    lower_bedrooms='', upper_bedrooms=''):
 #    lower_bedrooms='', upper_bedrooms=''):
-  def __init__(self):
+  def __init__(self, file = '../landsearch.conf'):
+    self.file = file
+    if not path.exists(self.file):
+      raise FileNotFoundError("The config file cannot be opened", self.file)
     try:
     try:
       config = ConfigParser()
       config = ConfigParser()
-      if path.exists('../landsearch.conf'):
-        config.read('../landsearch.conf')
-        search_params = config['Search']
-      else:
-        raise FileNotFoundError("Config file $HOME/TopGunSoftware/landsearch.conf not found.")
+      config.read(self.file)
+      search_params = config['Search']
     except FileNotFoundError as err:
     except FileNotFoundError as err:
       print(err, "Using default search parameters.")
       print(err, "Using default search parameters.")
     except Exception as err:
     except Exception as err:
       print(err, "Using default search parameters.")
       print(err, "Using default search parameters.")
 
 
+    county = search_params.get('county', ['Gwinnett', 'Hall', 'Jackson', 'Walton', 'Barrow'])
+    if isinstance(county, str):
+      county = county.split(", ")
+    type = search_params.get('type', ['farm', 'house', 'land'])
+    if isinstance(type, str):
+      type = type.split(", ")
+
     self.types=['land', 'farm', 'home', 'house']
     self.types=['land', 'farm', 'home', 'house']
-    self.county = search_params.get('county', ['Gwinnett', 'Hall', 'Jackson', 'Walton', 'Barrow'])
+    self.county = county
     self.lower_price = search_params.get('lower_price', 0)
     self.lower_price = search_params.get('lower_price', 0)
     self.upper_price = search_params.get('upper_price', 525000)
     self.upper_price = search_params.get('upper_price', 525000)
     self.lower_acres = search_params.get('lower_acres', 5)
     self.lower_acres = search_params.get('lower_acres', 5)
     self.upper_acres = search_params.get('upper_acres', 15)
     self.upper_acres = search_params.get('upper_acres', 15)
-    self.type = search_params.get('type', ['farm', 'house', 'land'])			##accept list!
+    self.type = type			##accept list!
     self.lower_sqft = search_params.get('lower_sqft', '')
     self.lower_sqft = search_params.get('lower_sqft', '')
     self.upper_sqft = search_params.get('upper_sqft', '')
     self.upper_sqft = search_params.get('upper_sqft', '')
     self.lower_bedrooms = search_params.get('lower_bedrooms', '')
     self.lower_bedrooms = search_params.get('lower_bedrooms', '')
@@ -91,7 +100,7 @@ class Search:
       assert property_type in self.types, ("Unknown type '" + property_type + "'. Property Type must be of type: " + str(self.types))
       assert property_type in self.types, ("Unknown type '" + property_type + "'. Property Type must be of type: " + str(self.types))
 
 
 ## FOR TESTING, PRINT ALL ATTRIBUTES OF SEARCH ##
 ## FOR TESTING, PRINT ALL ATTRIBUTES OF SEARCH ##
-    print(vars(self))
+#    print(vars(self))
 
 
     
     
 class ImproperSearchError(Exception):
 class ImproperSearchError(Exception):
@@ -114,12 +123,12 @@ class MLSDATA:
     self.cnx = ''
     self.cnx = ''
     self.new_listings = []
     self.new_listings = []
 
 
-  def stringbuilder(self, search: Search):
+  def stringbuilder(self, search: Search, county):
     """ Takes Search class and build appropriate URL query based on mlstype.  Currently only supports gmls."""
     """ Takes Search class and build appropriate URL query based on mlstype.  Currently only supports gmls."""
 
 
     if self.mlstype == 'gmls':
     if self.mlstype == 'gmls':
       base_addr = 'https://www.georgiamls.com/real-estate/search-action.cfm?'
       base_addr = 'https://www.georgiamls.com/real-estate/search-action.cfm?'
-      params = [('cnty', search.county), \
+      params = [('cnty', county), \
         ('lpl', search.lower_price), ('lph', search.upper_price), \
         ('lpl', search.lower_price), ('lph', search.upper_price), \
         ('acresL', search.lower_acres), ('acresH', search.upper_acres), \
         ('acresL', search.lower_acres), ('acresH', search.upper_acres), \
         ('orderBy', 'b'), \
         ('orderBy', 'b'), \
@@ -226,25 +235,24 @@ class MLSDATA:
 
 
     return properties_list
     return properties_list
 
 
-  def getmlsdata(self, search: Search):
+  def getmlsdata(self, search: Search, county):
     """This is the main entrypoint.  Takes arguments to pass to stringbuilder to create the URL.
     """This is the main entrypoint.  Takes arguments to pass to stringbuilder to create the URL.
        Selects appropriate parser based on self.mlstype from class intance.
        Selects appropriate parser based on self.mlstype from class intance.
        Needs any modifications from the standard search ($0 to $500,000, 5 to 15 acres, etc)
        Needs any modifications from the standard search ($0 to $500,000, 5 to 15 acres, etc)
        See class search for more information.
        See class search for more information.
        --> 9/1/20 - takes Search class as argument.  All properties are handled by the class <--"""
        --> 9/1/20 - takes Search class as argument.  All properties are handled by the class <--"""
     if isinstance(search, Search):
     if isinstance(search, Search):
-      print(search.county)
 
 
 ##
 ##
-# PROGRAM BREAKS HERE
+# PROGRAM BREAKS HERE  - Used to loop for each county, not Search class contains list of counties.  Need to automate looping.
 ##
 ##
 
 
-      if not search.county in self.counties:  ### FIX for lower()
-        print("County " + search.county + " not regognized.  Exiting")
+      if not county in self.counties:  ### FIX for lower()
+        print("County " + county + " not regognized.  Exiting")
       else:
       else:
-        print("Scanning for results in " + search.county + " using the " + self.mlstype.upper() + " database.")
+        print("Scanning for results in " + county + " using the " + self.mlstype.upper() + " database.")
         if self.mlstype == 'gmls':
         if self.mlstype == 'gmls':
-          list = self.gmlsparser(self.stringbuilder(search), search.county)
+          list = self.gmlsparser(self.stringbuilder(search, county), county)
         return list
         return list
     else:
     else:
      raise ImproperSearchError(search)
      raise ImproperSearchError(search)
@@ -398,20 +406,34 @@ The following properties have been found which may be of interest.\n
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
-#  gmls = MLSDATA('GMLS')
-#  Search()
-
-  gmls = MLSDATA('GMLS')
-
-  #new_properties = []
-
-  for county in ['Walton']:							### FIX
-    mysearch = Search()		### FIX
-    mydata = gmls.getmlsdata(mysearch)
 
 
-    gmls.connectdb()
-    gmls.dbinsert(mydata)
-    gmls.closedb()
+  gmls = MLSDATA('GMLS')	# Create MLSDATA object
+
+  mysearch = Search()  		# Create a custom search object
+#  print(len(mysearch.county))
+#  print(mysearch.county[0])
+  myresults = []
+ 
+## Create function in MLSDATA module:
+#    - takes counties from configparser and calls getmlsdata for each county.
+#    - Compiles results into single list and returns that list
+#    - User code would look something like this:
+#    _   mysearch = Search()
+#    _   mydata = gmls.findalllistings(mysearch)  # This would control the looping of counties and return a list like normal
+#    _   gmls.dbinsert(myresults)                # This would automate db opening and closing
+  for county in mysearch.county:
+    print("local search: ", county)
+    mysearch = Search()		## Search used to take county as parameter, so this loop would work.  Now Search class contains list.  loop must occur in getmlsdata module
+    mydata = gmls.getmlsdata(mysearch, county)
+
+    for listing in mydata:
+      myresults.append(listing)
+
+#  print(len(myresults))
+#  print(myresults[0].address)
+  gmls.connectdb()
+  gmls.dbinsert(myresults)
+  gmls.closedb()
 #
 #
 #  gmls.email()
 #  gmls.email()
 #
 #