diff --git a/Json/Query.py b/Json/Query.py new file mode 100644 index 0000000..6c07219 --- /dev/null +++ b/Json/Query.py @@ -0,0 +1,7 @@ +def convertJson(cursor): + data_json = [] + header = [i[0] for i in cursor.description] + data = cursor.fetchall() + for i in data: + data_json.append(dict(zip(header, i))) + return data_json diff --git a/dal/dao.py b/dal/dao.py index 55b125b..149ec52 100644 --- a/dal/dao.py +++ b/dal/dao.py @@ -1,13 +1,10 @@ import sqlite3 - -''' -Connecting with database -''' - - -class Database: - def __init__(self, path): - self.databasePath = path - - def makeConnection(self): - return sqlite3.connect(f"{self.databasePath}") +import os + +def create_cursor(): + dirname = os.path.dirname(__file__) + file_name = os.path.join(dirname, '..', 'database', 'hawqalDB.sqlite') + with open(file_name, 'r', encoding="utf8"): + database = sqlite3.connect(file_name) + cursor = database.cursor() + return cursor \ No newline at end of file diff --git a/hawqal/__init__.py b/hawqal/__init__.py index 7fb398c..7c4c6d1 100644 --- a/hawqal/__init__.py +++ b/hawqal/__init__.py @@ -1,9 +1,17 @@ from hawqal.cities import City from hawqal.country import Country from hawqal.states import States +from .filters.state_filter import StateFilter +from .filters.city_filter import CityFilter +from .filters.country_filter import CountryFilter + getCities = City.getCities +getCity = City.getCity getCountries = Country.getCountries +getCountry = Country.getCountry getStates = States.getStates +getState = States.getState -__all__ = [getCities, getCountries, getStates] +__all__ = [getCountries, getStates, + getState, StateFilter, CountryFilter, getCountry, getCities, CityFilter, getCity] diff --git a/hawqal/cities.py b/hawqal/cities.py index 41c885a..fed0da2 100644 --- a/hawqal/cities.py +++ b/hawqal/cities.py @@ -1,66 +1,101 @@ -from dal.dao import Database -from filter.filter import Filter +from dal.dao import create_cursor import string import os +from .filters.city_filter import CityFilter +from Json.Query import convertJson class City: @staticmethod - def getCities(country="", state="", meta={}): + def getCities(country_name="", state_name="", filters=CityFilter()): """ - 1. Countries function takes two parameters as input country name and filters.\n - 2. By default, function will return countries name.\n - 3. Additional fields are included in filter.\n - 4. From filter of boolean TRUE fields will be included in output - e.g - { - "coordinates": True, - "country": True, - "state":True - } + it takes 3 optional parameters and return JSON object. + + Default: + By default it will return all the cities with all the fields including + + - city_id + + Args: + country_name (str): Optional - To get the cities of some specific country. + state_name (str): Optional - To get the cities of some specific state. + filters (CityFilter): Optional - A class object specifying which fields to include in the results. + + Returns: + list: A json object containing the requested information about the cities. + + Example: + - To get all cities + + ``` + hawqal.getCities() + ``` + + - To get all cities of some country + + ``` + hawqal.getCities(country_name="Pakistan") + ``` + + - To get all cities of some state in a country + + ``` + hawqal.getCities(country_name="Pakistan",state_name="Punjab") + ``` + + - To apply filters and exclude state_name + ``` + hawqal.getCities(filter=hawqal.CityFilter(state_name=False)) + ``` """ - file_name = os.path.join( - os.path.dirname(__file__), '..', 'database', 'hawqalDB.sqlite') + cursor = create_cursor() + query = "SELECT " + str(filters) + " FROM cities" - with open(file_name, 'r', encoding="utf8") as db: - database = Database(file_name).makeConnection() - cursor = database.cursor() + if country_name != "": + query = query + \ + f" WHERE country_name = '{string.capwords(country_name)}'" + elif state_name != "": + query = query + \ + f" WHERE state_name = '{string.capwords(state_name)}'" - if state == "" and country == "" and len(meta) == 0: - data = cursor.execute( - f"SELECT city_name FROM cities ORDER BY city_name") - cities = [city[0] for city in data] - return cities - elif country != "" and type(country) != type({}) and state == "" and len(meta) == 0: - data = cursor.execute( - f"SELECT city_name FROM cities WHERE (country_name='{string.capwords(country)}' OR state_name='{string.capwords(country)}') ORDER BY city_name") - return [city[0] for city in data] + cursor.execute(query) - elif (type(country) == type({}) and state == "" and len(meta) == 0): - selectedFields = Filter.CityFilters(country) - if len(selectedFields) != 0: - data = cursor.execute( - f"SELECT city_name,{selectedFields} FROM cities ORDER BY city_name") - return [list(city) for city in list(data)] - else: - data = cursor.execute( - f"SELECT city_name FROM cities ORDER BY city_name") - return [city[0] for city in list(data)] + return convertJson(cursor) - elif country != "" and type(state) == type({}) and len(meta) == 0: - selectedFields = Filter.CityFilters(state) - if len(selectedFields) != 0: - data = cursor.execute( - f"SELECT city_name,{selectedFields} FROM cities WHERE (country_name='{string.capwords(country)}' OR state_name='{string.capwords(country)}') ORDER BY city_name") - return [list(city) for city in list(data)] - else: - data = cursor.execute( - f"SELECT city_name FROM cities WHERE (country_name='{string.capwords(country)}' OR state_name='{string.capwords(country)}') ORDER BY city_name") - return [city[0] for city in data] + @staticmethod + def getCity(country_name="", state_name="", city_name="", filters=CityFilter()): + """ + Retrieves information about a city from the database. + + Parameters: + country_name (str): The name of the country where the city is located. Optional. + state_name (str): The name of the state or province where the city is located. Optional. + city_name (str): The name of the city. Required. + filters (CityFilter): An object specifying which fields to include in the results. Optional. + + Returns: + A Json object containing the requested information about the city. + + Raises: + ValueError: If `city_name` is not specified. + """ + cursor = create_cursor() + country_name = string.capwords(country_name) + state_name = string.capwords(state_name) + city_name = string.capwords(city_name) + if city_name == "": + raise ValueError("City name must be set") + query = "SELECT " + str(filters) + " FROM CITIES " + if country_name != "": + query = query + f"WHERE country_name='{country_name}' AND city_name='{city_name}' " + elif state_name != "": + query = query + f"Where state_name='{state_name}' and city_name='{city_name}'" + elif country_name != "" and state_name != "": + query = query + f"Where state_name='{state_name}' and country_name='{country_name} and city_name='{city_name}' '" + else: + query = query + f"where city_name='{city_name}'" + + cursor.execute(query) - elif country != "" and state != "" and len(meta) > 0: - selectedFields = Filter.CityFilters(meta) - data = cursor.execute( - f"SELECT city_name,{selectedFields} FROM cities WHERE country_name='{string.capwords(string.capwords(country))}' AND state_name='{string.capwords(string.capwords(state))}' ORDER BY city_name") - return [list(city) for city in list(data)] + return convertJson(cursor) diff --git a/hawqal/country.py b/hawqal/country.py index 5601c79..25e39b7 100644 --- a/hawqal/country.py +++ b/hawqal/country.py @@ -1,19 +1,22 @@ -from dal.dao import Database -from filter.filter import Filter -import os +from dal.dao import create_cursor +# from .filters.filter import Filter +from Json.Query import convertJson +from .filters.country_filter import CountryFilter import string +import os class Country: @staticmethod - def getCountries(country="", meta={}): + def getCountries(filters=CountryFilter()): """ - 1. Countries function takes two parameters as input country name and filters.\n - 2. By default, function will return countries name.\n + 1. getCountries function takes an opti\n + 2. By default, function will return countries name with all the filters.\n 3. Additional fields are included in filter.\n - 4. From filter of boolean TRUE fields will be included in output + 4. From meta TRUE fields will be included in output e.g + { "coordinates": True, "region": True, @@ -23,55 +26,43 @@ def getCountries(country="", meta={}): } """ + cursor=create_cursor() + query = "SELECT " + str(filters) + + query = query + " FROM countries ORDER BY country_name ASC" + print(query) + cursor.execute(query) + + return convertJson(cursor) + + @staticmethod + def getCountry(country_name="", filters=CountryFilter()): + """ + 1. Countries function takes two parameters as input country name and meta.\n + 2. By default, function will return countries name.\n + 3. Additional fields are included in filter.\n + 4. From meta TRUE fields will be included in output + e.g + { + "coordinates": True, + "region": True, + "currency": True, + "timezone": True, + "capital": True + } - file_name = os.path.join(os.path.dirname( - __file__), '..', 'database', 'hawqalDB.sqlite') + """ + cursor = create_cursor() + if country_name == "": + raise ValueError("country_name must be set") - with open(file_name, 'r', encoding="utf8") as db: - database = Database(file_name).makeConnection() - cursor = database.cursor() + query = "SELECT " + str(filters) + " FROM countries" - if country == "" and len(meta) == 0: - data = cursor.execute( - f"SELECT country_name FROM countries ORDER BY country_name ASC") - return [country[0] for country in list(data)] + if country_name != "": - elif type(country) == type({}): - if type(meta) == type(""): - if meta != "": - selectedFields = Filter.CountryFilter(country) - data = cursor.execute( - f'SELECT country_name,{selectedFields} FROM countries WHERE country_name = "{string.capwords(meta)}"') - return [list(country) for country in data][0] - else: - selectedFields = Filter.CountryFilter(country) - data = cursor.execute( - f'SELECT country_name,{selectedFields} FROM countries') - return [list(country) for country in data] - else: - meta, country = country, "" - selectedFields = Filter.CountryFilter(meta) - if len(selectedFields) != 0: - data = cursor.execute( - f'SELECT country_name,{selectedFields} FROM countries') - return [list(country) for country in data] - else: - data = cursor.execute( - f'SELECT country_name FROM countries') - return [country[0] for country in data] + query = query + \ + f" WHERE country_name = '{string.capwords(country_name)}' ORDER BY country_name ASC" - elif (country != "" and len(meta) > 0): - selectedFields = Filter.CountryFilter(meta) - if len(selectedFields) != 0: - data = cursor.execute( - f'SELECT country_name,{selectedFields} FROM countries WHERE country_name = "{string.capwords(country)}"') - return [list(country) for country in data][0] - else: - data = cursor.execute( - f'SELECT country_name FROM countries WHERE country_name = "{string.capwords(country)}"') - return [list(country) for country in data][0] + cursor.execute(query) - elif (country != "" and len(meta) == 0): - data = cursor.execute( - f'SELECT * FROM countries WHERE country_name = "{string.capwords(country)}"') - return [list(country) for country in data][0] + return convertJson(cursor) diff --git a/hawqal/filters/city_filter.py b/hawqal/filters/city_filter.py new file mode 100644 index 0000000..614b636 --- /dev/null +++ b/hawqal/filters/city_filter.py @@ -0,0 +1,17 @@ +class CityFilter: + def __init__(self, city_id=True, city_name=True, state_name=True, state_id=True, country_name=True, latitude=True, + longitude=True): + self.country_name = country_name + self.longitude = longitude + self.latitude = latitude + self.city_id = city_id + self.city_name = city_name + self.state_name = state_name + self.state_id = state_id + + def __str__(self): + fields = "" + for field in ['country_name', 'city_id', 'city_name', 'state_id', 'state_name', 'latitude', 'longitude']: + if getattr(self, field): + fields = fields + field + ', ' + return fields[:-2] diff --git a/hawqal/filters/country_filter.py b/hawqal/filters/country_filter.py new file mode 100644 index 0000000..06e3ef2 --- /dev/null +++ b/hawqal/filters/country_filter.py @@ -0,0 +1,26 @@ +class CountryFilter: + def __init__(self, country_name=True, iso_code=True, phone_code=True, capital=True, currency=True, currency_name=True, currency_symbol=True, country_domain=True, region=True, subregion=-True, timezone=True, zone_city=True, UTC=True, latitude=True, longitude=True): + self.country_name = country_name + self.longitude = longitude + self.latitude = latitude + self.iso_code = iso_code + self.phone_code = phone_code + self.capital = capital + self.currency = currency + self.currency_name = currency_name + self.currency_symbol = currency_symbol + self.country_domain = country_domain + self.region = region + self.subregion = subregion + self.timezone = timezone + self.zone_city = zone_city + self.UTC = UTC + + + + def __str__(self): + fields = "" + for field in ['country_name', 'iso_code', 'phone_code', 'capital', 'currency', 'currency_name', 'currency_symbol', 'country_domain', 'region', 'subregion', 'timezone', 'zone_city', 'UTC', 'longitude', 'latitude']: + if getattr(self, field): + fields = fields + field + ', ' + return fields[:-2] \ No newline at end of file diff --git a/filter/filter.py b/hawqal/filters/filter.py similarity index 98% rename from filter/filter.py rename to hawqal/filters/filter.py index d279480..def18d4 100644 --- a/filter/filter.py +++ b/hawqal/filters/filter.py @@ -50,4 +50,4 @@ def CityFilters(meta): for key, value in meta.items(): if value: fields = fields + keyArrtibutes[key] + ',' - return fields[:-1] + return fields[:-1] \ No newline at end of file diff --git a/hawqal/filters/state_filter.py b/hawqal/filters/state_filter.py new file mode 100644 index 0000000..1296431 --- /dev/null +++ b/hawqal/filters/state_filter.py @@ -0,0 +1,14 @@ +class StateFilter: + def __init__(self, state_id=True, state_name=True, country_name=True, longitude=True, latitude=True): + self.state_id = state_id + self.state_name = state_name + self.country_name = country_name + self.longitude = longitude + self.latitude = latitude + + def __str__(self): + fields = "" + for field in ['state_id', 'state_name', 'country_name', 'longitude', 'latitude']: + if getattr(self, field): + fields = fields + field + ', ' + return fields[:-2] diff --git a/hawqal/states.py b/hawqal/states.py index 0e78990..e92e316 100644 --- a/hawqal/states.py +++ b/hawqal/states.py @@ -1,17 +1,18 @@ -from dal.dao import Database -from filter.filter import Filter +from dal.dao import create_cursor +from .filters.state_filter import StateFilter import string +from Json.Query import convertJson import os class States: @staticmethod - def getStates(country="", meta={}): + def getStates(country_name="", filters=StateFilter()): """ 1. States function takes two parameters as input state name and filters.\n 2. By default, function will return states name.\n - 3. Additional fields are included in filter.\n + 3. Additional fields are included in filters.\n 4. From filter of boolean TRUE fields will be included in output e.g { @@ -19,55 +20,36 @@ def getStates(country="", meta={}): } """ - file_name = os.path.join( - os.path.dirname(__file__), '..', 'database', 'hawqalDB.sqlite') + cursor = create_cursor() - with open(file_name, 'r', encoding="utf8") as db: - database = Database(file_name).makeConnection() - cursor = database.cursor() + query = "SELECT " + str(filters) + " FROM states" - if country == "" and len(meta) == 0: - data = cursor.execute( - f'SELECT state_name FROM states') - return [state[0] for state in data] + if len(country_name) > 0: + query = query + \ + f' where country_name= "{string.capwords(country_name)}"' - elif type(country) == type({}) and len(meta) == 0: - if type(meta) == type(""): - if meta != "": - selectedFields = Filter.CountryFilter(country) - data = cursor.execute( - f'SELECT state_name,{selectedFields} FROM states WHERE country_name = "{string.capwords(meta)}"') - return [list(country) for country in data] - else: - meta, country = country, "" - selectedFields = Filter.StateFilter(meta) - data = cursor.execute( - f'SELECT state_name,{selectedFields} FROM states') - return [list(country) for country in data] - else: - selectedFields = Filter.CountryFilter(country) - if len(selectedFields) != 0: - data = cursor.execute( - f'SELECT state_name,{selectedFields} FROM states ORDER BY state_name') - return [list(country) for country in data] - else: - data = cursor.execute( - f'SELECT state_name FROM states ORDER BY state_name') - return [country[0] for country in data] + cursor.execute(query) - elif country != "" and len(meta) > 0: - selectedFields = Filter.StateFilter(meta) - if len(selectedFields) != 0: - data = cursor.execute( - f'SELECT state_name,{selectedFields} FROM states WHERE country_name = "{string.capwords(country)}"') - return [list(country) for country in data] - else: - data = cursor.execute( - f'SELECT state_name FROM states WHERE country_name = "{string.capwords(country)}"') - return [country[0] for country in data] + return convertJson(cursor) - elif country != "" and len(meta) == 0: - selectedFields = Filter.StateFilter(meta) - data = cursor.execute( - f'SELECT state_name FROM states WHERE country_name = "{string.capwords(country)}"') - return [country[0] for country in list(data)] + @staticmethod + def getState(country_name="", state_name="", filters=StateFilter()): + if state_name == "": + raise ValueError("state_name must be set") + + query = "SELECT " + filters + " FROM states" + cursor=create_cursor() + if len(country_name) > 0 and len(state_name) > 0: + query = f'where country_name= "{string.capwords(country_name)}" and state_name= "{string.capwords(state_name)}"' + elif len(country_name) > 0: + query = query + \ + f'where country_name= "{string.capwords(country_name)}"' + elif len(state_name) > 0: + query = query + \ + f'where state_name= "{string.capwords(state_name)}"' + + query = query + " ORDER BY country_name" + + cursor.execute(query) + + return convertJson(cursor) diff --git a/test_hawqal.py b/test_hawqal.py index 145b0dc..00629e1 100644 --- a/test_hawqal.py +++ b/test_hawqal.py @@ -9,16 +9,16 @@ class TestFunc(unittest.TestCase): def test_getCountries(self): self.assertEqual(len(Country.getCountries()), 250) self.assertEqual(len(Country.getCountries( - "pakistan", {"coordinates": True})), 3) + country="pakistan", meta={"coordinates": True})), 3) def test_getStates(self): self.assertEqual(len(States.getStates()), 4989) - self.assertEqual(len(States.getStates("pakistan")), 8) + self.assertEqual(len(States.getStates(country="pakistan")), 8) def test_getCities(self): self.assertEqual(len(City.getCities()), 150710) - self.assertEqual(len(City.getCities("pakistan")), 458) - self.assertEqual(len(City.getCities("punjab")), 329) + self.assertEqual(len(City.getCities(country="pakistan")), 458) + self.assertEqual(len(City.getCities(state="punjab")), 329) if __name__ == '__main__':