kerykeion 4.0.6__py3-none-any.whl → 4.12.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kerykeion might be problematic. Click here for more details.

@@ -1,30 +1,40 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- This is part of Kerykeion (C) 2023 Giacomo Battaglia
3
+ This is part of Kerykeion (C) 2024 Giacomo Battaglia
4
4
  """
5
5
 
6
6
 
7
- import pytz
7
+ import logging
8
8
 
9
- from datetime import datetime
10
- from kerykeion.settings.kerykeion_settings import get_settings_dict
9
+ from kerykeion.settings.kerykeion_settings import get_settings
11
10
  from kerykeion.aspects.synastry_aspects import SynastryAspects
12
11
  from kerykeion.aspects.natal_aspects import NatalAspects
13
12
  from kerykeion.astrological_subject import AstrologicalSubject
14
13
  from kerykeion.kr_types import KerykeionException, ChartType
15
- from kerykeion.kr_types.chart_types import ChartTemplateModel
16
- from kerykeion.charts.charts_utils import decHourJoin, degreeDiff, offsetToTz, sliceToX, sliceToY
17
- from logging import getLogger, basicConfig
14
+ from kerykeion.kr_types import ChartTemplateDictionary
15
+ from kerykeion.kr_types.settings_models import KerykeionSettingsCelestialPointModel
16
+ from kerykeion.charts.charts_utils import (
17
+ degreeDiff,
18
+ sliceToX,
19
+ sliceToY,
20
+ draw_zodiac_slice,
21
+ convert_latitude_coordinate_to_string,
22
+ convert_longitude_coordinate_to_string,
23
+ draw_aspect_line,
24
+ draw_elements_percentages,
25
+ convert_decimal_to_degree_string,
26
+ draw_transit_ring_degree_steps,
27
+ draw_degree_ring,
28
+ draw_transit_ring,
29
+ draw_first_circle,
30
+ draw_second_circle
31
+ )
18
32
  from pathlib import Path
33
+ from scour.scour import scourString
19
34
  from string import Template
20
- from typing import Union
21
-
35
+ from typing import Union, List
36
+ from datetime import datetime
22
37
 
23
- logger = getLogger(__name__)
24
- basicConfig(
25
- format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
26
- level="INFO"
27
- )
28
38
 
29
39
 
30
40
  class KerykeionChartSVG:
@@ -36,11 +46,17 @@ class KerykeionChartSVG:
36
46
  - first_obj: First kerykeion object
37
47
  - chart_type: Natal, ExternalNatal, Transit, Synastry (Default: Type="Natal").
38
48
  - second_obj: Second kerykeion object (Not required if type is Natal)
39
- - new_output_directory: Set the output directory (default: output_directory)
40
- - lang: language settings (default: "EN")
41
- - new_settings_file: Set the settings file (default: kr.config.json)
49
+ - new_output_directory: Set the output directory (default: home directory).
50
+ - new_settings_file: Set the settings file (default: kr.config.json).
51
+ In the settings file you can set the language, colors, planets, aspects, etc.
42
52
  """
53
+
54
+ # Constants
55
+ _DEFAULT_HEIGHT = 546.0
56
+ _DEFAULT_FULL_WIDTH = 1200
57
+ _DEFAULT_NATAL_WIDTH = 772.2
43
58
 
59
+ # Set at init
44
60
  first_obj: AstrologicalSubject
45
61
  second_obj: Union[AstrologicalSubject, None]
46
62
  chart_type: ChartType
@@ -48,6 +64,44 @@ class KerykeionChartSVG:
48
64
  new_settings_file: Union[Path, None]
49
65
  output_directory: Path
50
66
 
