feat: DeveloperImage downloading, database saving to home directory

refactor: importing
main
Khiem Ton 2 years ago
parent c95dd99a5c
commit 76fbf9b46d
Signed by: th4tkh13m
GPG Key ID: 4D9CF147DCADD05D

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="iSpoof_dev" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="iSpoof_dev" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/iSpoof.iml" filepath="$PROJECT_DIR$/.idea/iSpoof.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -1,6 +1,7 @@
from math import radians, sin, cos, asin, sqrt from math import radians, sin, cos, asin, sqrt
from sqlalchemy.types import TypeDecorator, String from sqlalchemy.types import TypeDecorator, String
class Location(TypeDecorator): class Location(TypeDecorator):
impl = String impl = String
cache_ok = True cache_ok = True

@ -1,13 +1,28 @@
from ispoof.objects import Pokemon, Raid from ispoof.objects import Pokemon, Raid
from ispoof.lists.playerhistory import PlayerHistory from ispoof.lists.playerhistory import PlayerHistory
from sqlalchemy.engine import Engine
from sqlalchemy.exc import ArgumentError from sqlalchemy.exc import ArgumentError
from sqlalchemy import create_engine
from ispoof.utils import get_home_folder
import logging
from sqlalchemy.engine import Engine
logger = logging.getLogger(__name__)
class Database:
def __init__(self):
self.data = get_home_folder() / "data"
self.data.mkdir(parents=True, exist_ok=True)
self.engine = create_engine(f"sqlite:///{(self.data / 'data.db').absolute()}")
def initialize_database(self):
logger.info("Creating databases.")
try:
Pokemon.metadata.create_all(self.engine)
Raid.metadata.create_all(self.engine)
PlayerHistory.metadata.create_all(self.engine)
except ArgumentError:
logger.info("Databases existed.")
def initialize_database(engine: Engine): def get_engine(self) -> Engine:
try: return self.engine
Pokemon.metadata.create_all(engine)
Raid.metadata.create_all(engine)
PlayerHistory.metadata.create_all(engine)
except ArgumentError:
print("Exception")

@ -1,11 +1,8 @@
import sqlalchemy.exc from ispoof.core.location import Location
from geopy.geocoders import Nominatim
from ..core.location import Location
from sqlalchemy.orm import declarative_base from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, DateTime, PrimaryKeyConstraint from sqlalchemy import Column, DateTime, PrimaryKeyConstraint
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from datetime import datetime, timedelta from datetime import datetime, timedelta
from math import ceil
Base = declarative_base() Base = declarative_base()

@ -1,5 +1,5 @@
from ..objects.pokemon import Pokemon from ispoof.objects.pokemon import Pokemon
from ..core.location import Location from ispoof.core.location import Location
from thefuzz.fuzz import partial_ratio from thefuzz.fuzz import partial_ratio
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.engine import Engine from sqlalchemy.engine import Engine
@ -10,7 +10,6 @@ from datetime import datetime, timedelta
class PokemonList: class PokemonList:
def __init__(self, engine: Engine): def __init__(self, engine: Engine):
self.pokemons = None
self.engine = engine self.engine = engine
self.timedelta = timedelta(minutes=2) self.timedelta = timedelta(minutes=2)
@ -48,13 +47,16 @@ class PokemonList:
return result.all() return result.all()
def sort_by_distance(self, location: Location, reverse=False): def sort_by_distance(self, location: Location, reverse=False):
self.pokemons.sort(key=lambda pokemon: location.distance(pokemon.location), reverse=False) with Session(self.engine) as session:
result = session.query(Pokemon).where(Pokemon.end_time > datetime.now() + self.timedelta)
def get_at(self, index: int): session.commit()
return self.pokemons[index] return result.all().sort(key=lambda pokemon: location.distance(pokemon.location), reverse=reverse)
def search_by_name(self, query:str): def search_by_name(self, query: str):
return PokemonList(*filter(lambda pokemon: partial_ratio(query.lower(), pokemon.name) >= 80, self.pokemons)) with Session(self.engine) as session:
result = session.query(Pokemon).where(Pokemon.end_time > datetime.now() + self.timedelta)
session.commit()
return list(filter(lambda pokemon: partial_ratio(query.lower(), pokemon.name) >= 80, result.all()))
def insert_to_database(self, pokemons: List[Pokemon]): def insert_to_database(self, pokemons: List[Pokemon]):
with Session(self.engine) as session: with Session(self.engine) as session:

