diff --git a/LICENSE b/LICENSE index 19a3cdd..852f98f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Scott Caratozzolo +Copyright (c) 2021 Scott Caratozzolo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MouseTools/MouseTools.db b/MouseTools/MouseTools.db deleted file mode 100644 index e69de29..0000000 diff --git a/MouseTools/__init__.py b/MouseTools/__init__.py index 370a352..194f277 100644 --- a/MouseTools/__init__.py +++ b/MouseTools/__init__.py @@ -6,12 +6,11 @@ from MouseTools.facilities import Facility from MouseTools.pointsofinterest import PointOfInterest from MouseTools.destinations import Destination -from MouseTools.database import DisneyDatabase import MouseTools.ids name = "MouseTools" -__version__ = "2.0.2" +__version__ = "2.1.0" __all__ = ["Destination", "Park", "EntertainmentVenue", "Attraction", "Entertainment", "Facility", "Character", "PointOfInterest", "DisneyDatabase"] diff --git a/MouseTools/attractions.py b/MouseTools/attractions.py index 9e0b48e..74c8b16 100644 --- a/MouseTools/attractions.py +++ b/MouseTools/attractions.py @@ -3,14 +3,15 @@ import sys import sqlite3 from datetime import datetime, timedelta -from .auth import getHeaders, couchbaseHeaders +from .auth import getHeaders from .parks import Park -from .database import DisneyDatabase +from .ids import themeparkapi_ids + class Attraction(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all attraction data available and stores various elements into variables. @@ -27,10 +28,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That attraction is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - self.__id = id self.__name = self.__data['name'] self.__entityType = self.__data['type'] @@ -38,15 +35,11 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() + try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -94,22 +87,6 @@ def __init__(self, id = None, sync_on_init=True): except: self.__anc_ev_id = None - conn.commit() - conn.close() - - def get_possible_ids(self): - """Returns a list of possible ids of this entityType""" - attractions = [] - - dest_data = requests.get("https://api.wdpro.disney.go.com/facility-service/destinations/{}".format(self.__anc_dest_id), headers=getHeaders()).json() - data = requests.get(dest_data['links']['attractions']['href'], headers=getHeaders()).json() - - for attract in data['entries']: - try: - attractions.append(attract['links']['self']['href'].split('/')[-1].split('?')[0]) - except: - pass - return attractions def get_id(self): """Return object id""" @@ -127,14 +104,6 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code - def get_ancestor_destination_id(self): """Return object ancestor destination id""" return self.__anc_dest_id @@ -167,108 +136,77 @@ def get_raw_data(self): """Returns the raw data from global-facility-service""" return self.__data - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone() - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data[0]) - - def get_raw_facilitystatus_data(self): - """Returns the raw facilitystatus data from the database after syncing with Disney (returns most recent data)""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType=Attraction".format(self.__dest_code, self.__id),)).fetchone() - if data is None: - return None - else: - return json.loads(data[0]) + def get_themeparkapi_data(self): + """Returns the dictionary from the themepark api for the given id""" + park = themeparkapi_ids[self.__anc_park_id] + themepark_id = f"{park}_{self.__id}" + all_data = requests.get(f"https://api.themeparks.wiki/preview/parks/{park}/waittime").json() + for i in all_data: + if i["id"] == themepark_id: + return i + return None def get_wait_time(self): """Return current wait time of the object. Returns None if object doesn't have a wait time or no wait currently exists (eg. closed)""" - data = self.get_raw_facilitystatus_data() + data = self.get_themeparkapi_data() if data is None: return None else: - return data['waitMinutes'] + return data['waitTime'] def get_status(self): """Return current status of the object.""" - data = self.get_raw_facilitystatus_data() + data = self.get_themeparkapi_data() if data is None: return None else: return data['status'] - # TODO might have to change this from facilitystatus data to scheduleType from today, or test if none from status then get from today instead def fastpass_available(self): """Returns a boolean of whether this object has FastPass""" - data = self.get_raw_facilitystatus_data() + data = self.get_themeparkapi_data() if data is None: return False else: - return data['fastPassAvailable'] == 'true' - - def fastpass_times(self): - """Returns the current start and end time of the FastPass""" - start_time = None - end_time = None - - if self.fastpass_available(): - data = self.get_raw_facilitystatus_data() - - start_time = datetime.strptime(data['fastPassStartTime'], "%Y-%m-%dT%H:%M:%SZ") - end_time = datetime.strptime(data['fastPassEndTime'], "%Y-%m-%dT%H:%M:%SZ") - - return start_time, end_time + return data['fastPass'] def get_last_update(self): """Returns facilities last update time as a datetime object""" - facility_data = self.get_raw_facilities_data() + facility_data = self.get_themeparkapi_data() if facility_data is None: return None else: - return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") + return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") def get_coordinates(self): """Returns the object's latitude and longitude""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: + try: + return self.__data['coordinates']['Guest Entrance']['gps'] + except: return None - else: - return facility_data['latitude'], facility_data['longitude'] def get_description(self): - """Returns the object's descriptions""" - facility_data = self.get_raw_facilities_data() + """Returns the object's description""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['description'] + try: + return facility_data['descriptions']['shortDescription']['sections']['body'] + except: + return None - def get_list_image(self): - """Returns the url to the object's list image""" - facility_data = self.get_raw_facilities_data() + def get_media(self): + """Returns a dictionary of dictionaries of media relating to the entity""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['listImageUrl'] + return facility_data['media'] def get_facets(self): """Returns a list of dictionaries of the object's facets""" - facility_data = self.get_raw_facilities_data() + facility_data = self.__data if facility_data is None: return None else: @@ -277,6 +215,23 @@ def get_facets(self): except: return None + def get_classifications(self): + """Returns a dictionary of lists of classifications related to the entity""" + + classifications = {} + + try: + for i in self.__data['classifications']: + id = i['id'].split("/")[-1] + if id not in classifications: + classifications[id] = [i['text']] + else: + classifications[id].append(i['text']) + except: + pass + + return classifications + def admission_required(self): """Returns boolean of admission required""" return self.__data['admissionRequired'] @@ -287,7 +242,7 @@ def get_hours(self, date = ""): Returns the object's hours in the following order: operating open, operating close, Extra Magic open, Extra Magic close. Extra Magic hours will return None if there are none for today. If all hours are None then Disney has no hours for that day. - date = "YEAR-MONTH-DATE" + date = "yyyy-mm-dd" If you don't pass a date, it will get today's hours """ diff --git a/MouseTools/auth.py b/MouseTools/auth.py index f7ce88b..39b0363 100644 --- a/MouseTools/auth.py +++ b/MouseTools/auth.py @@ -28,8 +28,3 @@ def getHeaders(): headers = {"Authorization":"BEARER {}".format(access_token), "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36", "Content-Type":"application/json;charset=UTF-8","Accept":"*/*"} return headers - -def couchbaseHeaders(): - - header = {"Authorization":"Basic RFBFQ1AtTU9CSUxFLldEVy5BTkRST0lELVBST0Q6RGhyeHMyZHVReGdiVjZ5Mg==","User-Agent":"CouchbaseLite/1.3 (1.4.1/8a21c5927a273a038fb3b66ec29c86425e871b11)","Content-Type":"application/json","Accept":"multipart/related"} - return header diff --git a/MouseTools/characters.py b/MouseTools/characters.py index 6b53220..33614b1 100644 --- a/MouseTools/characters.py +++ b/MouseTools/characters.py @@ -7,12 +7,12 @@ from .attractions import Attraction from .entertainments import Entertainment from .facilities import Facility -from .database import DisneyDatabase + class Character(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all character data available and stores various elements into variables. @@ -29,10 +29,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That character is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - self.__id = id self.__name = self.__data['name'] self.__entityType = self.__data['type'] @@ -40,15 +36,10 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -96,24 +87,7 @@ def __init__(self, id = None, sync_on_init=True): except: self.__anc_ev_id = None - conn.commit() - conn.close() - - - - def get_possible_ids(self): - """Returns a list of possible ids of this entityType""" - ids = [] - - data = requests.get("https://api.wdpro.disney.go.com/facility-service/characters", headers=getHeaders()).json() - for entry in data['entries']: - try: - ids.append(entry['links']['self']['href'].split('/')[-1].split('?')[0]) - except: - pass - - return ids def get_id(self): """Return object id""" @@ -131,14 +105,6 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code - def get_ancestor_destination_id(self): """Return object ancestor destination id""" return self.__anc_dest_id @@ -163,22 +129,14 @@ def get_ancestor_entertainment_venue_id(self): """Return object entertainment venue id""" return self.__anc_ev_id + def get_raw_data(self): + """Returns the raw data from global-facility-service""" + return self.__data + def get_links(self): """Returns a dictionary of related links""" return self.__data['links'] - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone() - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data[0]) def check_related_locations(self): """ diff --git a/MouseTools/database.py b/MouseTools/database.py deleted file mode 100644 index 2639696..0000000 --- a/MouseTools/database.py +++ /dev/null @@ -1,576 +0,0 @@ -from .auth import couchbaseHeaders -from pathlib import Path -import datetime -import pkg_resources -import sqlite3 -import requests -import json -import re -import os - -# The facilities channel either doesn't have everything or parsing the links from global-facility-service has things that don't exist -class DisneyDatabase: - - def __init__(self, sync_on_init=True): - self.db_path = os.path.join(Path(os.path.abspath(__file__)).parent, "MouseTools.db") - self.conn = sqlite3.connect(self.db_path) - self.c = self.conn.cursor() - - self.create_last_sequence_table() - self.create_sync_table() - self.create_facilities_table() - self.create_calendar_table() - - last_sequence = self.c.execute("""SELECT COUNT(value) FROM lastSequence""").fetchone()[0] - if last_sequence != 0: - if sync_on_init: - self.sync_database() - else: - self.create_facilities_channel('wdw.facilities.1_0.en_us') - self.create_facilities_channel('dlr.facilities.1_0.en_us') - - - def sync_database(self): - - self.sync_facilities_channel() - self.sync_facilitystatus_channel() - self.sync_today_channel() - self.sync_calendar_channel() - - - def create_last_sequence_table(self): - - - self.c.execute("""CREATE TABLE IF NOT EXISTS lastSequence (channel TEXT PRIMARY KEY, value TEXT, channel_type TEXT)""") - - self.conn.commit() - - - - def create_facilities_table(self): - - # subType - self.c.execute("""CREATE TABLE IF NOT EXISTS facilities (id TEXT PRIMARY KEY, name TEXT, entityType TEXT, subType TEXT, doc_id TEXT, destination_code TEXT, park_id TEXT, resort_id TEXT, land_id TEXT, resort_area_id TEXT, entertainment_venue_id TEXT)""") - - self.conn.commit() - - def create_calendar_table(self): - - # subType - self.c.execute("""CREATE TABLE IF NOT EXISTS calendar (id TEXT PRIMARY KEY, date TEXT, destination_code TEXT, body TEXT)""") - - self.conn.commit() - - def create_sync_table(self): - - self.c.execute("""CREATE TABLE IF NOT EXISTS sync (id TEXT PRIMARY KEY, rev TEXT, body TEXT, channel TEXT)""") - - self.conn.commit() - - def channel_exists(self, channel): - - facility_channel_exists = self.c.execute("""SELECT COUNT(value) FROM lastSequence WHERE channel = '{}'""".format(channel)).fetchone()[0] - self.conn.commit() - - - return facility_channel_exists != 0 - - - - def create_facilities_channel(self, channel): - - payload = { - "channels": channel, - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&filter=sync_gateway%2Fbychannel", data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - self.c.execute("INSERT INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'facilities')", (channel, s['last_seq'],)) - - # search for deleted: i['deleted'] or i['removed'] - docs = [] - for i in s['results']: - try: - i['deleted'] - continue - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - # print('getting {} docs'.format(len(docs))) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '' and x[0] != '-': - try: - x = json.loads(x) - self.c.execute("INSERT INTO sync (id, rev, body, channel) VALUES (?, ?, ?, ?)", (x['_id'], x['_rev'], json.dumps(x), channel,)) - - split_id = x['_id'].split(':') - this['id'] = split_id[-1].split(';')[0].split('.')[-1] - - - this['name'] = x['name'] - this['entityType'] = x['type'] - - try: - this['sub'] = x['subType'] - except: - this['sub'] = None - - this['cb_id'] = x['_id'] - this['dest_code'] = x['_id'].split('.')[0] - - try: - this['park_id'] = x['ancestorThemeParkId'].split(';')[0] - except: - try: - this['park_id'] = x['ancestorWaterParkId'].split(';')[0] - except: - this['park_id'] = None - - try: - this['land_id'] = x['ancestorLandId'].split(';')[0] - except: - this['land_id'] = None - - try: - this['resort_id'] = x['ancestorResortId'].split(';')[0] - except: - this['resort_id'] = None - - try: - this['ra_id'] = x['ancestorResortAreaId'].split(';')[0] - except: - this['ra_id'] = None - - try: - this['ev_id'] = x['ancestorEntertainmentVenueId'].split(';')[0] - except: - this['ev_id'] = None - - self.c.execute("INSERT INTO facilities (id, name, entityType, subType, doc_id, destination_code, park_id, land_id, resort_id, resort_area_id, entertainment_venue_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (this['id'], this['name'], this['entityType'], this['sub'], this['cb_id'], this['dest_code'], this['park_id'], this['land_id'], this['resort_id'], this['ra_id'], this['ev_id'],)) - except Exception as e: - # print(x) - # print(e) - continue - - self.conn.commit() - - def sync_facilities_channel(self): - - docs = [] - for row in self.c.execute("""SELECT * FROM lastSequence WHERE channel_type = 'facilities'""").fetchall(): - payload = { - "channels": row[0], - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&since={}&filter=sync_gateway%2Fbychannel".format(row[1]), data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - self.c.execute("REPLACE INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'facilities')", (row[0], s['last_seq'],)) - - # search for deleted: i['deleted'] or i['removed'] - - for i in s['results']: - try: - test = i['deleted'] - self.c.execute("DELETE FROM facilities WHERE doc_id = ?", (i['id'],)) - self.c.execute("DELETE FROM sync WHERE id = ?", (i['id'],)) - num_id = i['id'].split(".")[-1].split(";")[0] - self.c.execute("DELETE FROM sync WHERE id LIKE '%facilitystatus.1_0.{}%'".format(num_id)) - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - # print('updating {} docs'.format(len(docs))) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '': - try: - x = json.loads(x) - self.c.execute("INSERT OR REPLACE INTO sync (id, rev, body, channel) VALUES (?, ?, ?, ?)", (x['_id'], x['_rev'], json.dumps(x), row[0],)) - - split_id = x['_id'].split(':') - this['id'] = split_id[-1].split(';')[0].split('.')[-1] - - - this['name'] = x['name'] - this['entityType'] = x['type'] - - try: - this['sub'] = x['subType'] - except: - this['sub'] = None - - this['cb_id'] = x['_id'] - this['dest_code'] = x['_id'].split('.')[0] - - try: - this['park_id'] = x['ancestorThemeParkId'].split(';')[0] - except: - this['park_id'] = None - - try: - this['land_id'] = x['ancestorLandId'].split(';')[0] - except: - this['land_id'] = None - - try: - this['resort_id'] = x['ancestorResortId'].split(';')[0] - except: - this['resort_id'] = None - - try: - this['ra_id'] = x['ancestorResortAreaId'].split(';')[0] - except: - this['ra_id'] = None - - try: - this['ev_id'] = x['ancestorEntertainmentVenueId'].split(';')[0] - except: - this['ev_id'] = None - - self.c.execute("INSERT OR REPLACE INTO facilities (id, name, entityType, subType, doc_id, destination_code, park_id, land_id, resort_id, resort_area_id, entertainment_venue_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (this['id'], this['name'], this['entityType'], this['sub'], this['cb_id'], this['dest_code'], this['park_id'], this['land_id'], this['resort_id'], this['ra_id'], this['ev_id'],)) - except Exception as e: - # print(e) - continue - - - self.conn.commit() - - - - - def create_facilitystatus_channel(self, channel): - - payload = { - "channels": channel, - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&filter=sync_gateway%2Fbychannel", data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - self.c.execute("INSERT OR REPLACE INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'facilitystatus')", (channel, s['last_seq'],)) - - # search for deleted: i['deleted'] or i['removed'] - docs = [] - for i in s['results']: - try: - i['deleted'] - continue - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - # print('getting {} docs'.format(len(docs))) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '' and x[0] != '-': - try: - x = json.loads(x) - self.c.execute("INSERT INTO sync (id, rev, body, channel) VALUES (?, ?, ?, ?)", (x['_id'], x['_rev'], json.dumps(x), channel,)) - except Exception as e: - # print(e) - # print(x) - continue - - self.conn.commit() - - - def sync_facilitystatus_channel(self): - - docs = [] - for row in self.c.execute("""SELECT * FROM lastSequence WHERE channel_type = 'facilitystatus'""").fetchall(): - payload = { - "channels": row[0], - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&since={}&filter=sync_gateway%2Fbychannel".format(row[1]), data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - - - self.c.execute("REPLACE INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'facilitystatus')", (row[0], s['last_seq'],)) - - # search for deleted: i['deleted'] or i['removed'] - - for i in s['results']: - try: - i['deleted'] - continue - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - # print('getting {} docs'.format(len(docs))) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '' and x[0] != '-': - try: - x = json.loads(x) - self.c.execute("INSERT OR REPLACE INTO sync (id, rev, body, channel) VALUES (?, ?, ?, ?)", (x['_id'], x['_rev'], json.dumps(x), row[0],)) - except: - continue - - self.conn.commit() - - - - - def create_today_channel(self, channel): - - payload = { - "channels": channel, - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&filter=sync_gateway%2Fbychannel", data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - self.c.execute("INSERT OR REPLACE INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'today')", (channel, s['last_seq'],)) - - docs = [] - for i in s['results']: - try: - i['deleted'] - continue - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '' and x[0] != '-': - try: - x = json.loads(x) - self.c.execute("INSERT INTO sync (id, rev, body, channel) VALUES (?, ?, ?, ?)", (x['_id'], x['_rev'], json.dumps(x), channel,)) - except: - continue - - self.conn.commit() - - - def sync_today_channel(self): - - docs = [] - for row in self.c.execute("""SELECT * FROM lastSequence WHERE channel_type = 'today'""").fetchall(): - payload = { - "channels": row[0], - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&since={}&filter=sync_gateway%2Fbychannel".format(row[1]), data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - - - self.c.execute("REPLACE INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'today')", (row[0], s['last_seq'],)) - - # search for deleted: i['deleted'] or i['removed'] - - for i in s['results']: - try: - i['deleted'] - continue - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - # print('getting {} docs'.format(len(docs))) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '' and x[0] != '-': - try: - x = json.loads(x) - self.c.execute("INSERT OR REPLACE INTO sync (id, rev, body, channel) VALUES (?, ?, ?, ?)", (x['_id'], x['_rev'], json.dumps(x), row[0],)) - except: - continue - - self.conn.commit() - - - - def create_calendar_channel(self, channel): - - today = datetime.datetime.today() - - dest_code = channel.split('.')[0] - - self.c.execute("DELETE FROM calendar WHERE destination_code = ?", (dest_code,)) - - payload = { - "channels": channel, - "style": 'all_docs', - "filter": 'sync_gateway/bychannel', - "feed": 'normal', - "heartbeat": 30000 - } - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_changes?feed=normal&heartbeat=30000&style=all_docs&filter=sync_gateway%2Fbychannel", data=json.dumps(payload), headers=couchbaseHeaders()) - s = json.loads(r.text) - - self.c.execute("INSERT OR REPLACE INTO lastSequence (channel, value, channel_type) VALUES (?, ?, 'calendar')", (channel, s['last_seq'],)) - - docs = [] - for i in s['results']: - try: - i['deleted'] - continue - except: - this = {} - this['id'] = i['id'] - - docs.append(this) - - split_id = i['id'].split(":") - if len(split_id) > 1: - this = {} - this['id'] = split_id[0] - docs.append(this) - - payload = {"docs": docs, "json":True} - r = requests.post("https://realtime-sync-gw.wdprapps.disney.com/park-platform-pub/_bulk_get?revs=true&attachments=true", data=json.dumps(payload), headers=couchbaseHeaders()) - s = r.text - - cont_reg = re.compile("\w+-\w+:\s\w+\/\w+") - s = re.sub(cont_reg, "", s) - s = s.splitlines() - for x in s: - if x != '' and x[0] != '-': - try: - x = json.loads(x) - - split_id = x['id'].split('-') - day = split_id[0] - month = split_id[1] - if today.month > int(month): - year = today.year + 1 - elif today.month == int(month) and today.day > int(day): - year = today.year + 1 - else: - year = today.year - - date = "{}-{}-{}".format(year, month, day) - - dest_code = x['_id'].split('.')[0] - - self.c.execute("INSERT INTO calendar (id, date, destination_code, body) VALUES (?, ?, ?, ?)", (x['_id'], date, dest_code, json.dumps(x),)) - - except Exception as e: - # print(e) - continue - - self.conn.commit() - - - def sync_calendar_channel(self): - - - for row in self.c.execute("""SELECT * FROM lastSequence WHERE channel_type = 'calendar'""").fetchall(): - self.create_calendar_channel(row[0]) diff --git a/MouseTools/destinations.py b/MouseTools/destinations.py index af2cf45..71fb783 100644 --- a/MouseTools/destinations.py +++ b/MouseTools/destinations.py @@ -7,15 +7,12 @@ from .parks import Park from .entertainments import Entertainment from .attractions import Attraction -from .database import DisneyDatabase +from .ids import WDW_PARK_IDS, DLR_PARK_IDS, WDW_ID, DLR_ID, DESTINATION_IDS, themeparkapi_ids -WDW_CODE = 'wdw' -DLR_CODE = 'dlr' -DEST_CODES = [WDW_CODE, DLR_CODE] class Destination(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Allows access to various destination related data. @@ -29,36 +26,18 @@ def __init__(self, id = None, sync_on_init=True): pass if error: - raise ValueError('That destination is not available. id: ' + str(id) + '. Available destinations: {}'.format(", ".join(DEST_IDS))) + raise ValueError('That destination is not available. id: ' + str(id) + '. Available destinations: {}'.format(", ".join(DESTINATION_IDS))) self.__id = id + self.__name = self.__data['name'] + self.__entityType = self.__data['type'] - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - dest_data = c.execute("SELECT id, name, doc_id, destination_code, entityType FROM facilities WHERE entityType = 'destination' and id = ?", (self.__id,)).fetchone() - self.__id = dest_data[0] - self.__name = dest_data[1] - self.__doc_id = dest_data[2] - self.__dest_code = dest_data[3] - self.__entityType = dest_data[4] - self.__facilities_data = json.loads(c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone()[0]) - - conn.commit() - conn.close() def get_possible_ids(self): """Returns a list of possible ids of this entityType""" - conn = sqlite3.connect(DisneyDatabase().db_path) - c = conn.cursor() - pos_ids = [row[0] for row in c.execute("SELECT id FROM facilities WHERE entityType = 'destination'")] - return pos_ids - - def get_destination_code(self): - """Returns the destination code""" - return self.__dest_code + return DESTINATION_IDS def get_id(self): """Returns the id of the destination""" @@ -68,10 +47,6 @@ def get_name(self): """Returns the name of the destination""" return self.__name - def get_doc_id(self): - """Returns the doc id""" - return self.__doc_id - def get_entityType(self): """Returns the entityType""" return self.__entityType @@ -84,18 +59,6 @@ def get_raw_data(self): """Returns the raw data from global-facility-service""" return self.__data - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone() - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data[0]) def get_attraction_ids(self): """ @@ -187,240 +150,215 @@ def get_character_ids(self): return ids - def get_wait_times(self): - """Returns a list of dictionaries in the form of {rideid:time} for attractions and entertainments for this destination""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) + def get_themeparkapi_data(self): + """Returns the list of dictionaries for all parks from the themeparks api""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + all_data = [] - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE destination_code = ? and (entityType = 'Attraction' or entityType = 'Entertainment')", (self.__dest_code,))] + if self.__id == WDW_ID: + parks = WDW_PARK_IDS + else: + parks = DLR_PARK_IDS - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for id in parks: try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] + park = themeparkapi_ids[id] + all_data.extend(requests.get(f"https://api.themeparks.wiki/preview/parks/{park}/waittime").json()) except: continue - return data + return all_data + + + def get_wait_times(self): + """Returns a list of dictionaries in the form of {rideid:time} for attractions and entertainments for this destination""" + data = self.get_themeparkapi_data() + + times = {} + + for i in data: + id = i['id'].split("_")[-1] + try: + if i['meta']['type'] != "RESTAURANT": + times[id] = i['waitTime'] + except: + times[id] = i['waitTime'] + + return times def get_wait_times_detailed(self): """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for attractions and entertainments for this destination""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE destination_code = ? and (entityType = 'Attraction' or entityType = 'Entertainment')", (self.__dest_code,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] + this = {} try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - this['entityType'] = row[1] - data[row[0]] = this - except Exception as e: - # print(e) - continue + if i['meta']['type'] != "RESTAURANT": + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = i['meta']['type'].capitalize() + times[id] = this + except: + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = "Entertainment" + times[id] = this - return data + return times def get_attraction_wait_times(self): """Returns a list of dictionaries in the form of {rideid:time} for attractions for this destination""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE destination_code = ? and entityType = 'Attraction'", (self.__dest_code,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] + if i['meta']['type'] == "ATTRACTION": + times[id] = i['waitTime'] except: continue - return data + return times def get_attraction_wait_times_detailed(self): """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for attractions for this destination""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE destination_code = ? and entityType = 'Attraction'", (self.__dest_code,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] + this = {} try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) + if i['meta']['type'] == "ATTRACTION": + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = i['meta']['type'].capitalize() + times[id] = this + except: continue - return data + return times def get_entertainment_wait_times(self): """Returns a list of dictionaries in the form of {rideid:time} for entertainments for this destination""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) + data = self.get_themeparkapi_data() - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + times = {} - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE destination_code = ? and entityType = 'Entertainment'", (self.__dest_code,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] - except: - continue + for i in data: + id = i['id'].split("_")[-1] + if 'type' not in i['meta'].keys(): + times[id] = i['waitTime'] - return data + return times def get_entertainment_wait_times_detailed(self): """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for entertainments for this destination""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE destination_code = ? and entityType = 'Entertainment'", (self.__dest_code,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) - continue - - return data - - def get_raw_calendar_data(self, date=""): - """ - Returns raw calendar data on a date - """ - if self.__db.channel_exists('{}.calendar.1_0'.format(self.__dest_code)): - self.__db.sync_calendar_channel() - else: - self.__db.create_calendar_channel('{}.calendar.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM calendar WHERE date = ?", (date,)).fetchone() - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data[0]) - - def get_refurbishments(self, date=""): - """ - Returns a list of tuples in the form of (id, entityType) that are under refurbishment on a specified date - date = "YYY-MM-DD" - """ - if date == "": - DATE = datetime.today() - else: - year, month, day = date.split('-') - DATE = datetime(int(year), int(month), int(day)) - - STRDATE = "{}-{}-{}".format(DATE.year, self.__formatDate(str(DATE.month)), self.__formatDate(str(DATE.day))) - date = self.get_raw_calendar_data(STRDATE) - - ids = [] - try: - for i in date['refurbishments']: - split = i['facilityId'].split(";") - id = split[0] - entityType = split[1].split("=")[-1] - ids.append((id, entityType)) - except Exception as e: - print(e) - - return ids - - def get_closed(self, date=""): - """ - Returns a list of tuples in the form of (id, entityType) that are under closed on a specified date - date = "YYY-MM-DD" - """ - if date == "": - DATE = datetime.today() - else: - year, month, day = date.split('-') - DATE = datetime(int(year), int(month), int(day)) - - STRDATE = "{}-{}-{}".format(DATE.year, self.__formatDate(str(DATE.month)), self.__formatDate(str(DATE.day))) - date = self.get_raw_calendar_data(STRDATE) - - ids = [] - try: - for i in date['closed']: - split = i['facilityId'].split(";") - id = split[0] - entityType = split[1].split("=")[-1] - ids.append((id, entityType)) - except Exception as e: - print(e) - - return ids + data = self.get_themeparkapi_data() + + times = {} + + for i in data: + id = i['id'].split("_")[-1] + this = {} + if 'type' not in i['meta'].keys(): + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = "Entertainment" + times[id] = this + + return times + + + # Deprecated, remove or replace? + # Replace with all park hours + # def get_raw_calendar_data(self, date=""): + # """ + # Returns raw calendar data on a date. Date should be in the form yyyy-mm-dd + # """ + # if self.__db.channel_exists('{}.calendar.1_0'.format(self.__dest_code)): + # self.__db.sync_calendar_channel() + # else: + # self.__db.create_calendar_channel('{}.calendar.1_0'.format(self.__dest_code)) + + # conn = sqlite3.connect(self.__db.db_path) + # c = conn.cursor() + # data = c.execute("SELECT body FROM calendar WHERE date = ?", (date,)).fetchone() + # conn.commit() + # conn.close() + + # if data is None: + # return None + # else: + # return json.loads(data[0]) + + # Can only get today's refurbishments now, will probably have to change this + # def get_refurbishments(self, date=""): + # """ + # Returns a list of tuples in the form of (id, entityType) that are under refurbishment on a specified date + # date = "YYY-MM-DD" + # """ + # if date == "": + # DATE = datetime.today() + # else: + # year, month, day = date.split('-') + # DATE = datetime(int(year), int(month), int(day)) + + # STRDATE = "{}-{}-{}".format(DATE.year, self.__formatDate(str(DATE.month)), self.__formatDate(str(DATE.day))) + # date = self.get_raw_calendar_data(STRDATE) + + # ids = [] + # try: + # for i in date['refurbishments']: + # split = i['facilityId'].split(";") + # id = split[0] + # entityType = split[1].split("=")[-1] + # ids.append((id, entityType)) + # except Exception as e: + # print(e) + + # return ids + + # Similar to refurbishments, can only get today's + # def get_closed(self, date=""): + # """ + # Returns a list of tuples in the form of (id, entityType) that are under closed on a specified date + # date = "YYY-MM-DD" + # """ + # if date == "": + # DATE = datetime.today() + # else: + # year, month, day = date.split('-') + # DATE = datetime(int(year), int(month), int(day)) + + # STRDATE = "{}-{}-{}".format(DATE.year, self.__formatDate(str(DATE.month)), self.__formatDate(str(DATE.day))) + # date = self.get_raw_calendar_data(STRDATE) + + # ids = [] + # try: + # for i in date['closed']: + # split = i['facilityId'].split(";") + # id = split[0] + # entityType = split[1].split("=")[-1] + # ids.append((id, entityType)) + # except Exception as e: + # print(e) + + # return ids def __formatDate(self, num): """ diff --git a/MouseTools/entertainments.py b/MouseTools/entertainments.py index a3123ff..e1d4a79 100644 --- a/MouseTools/entertainments.py +++ b/MouseTools/entertainments.py @@ -6,12 +6,13 @@ from .auth import getHeaders from .parks import Park from .pointsofinterest import PointOfInterest -from .database import DisneyDatabase +from .ids import themeparkapi_ids + class Entertainment(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all entertainment data available and stores various elements into variables. @@ -28,11 +29,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That entertainment is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - self.__id = id self.__name = self.__data['name'] self.__entityType = self.__data['type'] @@ -40,16 +36,11 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() - # ID: 266858 doesn't have any of this information which causes a problem. try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None + try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -99,9 +90,6 @@ def __init__(self, id = None, sync_on_init=True): - conn.commit() - conn.close() - def get_possible_ids(self): """Returns a list of possible ids of this entityType""" entertainments = [] @@ -133,14 +121,6 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code - def get_ancestor_destination_id(self): """Return object ancestor theme or water park id""" return self.__anc_dest_id @@ -173,108 +153,77 @@ def get_raw_data(self): """Returns the raw data from global-facility-service""" return self.__data - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone() - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data[0]) - - def get_raw_facilitystatus_data(self): - """Returns the raw facilitystatus data from the database after syncing with Disney (returns most recent data)""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType=Entertainment".format(self.__dest_code, self.__id),)).fetchone() - if data is None: - return None - else: - return json.loads(data[0]) + def get_themeparkapi_data(self): + """Returns the dictionary from the themepark api for the given id""" + park = themeparkapi_ids[self.__anc_park_id] + themepark_id = f"{park}_{self.__id}" + all_data = requests.get(f"https://api.themeparks.wiki/preview/parks/{park}/waittime").json() + for i in all_data: + if i["id"] == themepark_id: + return i + return None def get_wait_time(self): """Return current wait time of the object. Returns None if object doesn't have a wait time or no wait currently exists (eg. closed)""" - data = self.get_raw_facilitystatus_data() + data = self.get_themeparkapi_data() if data is None: return None else: - return data['waitMinutes'] + return data['waitTime'] def get_status(self): """Return current status of the object.""" - data = self.get_raw_facilitystatus_data() + data = self.get_themeparkapi_data() if data is None: return None else: return data['status'] - # TODO might have to change this from facilitystatus data to scheduleType from today, or test if none from status then get from today instead def fastpass_available(self): """Returns a boolean of whether this object has FastPass""" - data = self.get_raw_facilitystatus_data() + data = self.get_themeparkapi_data() if data is None: return False else: - return data['fastPassAvailable'] == 'true' - - def fastpass_times(self): - """Returns the current start and end time of the FastPass""" - start_time = None - end_time = None - - if self.fastpass_available(): - data = self.get_raw_facilitystatus_data() - - start_time = datetime.strptime(data['fastPassStartTime'], "%Y-%m-%dT%H:%M:%SZ") - end_time = datetime.strptime(data['fastPassEndTime'], "%Y-%m-%dT%H:%M:%SZ") - - return start_time, end_time + return data['fastPass'] def get_last_update(self): """Returns facilities last update time as a datetime object""" - facility_data = self.get_raw_facilities_data() + facility_data = self.get_themeparkapi_data() if facility_data is None: return None else: - return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") + return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") def get_coordinates(self): """Returns the object's latitude and longitude""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: + try: + return self.__data['coordinates']['Guest Entrance']['gps'] + except: return None - else: - return {"latitude": facility_data['latitude'], "longitude": facility_data['longitude']} def get_description(self): - """Returns the object's descriptions""" - facility_data = self.get_raw_facilities_data() + """Returns the object's description""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['description'] + try: + return facility_data['descriptions']['shortDescription']['sections']['body'] + except: + return None - def get_list_image(self): - """Returns the url to the object's list image""" - facility_data = self.get_raw_facilities_data() + def get_media(self): + """Returns a dictionary of dictionaries of media relating to the entity""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['listImageUrl'] + return facility_data['media'] def get_facets(self): """Returns a list of dictionaries of the object's facets""" - facility_data = self.get_raw_facilities_data() + facility_data = self.get_themeparkapi_data() if facility_data is None: return None else: @@ -283,6 +232,23 @@ def get_facets(self): except: return None + def get_classifications(self): + """Returns a dictionary of lists of classifications related to the entity""" + + classifications = {} + + try: + for i in self.__data['classifications']: + id = i['id'].split("/")[-1] + if id not in classifications: + classifications[id] = [i['text']] + else: + classifications[id].append(i['text']) + except: + pass + + return classifications + def admission_required(self): """Returns boolean of admission required""" return self.__data['admissionRequired'] @@ -323,13 +289,13 @@ def get_associated_characters(self): chars.append(Character(data['entries'][i]['links']['self']['href'].split('/')[-1])) except: pass + return chars - def get_associated_characters(self): + def get_associated_character_ids(self): """ Returns a list of associated characters IDs """ - from .characters import Character chars = [] s = requests.get("https://api.wdpro.disney.go.com/global-pool-override-B/facility-service/associated-characters/{};entityType={}".format(self.__id, self.__entityType), headers=getHeaders()) diff --git a/MouseTools/entertainmentvenues.py b/MouseTools/entertainmentvenues.py index 545da2d..000911a 100644 --- a/MouseTools/entertainmentvenues.py +++ b/MouseTools/entertainmentvenues.py @@ -3,12 +3,12 @@ import sys import sqlite3 from datetime import datetime, timedelta -from .auth import getHeaders, couchbaseHeaders -from .database import DisneyDatabase +from .auth import getHeaders + class EntertainmentVenue(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all venue data available and stores various elements into variables. @@ -25,10 +25,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That entertainment venue is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - self.__id = id self.__name = self.__data['name'] @@ -37,15 +33,10 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -93,8 +84,6 @@ def __init__(self, id = None, sync_on_init=True): except: self.__anc_ev_id = None - conn.commit() - conn.close() def get_possible_ids(self): """Returns a list of possible ids of this entityType""" @@ -127,14 +116,6 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code - def get_ancestor_destination_id(self): """Return object ancestor destination id""" return self.__anc_dest_id @@ -167,211 +148,6 @@ def get_raw_data(self): """Returns the raw data from global-facility-service""" return self.__data - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone()[0] - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data) - - def get_wait_times(self): - """Returns a list of dictionaries in the form of {rideid:time} for attractions and entertainments for this venue""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE entertainment_venue_id = ? and (entityType = 'Attraction' or entityType = 'Entertainment')", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] - except: - continue - - return data - - def get_wait_times_detailed(self): - """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for attractions and entertainments for this venue""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE entertainment_venue_id = ? and (entityType = 'Attraction' or entityType = 'Entertainment')", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) - continue - - return data - - def get_attraction_wait_times(self): - """Returns a list of dictionaries in the form of {rideid:time} for attractions for this venue""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE entertainment_venue_id = ? and entityType = 'Attraction'", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] - except: - continue - - return data - - def get_attraction_wait_times_detailed(self): - """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for attractions for this venue""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE entertainment_venue_id = ? and entityType = 'Attraction'", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) - continue - - return data - - def get_entertainment_wait_times(self): - """Returns a list of dictionaries in the form of {rideid:time} for entertainments for this venue""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE entertainment_venue_id = ? and entityType = 'Entertainment'", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] - except: - continue - - return data - - def get_entertainment_wait_times_detailed(self): - """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for entertainments for this venue""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE entertainment_venue_id = ? and entityType = 'Entertainment'", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) - continue - - return data - - def get_status(self): - """Return current status of the object.""" - if self.__db.channel_exists('{}.today.1_0'.format(self.__dest_code)): - self.__db.sync_today_channel() - # maybe just sync this channel? and do same for previous methods - else: - self.__db.create_today_channel('{}.today.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - today_data = c.execute("""SELECT body FROM sync WHERE id = '{}.today.1_0.{}'""".format(self.__dest_code, self.__entityType)).fetchone() - - if today_data is None: - return None - else: - body = json.loads(today_data[0]) - try: - return body['facilities'][str(self.__id) + ';entityType=' + self.__entityType][0]['scheduleType'] - except: - return None - - def get_last_update(self): - """Returns facilities last update time as a datetime object""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: - return None - else: - return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - def get_coordinates(self): """Returns the object's latitude and longitude""" try: @@ -387,21 +163,13 @@ def get_description(self): except: return None - def get_list_image(self): - """Returns the url to the object's list image""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: - return None - else: - return facility_data['listImageUrl'] - - def get_detail_image(self): - """Returns the url to the object's detail image""" - facility_data = self.get_raw_facilities_data() + def get_media(self): + """Returns a dictionary of dictionaries of media relating to the entity""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['detailImageUrl'] + return facility_data['media'] def get_hours(self, date = ""): """ diff --git a/MouseTools/facilities.py b/MouseTools/facilities.py index f511594..5a72261 100644 --- a/MouseTools/facilities.py +++ b/MouseTools/facilities.py @@ -4,12 +4,12 @@ import sqlite3 from datetime import datetime, timedelta from .auth import getHeaders -from .database import DisneyDatabase + class Facility(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all facility data available and stores various elements into variables. @@ -26,10 +26,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That facility is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - self.__id = id self.__name = self.__data['name'] self.__entityType = self.__data['type'] @@ -37,15 +33,11 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() + try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -93,15 +85,21 @@ def __init__(self, id = None, sync_on_init=True): except: self.__anc_ev_id = None - conn.commit() - conn.close() + # There are just too many variations, could explore more + # def get_possible_ids(self): + # """Returns a list of possible ids of this entityType""" + # ids = [] + + # dest_data = requests.get("https://api.wdpro.disney.go.com/facility-service/destinations/{}".format(self.__anc_dest_id), headers=getHeaders()).json() + # data = requests.get(dest_data['links']['facilities']['href'], headers=getHeaders()).json() + + # for entry in data['entries']: + # try: + # ids.append(entry['links']['self']['href'].split('/')[-1].split('?')[0]) + # except: + # pass - def get_possible_ids(self): - """Returns a list of possible ids of this entityType""" - conn = sqlite3.connect(DisneyDatabase().db_path) - c = conn.cursor() - pos_ids = [row[0] for row in c.execute("SELECT id FROM facilities WHERE entityType ?", (self.__entityType,))] - return pos_ids + # return ids def get_id(self): """Return object id""" @@ -119,13 +117,9 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code + def get_ancestor_destination_id(self): + """Return object ancestor destination id""" + return self.__anc_dest_id def get_ancestor_park_id(self): """Return object ancestor theme or water park id""" @@ -151,107 +145,88 @@ def get_links(self): """Returns a dictionary of related links""" return self.__data['links'] - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone() - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data[0]) - - def get_status(self): - """Return current status of the object.""" - if self.__db.channel_exists('{}.today.1_0'.format(self.__dest_code)): - self.__db.sync_today_channel() - # maybe just sync this channel? and do same for previous methods - else: - self.__db.create_today_channel('{}.today.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - today_data = c.execute("SELECT body FROM sync WHERE id = ?", ('{}.today.1_0.{}'.format(self.__dest_code, self.__entityType),)).fetchone() - - if today_data is None: - return None - else: - body = json.loads(today_data[0]) - - return body['facilities'][self.__id + ';entityType=' + self.__entityType][0]['scheduleType'] - - def get_last_update(self): - """Returns facilities last update time as a datetime object""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: - return None - else: - return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - def get_coordinates(self): """Returns the object's latitude and longitude""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: + try: + return self.__data['coordinates']['Guest Entrance']['gps'] + except: return None - else: - return facility_data['latitude'], facility_data['longitude'] def get_description(self): - """Returns the object's descriptions""" - facility_data = self.get_raw_facilities_data() + """Returns the object's description""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['description'] + try: + return facility_data['descriptions']['shortDescription']['sections']['body'] + except: + return None - def get_list_image(self): - """Returns the url to the object's list image""" - facility_data = self.get_raw_facilities_data() + def get_media(self): + """Returns a dictionary of dictionaries of media relating to the entity""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['listImageUrl'] + return facility_data['media'] def get_facets(self): """Returns a list of dictionaries of the object's facets""" - facility_data = self.get_raw_facilities_data() + facility_data = self.__data if facility_data is None: return None else: - return facility_data['facets'] - - def get_todays_hours(self): - """Returns the start and end times for the object. Will return None, None if closed""" - start_time = None - end_time = None - - if self.__db.channel_exists('{}.today.1_0'.format(self.__dest_code)): - self.__db.sync_today_channel() - # maybe just sync this channel? and do same for previous methods - else: - self.__db.create_today_channel('{}.today.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + try: + return facility_data['facets'] + except: + return None - today_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.today.1_0.{}".format(self.__dest_code, self.__entityType),)).fetchone() + def get_todays_hours(self, date=""): + """ + Gets the object's hours on a specific day and returns them as a datetime object. + Returns the object's hours in the following order: operating open, operating close, Extra Magic open, Extra Magic close. + Extra Magic hours will return None if there are none for today. + If all hours are None then Disney has no hours for that day. + date = "yyyy-mm-dd" + If you don't pass a date, it will get today's hours + """ - if today_data is None: - return start_time, end_time + if date == "": + DATE = datetime.today() else: - body = json.loads(today_data[0]) + year, month, day = date.split('-') + DATE = datetime(int(year), int(month), int(day)) - if body['facilities'][self.__id + ';entityType=' + self.__entityType][0]['scheduleType'] == 'Closed' or body['facilities'][self.__id + ';entityType=Attraction'][0]['scheduleType'] == 'Refurbishment': - return start_time, end_time + s = requests.get("https://api.wdpro.disney.go.com/facility-service/schedules/{}?date={}-{}-{}".format(self.__id, DATE.year, self.__formatDate(str(DATE.month)), self.__formatDate(str(DATE.day))), headers=getHeaders()) + data = json.loads(s.content) - start_time = datetime.strptime(body['facilities'][self.__id + ';entityType=' + self.__entityType][0]['startTime'], "%Y-%m-%dT%H:%M:%SZ") - end_time = datetime.strptime(body['facilities'][self.__id + ';entityType=' + self.__entityType][0]['endTime'], "%Y-%m-%dT%H:%M:%SZ") + operating_hours_start = None + operating_hours_end = None + extra_hours_start = None + extra_hours_end = None - return start_time, end_time + try: + for i in range(len(data['schedules'])): + if data['schedules'][i]['type'] == 'Operating': + operating_hours_start = datetime(DATE.year, DATE.month, DATE.day, int(data['schedules'][i]['startTime'][0:2]), int(data['schedules'][i]['startTime'][3:5])) + if int(data['schedules'][i]['endTime'][0:2]) >= 0 and int(data['schedules'][i]['endTime'][0:2]) <= 7: + DATETEMP = DATE + timedelta(days=1) + operating_hours_end = datetime(DATETEMP.year, DATETEMP.month, DATETEMP.day, int(data['schedules'][i]['endTime'][0:2]), int(data['schedules'][i]['endTime'][3:5])) + else: + operating_hours_end = datetime(DATE.year, DATE.month, DATE.day, int(data['schedules'][i]['endTime'][0:2]), int(data['schedules'][i]['endTime'][3:5])) + + if data['schedules'][i]['type'] == "Special Ticketed Event": + extra_hours_start = datetime(DATE.year, DATE.month, DATE.day, int(data['schedules'][i]['startTime'][0:2]), int(data['schedules'][i]['startTime'][3:5])) + if int(data['schedules'][i]['endTime'][0:2]) >= 0 and int(data['schedules'][i]['endTime'][0:2]) <= 7: + DATETEMP = DATE + timedelta(days=1) + extra_hours_end = datetime(DATETEMP.year, DATETEMP.month, DATETEMP.day, int(data['schedules'][i]['endTime'][0:2]), int(data['schedules'][i]['endTime'][3:5])) + else: + operating_hours_end = datetime(DATE.year, DATE.month, DATE.day, int(data['schedules'][i]['endTime'][0:2]), int(data['schedules'][i]['endTime'][3:5])) + + except KeyError: + pass + return operating_hours_start, operating_hours_end, extra_hours_start, extra_hours_end def __eq__(self, other): """ diff --git a/MouseTools/ids.py b/MouseTools/ids.py index 1ae561d..2cd2ce6 100644 --- a/MouseTools/ids.py +++ b/MouseTools/ids.py @@ -17,6 +17,9 @@ WDW_PARK_IDS = [MK_ID, EPCOT_ID, HS_ID, AK_ID, TL_ID, BB_ID] DLR_PARK_IDS = [DLP_ID, CA_ID] +themeparkapi_ids = {MK_ID: "WaltDisneyWorldMagicKingdom", EPCOT_ID: "WaltDisneyWorldEpcot", HS_ID: "WaltDisneyWorldHollywoodStudios", + AK_ID: "WaltDisneyWorldAnimalKingdom", DLP_ID: "DisneylandResortMagicKingdom", CA_ID: "DisneylandResortCaliforniaAdventure"} + def ids(dest, type): dest_data = requests.get("https://api.wdpro.disney.go.com/facility-service/destinations/{}".format(dest), headers=getHeaders()).json() diff --git a/MouseTools/parks.py b/MouseTools/parks.py index 26f7cc7..9cd1408 100644 --- a/MouseTools/parks.py +++ b/MouseTools/parks.py @@ -3,12 +3,13 @@ import sys import sqlite3 from datetime import datetime, timedelta -from .auth import getHeaders, couchbaseHeaders -from .database import DisneyDatabase +from .auth import getHeaders +from .ids import themeparkapi_ids + class Park(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all park data available and stores various elements into variables. @@ -30,9 +31,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That park is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() self.__id = id @@ -42,15 +40,11 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() + try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -98,8 +92,6 @@ def __init__(self, id = None, sync_on_init=True): except: self.__anc_ev_id = None - conn.commit() - conn.close() def get_possible_ids(self): """Returns a list of possible ids of this entityType""" @@ -142,14 +134,6 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code - def get_ancestor_destination_id(self): """Return object ancestor destination id""" return self.__anc_dest_id @@ -182,209 +166,130 @@ def get_raw_data(self): """Returns the raw data from global-facility-service""" return self.__data - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone()[0] - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data) + def get_themeparkapi_data(self): + """Returns the list of dictionaries from the themepark api for the given id""" + park = themeparkapi_ids[self.__anc_park_id] + all_data = requests.get(f"https://api.themeparks.wiki/preview/parks/{park}/waittime").json() + return all_data def get_wait_times(self): """Returns a list of dictionaries in the form of {rideid:time} for attractions and entertainments for this park""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE park_id = ? and (entityType = 'Attraction' or entityType = 'Entertainment')", (self.__id,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] + if i['meta']['type'] != "RESTAURANT": + times[id] = i['waitTime'] except: - continue + times[id] = i['waitTime'] - return data + return times def get_wait_times_detailed(self): """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for attractions and entertainments for this park""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE park_id = ? and (entityType = 'Attraction' or entityType = 'Entertainment')", (self.__id,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] + this = {} try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - this['entityType'] = row[1] - data[row[0]] = this - except Exception as e: - # print(e) - continue + if i['meta']['type'] != "RESTAURANT": + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = i['meta']['type'].capitalize() + times[id] = this + except: + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = "Entertainment" + times[id] = this - return data + return times def get_attraction_wait_times(self): """Returns a list of dictionaries in the form of {rideid:time} for attractions for this park""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE park_id = ? and entityType = 'Attraction'", (self.__id,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] + if i['meta']['type'] == "ATTRACTION": + times[id] = i['waitTime'] except: continue - return data + return times def get_attraction_wait_times_detailed(self): """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for attractions for this park""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) + data = self.get_themeparkapi_data() - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + times = {} - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE park_id = ? and entityType = 'Attraction'", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() + for i in data: + id = i['id'].split("_")[-1] + this = {} try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) + if i['meta']['type'] == "ATTRACTION": + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = i['meta']['type'].capitalize() + times[id] = this + except: continue - return data + return times def get_entertainment_wait_times(self): """Returns a list of dictionaries in the form of {rideid:time} for entertainments for this park""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE park_id = ? and entityType = 'Entertainment'", (self.__id,))] + times = {} - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - data[row[0]] = body['waitMinutes'] - except: - continue + for i in data: + id = i['id'].split("_")[-1] + if 'type' not in i['meta'].keys(): + times[id] = i['waitTime'] - return data + return times def get_entertainment_wait_times_detailed(self): """Returns a list of dictionaries in the form of {rideid:{name, status, wait_time}} for entertainments for this park""" - if self.__db.channel_exists('{}.facilitystatus.1_0'.format(self.__dest_code)): - self.__db.sync_facilitystatus_channel() - else: - self.__db.create_facilitystatus_channel('{}.facilitystatus.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - - ids = [row for row in c.execute("SELECT id, entityType FROM facilities WHERE park_id = ? and entityType = 'Entertainment'", (self.__id,))] - - data = {} - for row in ids: - status_data = c.execute("SELECT body FROM sync WHERE id = ?", ("{}.facilitystatus.1_0.{};entityType={}".format(self.__dest_code, row[0], row[1]),)).fetchone() - try: - if status_data is not None: - body = json.loads(status_data[0]) - this = {} - this['name'] = c.execute("SELECT name FROM facilities WHERE id = ?", (row[0],)).fetchone()[0] - this['status'] = body['status'] - this['wait_time'] = body['waitMinutes'] - this['last_updated'] = datetime.strptime(body['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - data[row[0]] = this - except Exception as e: - # print(e) - continue - - return data - - def get_status(self): - """Return current status of the object.""" - if self.__db.channel_exists('{}.today.1_0'.format(self.__dest_code)): - self.__db.sync_today_channel() - # maybe just sync this channel? and do same for previous methods - else: - self.__db.create_today_channel('{}.today.1_0'.format(self.__dest_code)) - - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() + data = self.get_themeparkapi_data() - today_data = c.execute("""SELECT body FROM sync WHERE id = '{}.today.1_0.{}'""".format(self.__dest_code, self.__entityType)).fetchone() + times = {} - if today_data is None: - return None - else: - body = json.loads(today_data[0]) - - return body['facilities'][self.__id + ';entityType=' + self.__entityType][0]['scheduleType'] - - def get_last_update(self): - """Returns facilities last update time as a datetime object""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: - return None - else: - return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") + for i in data: + id = i['id'].split("_")[-1] + this = {} + if 'type' not in i['meta'].keys(): + this['name'] = i['name'] + this['status'] = i['status'] + this['wait_time'] = i['waitTime'] + this['last_updated'] = datetime.strptime(i['lastUpdate'], "%Y-%m-%dT%H:%M:%S.%fZ") + this['entityType'] = "Entertainment" + times[id] = this + + return times + + # Figure out how to get the current status + # def get_status(self): + # """Return current status of the object.""" + # park = themeparkapi_ids[self.__anc_park_id] + # all_data = requests.get(f"https://api.themeparks.wiki/preview/parks/{park}/calendar").json() def get_coordinates(self): """Returns the object's latitude and longitude""" @@ -401,21 +306,13 @@ def get_description(self): except: return None - def get_list_image(self): - """Returns the url to the object's list image""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: - return None - else: - return facility_data['listImageUrl'] - - def get_detail_image(self): - """Returns the url to the object's detail image""" - facility_data = self.get_raw_facilities_data() + def get_media(self): + """Returns a dictionary of dictionaries of media relating to the entity""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['detailImageUrl'] + return facility_data['media'] def admission_required(self): """Returns boolean of admission required""" diff --git a/MouseTools/pointsofinterest.py b/MouseTools/pointsofinterest.py index e4ed517..9bff06c 100644 --- a/MouseTools/pointsofinterest.py +++ b/MouseTools/pointsofinterest.py @@ -4,11 +4,11 @@ import sqlite3 from datetime import datetime, timedelta from .auth import getHeaders -from .database import DisneyDatabase + class PointOfInterest(object): - def __init__(self, id = None, sync_on_init=True): + def __init__(self, id = None): """ Constructor Function Gets all points of interest data available and stores various elements into variables. @@ -25,10 +25,6 @@ def __init__(self, id = None, sync_on_init=True): if error: raise ValueError('That point of interest is not available. id: ' + str(id)) - self.__db = DisneyDatabase(sync_on_init) - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - self.__id = id self.__name = self.__data['name'] self.__entityType = self.__data['type'] @@ -36,15 +32,11 @@ def __init__(self, id = None, sync_on_init=True): self.__subType = self.__data['subType'] except: self.__subType = None - doc_id_query = c.execute("SELECT doc_id from facilities where doc_id LIKE ?", ("%{};entityType={}".format(self.__id, self.__entityType),)).fetchone() - self.__doc_id = doc_id_query[0] if doc_id_query is not None else None - self.__facilities_data = self.get_raw_facilities_data() + try: self.__anc_dest_id = self.__data['ancestorDestination']['id'].split(';')[0] - self.__dest_code = c.execute("SELECT destination_code FROM facilities WHERE id = ?", (self.__anc_dest_id,)).fetchone()[0] except: self.__anc_dest_id = None - self.__dest_code = None try: self.__anc_park_id = self.__data['links']['ancestorThemePark']['href'].split('/')[-1].split('?')[0] @@ -92,15 +84,14 @@ def __init__(self, id = None, sync_on_init=True): except: self.__anc_ev_id = None - conn.commit() - conn.close() - def get_possible_ids(self): - """Returns a list of possible ids of this entityType""" - conn = sqlite3.connect(DisneyDatabase().db_path) - c = conn.cursor() - pos_ids = [row[0] for row in c.execute("SELECT id FROM facilities WHERE entityType = ?", (self.__entityType,))] - return pos_ids + + # def get_possible_ids(self): + # """Returns a list of possible ids of this entityType""" + # conn = sqlite3.connect(DisneyDatabase().db_path) + # c = conn.cursor() + # pos_ids = [row[0] for row in c.execute("SELECT id FROM facilities WHERE entityType = ?", (self.__entityType,))] + # return pos_ids def get_id(self): """Return object id""" @@ -118,14 +109,6 @@ def get_subType(self): """Return object subType""" return self.__subType - def get_doc_id(self): - """Return object doc id""" - return self.__doc_id - - def get_destination_code(self): - """Return object destination code""" - return self.__dest_code - def get_ancestor_destination_id(self): """Return object ancestor destination id""" return self.__anc_dest_id @@ -158,53 +141,31 @@ def get_raw_data(self): """Returns the raw data from global-facility-service""" return self.__data - def get_raw_facilities_data(self): - """Returns the raw facilities data currently stored in the database""" - conn = sqlite3.connect(self.__db.db_path) - c = conn.cursor() - data = c.execute("SELECT body FROM sync WHERE id = ?", (self.__doc_id,)).fetchone()[0] - conn.commit() - conn.close() - - if data is None: - return None - else: - return json.loads(data) - - def get_last_update(self): - """Returns facilities last update time as a datetime object""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: - return None - else: - return datetime.strptime(facility_data['lastUpdate'], "%Y-%m-%dT%H:%M:%SZ") - def get_coordinates(self): """Returns the object's latitude and longitude""" - facility_data = self.get_raw_facilities_data() - if facility_data is None: + try: + return self.__data['coordinates']['Guest Entrance']['gps'] + except: return None - else: - return facility_data['latitude'], facility_data['longitude'] def get_description(self): - """Returns the object's descriptions""" - facility_data = self.get_raw_facilities_data() + """Returns the object's description""" + facility_data = self.__data if facility_data is None: return None else: - return facility_data['description'] + try: + return facility_data['descriptions']['shortDescription']['sections']['body'] + except: + return None - def get_list_image(self): - """Returns the url to the object's list image""" - facility_data = self.get_raw_facilities_data() + def get_media(self): + """Returns a dictionary of dictionaries of media relating to the entity""" + facility_data = self.__data if facility_data is None: return None else: - try: - return facility_data['listImageUrl'] - except: - return None + return facility_data['media'] def admission_required(self): """Returns boolean of admission required""" diff --git a/README.md b/README.md index 3d5eb72..171f1b7 100644 --- a/README.md +++ b/README.md @@ -17,16 +17,13 @@ pip install git+https://github.com/scaratozzolo/MouseTools ### Example usage: -The first time you load MouseTools in any project, it will take a while to load as the initial database is set up and created. There is a lot of data to load and parse so just be patient. After this it shouldn't take as long as syncing takes less time. ```python import MouseTools wdw_dest = MouseTools.Destination(80007798) print(wdw_dest.get_park_ids()) -# sync_on_init means sync the database with Disney on object instantiation. Default is True. -# This parameter is helpful when creating many objects back to back as syncing only once is necessary. -dlr_dest = MouseTools.Destination(80008297, sync_on_init=True) +dlr_dest = MouseTools.Destination(80008297) print(dlr_dest.get_attraction_ids()) mk = MouseTools.Park(80007944) @@ -79,7 +76,7 @@ I created this project to help with another project found [here](https://github. If you notice any issues please open a new issue with a "bug" label. Furthermore, if you have any feature requests, open a new issue with a "feature request" label. -This update would not have been possible without the work being done on the [themeparks package](https://github.com/cubehouse/themeparks). Parts of this update were inspired by them. +This package uses the [ThemeParks.wiki API](https://api.themeparks.wiki/). ### License This project is distributed under the MIT license. For more information see [LICENSE](https://github.com/scaratozzolo/MouseTools/blob/master/LICENSE) diff --git a/setup.py b/setup.py index f92ae11..97b68f9 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,5 @@ import setuptools from MouseTools.__init__ import __version__ -from MouseTools import DisneyDatabase @@ -17,7 +16,6 @@ long_description_content_type="text/markdown", url="https://github.com/scaratozzolo/MouseTools", packages=setuptools.find_packages(), - package_data = {'MouseTools': ['MouseTools.db']}, install_requires=["requests"], classifiers=( "Programming Language :: Python :: 3.7",