67
+ # Internal properties
68
+ fire: float
69
+ earth: float
70
+ air: float
71
+ water: float
72
+ c1: float
73
+ c2: float
74
+ c3: float
75
+ homedir: Path
76
+ xml_svg: Path
77
+ width: Union[float, int]
78
+ language_settings: dict
79
+ chart_colors_settings: dict
80
+ planets_settings: dict
81
+ aspects_settings: dict
82
+ planet_in_zodiac_extra_points: int
83
+ chart_settings: dict
84
+ user: AstrologicalSubject
85
+ available_planets_setting: List[KerykeionSettingsCelestialPointModel]
86
+ transit_ring_exclude_points_names: List[str]
87
+ points_deg_ut: list
88
+ points_deg: list
89
+ points_sign: list
90
+ points_retrograde: list
91
+ houses_sign_graph: list
92
+ t_points_deg_ut: list
93
+ t_points_deg: list
94
+ t_points_sign: list
95
+ t_points_retrograde: list
96
+ t_houses_sign_graph: list
97
+ height: float
98
+ location: str
99
+ geolat: float
100
+ geolon: float
101
+ zoom: int
102
+ zodiac: tuple
103
+ template: str
104
+
51
105
  def __init__(
52
106
  self,
53
107
  first_obj: AstrologicalSubject,
@@ -68,56 +122,59 @@ class KerykeionChartSVG:
68
122
 
69
123
  self.xml_svg = DATA_DIR / "templates/chart.xml"
70
124
 
71
- # SVG Width
72
- self.natal_width = 772.2
73
- self.full_width = 1200
74
-
75
125
  self.parse_json_settings(new_settings_file)
76
126
  self.chart_type = chart_type
77
127
 
78
128
  # Kerykeion instance
79
129
  self.user = first_obj
80
130
 
81
- # Make a list for the absolute degrees of the points of the graphic.
82
- self.points_deg_ut = self.user.planets_degrees_ut + [
83
- self.user.houses_degree_ut[0],
84
- self.user.houses_degree_ut[9],
85
- self.user.houses_degree_ut[6],
86
- self.user.houses_degree_ut[3],
131
+ self.available_planets_setting = []
132
+ for body in self.planets_settings:
133
+ if body['is_active'] == False:
134
+ continue
135
+
136
+ self.available_planets_setting.append(body)
137
+
138
+ # House cusp points are excluded from the transit ring.
139
+ self.transit_ring_exclude_points_names = [
140
+ "First_House",
141
+ "Second_House",
142
+ "Third_House",
143
+ "Fourth_House",
144
+ "Fifth_House",
145
+ "Sixth_House",
146
+ "Seventh_House",
147
+ "Eighth_House",
148
+ "Ninth_House",
149
+ "Tenth_House",
150
+ "Eleventh_House",
151
+ "Twelfth_House"
87
152
  ]
88
153
 
154
+ # Available bodies
155
+ available_celestial_points = []
156
+ for body in self.available_planets_setting:
157
+ available_celestial_points.append(body["name"].lower())
158
+
159
+ # Make a list for the absolute degrees of the points of the graphic.
160
+ self.points_deg_ut = []
161
+ for planet in available_celestial_points:
162
+ self.points_deg_ut.append(self.user.get(planet).abs_pos)
163
+
89
164
  # Make a list of the relative degrees of the points in the graphic.
90
165
  self.points_deg = []
91
- for planet in self.user.planets_list:
92
- self.points_deg.append(planet["position"])
93
-
94
- self.points_deg = self.points_deg + [
95
- self.user.houses_list[0]["position"],
96
- self.user.houses_list[9]["position"],
97
- self.user.houses_list[6]["position"],
98
- self.user.houses_list[3]["position"],
99
- ]
166
+ for planet in available_celestial_points:
167
+ self.points_deg.append(self.user.get(planet).position)
100
168
 
101
169
  # Make list of the points sign
102
170
  self.points_sign = []
103
-
104
- for planet in self.user.planets_list:
105
- self.points_sign.append(planet["sign_num"])
106
-
107
- self.points_sign = self.points_sign + [
108
- self.user.houses_list[0]["sign_num"],
109
- self.user.houses_list[9]["sign_num"],
110
- self.user.houses_list[6]["sign_num"],
111
- self.user.houses_list[3]["sign_num"],
112
- ]
171
+ for planet in available_celestial_points:
172
+ self.points_sign.append(self.user.get(planet).sign_num)
113
173
 
114
174
  # Make a list of points if they are retrograde or not.
115
175
  self.points_retrograde = []
116
-
117
- for planet in self.user.planets_list:
118
- self.points_retrograde.append(planet["retrograde"])
119
-
120
- self.points_retrograde = self.points_retrograde + [False, False, False, False]
176
+ for planet in available_celestial_points:
177
+ self.points_retrograde.append(self.user.get(planet).retrograde)
121
178
 
122
179
  # Makes the sign number list.
123
180
 
@@ -127,7 +184,7 @@ class KerykeionChartSVG:
127
184
 
128
185
  if self.chart_type == "Natal" or self.chart_type == "ExternalNatal":
129
186
  natal_aspects_instance = NatalAspects(self.user, new_settings_file=self.new_settings_file)
130
- self.aspects_list = natal_aspects_instance.get_relevant_aspects()
187
+ self.aspects_list = natal_aspects_instance.relevant_aspects
131
188
 
132
189
  # TODO: If not second should exit
133
190
  if self.chart_type == "Transit" or self.chart_type == "Synastry":
@@ -138,112 +195,45 @@ class KerykeionChartSVG:
138
195
  self.t_user = second_obj
139
196
 
140
197
  # Make a list for the absolute degrees of the points of the graphic.
141
-
142
- self.t_points_deg_ut = self.t_user.planets_degrees_ut + [
143
- self.t_user.houses_degree_ut[0],
144
- self.t_user.houses_degree_ut[9],
145
- self.t_user.houses_degree_ut[6],
146
- self.t_user.houses_degree_ut[3],
147
- ]
198
+ self.t_points_deg_ut = []
199
+ for planet in available_celestial_points:
200
+ self.t_points_deg_ut.append(self.t_user.get(planet).abs_pos)
148
201
 
149
202
  # Make a list of the relative degrees of the points in the graphic.
150
-
151
203
  self.t_points_deg = []
152
- for planet in self.t_user.planets_list:
153
- self.t_points_deg.append(planet["position"])
154
-
155
- self.t_points_deg = self.t_points_deg + [
156
- self.t_user.houses_list[0]["position"],
157
- self.t_user.houses_list[9]["position"],
158
- self.t_user.houses_list[6]["position"],
159
- self.t_user.houses_list[3]["position"],
160
- ]
204
+ for planet in available_celestial_points:
205
+ self.t_points_deg.append(self.t_user.get(planet).position)
161
206
 
162
207
  # Make list of the poits sign.
163
-
164
208
  self.t_points_sign = []
165
-
166
- for planet in self.t_user.planets_list:
167
- self.t_points_sign.append(planet["sign_num"])
168
-
169
- self.t_points_sign = self.t_points_sign + [
170
- self.t_user.houses_list[0]["sign_num"],
171
- self.t_user.houses_list[9]["sign_num"],
172
- self.t_user.houses_list[6]["sign_num"],
173
- self.t_user.houses_list[3]["sign_num"],
174
- ]
209
+ for planet in available_celestial_points:
210
+ self.t_points_sign.append(self.t_user.get(planet).sign_num)
175
211
 
176
212
  # Make a list of poits if they are retrograde or not.
177
-
178
213
  self.t_points_retrograde = []
179
-
180
- for planet in self.t_user.planets_list:
181
- self.t_points_retrograde.append(planet["retrograde"])
182
-
183
- self.t_points_retrograde = self.t_points_retrograde + [False, False, False, False]
214
+ for planet in available_celestial_points:
215
+ self.t_points_retrograde.append(self.t_user.get(planet).retrograde)
184
216
 
185
217
  self.t_houses_sign_graph = []
186
218
  for h in self.t_user.houses_list:
187
219
  self.t_houses_sign_graph.append(h["sign_num"])
188
220
 
189
221
  # screen size
190
- if self.chart_type == "Natal":
191
- self.screen_width = 772.2
222
+ self.height = self._DEFAULT_HEIGHT
223
+ if self.chart_type == "Synastry" or self.chart_type == "Transit":
224
+ self.width = self._DEFAULT_FULL_WIDTH
192
225
  else:
193
- self.screen_width = 1200
194
- self.screen_height = 772.2
195
-
196
- # check for home
197
- self.home_location = self.user.city
198
- self.home_geolat = self.user.lat
199
- self.home_geolon = self.user.lng
200
- self.home_countrycode = self.user.nation
201
- self.home_timezonestr = self.user.tz_str
202
-
203
- print(f"{self.user.name} birth location: {self.home_location}, {self.home_geolat}, {self.home_geolon}")
226
+ self.width = self._DEFAULT_NATAL_WIDTH
204
227
 
205
228
  # default location
206
- self.location = self.home_location
207
- self.geolat = float(self.home_geolat)
208
- self.geolon = float(self.home_geolon)
209
- self.countrycode = self.home_countrycode
210
- self.timezonestr = self.home_timezonestr
211
-
212
- # current datetime
213
- now = datetime.now()
214
-
215
- # aware datetime object
216
- dt_input = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second)
217
- dt = pytz.timezone(self.timezonestr).localize(dt_input)
218
-
219
- # naive utc datetime object
220
- dt_utc = dt.replace(tzinfo=None) - dt.utcoffset() # type: ignore
221
-
222
- # Default
223
- self.name = self.user.name
224
- self.charttype = self.chart_type
225
- self.year = self.user.utc.year
226
- self.month = self.user.utc.month
227
- self.day = self.user.utc.day
228
- self.hour = self.user.utc.hour + self.user.utc.minute / 100
229
- self.timezone = offsetToTz(dt.utcoffset())
230
- self.altitude = 25
231
- self.geonameid = None
232
-
233
- # Transit
229
+ self.location = self.user.city
230
+ self.geolat = self.user.lat
231
+ self.geolon = self.user.lng
232
+
233
+ logging.info(f"{self.user.name} birth location: {self.location}, {self.geolat}, {self.geolon}")
234
234
 
235
235
  if self.chart_type == "Transit":
236
- self.t_geolon = self.geolon
237
- self.t_geolat = self.geolat
238
- self.t_altitude = self.altitude
239
236
  self.t_name = self.language_settings["transit_name"]
240
- self.t_year = dt_utc.year
241
- self.t_month = dt_utc.month
242
- self.t_day = dt_utc.day
243
- self.t_hour = decHourJoin(dt_utc.hour, dt_utc.minute, dt_utc.second)
244
- self.t_timezone = offsetToTz(dt.utcoffset())
245
- self.t_altitude = 25
246
- self.t_geonameid = None
247
237
 
248
238
  # configuration
249
239
  # ZOOM 1 = 100%
@@ -264,22 +254,20 @@ class KerykeionChartSVG:
264
254
  {"name": "pisces", "element": "water"},
265
255
  )
266
256
 
267
- # Immediately generate template.
268
- self.template = self.makeTemplate()
257
+ self.template = None
269
258
 
270
259
  def set_output_directory(self, dir_path: Path) -> None:
271
260
  """
272
261
  Sets the output direcotry and returns it's path.
273
262
  """
274
263
  self.output_directory = dir_path
275
- dir_string = f"Output direcotry set to: {self.output_directory}"
276
- return print(dir_string)
264
+ logging.info(f"Output direcotry set to: {self.output_directory}")
277
265
 
278
266
  def parse_json_settings(self, settings_file):
279
267
  """
280
268
  Parse the settings file.
281
269
  """
282
- settings = get_settings_dict(settings_file)
270
+ settings = get_settings(settings_file)
283
271
 
284
272
  language = settings["general_settings"]["language"]
285
273
  self.language_settings = settings["language_settings"].get(language, "EN")
@@ -289,163 +277,30 @@ class KerykeionChartSVG:
289
277
  self.planet_in_zodiac_extra_points = settings["general_settings"]["planet_in_zodiac_extra_points"]
290
278
  self.chart_settings = settings["chart_settings"]
291
279
 
292
- def _transitRing(self, r) -> str:
293
- """
294
- Draws the transit ring.
295
- """
296
- radius_offset = 18
297
-
298
- out = f'<circle cx="{r}" cy="{r}" r="{r - radius_offset}" style="fill: none; stroke: {self.chart_colors_settings["paper_1"]}; stroke-width: 36px; stroke-opacity: .4;"/>'
299
- out += f'<circle cx="{r}" cy="{r}" r="{r}" style="fill: none; stroke: {self.chart_colors_settings["zodiac_transit_ring_3"]}; stroke-width: 1px; stroke-opacity: .6;"/>'
300
-
301
- return out
302
-
303
- def _degreeRing(self, r) -> str:
280
+ def _draw_zodiac_circle_slices(self, r):
304
281
  """
305
- Draws the degree ring.
306
- """
307
- out = ""
308
- for i in range(72):
309
- offset = float(i * 5) - self.user.houses_degree_ut[6]
310
- if offset < 0:
311
- offset = offset + 360.0
312
- elif offset > 360:
313
- offset = offset - 360.0
314
- x1 = sliceToX(0, r - self.c1, offset) + self.c1
315
- y1 = sliceToY(0, r - self.c1, offset) + self.c1
316
- x2 = sliceToX(0, r + 2 - self.c1, offset) - 2 + self.c1
317
- y2 = sliceToY(0, r + 2 - self.c1, offset) - 2 + self.c1
318
-
319
- out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.chart_colors_settings["paper_0"]}; stroke-width: 1px; stroke-opacity:.9;"/>'
320
-
321
- return out
322
-
323
- def _degreeTransitRing(self, r):
324
- out = ""
325
- for i in range(72):
326
- offset = float(i * 5) - self.user.houses_degree_ut[6]
327
- if offset < 0:
328
- offset = offset + 360.0
329
- elif offset > 360:
330
- offset = offset - 360.0
331
- x1 = sliceToX(0, r, offset)
332
- y1 = sliceToY(0, r, offset)
333
- x2 = sliceToX(0, r + 2, offset) - 2
334
- y2 = sliceToY(0, r + 2, offset) - 2
335
- out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>'
336
-
337
- return out
338
-
339
- def _lat2str(self, coord):
340
- """Converts a floating point latitude to string with
341
- degree, minutes and seconds and the appropriate sign
342
- (north or south). Eg. 52.1234567 -> 52°7'25" N
282
+ Generate the SVG string representing the zodiac circle
283
+ with the 12 slices for each zodiac sign.
343
284
 
344
285
  Args:
345
- coord (float): latitude in floating point format
346
- Returns:
347
- str: latitude in string format with degree, minutes,
348
- seconds and sign (N/S)
349
- """
350
-
351
- sign = self.language_settings["north"]
352
- if coord < 0.0:
353
- sign = self.language_settings["south"]
354
- coord = abs(coord)
355
- deg = int(coord)
356
- min = int((float(coord) - deg) * 60)
357
- sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
358
- return f"{deg}°{min}'{sec}\" {sign}"
286
+ r (float): The radius of the zodiac slices.
359
287
 
