SergeyO7 commited on
Commit
4121b93
·
verified ·
1 Parent(s): 3b828dc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -25
app.py CHANGED
@@ -5,6 +5,9 @@ from datetime import datetime
5
  from dateutil import parser
6
  from io import BytesIO
7
  from PIL import Image
 
 
 
8
 
9
  # Russian translations for planets
10
  planet_ru = {
@@ -18,15 +21,11 @@ planet_symbols = {
18
  'Mars': '♂', 'Jupiter': '♃', 'Saturn': '♄'
19
  }
20
 
21
- # Parse date-time into ISO format
22
- def parse_date_time(date_time_str):
23
- try:
24
- dt = parser.parse(date_time_str)
25
- return dt.isoformat()
26
- except ValueError:
27
- return None
28
 
29
- # Convert longitude to zodiac sign and degrees
30
  def lon_to_sign(lon):
31
  signs = ["Овен", "Телец", "Близнецы", "Рак", "Лев", "Дева",
32
  "Весы", "Скорпион", "Стрелец", "Козерог", "Водолей", "Рыбы"]
@@ -35,7 +34,7 @@ def lon_to_sign(lon):
35
  minutes = int((lon % 1) * 60)
36
  return f"{signs[sign_index]} {degrees}°{minutes}'"
37
 
38
- # Calculate PLadder and zone sizes
39
  def PLadder_ZSizes(date_time_iso, lat, lon):
40
  try:
41
  dt = datetime.fromisoformat(date_time_iso)
@@ -84,7 +83,7 @@ def PLadder_ZSizes(date_time_iso, lat, lon):
84
  except Exception as e:
85
  return {"error": f"Ошибка: {str(e)}"}
86
 
87
- # Plot the planetary ladder
88
  def plot_pladder(PLadder):
89
  fig, ax = plt.subplots()
90
  ax.plot([0, 1.5, 3, 0], [0, 3, 0, 0], 'k-') # Triangle
@@ -99,27 +98,63 @@ def plot_pladder(PLadder):
99
  ax.axis('off')
100
  return fig
101
 
102
- # Main interface function
103
- def chat_interface(query, lat, lon):
 
104
  if not query.startswith("PLadder "):
105
- return "Запрос должен начинаться с 'PLadder' и содержать дату/время.", None
106
 
107
- date_time_str = query.split(" ", 1)[1]
108
- date_time_iso = parse_date_time(date_time_str)
109
- if not date_time_iso:
 
 
 
 
 
110
  return "Неверный формат даты и времени.", None
111
 
112
- result = PLadder_ZSizes(date_time_iso, lat, lon)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  if "error" in result:
114
  return result["error"], None
115
 
 
116
  PLadder = result["PLadder"]
117
  ZSizes = result["ZSizes"]
118
  longitudes = result["longitudes"]
119
 
 
120
  planet_list = "\n".join([f"{planet_ru[p]}: {lon_to_sign(longitudes[p])}" for p in PLadder])
121
  zones_text = "\n".join([f"Зона {i+1}: {size} ({cls})" for i, (size, cls) in enumerate(ZSizes)])
122
 
 
123
  fig = plot_pladder(PLadder)
124
  buf = BytesIO()
125
  fig.savefig(buf, format='png', bbox_inches='tight')
@@ -127,26 +162,23 @@ def chat_interface(query, lat, lon):
127
  img = Image.open(buf)
128
  plt.close(fig)
129
 
 
130
  text = f"Планетарная лестница:\n{planet_list}\n\nРазмеры зон:\n{zones_text}"
131
  return text, img
132
 
133
- # Gradio UI
134
  with gr.Blocks() as interface:
 
 
135
  with gr.Row():
136
  with gr.Column(scale=2):
137
  output_text = gr.Textbox(label="Ответ", lines=10)
138
  with gr.Column(scale=1):
139
  output_image = gr.Image(label="График планетарной лестницы")
140
- with gr.Row():
141
- with gr.Column(scale=1):
142
- query_text = gr.Textbox(label="Запрос", placeholder="Пример: PLadder 2023-10-10 12:00")
143
- location_lat = gr.Textbox(label="Широта", placeholder="Пример: 37.7749")
144
- location_lon = gr.Textbox(label="Долгота", placeholder="Пример: -122.4194")
145
- submit_button = gr.Button("Отправить")
146
 
147
  submit_button.click(
148
  fn=chat_interface,
149
- inputs=[query_text, location_lat, location_lon],
150
  outputs=[output_text, output_image]
151
  )
152
 
 
5
  from dateutil import parser
6
  from io import BytesIO
7
  from PIL import Image
8
+ from geopy.geocoders import Nominatim
9
+ from timezonefinder import TimezoneFinder
10
+ import pytz
11
 
12
  # Russian translations for planets
13
  planet_ru = {
 
21
  'Mars': '♂', 'Jupiter': '♃', 'Saturn': '♄'
22
  }
23
 
24
+ # Initialize geolocator and timezone finder
25
+ geolocator = Nominatim(user_agent="pladder_app")
26
+ tf = TimezoneFinder()
 
 
 
 
27
 
28
+ # Function to convert longitude to zodiac sign and degrees
29
  def lon_to_sign(lon):
30
  signs = ["Овен", "Телец", "Близнецы", "Рак", "Лев", "Дева",
31
  "Весы", "Скорпион", "Стрелец", "Козерог", "Водолей", "Рыбы"]
 
34
  minutes = int((lon % 1) * 60)
35
  return f"{signs[sign_index]} {degrees}°{minutes}'"
36
 
37
+ # Function to calculate PLadder and zone sizes (unchanged)
38
  def PLadder_ZSizes(date_time_iso, lat, lon):
39
  try:
40
  dt = datetime.fromisoformat(date_time_iso)
 
83
  except Exception as e:
84
  return {"error": f"Ошибка: {str(e)}"}
85
 
86
+ # Function to plot the planetary ladder (unchanged)
87
  def plot_pladder(PLadder):
88
  fig, ax = plt.subplots()
89
  ax.plot([0, 1.5, 3, 0], [0, 3, 0, 0], 'k-') # Triangle
 
98
  ax.axis('off')
99
  return fig
100
 
101
+ # Main interface function (reworked)
102
+ def chat_interface(query):
103
+ # Check for valid command
104
  if not query.startswith("PLadder "):
105
+ return "Запрос должен начинаться с 'PLadder' и содержать дату, время и местоположение.", None
106
 
107
+ # Extract date, time, and location
108
+ query_rest = query[len("PLadder "):]
109
+ try:
110
+ parsed_dt, skipped = parser.parse(query_rest, fuzzy_with_tokens=True)
111
+ location = " ".join(skipped)
112
+ if not location:
113
+ return "Укажите местоположение (город или населённый пункт).", None
114
+ except ValueError:
115
  return "Неверный формат даты и времени.", None
116
 
117
+ # Geocode the location to get latitude and longitude
118
+ try:
119
+ location_data = geolocator.geocode(location)
120
+ if location_data:
121
+ lat = location_data.latitude
122
+ lon = location_data.longitude
123
+ else:
124
+ return f"Не удалось найти координаты для '{location}'.", None
125
+ except Exception as e:
126
+ return f"Ошибка геокодирования: {str(e)}", None
127
+
128
+ # Determine time zone from coordinates
129
+ tz_name = tf.timezone_at(lng=lon, lat=lat)
130
+ if tz_name is None:
131
+ return f"Не удалось определить часовой пояс для '{location}'.", None
132
+ tz = pytz.timezone(tz_name)
133
+
134
+ # Localize the parsed local time and convert to UTC
135
+ try:
136
+ timezone_aware_dt = tz.localize(parsed_dt)
137
+ except pytz.exceptions.AmbiguousTimeError:
138
+ # Handle ambiguous times (e.g., DST transitions) by defaulting to standard time
139
+ timezone_aware_dt = tz.localize(parsed_dt, is_dst=False)
140
+ utc_dt = timezone_aware_dt.astimezone(pytz.utc)
141
+ date_time_iso = utc_dt.isoformat()
142
+
143
+ # Pass UTC time and coordinates to PLadder_ZSizes
144
+ result = PLadder_ZSizes(date_time_iso, str(lat), str(lon))
145
  if "error" in result:
146
  return result["error"], None
147
 
148
+ # Extract results
149
  PLadder = result["PLadder"]
150
  ZSizes = result["ZSizes"]
151
  longitudes = result["longitudes"]
152
 
153
+ # Format output text
154
  planet_list = "\n".join([f"{planet_ru[p]}: {lon_to_sign(longitudes[p])}" for p in PLadder])
155
  zones_text = "\n".join([f"Зона {i+1}: {size} ({cls})" for i, (size, cls) in enumerate(ZSizes)])
156
 
157
+ # Generate plot
158
  fig = plot_pladder(PLadder)
159
  buf = BytesIO()
160
  fig.savefig(buf, format='png', bbox_inches='tight')
 
162
  img = Image.open(buf)
163
  plt.close(fig)
164
 
165
+ # Combine text output
166
  text = f"Планетарная лестница:\n{planet_list}\n\nРазмеры зон:\n{zones_text}"
167
  return text, img
168
 
169
+ # Gradio UI (reworked for single query field)
170
  with gr.Blocks() as interface:
171
+ query_text = gr.Textbox(label="Запрос", placeholder="Пример: PLadder 2023-10-10 12:00 New York")
172
+ submit_button = gr.Button("Отправить")
173
  with gr.Row():
174
  with gr.Column(scale=2):
175
  output_text = gr.Textbox(label="Ответ", lines=10)
176
  with gr.Column(scale=1):
177
  output_image = gr.Image(label="График планетарной лестницы")
 
 
 
 
 
 
178
 
179
  submit_button.click(
180
  fn=chat_interface,
181
+ inputs=query_text,
182
  outputs=[output_text, output_image]
183
  )
184