@ -1,12 +1,11 @@
from geopy.geocoders import Nominatim from geopy.geocoders import Nominatim
from ..core.location import Location from ispoof.core.location import Location
from ..lists.playerhistory import PlayerHistory from ispoof.lists.playerhistory import PlayerHistory
from sqlalchemy.orm import Session
from datetime import datetime, timedelta from datetime import datetime, timedelta
from math import ceil from math import ceil
class Player(): class Player:
def __init__(self, engine, location=None, cooldown=0): def __init__(self, engine, location=None, cooldown=0):
self.location = location self.location = location

@ -1,10 +1,11 @@
from datetime import datetime from datetime import datetime
from sqlalchemy import Column, String, Integer, Boolean, DateTime, PrimaryKeyConstraint from sqlalchemy import Column, String, Integer, Boolean, DateTime, PrimaryKeyConstraint
from ..core.location import Location from ispoof.core.location import Location
from sqlalchemy.orm import declarative_base from sqlalchemy.orm import declarative_base
Base = declarative_base() Base = declarative_base()
class Pokemon(Base): class Pokemon(Base):
__tablename__ = "pokemon" __tablename__ = "pokemon"
name = Column(String(30)) name = Column(String(30))

@ -1,29 +1,59 @@
from pathlib import Path from pathlib import Path
from pymobiledevice3.lockdown import LockdownClient from pymobiledevice3.lockdown import LockdownClient
from pymobiledevice3.cli.mounter import MobileImageMounterService from pymobiledevice3.cli.mounter import MobileImageMounterService, download_developer_disk_image
from pymobiledevice3.cli.developer import DtSimulateLocation from pymobiledevice3.cli.developer import DtSimulateLocation
from pymobiledevice3.services.diagnostics import DiagnosticsService from pymobiledevice3.services.diagnostics import DiagnosticsService
from pymobiledevice3.exceptions import PasscodeRequiredError
import logging
from ispoof.utils import get_home_folder
DEVELOPER_DISK_IMAGE_URL = 'https://github.com/pdso/DeveloperDiskImage/raw/master/{ios_version}/{ios_version}.zip'
logger = logging.getLogger(__name__)
class Device(): class Device:
def __init__(self): def __init__(self):
self.lockdown = LockdownClient() self.lockdown = LockdownClient()
self.mounter = MobileImageMounterService(self.lockdown)
self.diagnostics = DiagnosticsService(self.lockdown) self.diagnostics = DiagnosticsService(self.lockdown)
self.mounter = None
self.location = None self.location = None
def mount_image(self, image_path, signature_path): def mount_image(self):
image_type = "Developer" try:
self.mounter = MobileImageMounterService(self.lockdown)
except PasscodeRequiredError as e:
logger.error(e)
image_type = 'Developer'
image_path = Path(image_path) if not self.mounter.is_image_mounted(image_type):
image = image_path.read_bytes() logger.debug("Image is not mounted yet")
signature_path = Path(signature_path) logger.debug('trying to figure out the best suited DeveloperDiskImage')
signature = signature_path.read_bytes() version = self.lockdown.sanitized_ios_version
image_dir = f'{get_home_folder()}/DevDiskImage/'
image_path = f'{image_dir}/DeveloperDiskImage.dmg'
signature = f'{image_path}.signature'
developer_disk_image_dir = Path(image_dir)
self.mounter.upload_image(image_type, image, signature) if not developer_disk_image_dir.exists():
self.mounter.mount(image_type, signature) try:
download_developer_disk_image(version, developer_disk_image_dir)
except PermissionError:
logger.error(
f'DeveloperDiskImage could not be saved to path ({developer_disk_image_dir}). '
f'Please make sure your user has the necessary permissions')
return
return True image_path = Path(image_path)
signature = Path(signature)
image_path = image_path.read_bytes()
signature = signature.read_bytes()
self.mounter.upload_image(image_type, image_path, signature)
self.mounter.mount(image_type, signature)
logger.info('DeveloperDiskImage mounted successfully')
else:
logger.debug("Image is mounted.")
def spoof_gps(self, destination): def spoof_gps(self, destination):
if self.location is None: if self.location is None:
@ -35,6 +65,10 @@ class Device():
self.location.clear() self.location.clear()
self.diagnostics.restart() self.diagnostics.restart()
def get_ios_version(self):
pass