360
- def _lon2str(self, coord):
361
- """Converts a floating point longitude to string with
362
- degree, minutes and seconds and the appropriate sign
363
- (east or west). Eg. 52.1234567 -> 52°7'25" E
364
-
365
- Args:
366
- coord (float): longitude in floating point format
367
288
  Returns:
368
- str: longitude in string format with degree, minutes,
369
- seconds and sign (E/W)
289
+ str: The SVG string representing the zodiac circle.
370
290
  """
371
291
 
372
- sign = self.language_settings["east"]
373
- if coord < 0.0:
374
- sign = self.language_settings["west"]
375
- coord = abs(coord)
376
- deg = int(coord)
377
- min = int((float(coord) - deg) * 60)
378
- sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
379
- return f"{deg}°{min}'{sec}\" {sign}"
380
-
381
- def _dec2deg(self, dec, type="3"):
382
- """Coverts decimal float to degrees in format
383
- a°b'c".
384
- """
385
-
386
- dec = float(dec)
387
- a = int(dec)
388
- a_new = (dec - float(a)) * 60.0
389
- b_rounded = int(round(a_new))
390
- b = int(a_new)
391
- c = int(round((a_new - float(b)) * 60.0))
392
- if type == "3":
393
- out = f"{a:02d}&#176;{b:02d}&#39;{c:02d}&#34;"
394
- elif type == "2":
395
- out = f"{a:02d}&#176;{b_rounded:02d}&#39;"
396
- elif type == "1":
397
- out = f"{a:02d}&#176;"
398
- else:
399
- raise KerykeionException(f"Wrong type: {type}, it must be 1, 2 or 3.")
400
- return str(out)
401
-
402
- def _drawAspect(self, r, ar, degA, degB, color):
403
- """
404
- Draws svg aspects: ring, aspect ring, degreeA degreeB
405
- """
406
- offset = (int(self.user.houses_degree_ut[6]) / -1) + int(degA)
407
- x1 = sliceToX(0, ar, offset) + (r - ar)
408
- y1 = sliceToY(0, ar, offset) + (r - ar)
409
- offset = (int(self.user.houses_degree_ut[6]) / -1) + int(degB)
410
- x2 = sliceToX(0, ar, offset) + (r - ar)
411
- y2 = sliceToY(0, ar, offset) + (r - ar)
412
- out = f' <line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {color}; stroke-width: 1; stroke-opacity: .9;"/>'
413
-
414
- return out
415
-
416
- def _zodiacSlice(self, num, r, style, type):
417
- # pie slices
418
- offset = 360 - self.user.houses_degree_ut[6]
419
- # check transit
420
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
421
- dropin = 0
422
- else:
423
- dropin = self.c1
424
- slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>'
425
-
426
- # symbols
427
- offset = offset + 15
428
- # check transit
429
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
430
- dropin = 54
431
- else:
432
- dropin = 18 + self.c1
433
- sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>'
434
-
435
- return slice + "" + sign
436
-
437
- def _makeZodiac(self, r):
438
292
  output = ""
