File size: 2,881 Bytes
cdcd73e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import swisseph as swe
from datetime import datetime
import pytz
from geopy.geocoders import Nominatim
from timezonefinder import TimezoneFinder
import requests
from pathlib import Path

def download_ephe_files():
    """Download and configure ephemeris files."""
    ephe_dir = Path("ephe")
    ephe_dir.mkdir(exist_ok=True)
    
    base_url = "https://raw.githubusercontent.com/aloistr/swisseph/master/ephe/"
    essential_files = ["seas_18.se1", "semo_18.se1", "sepl_18.se1"]
    
    for filename in essential_files:
        file_path = ephe_dir / filename
        if not file_path.exists():
            try:
                response = requests.get(f"{base_url}{filename}")
                response.raise_for_status()
                with open(file_path, "wb") as f:
                    f.write(response.content)
            except Exception:
                return False
    
    swe.set_ephe_path(str(ephe_dir))
    return True

def get_location_data(location_string):
    """Get coordinates and timezone for a location."""
    geolocator = Nominatim(user_agent="mystical_chart")
    location = geolocator.geocode(location_string)
    if not location:
        raise ValueError("Location not found")
    
    tf = TimezoneFinder()
    timezone_str = tf.timezone_at(lat=location.latitude, lng=location.longitude)
    
    return {
        'latitude': location.latitude,
        'longitude': location.longitude,
        'timezone': timezone_str
    }

def calculate_julian_day(date, time, timezone_str):
    """Calculate Julian Day from date and time."""
    tz = pytz.timezone(timezone_str)
    datetime_obj = datetime.combine(date, time)
    local_dt = tz.localize(datetime_obj)
    utc_dt = local_dt.astimezone(pytz.UTC)
    
    jd = swe.utc_to_jd(
        utc_dt.year, utc_dt.month, utc_dt.day,
        utc_dt.hour, utc_dt.minute, utc_dt.second,
        swe.GREG_CAL
    )[1]
    
    return jd

def get_planet_positions(jd):
    """Calculate positions for all planets."""
    planets = {
        "Sun": swe.SUN,
        "Moon": swe.MOON,
        "Mercury": swe.MERCURY,
        "Venus": swe.VENUS,
        "Mars": swe.MARS,
        "Jupiter": swe.JUPITER,
        "Saturn": swe.SATURN,
        "Uranus": swe.URANUS,
        "Neptune": swe.NEPTUNE,
        "Pluto": swe.PLUTO
    }
    
    positions = {}
    for name, planet_id in planets.items():
        result = swe.calc_ut(jd, planet_id)
        positions[name] = {
            'longitude': result[0][0],
            'latitude': result[0][1],
            'distance': result[0][2]
        }
    
    return positions

def calculate_houses(jd, lat, lon):
    """Calculate house cusps using Placidus system."""
    houses, angles = swe.houses(jd, lat, lon, b'P')
    return {
        'cusps': houses,
        'ascendant': angles[0],
        'mc': angles[1],
        'armc': angles[2],
        'vertex': angles[3]
    }