@ -1,8 +1,8 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import requests import requests
from ..objects.pokemon import Pokemon from ispoof.objects.pokemon import Pokemon
from ..objects.raid import Raid from ispoof.objects.raid import Raid
from ..core.location import Location from ispoof.core.location import Location
from datetime import datetime from datetime import datetime

@ -0,0 +1,8 @@
from pathlib import Path
HOME = Path.home() / ".ispoof"
def get_home_folder() -> Path:
HOME.mkdir(parents=True, exist_ok=True)
return HOME

@ -1,23 +1,15 @@
from ispoof.objects.player import Player from ispoof.objects.player import Player
from ispoof.spoofer.scraper import Scraper from ispoof.spoofer.scraper import Scraper
from ispoof.spoofer.device import Device from ispoof.spoofer.device import Device
from sqlalchemy import create_engine
from ispoof.lists.pokemonlist import PokemonList from ispoof.lists.pokemonlist import PokemonList
from ispoof.data import initialize_database from ispoof.data import Database
import traceback
if __name__ == "__main__": if __name__ == "__main__":
device = Device() device = Device()
image_path = "DeveloperDiskImage.dmg" device.mount_image()
signature_path = "DeveloperDiskImage.dmg.signature" database = Database()
try: database.initialize_database()
device.mount_image(image_path, signature_path) engine = database.get_engine()
except Exception as e:
# traceback.print_exc()
print("Already mounted. Continuing.")
engine = create_engine("sqlite:///data.db")
initialize_database(engine=engine)
player = Player(engine=engine) player = Player(engine=engine)
query = input("Enter your location: ") query = input("Enter your location: ")
@ -28,9 +20,23 @@ if __name__ == "__main__":
while True: while True:
pokemons = scraper.get_hundos() pokemons = scraper.get_hundos()
pokemon_lst.insert_to_database(pokemons) pokemon_lst.insert_to_database(pokemons)
print("Spoof to") print("1. Sort by name")
print("2. Sort by level")
print("3. Sort by CP")
print("4. Sort by distance")
print("5. Search name")
choice = int(input("Your choice: "))
if choice == 1:
pokemons = pokemon_lst.sort_by_name()
elif choice == 2:
pokemons = pokemon_lst.sort_by_level()
elif choice == 3:
pokemons = pokemon_lst.sort_by_cp()
elif choice == 4:
pokemons = pokemon_lst.sort_by_distance(player.location)
else:
pokemons = pokemon_lst.search_by_name(input("Enter query: "))
print("Pokemon List:") print("Pokemon List:")
pokemons = pokemon_lst.sort_by_name()
for i, pokemon in enumerate(pokemons): for i, pokemon in enumerate(pokemons):
print(i, pokemon) print(i, pokemon)
i = int(input("Choose pokemon: ")) i = int(input("Choose pokemon: "))
@ -38,6 +44,7 @@ if __name__ == "__main__":
location = pokemon.location location = pokemon.location
device.spoof_gps(location) device.spoof_gps(location)
did_activity = None did_activity = None
print("Spoof to")
print(pokemon) print(pokemon)
while True: while True:
activity = input("Did you do any cooldown activities? [Y/N] ").lower() activity = input("Did you do any cooldown activities? [Y/N] ").lower()

Loading…
Cancel
Save