439
- for i in range(len(self.zodiac)):
440
- output = (
441
- output
442
- + self._zodiacSlice(
443
- i,
444
- r,
445
- f'fill:{self.chart_colors_settings[f"zodiac_bg_{i}"]}; fill-opacity: 0.5;',
446
- self.zodiac[i]["name"],
447
- )
293
+ for i, zodiac_element in enumerate(self.zodiac):
294
+ output += draw_zodiac_slice(
295
+ c1=self.c1,
296
+ chart_type=self.chart_type,
297
+ seventh_house_degree_ut=self.user.houses_degree_ut[6],
298
+ num=i,
299
+ r=r,
300
+ style=f'fill:{self.chart_colors_settings[f"zodiac_bg_{i}"]}; fill-opacity: 0.5;',
301
+ type=zodiac_element["name"],
448
302
  )
303
+
449
304
  return output
450
305
 
451
306
  def _makeHouses(self, r):
@@ -535,44 +390,50 @@ class KerykeionChartSVG:
535
390
 
536
391
  return path
537
392
 
538
- def _value_element_from_planet(self, i):
393
+ def _calculate_elements_points_from_planets(self):
539
394
  """
540
395
  Calculate chart element points from a planet.
541
396
  """
397
+
398
+ for i in range(len(self.available_planets_setting)):
399
+ # element: get extra points if planet is in own zodiac sign.
400
+ related_zodiac_signs = self.available_planets_setting[i]["related_zodiac_signs"]
401
+ cz = self.points_sign[i]
402
+ extra_points = 0
403
+ if related_zodiac_signs != []:
404
+ for e in range(len(related_zodiac_signs)):
405
+ if int(related_zodiac_signs[e]) == int(cz):
406
+ extra_points = self.planet_in_zodiac_extra_points
542
407
 
543
- # element: get extra points if planet is in own zodiac sign.
544
- related_zodiac_signs = self.planets_settings[i]["related_zodiac_signs"]
545
- cz = self.points_sign[i]
546
- extra_points = 0
547
- if related_zodiac_signs != []:
548
- for e in range(len(related_zodiac_signs)):
549
- if int(related_zodiac_signs[e]) == int(cz):
550
- extra_points = self.planet_in_zodiac_extra_points
551
-
552
- ele = self.zodiac[self.points_sign[i]]["element"]
553
- if ele == "fire":
554
- self.fire = self.fire + self.planets_settings[i]["element_points"] + extra_points
408
+ ele = self.zodiac[self.points_sign[i]]["element"]
409
+ if ele == "fire":
410
+ self.fire = self.fire + self.available_planets_setting[i]["element_points"] + extra_points
555
411
 
556
- elif ele == "earth":
557
- self.earth = self.earth + self.planets_settings[i]["element_points"] + extra_points
412
+ elif ele == "earth":
413
+ self.earth = self.earth + self.available_planets_setting[i]["element_points"] + extra_points
558
414
 
559
- elif ele == "air":
560
- self.air = self.air + self.planets_settings[i]["element_points"] + extra_points
415
+ elif ele == "air":
416
+ self.air = self.air + self.available_planets_setting[i]["element_points"] + extra_points
561
417
 
562
- elif ele == "water":
563
- self.water = self.water + self.planets_settings[i]["element_points"] + extra_points
418
+ elif ele == "water":
419
+ self.water = self.water + self.available_planets_setting[i]["element_points"] + extra_points
564
420
 
565
421
  def _make_planets(self, r):
566
422
  planets_degut = {}
567
- diff = range(len(self.planets_settings))
423
+ diff = range(len(self.available_planets_setting))
568
424
 
569
- for i in range(len(self.planets_settings)):
570
- if self.planets_settings[i]["is_active"] == 1:
571
- # list of planets sorted by degree
572
- logger.debug(f"planet: {i}, degree: {self.points_deg_ut[i]}")
573
- planets_degut[self.points_deg_ut[i]] = i
425
+ for i in range(len(self.available_planets_setting)):
426
+ # list of planets sorted by degree
427
+ logging.debug(f"planet: {i}, degree: {self.points_deg_ut[i]}")
428
+ planets_degut[self.points_deg_ut[i]] = i
574
429
 
575
- self._value_element_from_planet(i)
430
+ """
431
+ FIXME: The planets_degut is a dictionary like:
432
+ {planet_degree: planet_index}
433
+ It should be replaced bu points_deg_ut
434
+ print(self.points_deg_ut)
435
+ print(planets_degut)
436
+ """
576
437
 
577
438
  output = ""
578
439
  keys = list(planets_degut.keys())
@@ -601,24 +462,24 @@ class KerykeionChartSVG:
601
462
  diffb = degreeDiff(next, self.points_deg_ut[i])
602
463
  planets_by_pos[e] = [i, diffa, diffb]
603
464
 
604
- logger.debug(f'{self.planets_settings[i]["label"]}, {diffa}, {diffb}')
465
+ logging.debug(f'{self.available_planets_setting[i]["label"]}, {diffa}, {diffb}')
605
466
 
606
467
  if diffb < planet_drange:
607
468
  if group_open:
608
- groups[-1].append([e, diffa, diffb, self.planets_settings[planets_degut[keys[e]]]["label"]])
469
+ groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
609
470
  else:
610
471
  group_open = True
611
472
  groups.append([])
612
- groups[-1].append([e, diffa, diffb, self.planets_settings[planets_degut[keys[e]]]["label"]])
473
+ groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
613
474
  else:
614
475
  if group_open:
615
- groups[-1].append([e, diffa, diffb, self.planets_settings[planets_degut[keys[e]]]["label"]])
476
+ groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
616
477
  group_open = False
617
478
 
618
479
  def zero(x):
619
480
  return 0
620
481
 
621
- planets_delta = list(map(zero, range(len(self.planets_settings))))
482
+ planets_delta = list(map(zero, range(len(self.available_planets_setting))))
622
483
 
623
484
  # print groups
624
485
  # print planets_by_pos
@@ -730,7 +591,7 @@ class KerykeionChartSVG:
730
591
  y1 = sliceToY(0, (r - self.c3), trueoffset) + self.c3
731
592
  x2 = sliceToX(0, (r - rplanet - 30), trueoffset) + rplanet + 30
732
593
  y2 = sliceToY(0, (r - rplanet - 30), trueoffset) + rplanet + 30
733
- color = self.planets_settings[i]["color"]
594
+ color = self.available_planets_setting[i]["color"]
734
595
  output += (
735
596
  '<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke-width:1px;stroke:%s;stroke-opacity:.3;"/>\n'
736
597
  % (x1, y1, x2, y2, color)
@@ -748,20 +609,21 @@ class KerykeionChartSVG:
748
609
  else:
749
610
  scale = 1
750
611
  # output planet
751
- output += f'<g transform="translate(-{12 * scale},-{12 * scale})"><g transform="scale({scale})"><use x="{planet_x * (1/scale)}" y="{planet_y * (1/scale)}" xlink:href="#{self.planets_settings[i]["name"]}" /></g></g>'
612
+ output += f'<g transform="translate(-{12 * scale},-{12 * scale})"><g transform="scale({scale})"><use x="{planet_x * (1/scale)}" y="{planet_y * (1/scale)}" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g></g>'
752
613
 
753
614
  # make transit degut and display planets
754
615
  if self.chart_type == "Transit" or self.chart_type == "Synastry":
755
616
  group_offset = {}
756
617
  t_planets_degut = {}
757
- if self.chart_type == "Transit":
758
- list_range = len(self.planets_settings) - 4
759
- else:
760
- list_range = len(self.planets_settings)
618
+ list_range = len(self.available_planets_setting)
619
+
761
620
  for i in range(list_range):
621
+ if self.chart_type == "Transit" and self.available_planets_setting[i]['name'] in self.transit_ring_exclude_points_names:
622
+ continue
623
+
762
624
  group_offset[i] = 0
763
- if self.planets_settings[i]["is_active"] == 1:
764
- t_planets_degut[self.t_points_deg_ut[i]] = i
625
+ t_planets_degut[self.t_points_deg_ut[i]] = i
626
+
765
627
  t_keys = list(t_planets_degut.keys())
766
628
  t_keys.sort()
767
629
 
@@ -803,7 +665,12 @@ class KerykeionChartSVG:
803
665
  group_offset[groups[i][3]] = 2.0
804
666
 
805
667
  switch = 0
668
+
669
+ # Transit planets loop
806
670
  for e in range(len(t_keys)):
671
+ if self.chart_type == "Transit" and self.available_planets_setting[e]["name"] in self.transit_ring_exclude_points_names:
672
+ continue
673
+
807
674
  i = t_planets_degut[t_keys[e]]
808
675
 
809
676
  if 22 < i < 27:
@@ -815,20 +682,21 @@ class KerykeionChartSVG:
815
682
  rplanet = 26
816
683
  switch = 1
817
684
 
685
+ # Transit planet name
818
686
  zeropoint = 360 - self.user.houses_degree_ut[6]
819
687
  t_offset = zeropoint + self.t_points_deg_ut[i]
820
688
  if t_offset > 360:
821
689
  t_offset = t_offset - 360
822
690
  planet_x = sliceToX(0, (r - rplanet), t_offset) + rplanet
823
691
  planet_y = sliceToY(0, (r - rplanet), t_offset) + rplanet
824
- output += f'<g transform="translate(-6,-6)"><g transform="scale(0.5)"><use x="{planet_x*2}" y="{planet_y*2}" xlink:href="#{self.planets_settings[i]["name"]}" /></g></g>'
692
+ output += f'<g class="transit-planet-name" transform="translate(-6,-6)"><g transform="scale(0.5)"><use x="{planet_x*2}" y="{planet_y*2}" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g></g>'
825
693
 
826
- # transit planet line
694
+ # Transit planet line
827
695
  x1 = sliceToX(0, r + 3, t_offset) - 3
828
696
  y1 = sliceToY(0, r + 3, t_offset) - 3
829
697
  x2 = sliceToX(0, r - 3, t_offset) + 3
830
698
  y2 = sliceToY(0, r - 3, t_offset) + 3
831
- output += f'<line x1="{str(x1)}" y1="{str(y1)}" x2="{str(x2)}" y2="{str(y2)}" style="stroke: {self.planets_settings[i]["color"]}; stroke-width: 1px; stroke-opacity:.8;"/>'
699
+ output += f'<line class="transit-planet-line" x1="{str(x1)}" y1="{str(y1)}" x2="{str(x2)}" y2="{str(y2)}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 1px; stroke-opacity:.8;"/>'
832
700
 
833
701
  # transit planet degree text
834
702
  rotate = self.user.houses_degree_ut[0] - self.t_points_deg_ut[i]
@@ -852,7 +720,7 @@ class KerykeionChartSVG:
852
720
  degree = int(t_offset)
853
721
  output += f'<g transform="translate({deg_x},{deg_y})">'
854
722
  output += f'<text transform="rotate({rotate})" text-anchor="{textanchor}'
855
- output += f'" style="fill: {self.planets_settings[i]["color"]}; font-size: 10px;">{self._dec2deg(self.t_points_deg[i], type="1")}'
723
+ output += f'" style="fill: {self.available_planets_setting[i]["color"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.t_points_deg[i], type="1")}'
856
724
  output += "</text></g>"
857
725
 
858
726
  # check transit
@@ -867,7 +735,7 @@ class KerykeionChartSVG:
867
735
  x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
868
736
  y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
869
737
 
870
- output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.planets_settings[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
738
+ output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
871
739
 
872
740
  # check transit
873
741
  if self.chart_type == "Transit" or self.chart_type == "Synastry":
@@ -879,7 +747,7 @@ class KerykeionChartSVG:
879
747
  y1 = sliceToY(0, r - dropin, offset) + dropin
880
748
  x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
881
749
  y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
882
- output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.planets_settings[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
750
+ output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
883
751
 
884
752
  return output
885
753
 
@@ -897,7 +765,7 @@ class KerykeionChartSVG:
897
765
  tr = {} # 6
898
766
  qc = {} # 9
899
767
  sext = {} # 3
900
- for i in range(len(self.planets_settings)):
768
+ for i in range(len(self.available_planets_setting)):
901
769
  a = self.points_deg_ut[i]
902
770
  qc[i] = {}
903
771
  sext[i] = {}
@@ -906,14 +774,14 @@ class KerykeionChartSVG:
906
774
  tr[i] = {}
907
775
  conj[i] = {}
908
776
  # skip some points
909
- n = self.planets_settings[i]["name"]
777
+ n = self.available_planets_setting[i]["name"]
910
778
  if n == "earth" or n == "True_Node" or n == "osc. apogee" or n == "intp. apogee" or n == "intp. perigee":
911
779
  continue
912
780
  if n == "Dsc" or n == "Ic":
913
781
  continue
914
- for j in range(len(self.planets_settings)):
782
+ for j in range(len(self.available_planets_setting)):
915
783
  # skip some points
916
- n = self.planets_settings[j]["name"]
784
+ n = self.available_planets_setting[j]["name"]
917
785
  if n == "earth" or n == "True_Node" or n == "osc. apogee" or n == "intp. apogee" or n == "intp. perigee":
918
786
  continue
919
787
  if n == "Dsc" or n == "Ic":
@@ -966,12 +834,12 @@ class KerykeionChartSVG:
966
834
  for l, w in opp[k].items():
967
835
  for a, b in sq.items():
968
836
  if k in sq[a] and l in sq[a]:
969
- logger.debug(f"Got tsquare {a} {k} {l}")
837
+ logging.debug(f"Got tsquare {a} {k} {l}")
970
838
  if k > l:
971
- tsquare[f"{a},{l},{k}"] = f"{self.planets_settings[a]['label']} => {self.planets_settings[l]['label']}, {self.planets_settings[k]['label']}"
839
+ tsquare[f"{a},{l},{k}"] = f"{self.available_planets_setting[a]['label']} => {self.available_planets_setting[l]['label']}, {self.available_planets_setting[k]['label']}"
972
840
 
973
841
  else:
974
- tsquare[f"{a},{k},{l}"] = f"{self.planets_settings[a]['label']} => {self.planets_settings[k]['label']}, {self.planets_settings[l]['label']}"
842
+ tsquare[f"{a},{k},{l}"] = f"{self.available_planets_setting[a]['label']} => {self.available_planets_setting[k]['label']}, {self.available_planets_setting[l]['label']}"
975
843
 
976
844
  stellium = {}
977
845
  # check for 4 continuous conjunctions
@@ -1000,10 +868,10 @@ class KerykeionChartSVG:
1000
868
  l = [k, n, p, r]
1001
869
  l.sort()
1002
870
  stellium["%s %s %s %s" % (l[0], l[1], l[2], l[3])] = "%s %s %s %s" % (
1003
- self.planets_settings[l[0]]["label"],
1004
- self.planets_settings[l[1]]["label"],
1005
- self.planets_settings[l[2]]["label"],
1006
- self.planets_settings[l[3]]["label"],
871
+ self.available_planets_setting[l[0]]["label"],
872
+ self.available_planets_setting[l[1]]["label"],
873
+ self.available_planets_setting[l[2]]["label"],
874
+ self.available_planets_setting[l[3]]["label"],
1007
875
  )
1008
876
  # print yots
1009
877
  out = '<g transform="translate(-30,380)">'
@@ -1014,15 +882,15 @@ class KerykeionChartSVG:
1014
882
 
1015
883
  # first planet symbol
1016
884
  out += f'<g transform="translate(20,{y})">'
1017
- out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.planets_settings[yot[k][0]]["name"]}" /></g>'
885
+ out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.available_planets_setting[yot[k][0]]["name"]}" /></g>'
1018
886
 
1019
887
  # second planet symbol
1020
888
  out += f'<g transform="translate(30,{y})">'
1021
- out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.planets_settings[yot[k][1]]["name"]}" /></g>'
889
+ out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.available_planets_setting[yot[k][1]]["name"]}" /></g>'
1022
890
 
