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 sqlalchemy.types import TypeDecorator, String
class Location(TypeDecorator):
impl = String
cache_ok = True

@ -1,13 +1,28 @@
from ispoof.objects import Pokemon, Raid
from ispoof.lists.playerhistory import PlayerHistory
from sqlalchemy.engine import Engine
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__)
def initialize_database(engine: Engine):
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(engine)
Raid.metadata.create_all(engine)
PlayerHistory.metadata.create_all(engine)
Pokemon.metadata.create_all(self.engine)
Raid.metadata.create_all(self.engine)
PlayerHistory.metadata.create_all(self.engine)
except ArgumentError:
print("Exception")
logger.info("Databases existed.")
def get_engine(self) -> Engine:
return self.engine

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

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

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

@ -1,10 +1,11 @@
from datetime import datetime
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
Base = declarative_base()
class Pokemon(Base):
__tablename__ = "pokemon"
name = Column(String(30))

@ -1,29 +1,59 @@
from pathlib import Path
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.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):
self.lockdown = LockdownClient()
self.mounter = MobileImageMounterService(self.lockdown)
self.diagnostics = DiagnosticsService(self.lockdown)
self.mounter = None
self.location = None
def mount_image(self, image_path, signature_path):
image_type = "Developer"
def mount_image(self):
try:
self.mounter = MobileImageMounterService(self.lockdown)
except PasscodeRequiredError as e:
logger.error(e)
image_type = 'Developer'
if not self.mounter.is_image_mounted(image_type):
logger.debug("Image is not mounted yet")
logger.debug('trying to figure out the best suited DeveloperDiskImage')
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)
if not developer_disk_image_dir.exists():
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
image_path = Path(image_path)
image = image_path.read_bytes()
signature_path = Path(signature_path)
signature = signature_path.read_bytes()
signature = Path(signature)
image_path = image_path.read_bytes()
signature = signature.read_bytes()
self.mounter.upload_image(image_type, image, signature)
self.mounter.upload_image(image_type, image_path, signature)
self.mounter.mount(image_type, signature)
return True
logger.info('DeveloperDiskImage mounted successfully')
else:
logger.debug("Image is mounted.")
def spoof_gps(self, destination):
if self.location is None:
@ -35,6 +65,10 @@ class Device():
self.location.clear()
self.diagnostics.restart()
def get_ios_version(self):
pass

@ -1,8 +1,8 @@
from bs4 import BeautifulSoup
import requests
from ..objects.pokemon import Pokemon
from ..objects.raid import Raid
from ..core.location import Location
from ispoof.objects.pokemon import Pokemon
from ispoof.objects.raid import Raid
from ispoof.core.location import Location
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.spoofer.scraper import Scraper
from ispoof.spoofer.device import Device
from sqlalchemy import create_engine
from ispoof.lists.pokemonlist import PokemonList
from ispoof.data import initialize_database
import traceback
from ispoof.data import Database
if __name__ == "__main__":
device = Device()
image_path = "DeveloperDiskImage.dmg"
signature_path = "DeveloperDiskImage.dmg.signature"
try:
device.mount_image(image_path, signature_path)
except Exception as e:
# traceback.print_exc()
print("Already mounted. Continuing.")
engine = create_engine("sqlite:///data.db")
initialize_database(engine=engine)
device.mount_image()
database = Database()
database.initialize_database()
engine = database.get_engine()
player = Player(engine=engine)
query = input("Enter your location: ")
@ -28,9 +20,23 @@ if __name__ == "__main__":
while True:
pokemons = scraper.get_hundos()
pokemon_lst.insert_to_database(pokemons)
print("Spoof to")
print("Pokemon List:")
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:")
for i, pokemon in enumerate(pokemons):
print(i, pokemon)
i = int(input("Choose pokemon: "))
@ -38,6 +44,7 @@ if __name__ == "__main__":
location = pokemon.location
device.spoof_gps(location)
did_activity = None
print("Spoof to")
print(pokemon)
while True:
activity = input("Did you do any cooldown activities? [Y/N] ").lower()

Loading…
Cancel
Save