1023
891
  # third planet symbol
1024
892
  out += f'<g transform="translate(40,{y})">'
1025
- out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.planets_settings[yot[k][2]]["name"]}" /></g>'
893
+ out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.available_planets_setting[yot[k][2]]["name"]}" /></g>'
1026
894
 
1027
895
  y = y + 14
1028
896
  # finalize
@@ -1034,12 +902,13 @@ class KerykeionChartSVG:
1034
902
  def _makeAspects(self, r, ar):
1035
903
  out = ""
1036
904
  for element in self.aspects_list:
1037
- out += self._drawAspect(
1038
- r,
1039
- ar,
1040
- element["p1_abs_pos"],
1041
- element["p2_abs_pos"],
1042
- self.aspects_settings[element["aid"]]["color"],
905
+ out += draw_aspect_line(
906
+ r=r,
907
+ ar=ar,
908
+ degA=element["p1_abs_pos"],
909
+ degB=element["p2_abs_pos"],
910
+ color=self.aspects_settings[element["aid"]]["color"],
911
+ seventh_house_degree_ut=self.user.seventh_house.abs_pos
1043
912
  )
1044
913
 
1045
914
  return out
@@ -1050,29 +919,27 @@ class KerykeionChartSVG:
1050
919
  xindent = 380
1051
920
  yindent = 468
1052
921
  box = 14
1053
- revr = list(range(len(self.planets_settings)))
922
+ revr = list(range(len(self.available_planets_setting)))
1054
923
  revr.reverse()
1055
924
  counter = 0
1056
925
  for a in revr:
1057
926
  counter += 1
1058
- if self.planets_settings[a]["is_active"] == 1:
1059
- out += f'<rect x="{xindent}" y="{yindent}" width="{box}" height="{box}" style="{style}"/>'
1060
- out += f'<use transform="scale(0.4)" x="{(xindent+2)*2.5}" y="{(yindent+1)*2.5}" xlink:href="#{self.planets_settings[a]["name"]}" />'
1061
-
1062
- xindent = xindent + box
1063
- yindent = yindent - box
1064
- revr2 = list(range(a))
1065
- revr2.reverse()
1066
- xorb = xindent
1067
- yorb = yindent + box
1068
- for b in revr2:
1069
- if self.planets_settings[b]["is_active"] == 1:
1070
- out += f'<rect x="{xorb}" y="{yorb}" width="{box}" height="{box}" style="{style}"/>'
1071
-
1072
- xorb = xorb + box
1073
- for element in self.aspects_list:
1074
- if (element["p1"] == a and element["p2"] == b) or (element["p1"] == b and element["p2"] == a):
1075
- out += f'<use x="{xorb-box+1}" y="{yorb+1}" xlink:href="#orb{element["aspect_degrees"]}" />'
927
+ out += f'<rect x="{xindent}" y="{yindent}" width="{box}" height="{box}" style="{style}"/>'
928
+ out += f'<use transform="scale(0.4)" x="{(xindent+2)*2.5}" y="{(yindent+1)*2.5}" xlink:href="#{self.available_planets_setting[a]["name"]}" />'
929
+
930
+ xindent = xindent + box
931
+ yindent = yindent - box
932
+ revr2 = list(range(a))
933
+ revr2.reverse()
934
+ xorb = xindent
935
+ yorb = yindent + box
936
+ for b in revr2:
937
+ out += f'<rect x="{xorb}" y="{yorb}" width="{box}" height="{box}" style="{style}"/>'
938
+
939
+ xorb = xorb + box
940
+ for element in self.aspects_list:
941
+ if (element["p1"] == a and element["p2"] == b) or (element["p1"] == b and element["p2"] == a):
942
+ out += f'<use x="{xorb-box+1}" y="{yorb+1}" xlink:href="#orb{element["aspect_degrees"]}" />'
1076
943
 
1077
944
  return out
1078
945
 
@@ -1080,15 +947,16 @@ class KerykeionChartSVG:
1080
947
  def _makeAspectsTransit(self, r, ar):
1081
948
  out = ""
1082
949
 
1083
- self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).get_relevant_aspects()
950
+ self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).relevant_aspects
1084
951
 
1085
952
  for element in self.aspects_list:
1086
- out += self._drawAspect(
1087
- r,
1088
- ar,
1089
- element["p1_abs_pos"],
1090
- element["p2_abs_pos"],
1091
- self.aspects_settings[element["aid"]]["color"],
953
+ out += draw_aspect_line(
954
+ r=r,
955
+ ar=ar,
956
+ degA=element["p1_abs_pos"],
957
+ degB=element["p2_abs_pos"],
958
+ color=self.aspects_settings[element["aid"]]["color"],
959
+ seventh_house_degree_ut=self.user.seventh_house.abs_pos
1092
960
  )
1093
961
 
1094
962
  return out
@@ -1126,55 +994,37 @@ class KerykeionChartSVG:
1126
994
  line = 0
1127
995
 
1128
996
  out += f'<g transform="translate({nl},{line})">'
997
+
1129
998
  # first planet symbol
1130
-
1131
- # TODO: (next((item for item in self.planets_settings if item["id"] == self.aspects_list[i]["p1"]))) It preventes the use ot numeric ID, but it is not working.
1132
999
  out += f'<use transform="scale(0.4)" x="0" y="3" xlink:href="#{self.planets_settings[self.aspects_list[i]["p1"]]["name"]}" />'
1133
1000
 
1134
1001
  # aspect symbol
1135
1002
  out += f'<use x="15" y="0" xlink:href="#orb{self.aspects_settings[self.aspects_list[i]["aid"]]["degree"]}" />'
1003
+
1136
1004
  # second planet symbol
1137
1005
  out += '<g transform="translate(30,0)">'
1138
-
1139
- # TODO: (next((item for item in self.planets_settings if item["id"] == self.aspects_list[i]["p3"])))
1140
1006
  out += '<use transform="scale(0.4)" x="0" y="3" xlink:href="#%s" />' % (self.planets_settings[self.aspects_list[i]["p2"]]["name"])
1141
1007
 
1142
1008
  out += "</g>"
1143
1009
  # difference in degrees
1144
- out += f'<text y="8" x="45" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self._dec2deg(self.aspects_list[i]["orbit"])}</text>'
1010
+ out += f'<text y="8" x="45" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.aspects_list[i]["orbit"])}</text>'
1145
1011
  # line
1146
1012
  out += "</g>"
1147
1013
  line = line + 14
1148
1014
  out += "</g>"
1149
1015
  return out
1150
1016
 
1151
- def _makeElements(self, r):
1152
- total = self.fire + self.earth + self.air + self.water
1153
- pf = int(round(100 * self.fire / total))
1154
- pe = int(round(100 * self.earth / total))
1155
- pa = int(round(100 * self.air / total))
1156
- pw = int(round(100 * self.water / total))
1157
-
1158
- out = '<g transform="translate(-30,79)">'
1159
- out += f'<text y="0" style="fill:#ff6600; font-size: 10px;">{self.language_settings["fire"]} {str(pf)}%</text>'
1160
- out += f'<text y="12" style="fill:#6a2d04; font-size: 10px;">{self.language_settings["earth"]} {str(pe)}%</text>'
1161
- out += f'<text y="24" style="fill:#6f76d1; font-size: 10px;">{self.language_settings["air"]} {str(pa)}%</text>'
1162
- out += f'<text y="36" style="fill:#630e73; font-size: 10px;">{self.language_settings["water"]} {str(pw)}%</text>'
1163
- out += "</g>"
1164
-
1165
- return out
1166
-
1167
1017
  def _makePlanetGrid(self):
1168
1018
  li = 10
1169
1019
  offset = 0
1170
1020
 
1171
- out = '<g transform="translate(500,-20)">'
1021
+ out = '<g transform="translate(510,-20)">'
1172
1022
  out += '<g transform="translate(140, -15)">'
1173
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.name}:</text>'
1023
+ out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.user.name}:</text>'
1174
1024
  out += "</g>"
1175
1025
 
1176
1026
  end_of_line = None
1177
- for i in range(len(self.planets_settings)):
1027
+ for i in range(len(self.available_planets_setting)):
1178
1028
  offset_between_lines = 14
1179
1029
  end_of_line = "</g>"
1180
1030
 
@@ -1183,30 +1033,29 @@ class KerykeionChartSVG:
1183
1033
  li = 10
1184
1034
  offset = -120
1185
1035
 
1186
- if self.planets_settings[i]["is_active"] == 1:
1187
- # start of line
1188
- out += f'<g transform="translate({offset},{li})">'
1036
+ # start of line
1037
+ out += f'<g transform="translate({offset},{li})">'
1189
1038
 
1190
- # planet text
1191
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.planets_settings[i]["label"]]}</text>'
1039
+ # planet text
1040
+ out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.available_planets_setting[i]["label"]]}</text>'
1192
1041
 
1193
- # planet symbol
1194
- out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.planets_settings[i]["name"]}" /></g>'
1042
+ # planet symbol
1043
+ out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g>'
1195
1044
 
1196
- # planet degree
1197
- out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self._dec2deg(self.points_deg[i])}</text>'
1045
+ # planet degree
1046
+ out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.points_deg[i])}</text>'
1198
1047
 
1199
- # zodiac
1200
- out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.points_sign[i]]["name"]}" /></g>'
1048
+ # zodiac
1049
+ out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.points_sign[i]]["name"]}" /></g>'
1201
1050
 
1202
- # planet retrograde
1203
- if self.points_retrograde[i]:
1204
- out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
1051
+ # planet retrograde
1052
+ if self.points_retrograde[i]:
1053
+ out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
1205
1054
 
1206
- # end of line
1207
- out += end_of_line
1055
+ # end of line
1056
+ out += end_of_line
1208
1057
 
1209
- li = li + offset_between_lines
1058
+ li = li + offset_between_lines
1210
1059
 
1211
1060
  if self.chart_type == "Transit" or self.chart_type == "Synastry":
1212
1061
  if self.chart_type == "Transit":
@@ -1221,32 +1070,31 @@ class KerykeionChartSVG:
1221
1070
  t_li = 10
1222
1071
  t_offset = 250
1223
1072
 
1224
- for i in range(len(self.planets_settings)):
1073
+ for i in range(len(self.available_planets_setting)):
1225
1074
  if i == 27:
1226
1075
  t_li = 10
1227
1076
  t_offset = -120
1228
1077
 
1229
- if self.planets_settings[i]["is_active"] == 1:
1230
- # start of line
1231
- out += f'<g transform="translate({t_offset},{t_li})">'
1078
+ # start of line
1079
+ out += f'<g transform="translate({t_offset},{t_li})">'
1232
1080
 
1233
- # planet text
1234
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.planets_settings[i]["label"]]}</text>'
1235
- # planet symbol
1236
- out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.planets_settings[i]["name"]}" /></g>'
1237
- # planet degree
1238
- out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self._dec2deg(self.t_points_deg[i])}</text>'
1239
- # zodiac
1240
- out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_points_sign[i]]["name"]}" /></g>'
1081
+ # planet text
1082
+ out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.available_planets_setting[i]["label"]]}</text>'
1083
+ # planet symbol
1084
+ out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g>'
1085
+ # planet degree
1086
+ out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.t_points_deg[i])}</text>'
1087
+ # zodiac
1088
+ out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_points_sign[i]]["name"]}" /></g>'
1241
1089
 
1242
- # planet retrograde
1243
- if self.t_points_retrograde[i]:
1244
- out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
1090
+ # planet retrograde
1091
+ if self.t_points_retrograde[i]:
1092
+ out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
1245
1093
 
1246
- # end of line
1247
- out += end_of_line
1094
+ # end of line
1095
+ out += end_of_line
1248
1096
 
1249
- t_li = t_li + offset_between_lines
1097
+ t_li = t_li + offset_between_lines
1250
1098
 
1251
1099
  if end_of_line is None:
1252
1100
  raise KerykeionException("End of line not found")
@@ -1254,8 +1102,14 @@ class KerykeionChartSVG:
1254
1102
  out += end_of_line
1255
1103
  return out
1256
1104
 
1257
- def _makeHousesGrid(self):
1258
- out = '<g transform="translate(600,-20)">'
1105
+ def _draw_house_grid(self):
1106
+ """
1107
+ Generate SVG code for a grid of astrological houses.
1108
+
1109
+ Returns:
1110
+ str: The SVG code for the grid of houses.
1111
+ """
1112
+ out = '<g transform="translate(610,-20)">'
1259
1113
 
1260
1114
  li = 10
1261
1115
  for i in range(12):
@@ -1266,15 +1120,17 @@ class KerykeionChartSVG:
1266
1120
  out += f'<g transform="translate(0,{li})">'
1267
1121
  out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
1268
1122
  out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.houses_sign_graph[i]]["name"]}" /></g>'
1269
- out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {self._dec2deg(self.user.houses_list[i]["position"])}</text>'
1123
+ out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {convert_decimal_to_degree_string(self.user.houses_list[i]["position"])}</text>'
1270
1124
  out += "</g>"
1271
1125
  li = li + 14
1272
1126
 
1273
1127
  out += "</g>"
1274
1128
 
1275
1129
  if self.chart_type == "Synastry":
1276
- out += '<g transform="translate(840, -20)">'
1130
+ out += '<!-- Synastry Houses -->'
1131
+ out += '<g transform="translate(850, -20)">'
1277
1132
  li = 10
1133
+
1278
1134
  for i in range(12):
1279
1135
  if i < 9:
1280
1136
  cusp = "&#160;&#160;" + str(i + 1)
@@ -1283,14 +1139,14 @@ class KerykeionChartSVG:
1283
1139
  out += '<g transform="translate(0,' + str(li) + ')">'
1284
1140
  out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
1285
1141
  out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_houses_sign_graph[i]]["name"]}" /></g>'
1286
- out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {self._dec2deg(self.t_user.houses_list[i]["position"])}</text>'
1142
+ out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {convert_decimal_to_degree_string(self.t_user.houses_list[i]["position"])}</text>'
1287
1143
  out += "</g>"
1288
1144
  li = li + 14
1289
1145
  out += "</g>"
1290
1146
 
1291
1147
  return out
1292
1148
 
1293
- def _createTemplateDictionary(self):
1149
+ def _createTemplateDictionary(self) -> ChartTemplateDictionary:
1294
1150
  # self.chart_type = "Transit"
1295
1151
  # empty element points
1296
1152
  self.fire = 0.0
@@ -1298,18 +1154,13 @@ class KerykeionChartSVG:
1298
1154
  self.air = 0.0
1299
1155
  self.water = 0.0
1300
1156
 
1301
- # width and height from screen
1302
- ratio = float(self.screen_width) / float(self.screen_height)
1303
- if ratio < 1.3: # 1280x1024
1304
- wm_off = 130
1305
- else: # 1024x768, 800x600, 1280x800, 1680x1050
1306
- wm_off = 100
1157
+ # Calculate the elements points
1158
+ self._calculate_elements_points_from_planets()
1307
1159
 
1308
1160
  # Viewbox and sizing
1309
1161
  svgHeight = "100%"
1310
1162
  svgWidth = "100%"
1311
1163
  rotate = "0"
1312
- translate = "0"
1313
1164
 
1314
1165
  # To increase the size of the chart, change the viewbox
1315
1166
  if self.chart_type == "Natal" or self.chart_type == "ExternalNatal":
@@ -1318,7 +1169,7 @@ class KerykeionChartSVG:
1318
1169
  viewbox = self.chart_settings["wide_chart_viewBox"]
1319
1170
 
1320
1171
  # template dictionary
1321
- td: ChartTemplateModel = dict()
1172
+ td: ChartTemplateDictionary = dict() # type: ignore
1322
1173
  r = 240
1323
1174
 
1324
1175
  if self.chart_type == "ExternalNatal":
@@ -1332,14 +1183,12 @@ class KerykeionChartSVG:
1332
1183
 
1333
1184
  # transit
1334
1185
  if self.chart_type == "Transit" or self.chart_type == "Synastry":
1335
- td["transitRing"] = self._transitRing(r)
1336
- td["degreeRing"] = self._degreeTransitRing(r)
1186
+ td["transitRing"] = draw_transit_ring(r, self.chart_colors_settings["paper_1"], self.chart_colors_settings["zodiac_transit_ring_3"])
1187
+ td["degreeRing"] = draw_transit_ring_degree_steps(r, self.user.seventh_house.abs_pos)
1337
1188
 
1338
1189
  # circles
1339
- td["c1"] = f'cx="{r}" cy="{r}" r="{r - 36}"'
1340
- td["c1style"] = f'fill: none; stroke: {self.chart_colors_settings["zodiac_transit_ring_2"]}; stroke-width: 1px; stroke-opacity:.4;'
1341
- td["c2"] = 'cx="' + str(r) + '" cy="' + str(r) + '" r="' + str(r - 72) + '"'
1342
- td["c2style"] = f"fill: {self.chart_colors_settings['paper_1']}; fill-opacity:.4; stroke: {self.chart_colors_settings['zodiac_transit_ring_1']}; stroke-opacity:.4; stroke-width: 1px"
1190
+ td["first_circle"] = draw_first_circle(r, self.chart_colors_settings["zodiac_transit_ring_2"], self.chart_type)
1191
+ td["second_circle"] = draw_second_circle(r, self.chart_colors_settings['zodiac_transit_ring_1'], self.chart_colors_settings['paper_1'], self.chart_type)
1343
1192
 
1344
1193
  td["c3"] = 'cx="' + str(r) + '" cy="' + str(r) + '" r="' + str(r - 160) + '"'
1345
1194
  td["c3style"] = f"fill: {self.chart_colors_settings['paper_1']}; fill-opacity:.8; stroke: {self.chart_colors_settings['zodiac_transit_ring_0']}; stroke-width: 1px"
@@ -1347,49 +1196,59 @@ class KerykeionChartSVG:
1347
1196
  td["makeAspects"] = self._makeAspectsTransit(r, (r - 160))
1348
1197
  td["makeAspectGrid"] = self._makeAspectTransitGrid(r)
1349
1198
  td["makePatterns"] = ""
1350
- td["chart_width"] = self.full_width
1351
1199
  else:
1352
1200
  td["transitRing"] = ""
1353
- td["degreeRing"] = self._degreeRing(r)
1201
+ td["degreeRing"] = draw_degree_ring(r, self.c1, self.user.seventh_house.abs_pos, self.chart_colors_settings["paper_0"])
1354
1202
 
1355
- # circles
1356
- td["c1"] = f'cx="{r}" cy="{r}" r="{r - self.c1}"'
1357
- td["c1style"] = f'fill: none; stroke: {self.chart_colors_settings["zodiac_radix_ring_2"]}; stroke-width: 1px; '
1358
- td["c2"] = f'cx="{r}" cy="{r}" r="{r - self.c2}"'
1359
- td["c2style"] = f'fill: {self.chart_colors_settings["paper_1"]}; fill-opacity:.2; stroke: {self.chart_colors_settings["zodiac_radix_ring_1"]}; stroke-opacity:.4; stroke-width: 1px'
1203
+ td['first_circle'] = draw_first_circle(r, self.chart_colors_settings["zodiac_radix_ring_2"], self.chart_type, self.c1)
1204
+
1205
+ td["second_circle"] = draw_second_circle(r, self.chart_colors_settings["zodiac_radix_ring_1"], self.chart_colors_settings["paper_1"], self.chart_type, self.c2)
1206
+
1360
1207
  td["c3"] = f'cx="{r}" cy="{r}" r="{r - self.c3}"'
1361
1208
  td["c3style"] = f'fill: {self.chart_colors_settings["paper_1"]}; fill-opacity:.8; stroke: {self.chart_colors_settings["zodiac_radix_ring_0"]}; stroke-width: 1px'
1209
+
1362
1210
  td["makeAspects"] = self._makeAspects(r, (r - self.c3))
1363
1211
  td["makeAspectGrid"] = self._makeAspectGrid(r)
1364
1212
  td["makePatterns"] = self._makePatterns()
1365
- td["chart_width"] = self.natal_width
1366
-
1213
+
1214
+ td["chart_height"] = self.height
1215
+ td["chart_width"] = self.width
1367
1216
  td["circleX"] = str(0)
1368
1217
  td["circleY"] = str(0)
1369
1218
  td["svgWidth"] = str(svgWidth)
1370
1219
  td["svgHeight"] = str(svgHeight)
1371
1220
  td["viewbox"] = viewbox
1372
1221
 
1222
+ # Chart Title
1373
1223
  if self.chart_type == "Synastry":
1374
- td["stringTitle"] = f"{self.name} {self.language_settings['and_word']} {self.t_user.name}"
1224
+ td["stringTitle"] = f"{self.user.name} {self.language_settings['and_word']} {self.t_user.name}"
1375
1225
 
1376
1226
  elif self.chart_type == "Transit":
1377
1227
  td["stringTitle"] = f"{self.language_settings['transits']} {self.t_user.day}/{self.t_user.month}/{self.t_user.year}"
1378
1228
 
1379
1229
  else:
1380
- td["stringTitle"] = self.name
1230
+ td["stringTitle"] = self.user.name
1381
1231
 
1382
- # Tipo di carta
1383
- if self.chart_type == "Synastry" or self.name == "Transit":
1384
- td["stringName"] = f"{self.name}:"
1232
+ # Chart Name
1233
+ if self.chart_type == "Synastry" or self.chart_type == "Transit":
1234
+ td["stringName"] = f"{self.user.name}:"
1385
1235
  else:
1386
1236
  td["stringName"] = f'{self.language_settings["info"]}:'
1387
1237
 
1388
- # bottom left
1389
- td["bottomLeft1"] = ""
1390
- td["bottomLeft2"] = ""
1391
- td["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.user.lunar_phase.get("moon_phase", "")}'
1392
- td["bottomLeft4"] = ""
1238
+ # Bottom Left Corner
1239
+ if self.chart_type == "Natal" or self.chart_type == "ExternalNatal" or self.chart_type == "Synastry":
1240
+ td["bottomLeft0"] = f"{self.user.zodiac_type if self.user.zodiac_type == 'Tropic' else self.user.zodiac_type + ' ' + self.user.sidereal_mode}"
1241
+ td["bottomLeft1"] = f"{self.user.houses_system_name}"
1242
+ td["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.user.lunar_phase.get("moon_phase", "")}'
1243
+ td["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.user.lunar_phase.moon_phase_name}'
1244
+ td["bottomLeft4"] = f'{self.user.perspective_type}'
1245
+
1246
+ else:
1247
+ td["bottomLeft0"] = f"{self.user.zodiac_type if self.user.zodiac_type == 'Tropic' else self.user.zodiac_type + ' ' + self.user.sidereal_mode}"
1248
+ td["bottomLeft1"] = f"{self.user.houses_system_name}"
1249
+ td["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.t_user.lunar_phase.get("moon_phase", "")}'
1250
+ td["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.t_user.lunar_phase.moon_phase_name}'
1251
+ td["bottomLeft4"] = f'{self.t_user.perspective_type}'
1393
1252
 
1394
1253
  # lunar phase
1395
1254
  deg = self.user.lunar_phase["degrees_between_s_m"]
@@ -1457,17 +1316,26 @@ class KerykeionChartSVG:
1457
1316
  else:
1458
1317
  td["stringLocation"] = self.location
1459
1318
 
1460
- td["stringDateTime"] = f"{self.user.year}-{self.user.month}-{self.user.day} {self.user.hour:02d}:{self.user.minute:02d}"
1461
-
1462
1319
  if self.chart_type == "Synastry":
1463
1320
  td["stringLat"] = f"{self.t_user.name}: "
1464
1321
  td["stringLon"] = self.t_user.city
1465
1322
  td["stringPosition"] = f"{self.t_user.year}-{self.t_user.month}-{self.t_user.day} {self.t_user.hour:02d}:{self.t_user.minute:02d}"
1466
1323
 
1467
1324
  else:
1468
- td["stringLat"] = f"{self.language_settings['latitude']}: {self._lat2str(self.geolat)}"
1469
- td["stringLon"] = f"{self.language_settings['longitude']}: {self._lon2str(self.geolon)}"
1470
- td["stringPosition"] = f"{self.language_settings['type']}: {self.charttype}"
1325
+ latitude_string = convert_latitude_coordinate_to_string(
1326
+ self.geolat,
1327
+ self.language_settings['north'],
1328
+ self.language_settings['south']
1329
+ )
1330
+ longitude_string = convert_longitude_coordinate_to_string(
1331
+ self.geolon,
1332
+ self.language_settings['east'],
1333
+ self.language_settings['west']
1334
+ )
1335
+
1336
+ td["stringLat"] = f"{self.language_settings['latitude']}: {latitude_string}"
1337
+ td["stringLon"] = f"{self.language_settings['longitude']}: {longitude_string}"
1338
+ td["stringPosition"] = f"{self.language_settings['type']}: {self.chart_type}"
1471
1339
 
1472
1340
  # paper_color_X
1473
1341
  td["paper_color_0"] = self.chart_colors_settings["paper_0"]
@@ -1489,52 +1357,77 @@ class KerykeionChartSVG:
1489
1357
  # config
1490
1358
  td["cfgZoom"] = str(self.zoom)
1491
1359
  td["cfgRotate"] = rotate
1492
- td["cfgTranslate"] = translate
1493
1360
 
1494
- # functions
1495
- td["makeZodiac"] = self._makeZodiac(r)
1361
+ # ---
1362
+ # Drawing Functions
1363
+ #---
1364
+
1365
+ td["makeZodiac"] = self._draw_zodiac_circle_slices(r)
1366
+ td["makeHousesGrid"] = self._draw_house_grid()
1367
+ # TODO: Add the rest of the functions
1496
1368
  td["makeHouses"] = self._makeHouses(r)
1497
1369
  td["makePlanets"] = self._make_planets(r)
1498
- td["makeElements"] = self._makeElements(r)
1370
+ td["elements_percentages"] = draw_elements_percentages(
1371
+ self.language_settings['fire'],
1372
+ self.fire,
1373
+ self.language_settings['earth'],
1374
+ self.earth,
1375
+ self.language_settings['air'],
1376
+ self.air,
1377
+ self.language_settings['water'],
1378
+ self.water,
1379
+ )
1499
1380
  td["makePlanetGrid"] = self._makePlanetGrid()
1500
- td["makeHousesGrid"] = self._makeHousesGrid()
1381
+
1382
+ # Date time String
1383
+ dt = datetime.fromisoformat(self.user.iso_formatted_local_datetime)
1384
+ custom_format = dt.strftime('%Y-%-m-%-d %H:%M [%z]') # Note the use of '-' to remove leading zeros
1385
+ custom_format = custom_format[:-3] + ':' + custom_format[-3:]
1386
+ td["stringDateTime"] = f"{custom_format}"
1501
1387
 
1502
1388
  return td
1503
1389
 
1504
- def makeTemplate(self):
1390
+ def makeTemplate(self, minify: bool = False) -> str:
1505
1391
  """Creates the template for the SVG file"""
1506
1392
  td = self._createTemplateDictionary()
1507
1393
 
1508
1394
  # read template
1509
- with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as output_file:
1510
- f = open(self.xml_svg)
1395
+ with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as f:
1511
1396
  template = Template(f.read()).substitute(td)
1512
1397
 
1513
1398
  # return filename
1514
1399
 
1515
- logger.debug(f"Template dictionary keys: {td.keys()}")
1400
+ logging.debug(f"Template dictionary keys: {td.keys()}")
1516
1401
 
1517
1402
  self._createTemplateDictionary()
1518
- return template.replace('"', "'")
1519
1403
 
1520
- def makeSVG(self):
1404
+ if minify:
1405
+ template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
1406
+
1407
+ else:
1408
+ template = template.replace('"', "'")
1409
+
1410
+ return template
1411
+
1412
+ def makeSVG(self, minify: bool = False):
1521
1413
  """Prints out the SVG file in the specifide folder"""
1522
1414
 
1523
1415
  if not (self.template):
1524
- self.template = self.makeTemplate()
1416
+ self.template = self.makeTemplate(minify)
1525
1417
 
1526
- self.chartname = self.output_directory / f"{self.name}{self.chart_type}Chart.svg"
1418
+ self.chartname = self.output_directory / f"{self.user.name} - {self.chart_type} Chart.svg"
1527
1419
 
1528
1420
  with open(self.chartname, "w", encoding="utf-8", errors="ignore") as output_file:
1529
1421
  output_file.write(self.template)
1530
1422
 
1531
- return print(f"SVG Generated Correctly in: {self.chartname}")
1423
+ logging.info(f"SVG Generated Correctly in: {self.chartname}")
1532
1424
 
1533
1425
 
1534
1426
  if __name__ == "__main__":
1535
- basicConfig(level="DEBUG", force=True)
1427
+ from kerykeion.utilities import setup_logging
1428
+ setup_logging(level="debug")
1536
1429
 
1537
- first = AstrologicalSubject("John Lennon", 1940, 10, 9, 10, 30, "Liverpool", "GB")
1430
+ first = AstrologicalSubject("John Lennon", 1940, 10, 9, 18, 30, "Liverpool", "GB")
1538
1431
  second = AstrologicalSubject("Paul McCartney", 1942, 6, 18, 15, 30, "Liverpool", "GB")
1539
1432
 
1540
1433
  # Internal Natal Chart
@@ -1552,3 +1445,51 @@ if __name__ == "__main__":
1552
1445
  # Transits Chart
1553
1446
  transits_chart = KerykeionChartSVG(first, "Transit", second)
1554
1447
  transits_chart.makeSVG()
1448
+
1449
+ # Sidereal Birth Chart (Lahiri)
1450
+ sidereal_subject = AstrologicalSubject("John Lennon Lahiri", 1940, 10, 9, 18, 30, "Liverpool", "GB", zodiac_type="Sidereal", sidereal_mode="LAHIRI")
1451
+ sidereal_chart = KerykeionChartSVG(sidereal_subject)
1452
+ sidereal_chart.makeSVG()
1453
+
1454
+ # Sidereal Birth Chart (Fagan-Bradley)
1455
+ sidereal_subject = AstrologicalSubject("John Lennon Fagan-Bradley", 1940, 10, 9, 18, 30, "Liverpool", "GB", zodiac_type="Sidereal", sidereal_mode="FAGAN_BRADLEY")
1456
+ sidereal_chart = KerykeionChartSVG(sidereal_subject)
1457
+ sidereal_chart.makeSVG()
1458
+
1459
+ # Sidereal Birth Chart (DeLuce)
1460
+ sidereal_subject = AstrologicalSubject("John Lennon DeLuce", 1940, 10, 9, 18, 30, "Liverpool", "GB", zodiac_type="Sidereal", sidereal_mode="DELUCE")
1461
+ sidereal_chart = KerykeionChartSVG(sidereal_subject)
1462
+ sidereal_chart.makeSVG()
1463
+
1464
+ # Sidereal Birth Chart (J2000)
1465
+ sidereal_subject = AstrologicalSubject("John Lennon J2000", 1940, 10, 9, 18, 30, "Liverpool", "GB", zodiac_type="Sidereal", sidereal_mode="J2000")
1466
+ sidereal_chart = KerykeionChartSVG(sidereal_subject)
1467
+ sidereal_chart.makeSVG()
1468
+
1469
+ # House System Morinus
1470
+ morinus_house_subject = AstrologicalSubject("John Lennon - House System Morinus", 1940, 10, 9, 18, 30, "Liverpool", "GB", houses_system_identifier="M")
1471
+ morinus_house_chart = KerykeionChartSVG(morinus_house_subject)
1472
+ morinus_house_chart.makeSVG()
1473
+
1474
+ ## To check all the available house systems uncomment the following code:
1475
+ # from kerykeion.kr_types import HousesSystemIdentifier
1476
+ # from typing import get_args
1477
+ # for i in get_args(HousesSystemIdentifier):
1478
+ # alternatives_house_subject = AstrologicalSubject(f"John Lennon - House System {i}", 1940, 10, 9, 18, 30, "Liverpool", "GB", houses_system=i)
1479
+ # alternatives_house_chart = KerykeionChartSVG(alternatives_house_subject)
1480
+ # alternatives_house_chart.makeSVG()
1481
+
1482
+ # With True Geocentric Perspective
1483
+ true_geocentric_subject = AstrologicalSubject("John Lennon - True Geocentric", 1940, 10, 9, 18, 30, "Liverpool", "GB", perspective_type="True Geocentric")
1484
+ true_geocentric_chart = KerykeionChartSVG(true_geocentric_subject)
1485
+ true_geocentric_chart.makeSVG()
1486
+
1487
+ # With Heliocentric Perspective
1488
+ heliocentric_subject = AstrologicalSubject("John Lennon - Heliocentric", 1940, 10, 9, 18, 30, "Liverpool", "GB", perspective_type="Heliocentric")
1489
+ heliocentric_chart = KerykeionChartSVG(heliocentric_subject)
1490
+ heliocentric_chart.makeSVG()
1491
+
1492
+ # With Topocentric Perspective
1493
+ topocentric_subject = AstrologicalSubject("John Lennon - Topocentric", 1940, 10, 9, 18, 30, "Liverpool", "GB", perspective_type="Topocentric")
1494
+ topocentric_chart = KerykeionChartSVG(topocentric_subject)
1495
+ topocentric_chart.makeSVG()